From 1d6c08478d453c93b3951514b516066f4e68f458 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 20 Aug 2025 20:40:17 +0300 Subject: [PATCH] LibC: Fix sigsetjmp the call from C sigsetjmp messed up rbp, now sigsetjmp is also written in assembly. I did not test the 32 bit code, just ported the tested 64 bit version over :D --- userspace/libraries/LibC/arch/i686/setjmp.S | 25 +++++++++++++++++-- userspace/libraries/LibC/arch/x86_64/setjmp.S | 18 +++++++++++++ userspace/libraries/LibC/setjmp.cpp | 10 +------- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/userspace/libraries/LibC/arch/i686/setjmp.S b/userspace/libraries/LibC/arch/i686/setjmp.S index cbb318e57d..0779cd4ac9 100644 --- a/userspace/libraries/LibC/arch/i686/setjmp.S +++ b/userspace/libraries/LibC/arch/i686/setjmp.S @@ -19,7 +19,6 @@ setjmp: xorl %eax, %eax ret - .size setjmp, . - setjmp // void longjmp(jmp_buf env, int val) @@ -39,5 +38,27 @@ longjmp: movl 16(%edx), %edi movl 20(%edx), %esi jmp *%ecx - .size longjmp, . - longjmp + +// int sigsetjmp(sigjmp_buf env, int savemask) +.global sigsetjmp +sigsetjmp: + movl 4(%esp), %edx + movl 8(%esp), %ecx + + movl %ecx, 24(%edx) + testl %ecx, %ecx + jz setjmp + + leal 24(%edx), %edx + xorl %ecx, %ecx + + subl $12, %esp + movl %edx, 8(%esp) + movl %ecx, 4(%esp) + movl %ecx, 0(%esp) + call pthread_sigmask + addl $12, %esp + + jmp setjmp + .size sigsetjmp, . - sigsetjmp diff --git a/userspace/libraries/LibC/arch/x86_64/setjmp.S b/userspace/libraries/LibC/arch/x86_64/setjmp.S index da77a1fff7..bd6ed239be 100644 --- a/userspace/libraries/LibC/arch/x86_64/setjmp.S +++ b/userspace/libraries/LibC/arch/x86_64/setjmp.S @@ -38,3 +38,21 @@ longjmp: movq 56(%rdi), %r15 jmp *%rcx .size longjmp, . - longjmp + +// int sigsetjmp(sigjmp_buf env, int savemask) +.global sigsetjmp +sigsetjmp: + movq %rsi, 64(%rdi) + testq %rsi, %rsi + jz setjmp + + subq $8, %rsp + movq %rdi, (%rsp) + leaq 72(%rsi), %rdx + xorq %rsi, %rsi + call pthread_sigmask + movq (%rsp), %rdi + addq $8, %rsp + + jmp setjmp + .size sigsetjmp, . - sigsetjmp diff --git a/userspace/libraries/LibC/setjmp.cpp b/userspace/libraries/LibC/setjmp.cpp index 0774b1b464..1edeec1130 100644 --- a/userspace/libraries/LibC/setjmp.cpp +++ b/userspace/libraries/LibC/setjmp.cpp @@ -7,13 +7,5 @@ void siglongjmp(sigjmp_buf env, int val) { if (env[_JMP_BUF_REGS]) pthread_sigmask(SIG_SETMASK, reinterpret_cast(&env[_JMP_BUF_REGS + 1]), nullptr); - return longjmp(env, val); -} - -int sigsetjmp(sigjmp_buf env, int savemask) -{ - env[_JMP_BUF_REGS] = savemask; - if (savemask) - pthread_sigmask(0, nullptr, reinterpret_cast(&env[_JMP_BUF_REGS + 1])); - return setjmp(env); + longjmp(env, val); }