movl %ecx, JB_SAVEMASK(%eax) // jmpbuf[_JBLEN] = savemask;
cmpl $0, %ecx // if savemask != 0
jne _setjmp // setjmp(jmpbuf);
- BRANCH_EXTERN(__setjmp) // else
- // _setjmp(jmpbuf);
+ jmp L_do__setjmp // else _setjmp(jmpbuf);
LEAF(_setjmp, 0)
+ subl $4, %esp // make space for return from sigprocmask
+ pushl %esp // oset
+ pushl $0 // set = NULL
+ pushl $1 // how = SIG_BLOCK
+ CALL_EXTERN(_sigprocmask)
+ movl 12(%esp),%eax // save the mask
+ addl $16, %esp // restore original esp
movl 4(%esp), %ecx // jmp_buf (struct sigcontext *)
- pushl %ecx // save ecx
-
- // call sigstack to get the current signal stack
- subl $12, %esp // space for return structure
- pushl %esp
- pushl $0
- CALL_EXTERN(_sigaltstack)
- movl 12(%esp), %eax // save stack pointer
- movl %eax, JB_ONSTACK(%ecx)
- addl $20, %esp
-
- // call sigblock to get signal mask
- pushl $0
- CALL_EXTERN(_sigblock)
- addl $4, %esp
- popl %ecx // restore ecx
movl %eax, JB_MASK(%ecx)
-
- // now build sigcontext
- movl %ebx, JB_EBX(%ecx)
- movl %edi, JB_EDI(%ecx)
- movl %esi, JB_ESI(%ecx)
- movl %ebp, JB_EBP(%ecx)
-
- // EIP is set to the frame return address value
- movl (%esp), %eax
- movl %eax, JB_EIP(%ecx)
- // ESP is set to the frame return address plus 4
- movl %esp, %eax
- addl $4, %eax
- movl %eax, JB_ESP(%ecx)
-
- // segment registers
- movl $0, JB_SS(%ecx)
- mov %ss, JB_SS(%ecx)
- movl $0, JB_CS(%ecx)
- mov %cs, JB_CS(%ecx)
- movl $0, JB_DS(%ecx)
- mov %ds, JB_DS(%ecx)
- movl $0, JB_ES(%ecx)
- mov %es, JB_ES(%ecx)
- movl $0, JB_FS(%ecx)
- mov %fs, JB_FS(%ecx)
- movl $0, JB_GS(%ecx)
- mov %gs, JB_GS(%ecx)
-
- // save eflags - you can't use movl
- pushf
- popl %eax
- movl %eax, JB_EFLAGS(%ecx)
-
- // return 0
- xorl %eax, %eax
- ret
+L_do__setjmp:
+ BRANCH_EXTERN(__setjmp)
LEAF(_siglongjmp, 0)
movl 4(%esp), %eax // sigjmp_buf * jmpbuf;
cmpl $0, JB_SAVEMASK(%eax) // if jmpbuf[_JBLEN] != 0
jne _longjmp // longjmp(jmpbuf, var);
- BRANCH_EXTERN(__longjmp) // else
- // _longjmp(jmpbuf, var);
+ jmp L_do__longjmp // else _longjmp(jmpbuf, var);
LEAF(_longjmp, 0)
- subl $2,%esp
- fnstcw (%esp) // save FP control word
- fninit // reset FP coprocessor
- fldcw (%esp) // restore FP control word
- addl $2,%esp
- movl 4(%esp), %eax // address of jmp_buf (saved context)
- movl 8(%esp), %edx // return value
- movl %edx, JB_EAX(%eax) // return value into saved context
- movl $ SYS_sigreturn, %eax // sigreturn system call
- UNIX_SYSCALL_TRAP
- addl $8, %esp
- CALL_EXTERN(_longjmperror)
- CALL_EXTERN(_abort)
+ movl 4(%esp), %ecx // address of jmp_buf (saved context)
+ movl JB_MASK(%ecx),%eax // get the mask
+ pushl %eax // store the mask
+ movl %esp, %edx // save the address where we stored the mask
+ pushl $0 // oset = NULL
+ pushl %edx // set
+ pushl $3 // how = SIG_SETMASK
+ CALL_EXTERN_AGAIN(_sigprocmask)
+ addl $16, %esp // restore original esp
+L_do__longjmp:
+ BRANCH_EXTERN(__longjmp) // else
END(_longjmp)