X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/3d9156a7a519a5e3aa1b92e9d9d4b991f1aed7ff..ad3c9f2af814c84582fdd1649e49ec4f68572c5a:/sys/sigtramp.c diff --git a/sys/sigtramp.c b/sys/sigtramp.c index b387329..74f4963 100644 --- a/sys/sigtramp.c +++ b/sys/sigtramp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -26,9 +26,13 @@ #import "sigcatch.h" #import #import +#import +#import #import #import +extern int __sigreturn(ucontext_t *, int); + /* * sigvec registers _sigtramp as the handler for any signal requiring * user-mode intervention. All _sigtramp does is find the real handler, @@ -36,16 +40,18 @@ * * Note that the kernel saves/restores all of our register state. */ -#if defined(__DYNAMIC__) + +/* On i386, i386/sys/_sigtramp.s defines this. */ +#if defined(__DYNAMIC__) && ! defined(__i386__) int __in_sigtramp = 0; #endif /* These defn should match the kernel one */ #define UC_TRAD 1 +#define UC_FLAVOR 30 #if defined(__ppc__) || defined(__ppc64__) #define UC_TRAD64 20 #define UC_TRAD64_VEC 25 -#define UC_FLAVOR 30 #define UC_FLAVOR_VEC 35 #define UC_FLAVOR64 40 #define UC_FLAVOR64_VEC 45 @@ -62,7 +68,10 @@ int __in_sigtramp = 0; #define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) #endif -#if defined(__ppc__) || defined(__ppc64__) +#define UC_SET_ALT_STACK 0x40000000 +#define UC_RESET_ALT_STACK 0x80000000 + +#if defined(__ppc__) /* This routine will be replaced by an assembly soon */ static int restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) @@ -73,47 +82,47 @@ restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) return(0); if (mctx->ss.r0 != (unsigned int)mctx64->ss.r0) return(0); - if (mctx->ss.r1 != (unsigned int)mctx->ss.r1) + if (mctx->ss.r1 != (unsigned int)mctx64->ss.r1) return(0); - if (mctx->ss.r2 != (unsigned int)mctx->ss.r2) + if (mctx->ss.r2 != (unsigned int)mctx64->ss.r2) return(0); - if (mctx->ss.r3 != (unsigned int)mctx->ss.r3) + if (mctx->ss.r3 != (unsigned int)mctx64->ss.r3) return(0); - if (mctx->ss.r4 != (unsigned int)mctx->ss.r4) + if (mctx->ss.r4 != (unsigned int)mctx64->ss.r4) return(0); - if (mctx->ss.r5 != (unsigned int)mctx->ss.r5) + if (mctx->ss.r5 != (unsigned int)mctx64->ss.r5) return(0); - if (mctx->ss.r6 != (unsigned int)mctx->ss.r6) + if (mctx->ss.r6 != (unsigned int)mctx64->ss.r6) return(0); - if (mctx->ss.r7 != (unsigned int)mctx->ss.r7) + if (mctx->ss.r7 != (unsigned int)mctx64->ss.r7) return(0); - if (mctx->ss.r8 != (unsigned int)mctx->ss.r8) + if (mctx->ss.r8 != (unsigned int)mctx64->ss.r8) return(0); - if (mctx->ss.r9 != (unsigned int)mctx->ss.r9) + if (mctx->ss.r9 != (unsigned int)mctx64->ss.r9) return(0); - if (mctx->ss.r10 != (unsigned int)mctx->ss.r10) + if (mctx->ss.r10 != (unsigned int)mctx64->ss.r10) return(0); - if (mctx->ss.r11 != (unsigned int)mctx->ss.r11) + if (mctx->ss.r11 != (unsigned int)mctx64->ss.r11) return(0); - if (mctx->ss.r12 != (unsigned int)mctx->ss.r12) + if (mctx->ss.r12 != (unsigned int)mctx64->ss.r12) return(0); - if (mctx->ss.r13 != (unsigned int)mctx->ss.r13) + if (mctx->ss.r13 != (unsigned int)mctx64->ss.r13) return(0); - if (mctx->ss.r14 != (unsigned int)mctx->ss.r14) + if (mctx->ss.r14 != (unsigned int)mctx64->ss.r14) return(0); - if (mctx->ss.r15 != (unsigned int)mctx->ss.r15) + if (mctx->ss.r15 != (unsigned int)mctx64->ss.r15) return(0); - if (mctx->ss.r16 != (unsigned int)mctx->ss.r16) + if (mctx->ss.r16 != (unsigned int)mctx64->ss.r16) return(0); - if (mctx->ss.r17 != (unsigned int)mctx->ss.r17) + if (mctx->ss.r17 != (unsigned int)mctx64->ss.r17) return(0); - if (mctx->ss.r18 != (unsigned int)mctx->ss.r18) + if (mctx->ss.r18 != (unsigned int)mctx64->ss.r18) return(0); - if (mctx->ss.r19 != (unsigned int)mctx->ss.r19) + if (mctx->ss.r19 != (unsigned int)mctx64->ss.r19) return(0); - if (mctx->ss.r20 != (unsigned int)mctx->ss.r20) + if (mctx->ss.r20 != (unsigned int)mctx64->ss.r20) return(0); - if (mctx->ss.r21 != (unsigned int)mctx->ss.r21) + if (mctx->ss.r21 != (unsigned int)mctx64->ss.r21) return(0); if (mctx->ss.r22 != (unsigned int)mctx64->ss.r22) return(0); @@ -145,7 +154,7 @@ restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) if (mctx->ss.ctr != (unsigned int)mctx64->ss.ctr) return(0); - if (bcmp(&mctx->fs, &mctx64->ss, (PPC_FLOAT_STATE_COUNT * sizeof(int)))) + if (bcmp(&mctx->fs, &mctx64->fs, (PPC_FLOAT_STATE_COUNT * sizeof(int)))) return(0); if ((sigstyle == UC_DUAL_VEC) && bcmp(&mctx->vs, &mctx64->vs, (PPC_VECTOR_STATE_COUNT * sizeof(int)))) return(0); @@ -154,35 +163,18 @@ restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) } -#endif +/* This routine is called from ppc/sys/_sigtramp.s on return from + sa_handler. */ void -_sigtramp( - union __sigaction_u __sigaction_u, - int sigstyle, - int sig, - siginfo_t *sinfo, - ucontext_t *uctx +__finish_sigtramp( + ucontext_t *uctx, + int sigstyle ) { -#if defined(__ppc__) || defined(__ppc64__) int ctxstyle = UC_FLAVOR; -#endif mcontext_t mctx; mcontext64_t mctx64; -#if defined(__DYNAMIC__) - __in_sigtramp++; -#endif -#ifdef __i386__ - if (sigstyle == UC_TRAD) - sa_handler(sig); -#elif defined(__ppc__) || defined(__ppc64__) - if ((sigstyle == UC_TRAD) || (sigstyle == UC_TRAD64) || (sigstyle == UC_TRAD64_VEC)) - sa_handler(sig); - - else - sa_sigaction(sig, sinfo, uctx); - if ((sigstyle == UC_DUAL) || (sigstyle == UC_DUAL_VEC)) { mctx = uctx->uc_mcontext; mctx64 = (mcontext64_t)((char *)(uctx->uc_mcontext) + sizeof(struct mcontext)); @@ -204,19 +196,64 @@ _sigtramp( } } else ctxstyle = sigstyle; -#endif /* __ppc__ || __ppc64__ */ #if defined(__DYNAMIC__) __in_sigtramp--; #endif -#if defined(__ppc__) || defined(__ppc64__) - { + + __sigreturn (uctx, ctxstyle); +} + +#endif /* ppc */ + +/* + * Reset the kernel's idea of the use of an alternate stack; this is used by + * both longjmp() and siglongjmp(). Nothing other than this reset is needed, + * since restoring the registers and other operations that would normally be + * done by sigreturn() are handled in user space, so we do not pass a user + * context (in PPC, a user context is not the same as a jmpbuf mcontext, due + * to having more than one set of registers, etc., for the various 32/64 etc. + * contexts).. + */ +void +_sigunaltstack(int set) +{ /* sigreturn(uctx, ctxstyle); */ /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ - syscall (184, uctx, ctxstyle); + __sigreturn (NULL, (set == SS_ONSTACK) ? UC_SET_ALT_STACK : UC_RESET_ALT_STACK); +} + +/* On these architectures, _sigtramp is implemented in assembly to + ensure it matches its DWARF unwind information. */ +#if ! defined (__ppc__) && ! defined (__ppc64__) && ! defined (__i386__) \ + && ! defined (__x86_64__) + +void +_sigtramp( + union __sigaction_u __sigaction_u, + int sigstyle, + int sig, + siginfo_t *sinfo, + ucontext_t *uctx +) { + int ctxstyle = UC_FLAVOR; + +#if defined(__DYNAMIC__) + __in_sigtramp++; +#endif + + if (sigstyle == UC_TRAD) + sa_handler(sig); + else { + sa_sigaction(sig, sinfo, uctx); } -#else - sigreturn(uctx); -#endif /* __ppc__ || __ppc64__ */ + +#if defined(__DYNAMIC__) + __in_sigtramp--; +#endif + /* sigreturn(uctx, ctxstyle); */ + /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ + __sigreturn (uctx, ctxstyle); } +#endif /* not ppc nor ppc64 nor i386 nor x86_64 */