1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-18 11:35:06 +00:00
serenity/Userland/Libraries/LibC/arch/i386/setjmp.S
Jean-Baptiste Boric c87aa6d908 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.
2021-08-26 00:54:23 +02:00

82 lines
2 KiB
ArmAsm

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <bits/sighow.h>
//
// /!\ Read setjmp.h before modifying this file!
//
.Lget_pc:
mov (%esp), %ebx
ret
.global setjmp
setjmp:
xor %eax, %eax // Grab val argument (hardcoded to zero)
jmp .Lsigset_common
.global sigsetjmp
sigsetjmp:
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)
mov %edi, (2 * 4)(%ecx)
mov %ebp, (3 * 4)(%ecx)
mov %esp, (4 * 4)(%ecx)
mov %edx, (5 * 4)(%ecx)
xor %eax, %eax
ret
.global longjmp
longjmp:
mov 4(%esp), %ecx // Grab jmp_buf argument
mov 8(%esp), %eax // Grab val argument
test %eax, %eax
jnz .Lnonzero
mov $1, %eax
.Lnonzero:
mov (0 * 4)(%ecx), %ebx // Restore registers
mov (1 * 4)(%ecx), %esi
mov (2 * 4)(%ecx), %edi
mov (3 * 4)(%ecx), %ebp
//
// Until this point, the stack is still from the caller.
//
mov (4 * 4)(%ecx), %esp
mov (5 * 4)(%ecx), %edx
mov %edx, (%esp) // Patch return address
//
// From this point on, the former stack has been restored.
//
ret