summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibC/arch/i386/setjmp.S
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibC/arch/i386/setjmp.S')
-rw-r--r--Userland/Libraries/LibC/arch/i386/setjmp.S77
1 files changed, 55 insertions, 22 deletions
diff --git a/Userland/Libraries/LibC/arch/i386/setjmp.S b/Userland/Libraries/LibC/arch/i386/setjmp.S
index 629d894b97..9178690772 100644
--- a/Userland/Libraries/LibC/arch/i386/setjmp.S
+++ b/Userland/Libraries/LibC/arch/i386/setjmp.S
@@ -4,34 +4,67 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include <bits/sighow.h>
+
+//
+// /!\ Read setjmp.h before modifying this file!
+//
+
.global setjmp
setjmp:
- mov 4(%esp), %eax
- mov %ebx, 0(%eax)
- mov %esi, 4(%eax)
- mov %edi, 8(%eax)
- mov %ebp, 12(%eax)
- lea 4(%esp), %ecx
- mov %ecx, 16(%eax)
- mov (%esp), %ecx
- mov %ecx, 20(%eax)
+ 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 %eax, 24(%ecx) // Store val into did_save_signal_mask
+ movl $0, 28(%ecx) // Clear saved_signal_mask
+ test %eax, %eax
+ jz .Lsaveregs
+
+ lea 28(%ecx), %eax // Set argument oldset
+ push %eax
+ push $0 // Set argument set
+ push $0 // Set argument how
+ call sigprocmask
+ add $12, %esp
+
+.Lsaveregs:
+ 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), %edx
- mov 8(%esp), %eax
- mov 0(%edx), %ebx
- mov 4(%edx), %esi
- mov 8(%edx), %edi
- mov 12(%edx), %ebp
- mov 16(%edx), %ecx
- mov %ecx, %esp
- mov 20(%edx), %ecx
+ mov 4(%esp), %ecx // Grab jmp_buf argument
+ mov 8(%esp), %eax // Grab val argument
test %eax, %eax
- jnz .nonzero
- mov 1, %eax
-.nonzero:
- jmp *%ecx
+ 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