summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Boric <jblbeurope@gmail.com>2021-08-24 20:24:08 +0200
committerAndreas Kling <kling@serenityos.org>2021-08-26 00:54:23 +0200
commitc87aa6d908c8a4c3572d10c984f13a7191150113 (patch)
treee96134690bb080f9c73e7b54262b631f09d17c99
parent04694ae682993b463c1ee7bf540cc62f8765a074 (diff)
downloadserenity-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.S16
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)