*/
#include <architecture/i386/asm_help.h>
-#include <SYS.h>
#define JB_RBX 0
#define JB_RBP 8
#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;
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)
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)