From c87aa6d908c8a4c3572d10c984f13a7191150113 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Boric Date: Tue, 24 Aug 2021 20:24:08 +0200 Subject: [PATCH] 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. --- Userland/Libraries/LibC/arch/i386/setjmp.S | 16 ++++++++++++++-- 1 file 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)