]> git.saurik.com Git - apple/libc.git/blobdiff - x86_64/sys/setjmp.s
Libc-825.40.1.tar.gz
[apple/libc.git] / x86_64 / sys / setjmp.s
index 586608621a43c57d361c362dd3e6b2143ffbd60c..3f466013f199104c3b0b97376c08dfc7253aadd8 100644 (file)
@@ -43,7 +43,6 @@
  */
 
 #include <architecture/i386/asm_help.h>
-#include <SYS.h>
 
 #define JB_RBX                 0
 #define JB_RBP                 8
@@ -58,7 +57,9 @@
 #define JB_FPCONTROL   76
 #define JB_MASK                        80
 #define JB_SAVEMASK            84              // sigsetjmp/siglongjmp only
+#define JB_ONSTACK             88      
 
+#define STACK_SSFLAGS          16              // offsetof(stack_t, ss_flags)
 
 LEAF(_sigsetjmp, 0)
        // %rdi is sigjmp_buf * jmpbuf;
@@ -77,8 +78,19 @@ LEAF(_setjmp, 0)
        CALL_EXTERN(_sigprocmask)
        popq    %rax                    // Save the mask
        addq    $8, %rsp                // Restore the stack to before we align it
-       popq    %rdi                    // jmp_buf (struct sigcontext *)
-       movq    %rax, JB_MASK(%rdi)
+       movq    (%rsp), %rdi            // jmp_buf (struct sigcontext *).  Leave pointer on the stack for _sigaltstack call)
+       movl    %eax, JB_MASK(%rdi)
+
+       // Get current sigaltstack status (stack_t)
+       subq    $32, %rsp                       // 24 bytes for a stack_t, + 8 for the jmp_buf pointer, + 8 is correctly aligned
+       movq    %rsp, %rsi                      // oss
+       xorq    %rdi, %rdi                      // ss == NULL
+       CALL_EXTERN(_sigaltstack)               // sigaltstack(NULL, oss)
+       movl    STACK_SSFLAGS(%rsp), %eax       // oss.ss_flags
+       movq    32(%rsp), %rdi                  // jmpbuf (will be first argument to subsequent call)
+       movl    %eax, JB_ONSTACK(%rdi)          // Store ss_flags in jmpbuf
+       addq    $40, %rsp                       // restore %rsp
+
 L_do__setjmp:
        BRANCH_EXTERN(__setjmp)
 
@@ -97,9 +109,15 @@ LEAF(_longjmp, 0)
        movq    %rsp, %rsi                      // set = address where we stored the mask
        xorq    %rdx, %rdx                      // oset = NULL
        CALL_EXTERN_AGAIN(_sigprocmask)
-       addq    $8, %rsp
-       popq    %rsi                            // Restore the value
-       popq    %rdi                            // Restore the jmp_buf
+       
+       // Restore sigaltstack status
+       movq    16(%rsp), %rdi                  // Grab jmpbuf but leave it on the stack
+       movl    JB_ONSTACK(%rdi), %edi          // Pass old state to _sigunaltstack()
+       CALL_EXTERN(__sigunaltstack)
+       addq    $8, %rsp                        // Restore stack
+       popq    %rsi
+       popq    %rdi                            // Pass jmpbuf to _longjmp
+
 L_do__longjmp:
        BRANCH_EXTERN(__longjmp)        // else
 END(_longjmp)