diff --git a/src/system/kernel/lib/Jamfile b/src/system/kernel/lib/Jamfile index 4a4e24bc3b..49f0a2f07e 100644 --- a/src/system/kernel/lib/Jamfile +++ b/src/system/kernel/lib/Jamfile @@ -132,6 +132,7 @@ SEARCH_SOURCE += [ FDirName $(posixSources) string arch $(TARGET_ARCH) ] ; KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o : siglongjmp.S sigsetjmp.S + kernel_longjmp_return.c kernel_setjmp_save_sigs.c arch_string.S # TODO: Not needed for X86! diff --git a/src/system/kernel/lib/kernel_longjmp_return.c b/src/system/kernel/lib/kernel_longjmp_return.c new file mode 100644 index 0000000000..84f51ecb79 --- /dev/null +++ b/src/system/kernel/lib/kernel_longjmp_return.c @@ -0,0 +1,17 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include + + +/*! This function is called by [sig]longjmp(). */ + +int __longjmp_return(jmp_buf buffer, int value); + +int +__longjmp_return(jmp_buf buffer, int value) +{ + return (value == 0 ? 1 : value); +} diff --git a/src/system/libroot/posix/arch/x86/Jamfile b/src/system/libroot/posix/arch/x86/Jamfile index 07225f0140..df57fe9c91 100644 --- a/src/system/libroot/posix/arch/x86/Jamfile +++ b/src/system/libroot/posix/arch/x86/Jamfile @@ -1,9 +1,8 @@ SubDir HAIKU_TOP src system libroot posix arch x86 ; -# TODO: siglongjmp.S should use __longjmp_return to restore the signal mask. local genericSources = setjmp_save_sigs.c -# longjmp_return.c + longjmp_return.c ; MergeObject posix_arch_$(TARGET_ARCH).o : diff --git a/src/system/libroot/posix/arch/x86/siglongjmp.S b/src/system/libroot/posix/arch/x86/siglongjmp.S index 022890131c..63c0533e1c 100644 --- a/src/system/libroot/posix/arch/x86/siglongjmp.S +++ b/src/system/libroot/posix/arch/x86/siglongjmp.S @@ -3,7 +3,6 @@ ** Distributed under the terms of the Haiku License. */ - #include "setjmp_internal.h" @@ -19,12 +18,6 @@ FUNCTION(_longjmp): mov 4(%esp), %ecx mov 8(%esp), %eax - /* If value is 0, setjmp() must return 1. */ - test %eax, %eax - jnz 1f - mov $1, %eax -1: - // restore registers mov JMP_REGS_EBX(%ecx), %ebx mov JMP_REGS_ESI(%ecx), %esi @@ -32,8 +25,17 @@ FUNCTION(_longjmp): mov JMP_REGS_EBP(%ecx), %ebp mov JMP_REGS_ESP(%ecx), %esp - // jump back to the old program location + // prepare the stack so that we will return to the setjmp() program location mov JMP_REGS_PC(%ecx), %edx - jmp *%edx + push %edx // return address + + // let __setjmp_save_sigs deal with the signal mask and the return value + push %eax // value + push %ecx // buffer + call __longjmp_return + add $8, %esp + + ret + #pragma weak longjmp=siglongjmp