*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
- *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
#include <architecture/i386/asm_help.h>
-#include "SYS.h"
+#include <SYS.h>
-#define JB_ONSTACK 0
+// The FP control word is actually two bytes, but there's no harm in
+// using four bytes for it and keeping the struct aligned.
+#define JB_FPCW 0
#define JB_MASK 4
-#define JB_EAX 8
+#define JB_MXCSR 8
#define JB_EBX 12
-#define JB_ECX 16
+#define JB_ONSTACK 16
#define JB_EDX 20
#define JB_EDI 24
#define JB_ESI 28
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 $16, %esp // make space for return from sigprocmask
+ // + 12 to align stack
+ pushl %esp // oset
+ pushl $0 // set = NULL
+ pushl $1 // how = SIG_BLOCK
+ CALL_EXTERN(_sigprocmask)
+ movl 12(%esp),%eax // save the mask
+ addl $28, %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)
+ subl $20, %esp // temporary struct sigaltstack + 8 to
+ // align stack
+ pushl %esp // oss
+ pushl $0 // ss == NULL
+ CALL_EXTERN(_sigaltstack) // get alternate signal stack info
+ movl 16(%esp), %eax // oss->ss_flags
+ addl $28, %esp // Restore %esp
+ movl %eax, JB_ONSTACK(%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
+ subl $12, %esp // Make sure the stack is 16-byte
+ // aligned when we call sigprocmask
+ 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 $28, %esp // restore original esp
+
+ movl 4(%esp), %ecx // address of jmp_buf
+ movl JB_ONSTACK(%ecx), %eax // ss_flags
+ subl $8, %esp
+ pushl %eax
+ CALL_EXTERN(__sigunaltstack)
+ addl $12, %esp
+
+L_do__longjmp:
+ BRANCH_EXTERN(__longjmp) // else
END(_longjmp)