/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* 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
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
*/
/*
* NeXT 386 setjmp/longjmp
*
* Written by Bruce Martin, NeXT Inc. 4/9/92
*/
/*
* C library -- setjmp, longjmp
*
* longjmp(a,v)
* will generate a "return(v)" from
* the last call to
* setjmp(a)
* by restoring registers from the stack,
* The previous value of the signal mask is
* restored.
*
*/
#include <architecture/i386/asm_help.h>
#define JB_RBX 0
#define JB_RBP 8
#define JB_RSP 16
#define JB_R12 24
#define JB_R13 32
#define JB_R14 40
#define JB_R15 48
#define JB_RIP 56
#define JB_RFLAGS 64
#define JB_MXCSR 72
#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 movl %esi, JB_SAVEMASK(%rdi) // jmpbuf[_JBLEN] = savemask jne _setjmp // setjmp(jmpbuf)
LEAF(_setjmp, 0)
pushq %rdi // Preserve the jmp_buf across the call
movl $1, %edi // how = SIG_BLOCK
xorq %rsi, %rsi // set = NULL
subq $16, %rsp // Allocate space for the return from sigprocmask + 8 to align stack
movq %rsp, %rdx // oset = allocated space
CALL_EXTERN(_sigprocmask)
popq %rax // Save the mask
addq $8, %rsp // Restore the stack to before we align it
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)
LEAF(_siglongjmp, 0)
// %rdi is sigjmp_buf * jmpbuf jne _longjmp // longjmp(jmpbuf, var)
LEAF(_longjmp, 0)
// %rdi is address of jmp_buf (saved context)
pushq %rdi // Preserve the jmp_buf across the call
pushq %rsi // Preserve the value across the call
pushq JB_MASK(%rdi) // Put the mask on the stack
movq $3, %rdi // how = SIG_SETMASK
movq %rsp, %rsi // set = address where we stored the mask
xorq %rdx, %rdx // oset = NULL
CALL_EXTERN_AGAIN(_sigprocmask)
// 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)