diff options
author | Jean-Baptiste Boric <jblbeurope@gmail.com> | 2021-08-24 20:24:08 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-26 00:54:23 +0200 |
commit | c87aa6d908c8a4c3572d10c984f13a7191150113 (patch) | |
tree | e96134690bb080f9c73e7b54262b631f09d17c99 | |
parent | 04694ae682993b463c1ee7bf540cc62f8765a074 (diff) | |
download | serenity-c87aa6d908c8a4c3572d10c984f13a7191150113.zip |
LibC: Fix sigsetjmp on i686
Calling sigprocmask() through the PLT requires setting the ebx register
to the address of the global offset table, otherwise chaos ensues. Also
the value of the ecx register was assumed to be preserved across that
function call despite the fact that it is caller-saved in the x86
calling convention.
-rw-r--r-- | Userland/Libraries/LibC/arch/i386/setjmp.S | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/Userland/Libraries/LibC/arch/i386/setjmp.S b/Userland/Libraries/LibC/arch/i386/setjmp.S index 9fc704a884..27c934f80e 100644 --- a/Userland/Libraries/LibC/arch/i386/setjmp.S +++ b/Userland/Libraries/LibC/arch/i386/setjmp.S @@ -10,31 +10,43 @@ // /!\ Read setjmp.h before modifying this file! // +.Lget_pc: + mov (%esp), %ebx + ret + .global setjmp setjmp: - mov 4(%esp), %ecx // Grab jmp_buf argument xor %eax, %eax // Grab val argument (hardcoded to zero) jmp .Lsigset_common .global sigsetjmp sigsetjmp: - mov 4(%esp), %ecx // Grab jmp_buf argument mov 8(%esp), %eax // Grab val argument .Lsigset_common: + mov 4(%esp), %ecx // Grab jmp_buf argument mov %eax, 24(%ecx) // Store val into did_save_signal_mask movl $0, 28(%ecx) // Clear saved_signal_mask test %eax, %eax jz .Lsaveregs + push %ebp // Prepare ABI-compliant call to sigprocmask + mov %esp, %ebp + push %ebx + call .Lget_pc // Grab the GOT pointer + addl $_GLOBAL_OFFSET_TABLE_, %ebx + lea 28(%ecx), %eax // Set argument oldset push %eax push $0 // Set argument set push $0 // Set argument how call sigprocmask@plt add $12, %esp + pop %ebx + pop %ebp .Lsaveregs: + mov 4(%esp), %ecx // Grab jmp_buf argument mov (%esp), %edx // Grab return address mov %ebx, (0 * 4)(%ecx) // Save registers mov %esi, (1 * 4)(%ecx) |