]> git.saurik.com Git - apple/libc.git/blame - sys/sigtramp.c
Libc-825.40.1.tar.gz
[apple/libc.git] / sys / sigtramp.c
CommitLineData
e9ce8d39 1/*
224c7076 2 * Copyright (c) 1999, 2007 Apple Inc. All rights reserved.
e9ce8d39
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
734aad71
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
e9ce8d39
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
734aad71
A
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
e9ce8d39
A
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
25 */
26#import "sigcatch.h"
59e0d9fe 27#import <sys/types.h>
e9ce8d39 28#import <signal.h>
224c7076
A
29#import <strings.h>
30#import <unistd.h>
5b2abdfb 31#import <ucontext.h>
3d9156a7 32#import <mach/thread_status.h>
e9ce8d39 33
224c7076
A
34extern int __sigreturn(ucontext_t *, int);
35
e9ce8d39
A
36/*
37 * sigvec registers _sigtramp as the handler for any signal requiring
38 * user-mode intervention. All _sigtramp does is find the real handler,
39 * calls it, then sigreturn's.
40 *
41 * Note that the kernel saves/restores all of our register state.
42 */
224c7076
A
43
44/* On i386, i386/sys/_sigtramp.s defines this. */
45#if defined(__DYNAMIC__) && ! defined(__i386__)
e9ce8d39
A
46int __in_sigtramp = 0;
47#endif
48
9385eb3d
A
49/* These defn should match the kernel one */
50#define UC_TRAD 1
eb1cde05 51#define UC_FLAVOR 30
59e0d9fe 52#if defined(__ppc__) || defined(__ppc64__)
9385eb3d
A
53#define UC_TRAD64 20
54#define UC_TRAD64_VEC 25
9385eb3d
A
55#define UC_FLAVOR_VEC 35
56#define UC_FLAVOR64 40
57#define UC_FLAVOR64_VEC 45
58#define UC_DUAL 50
59#define UC_DUAL_VEC 55
60
61 /* The following are valid mcontext sizes */
62#define UC_FLAVOR_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
63
64#define UC_FLAVOR_VEC_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
65
66#define UC_FLAVOR64_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
67
68#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
69#endif
70
224c7076
A
71#define UC_SET_ALT_STACK 0x40000000
72#define UC_RESET_ALT_STACK 0x80000000
73
74#if defined(__ppc__)
9385eb3d
A
75/* This routine will be replaced by an assembly soon */
76static int
3d9156a7 77restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle)
9385eb3d
A
78{
79 if (mctx->ss.srr0 != (unsigned int)mctx64->ss.srr0)
80 return(0);
81 if (mctx->ss.srr1 != (unsigned int)mctx64->ss.srr1)
82 return(0);
83 if (mctx->ss.r0 != (unsigned int)mctx64->ss.r0)
84 return(0);
224c7076 85 if (mctx->ss.r1 != (unsigned int)mctx64->ss.r1)
9385eb3d 86 return(0);
224c7076 87 if (mctx->ss.r2 != (unsigned int)mctx64->ss.r2)
9385eb3d 88 return(0);
224c7076 89 if (mctx->ss.r3 != (unsigned int)mctx64->ss.r3)
9385eb3d 90 return(0);
224c7076 91 if (mctx->ss.r4 != (unsigned int)mctx64->ss.r4)
9385eb3d 92 return(0);
224c7076 93 if (mctx->ss.r5 != (unsigned int)mctx64->ss.r5)
9385eb3d 94 return(0);
224c7076 95 if (mctx->ss.r6 != (unsigned int)mctx64->ss.r6)
9385eb3d 96 return(0);
224c7076 97 if (mctx->ss.r7 != (unsigned int)mctx64->ss.r7)
9385eb3d 98 return(0);
224c7076 99 if (mctx->ss.r8 != (unsigned int)mctx64->ss.r8)
9385eb3d 100 return(0);
224c7076 101 if (mctx->ss.r9 != (unsigned int)mctx64->ss.r9)
9385eb3d 102 return(0);
224c7076 103 if (mctx->ss.r10 != (unsigned int)mctx64->ss.r10)
9385eb3d 104 return(0);
224c7076 105 if (mctx->ss.r11 != (unsigned int)mctx64->ss.r11)
9385eb3d 106 return(0);
224c7076 107 if (mctx->ss.r12 != (unsigned int)mctx64->ss.r12)
9385eb3d 108 return(0);
224c7076 109 if (mctx->ss.r13 != (unsigned int)mctx64->ss.r13)
9385eb3d 110 return(0);
224c7076 111 if (mctx->ss.r14 != (unsigned int)mctx64->ss.r14)
9385eb3d 112 return(0);
224c7076 113 if (mctx->ss.r15 != (unsigned int)mctx64->ss.r15)
9385eb3d 114 return(0);
224c7076 115 if (mctx->ss.r16 != (unsigned int)mctx64->ss.r16)
9385eb3d 116 return(0);
224c7076 117 if (mctx->ss.r17 != (unsigned int)mctx64->ss.r17)
9385eb3d 118 return(0);
224c7076 119 if (mctx->ss.r18 != (unsigned int)mctx64->ss.r18)
9385eb3d 120 return(0);
224c7076 121 if (mctx->ss.r19 != (unsigned int)mctx64->ss.r19)
9385eb3d 122 return(0);
224c7076 123 if (mctx->ss.r20 != (unsigned int)mctx64->ss.r20)
9385eb3d 124 return(0);
224c7076 125 if (mctx->ss.r21 != (unsigned int)mctx64->ss.r21)
9385eb3d
A
126 return(0);
127 if (mctx->ss.r22 != (unsigned int)mctx64->ss.r22)
128 return(0);
129 if (mctx->ss.r23 != (unsigned int)mctx64->ss.r23)
130 return(0);
131 if (mctx->ss.r24 != (unsigned int)mctx64->ss.r24)
132 return(0);
133 if (mctx->ss.r25 != (unsigned int)mctx64->ss.r25)
134 return(0);
135 if (mctx->ss.r26 != (unsigned int)mctx64->ss.r26)
136 return(0);
137 if (mctx->ss.r27 != (unsigned int)mctx64->ss.r27)
138 return(0);
139 if (mctx->ss.r28 != (unsigned int)mctx64->ss.r28)
140 return(0);
141 if (mctx->ss.r29 != (unsigned int)mctx64->ss.r29)
142 return(0);
143 if (mctx->ss.r30 != (unsigned int)mctx64->ss.r30)
144 return(0);
145 if (mctx->ss.r31 != (unsigned int)mctx64->ss.r31)
146 return(0);
147
148 if (mctx->ss.cr != mctx64->ss.cr)
149 return(0);
150 if (mctx->ss.xer != (unsigned int)mctx64->ss.xer)
151 return(0);
152 if (mctx->ss.lr != (unsigned int)mctx64->ss.lr)
153 return(0);
154 if (mctx->ss.ctr != (unsigned int)mctx64->ss.ctr)
155 return(0);
156
224c7076 157 if (bcmp(&mctx->fs, &mctx64->fs, (PPC_FLOAT_STATE_COUNT * sizeof(int))))
3d9156a7
A
158 return(0);
159 if ((sigstyle == UC_DUAL_VEC) && bcmp(&mctx->vs, &mctx64->vs, (PPC_VECTOR_STATE_COUNT * sizeof(int))))
160 return(0);
161
9385eb3d
A
162 return(1);
163
164}
165
224c7076
A
166/* This routine is called from ppc/sys/_sigtramp.s on return from
167 sa_handler. */
9385eb3d 168
e9ce8d39 169void
224c7076
A
170__finish_sigtramp(
171 ucontext_t *uctx,
172 int sigstyle
e9ce8d39 173) {
f74c7596 174 int ctxstyle = UC_FLAVOR;
9385eb3d
A
175 mcontext_t mctx;
176 mcontext64_t mctx64;
9385eb3d 177
9385eb3d
A
178 if ((sigstyle == UC_DUAL) || (sigstyle == UC_DUAL_VEC)) {
179 mctx = uctx->uc_mcontext;
180 mctx64 = (mcontext64_t)((char *)(uctx->uc_mcontext) + sizeof(struct mcontext));
181 /* restore 64bit state ? */
3d9156a7 182 if (restore64_state(mctx, mctx64, sigstyle)) {
9385eb3d
A
183 uctx->uc_mcontext = (void *)mctx64;
184 if (sigstyle == UC_DUAL) {
185 uctx->uc_mcsize = UC_FLAVOR64_SIZE;
186 ctxstyle = UC_FLAVOR64;
187 } else {
188 uctx->uc_mcsize = UC_FLAVOR64_VEC_SIZE;
189 ctxstyle = UC_FLAVOR64_VEC;
190 }
191 } else {
192 if (sigstyle == UC_DUAL)
193 ctxstyle = UC_FLAVOR;
194 else
195 ctxstyle = UC_FLAVOR_VEC;
196 }
197 } else
198 ctxstyle = sigstyle;
224c7076
A
199
200#if defined(__DYNAMIC__)
201 __in_sigtramp--;
202#endif
203
204 __sigreturn (uctx, ctxstyle);
205}
206
207#endif /* ppc */
208
209/*
210 * Reset the kernel's idea of the use of an alternate stack; this is used by
211 * both longjmp() and siglongjmp(). Nothing other than this reset is needed,
212 * since restoring the registers and other operations that would normally be
213 * done by sigreturn() are handled in user space, so we do not pass a user
214 * context (in PPC, a user context is not the same as a jmpbuf mcontext, due
215 * to having more than one set of registers, etc., for the various 32/64 etc.
216 * contexts)..
217 */
218void
219_sigunaltstack(int set)
220{
221 /* sigreturn(uctx, ctxstyle); */
222 /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */
223 __sigreturn (NULL, (set == SS_ONSTACK) ? UC_SET_ALT_STACK : UC_RESET_ALT_STACK);
224}
225
226/* On these architectures, _sigtramp is implemented in assembly to
227 ensure it matches its DWARF unwind information. */
228#if ! defined (__ppc__) && ! defined (__ppc64__) && ! defined (__i386__) \
229 && ! defined (__x86_64__)
230
231void
232_sigtramp(
233 union __sigaction_u __sigaction_u,
234 int sigstyle,
235 int sig,
236 siginfo_t *sinfo,
237 ucontext_t *uctx
238) {
239 int ctxstyle = UC_FLAVOR;
240
241#if defined(__DYNAMIC__)
242 __in_sigtramp++;
243#endif
244
245 if (sigstyle == UC_TRAD)
246 sa_handler(sig);
247 else {
248 sa_sigaction(sig, sinfo, uctx);
249 }
9385eb3d 250
e9ce8d39
A
251#if defined(__DYNAMIC__)
252 __in_sigtramp--;
253#endif
9385eb3d
A
254 /* sigreturn(uctx, ctxstyle); */
255 /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */
224c7076 256 __sigreturn (uctx, ctxstyle);
e9ce8d39 257}
9385eb3d 258
224c7076 259#endif /* not ppc nor ppc64 nor i386 nor x86_64 */