X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/734aad71947a79037af64f74c683f5eb36fe6065..224c70764cab4e0e39a26aaf3ad3016552f62f55:/i386/sys/setjmp.s diff --git a/i386/sys/setjmp.s b/i386/sys/setjmp.s index 72d6bff..461470a 100644 --- a/i386/sys/setjmp.s +++ b/i386/sys/setjmp.s @@ -3,8 +3,6 @@ * * @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 @@ -45,13 +43,15 @@ */ #include -#include "SYS.h" +#include -#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 @@ -73,85 +73,58 @@ LEAF(_sigsetjmp, 0) 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)