1 /* Fallback frame-state unwinder for Darwin.
2 Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combined
20 GCC is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
23 License for more details.
25 You should have received a copy of the GNU General Public License
26 along with GCC; see the file COPYING. If not, write to the Free
27 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "coretypes.h"
38 #include "unwind-dw2.h"
41 #include <sys/types.h>
44 typedef unsigned long reg_unit;
46 /* Place in GPRS the parameters to the first 'sc' instruction that would
47 have been executed if we were returning from this CONTEXT, or
48 return false if an unexpected instruction is encountered. */
51 interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
53 uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
55 reg_unit lr = (reg_unit) pc;
57 uint32_t *invalid_address = NULL;
61 for (i = 0; i < 13; i++)
63 gprs[1] = _Unwind_GetCFA (context);
65 gprs[i] = _Unwind_GetGR (context, i);
66 cr = _Unwind_GetGR (context, CR2_REGNO);
68 /* For each supported Libc, we have to track the code flow
69 all the way back into the kernel.
71 This code is believed to support all released Libc/Libsystem builds since
72 Jaguar 6C115, including all the security updates. To be precise,
74 Libc Libsystem Build(s)
81 262.4.1~1 63~84 6L123-6R172
83 320~1 71~101 7B85-7D28
84 320~1 71~266 7F54-7F56
87 320.1.3~1 71.1.1~29 7H60-7H105
88 320.1.3~1 71.1.1~30 7H110-7H113
89 320.1.3~1 71.1.1~31 7H114
91 That's a big table! It would be insane to try to keep track of
92 every little detail, so we just read the code itself and do what
100 if ((ins & 0xFC000003) == 0x48000000) /* b instruction */
102 pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
105 if ((ins & 0xFC600000) == 0x2C000000) /* cmpwi */
107 int32_t val1 = (int16_t) ins;
108 int32_t val2 = gprs[ins >> 16 & 0x1F];
109 /* Only beq and bne instructions are supported, so we only
110 need to set the EQ bit. */
111 uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
118 if ((ins & 0xFEC38003) == 0x40820000) /* forwards beq/bne */
120 if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
121 pc += (ins & 0x7FFC) / 4 - 1;
124 if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
126 gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
127 | gprs [ins >> 21 & 0x1F]);
130 if (ins >> 26 == 0x0E) /* addi, including li */
132 reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
133 gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
136 if (ins >> 26 == 0x0F) /* addis, including lis */
138 reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
139 gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
142 if (ins >> 26 == 0x20) /* lwz */
144 reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
145 uint32_t *p = (uint32_t *)(src + (int16_t) ins);
146 if (p == invalid_address)
148 gprs [ins >> 21 & 0x1F] = *p;
151 if (ins >> 26 == 0x21) /* lwzu */
153 uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
154 if (p == invalid_address)
156 gprs [ins >> 21 & 0x1F] = *p;
159 if (ins >> 26 == 0x24) /* stw */
160 /* What we hope this is doing is '--in_sigtramp'. We don't want
161 to actually store to memory, so just make a note of the
162 address and refuse to load from it. */
164 reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
165 uint32_t *p = (uint32_t *)(src + (int16_t) ins);
166 if (p == NULL || invalid_address != NULL)
171 if (ins >> 26 == 0x2E) /* lmw */
173 reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
174 uint32_t *p = (uint32_t *)(src + (int16_t) ins);
177 for (i = (ins >> 21 & 0x1F); i < 32; i++)
179 if (p == invalid_address)
185 if ((ins & 0xFC1FFFFF) == 0x7c0803a6) /* mtlr */
187 lr = gprs [ins >> 21 & 0x1F];
190 if ((ins & 0xFC1FFFFF) == 0x7c0802a6) /* mflr */
192 gprs [ins >> 21 & 0x1F] = lr;
195 if ((ins & 0xFC1FFFFF) == 0x7c0903a6) /* mtctr */
197 ctr = gprs [ins >> 21 & 0x1F];
200 /* The PowerPC User's Manual says that bit 11 of the mtcrf
201 instruction is reserved and should be set to zero, but it
202 looks like the Darwin assembler doesn't do that... */
203 if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
207 for (i = 0; i < 8; i++)
208 mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
209 cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
212 if (ins == 0x429f0005) /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
217 if (ins == 0x4e800420) /* bctr */
219 pc = (uint32_t *) ctr;
222 if (ins == 0x44000002) /* sc */
229 /* We used to include <ucontext.h> and <mach/thread_status.h>,
230 but they change so much between different Darwin system versions
231 that it's much easier to just write the structures involved here
234 /* These defines are from the kernel's bsd/dev/ppc/unix_signal.c. */
236 #define UC_TRAD_VEC 6
238 #define UC_TRAD64_VEC 25
240 #define UC_FLAVOR_VEC 35
241 #define UC_FLAVOR64 40
242 #define UC_FLAVOR64_VEC 45
244 #define UC_DUAL_VEC 55
253 struct gcc_ucontext *link;
255 struct gcc_mcontext32 *mcontext;
258 struct gcc_float_vector_state
263 uint32_t save_vr[32][4];
264 uint32_t save_vscr[4];
267 struct gcc_mcontext32 {
271 uint32_t padding1[5];
281 struct gcc_float_vector_state fvs;
284 /* These are based on /usr/include/ppc/ucontext.h and
285 /usr/include/mach/ppc/thread_status.h, but rewritten to be more
286 convenient, to compile on Jaguar, and to work around Radar 3712064
287 on Panther, which is that the 'es' field of 'struct mcontext64' has
288 the wrong type (doh!). */
290 struct gcc_mcontext64 {
294 uint32_t padding1[4];
299 uint32_t xer[2]; /* These are arrays because the original structure has them misaligned. */
303 struct gcc_float_vector_state fvs;
306 #define UC_FLAVOR_SIZE \
307 (sizeof (struct gcc_mcontext32) - 33*16)
309 #define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32))
311 #define UC_FLAVOR64_SIZE \
312 (sizeof (struct gcc_mcontext64) - 33*16)
314 #define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64))
316 /* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS
317 to represent the execution of a signal return; or, if not a signal
318 return, return false. */
321 handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32],
324 struct gcc_ucontext *uctx;
325 bool is_64, is_vector;
326 struct gcc_float_vector_state * float_vector_state;
329 static _Unwind_Ptr return_addr;
331 /* Yay! We're in a Libc that we understand, and it's made a
332 system call. In Jaguar, this is a direct system call with value 103;
333 in Panther and Tiger it is a SYS_syscall call for system call number 184,
334 and in Leopard it is a direct syscall with number 184. */
336 if (gprs[0] == 0x67 /* SYS_SIGRETURN */)
338 uctx = (struct gcc_ucontext *) gprs[3];
339 is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
340 || uctx->mcsize == UC_FLAVOR_VEC_SIZE);
341 is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
342 || uctx->mcsize == UC_FLAVOR64_SIZE);
344 else if (gprs[0] == 0 /* SYS_syscall */ && gprs[3] == 184)
346 int ctxstyle = gprs[5];
347 uctx = (struct gcc_ucontext *) gprs[4];
348 is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
349 || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
350 is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
351 || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
353 else if (gprs[0] == 184 /* SYS_sigreturn */)
355 int ctxstyle = gprs[4];
356 uctx = (struct gcc_ucontext *) gprs[3];
357 is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
358 || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
359 is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
360 || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
365 #define set_offset(r, addr) \
366 (fs->regs.reg[r].how = REG_SAVED_OFFSET, \
367 fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa)
369 /* Restore even the registers that are not call-saved, since they
370 might be being used in the prologue to save other registers,
371 for instance GPR0 is sometimes used to save LR. */
373 /* Handle the GPRs, and produce the information needed to do the rest. */
376 /* The context is 64-bit, but it doesn't carry any extra information
377 for us because only the low 32 bits of the registers are
379 struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext;
382 float_vector_state = &m64->fvs;
384 new_cfa = m64->gpr[1][1];
386 set_offset (CR2_REGNO, &m64->cr);
387 for (i = 0; i < 32; i++)
388 set_offset (i, m64->gpr[i] + 1);
389 set_offset (XER_REGNO, m64->xer + 1);
390 set_offset (LINK_REGISTER_REGNUM, m64->lr + 1);
391 set_offset (COUNT_REGISTER_REGNUM, m64->ctr + 1);
393 set_offset (VRSAVE_REGNO, &m64->vrsave);
395 /* Sometimes, srr0 points to the instruction that caused the exception,
396 and sometimes to the next instruction to be executed; we want
398 if (m64->exception == 3 || m64->exception == 4
399 || m64->exception == 6
400 || (m64->exception == 7 && !(m64->srr1 & 0x10000)))
401 return_addr = m64->srr0 + 4;
403 return_addr = m64->srr0;
407 struct gcc_mcontext32 *m = uctx->mcontext;
410 float_vector_state = &m->fvs;
414 set_offset (CR2_REGNO, &m->cr);
415 for (i = 0; i < 32; i++)
416 set_offset (i, m->gpr + i);
417 set_offset (XER_REGNO, &m->xer);
418 set_offset (LINK_REGISTER_REGNUM, &m->lr);
419 set_offset (COUNT_REGISTER_REGNUM, &m->ctr);
422 set_offset (VRSAVE_REGNO, &m->vrsave);
424 /* Sometimes, srr0 points to the instruction that caused the exception,
425 and sometimes to the next instruction to be executed; we want
427 if (m->exception == 3 || m->exception == 4
429 || (m->exception == 7 && !(m->srr1 & 0x10000)))
430 return_addr = m->srr0 + 4;
432 return_addr = m->srr0;
435 fs->regs.cfa_how = CFA_REG_OFFSET;
436 fs->regs.cfa_reg = STACK_POINTER_REGNUM;
437 fs->regs.cfa_offset = new_cfa - old_cfa;;
439 /* The choice of column for the return address is somewhat tricky.
440 Fortunately, the actual choice is private to this file, and
441 the space it's reserved from is the GCC register space, not the
442 DWARF2 numbering. So any free element of the right size is an OK
444 fs->retaddr_column = ARG_POINTER_REGNUM;
445 /* FIXME: this should really be done using a DWARF2 location expression,
446 not using a static variable. In fact, this entire file should
447 be implemented in DWARF2 expressions. */
448 set_offset (ARG_POINTER_REGNUM, &return_addr);
450 for (i = 0; i < 32; i++)
451 set_offset (32 + i, float_vector_state->fpregs + i);
452 set_offset (SPEFSCR_REGNO, &float_vector_state->fpscr);
456 for (i = 0; i < 32; i++)
457 set_offset (FIRST_ALTIVEC_REGNO + i, float_vector_state->save_vr + i);
458 set_offset (VSCR_REGNO, float_vector_state->save_vscr);
464 /* This is also prototyped in rs6000/darwin.h, inside the
465 MD_FALLBACK_FRAME_STATE_FOR macro. */
466 extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
467 _Unwind_FrameState *fs);
469 /* Implement the MD_FALLBACK_FRAME_STATE_FOR macro,
470 returning true iff the frame was a sigreturn() frame that we
474 _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
475 _Unwind_FrameState *fs)
479 if (!interpret_libc (gprs, context))
481 return handle_syscall (fs, gprs, _Unwind_GetCFA (context));