darwin-fallback.c revision 169689
1290931Srodrigc/* Fallback frame-state unwinder for Darwin.
2290931Srodrigc   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3290931Srodrigc
4290931Srodrigc   This file is part of GCC.
5290931Srodrigc
6290931Srodrigc   GCC is free software; you can redistribute it and/or modify it
7290931Srodrigc   under the terms of the GNU General Public License as published by
8290931Srodrigc   the Free Software Foundation; either version 2, or (at your option)
9290931Srodrigc   any later version.
10290931Srodrigc
11290931Srodrigc   In addition to the permissions in the GNU General Public License, the
12290931Srodrigc   Free Software Foundation gives you unlimited permission to link the
13290931Srodrigc   compiled version of this file into combinations with other programs,
14290931Srodrigc   and to distribute those combinations without any restriction coming
15290931Srodrigc   from the use of this file.  (The General Public License restrictions
16290931Srodrigc   do apply in other respects; for example, they cover modification of
17290931Srodrigc   the file, and distribution when not linked into a combined
18290931Srodrigc   executable.)
19290931Srodrigc
20290931Srodrigc   GCC is distributed in the hope that it will be useful, but WITHOUT
21290931Srodrigc   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22290931Srodrigc   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
23290931Srodrigc   License for more details.
24290931Srodrigc
25290931Srodrigc   You should have received a copy of the GNU General Public License
26290931Srodrigc   along with GCC; see the file COPYING.  If not, write to the Free
27290931Srodrigc   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
28290931Srodrigc   02110-1301, USA.  */
29290931Srodrigc
30290931Srodrigc#include "tconfig.h"
31290931Srodrigc#include "tsystem.h"
32290931Srodrigc#include "coretypes.h"
33290931Srodrigc#include "tm.h"
34290931Srodrigc#include "dwarf2.h"
35290931Srodrigc#include "unwind.h"
36290931Srodrigc#include "unwind-dw2.h"
37290931Srodrigc#include <stdint.h>
38290931Srodrigc#include <stdbool.h>
39290931Srodrigc#include <sys/types.h>
40290931Srodrigc#include <signal.h>
41290931Srodrigc
42290931Srodrigctypedef unsigned long reg_unit;
43290931Srodrigc
44290931Srodrigc/* Place in GPRS the parameters to the first 'sc' instruction that would
45290931Srodrigc   have been executed if we were returning from this CONTEXT, or
46290931Srodrigc   return false if an unexpected instruction is encountered.  */
47290931Srodrigc
48290931Srodrigcstatic bool
49290931Srodrigcinterpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
50290931Srodrigc{
51290931Srodrigc  uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
52290931Srodrigc  uint32_t cr;
53290931Srodrigc  reg_unit lr = (reg_unit) pc;
54290931Srodrigc  reg_unit ctr = 0;
55290931Srodrigc  uint32_t *invalid_address = NULL;
56290931Srodrigc
57290931Srodrigc  int i;
58290931Srodrigc
59290931Srodrigc  for (i = 0; i < 13; i++)
60290931Srodrigc    gprs[i] = 1;
61290931Srodrigc  gprs[1] = _Unwind_GetCFA (context);
62290931Srodrigc  for (; i < 32; i++)
63290931Srodrigc    gprs[i] = _Unwind_GetGR (context, i);
64290931Srodrigc  cr = _Unwind_GetGR (context, CR2_REGNO);
65290931Srodrigc
66290931Srodrigc  /* For each supported Libc, we have to track the code flow
67290931Srodrigc     all the way back into the kernel.
68290931Srodrigc
69290931Srodrigc     This code is believed to support all released Libc/Libsystem builds since
70290931Srodrigc     Jaguar 6C115, including all the security updates.  To be precise,
71290931Srodrigc
72290931Srodrigc     Libc	Libsystem	Build(s)
73290931Srodrigc     262~1	60~37		6C115
74290931Srodrigc     262~1	60.2~4		6D52
75290931Srodrigc     262~1	61~3		6F21-6F22
76290931Srodrigc     262~1	63~24		6G30-6G37
77290931Srodrigc     262~1	63~32		6I34-6I35
78290931Srodrigc     262~1	63~64		6L29-6L60
79290931Srodrigc     262.4.1~1	63~84		6L123-6R172
80290931Srodrigc
81290931Srodrigc     320~1	71~101		7B85-7D28
82290931Srodrigc     320~1	71~266		7F54-7F56
83290931Srodrigc     320~1	71~288		7F112
84290931Srodrigc     320~1	71~289		7F113
85290931Srodrigc     320.1.3~1	71.1.1~29	7H60-7H105
86290931Srodrigc     320.1.3~1	71.1.1~30	7H110-7H113
87290931Srodrigc     320.1.3~1	71.1.1~31	7H114
88290931Srodrigc
89290931Srodrigc     That's a big table!  It would be insane to try to keep track of
90290931Srodrigc     every little detail, so we just read the code itself and do what
91290931Srodrigc     it would do.
92290931Srodrigc  */
93290931Srodrigc
94290931Srodrigc  for (;;)
95290931Srodrigc    {
96290931Srodrigc      uint32_t ins = *pc++;
97290931Srodrigc
98290931Srodrigc      if ((ins & 0xFC000003) == 0x48000000)  /* b instruction */
99290931Srodrigc	{
100290931Srodrigc	  pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
101290931Srodrigc	  continue;
102290931Srodrigc	}
103290931Srodrigc      if ((ins & 0xFC600000) == 0x2C000000)  /* cmpwi */
104290931Srodrigc	{
105290931Srodrigc	  int32_t val1 = (int16_t) ins;
106290931Srodrigc	  int32_t val2 = gprs[ins >> 16 & 0x1F];
107290931Srodrigc	  /* Only beq and bne instructions are supported, so we only
108290931Srodrigc	     need to set the EQ bit.  */
109290931Srodrigc	  uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
110290931Srodrigc	  if (val1 == val2)
111290931Srodrigc	    cr |= mask;
112290931Srodrigc	  else
113290931Srodrigc	    cr &= ~mask;
114290931Srodrigc	  continue;
115290931Srodrigc	}
116290931Srodrigc      if ((ins & 0xFEC38003) == 0x40820000)  /* forwards beq/bne */
117290931Srodrigc	{
118290931Srodrigc	  if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
119290931Srodrigc	    pc += (ins & 0x7FFC) / 4 - 1;
120290931Srodrigc	  continue;
121290931Srodrigc	}
122290931Srodrigc      if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
123290931Srodrigc	{
124290931Srodrigc	  gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
125290931Srodrigc				     | gprs [ins >> 21 & 0x1F]);
126290931Srodrigc	  continue;
127290931Srodrigc	}
128290931Srodrigc      if (ins >> 26 == 0x0E)  /* addi, including li */
129290931Srodrigc	{
130290931Srodrigc	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
131290931Srodrigc	  gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
132290931Srodrigc	  continue;
133290931Srodrigc	}
134290931Srodrigc      if (ins >> 26 == 0x0F)  /* addis, including lis */
135290931Srodrigc	{
136290931Srodrigc	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
137290931Srodrigc	  gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
138290931Srodrigc	  continue;
139290931Srodrigc	}
140290931Srodrigc      if (ins >> 26 == 0x20)  /* lwz */
141290931Srodrigc	{
142290931Srodrigc	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
143290931Srodrigc	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
144290931Srodrigc	  if (p == invalid_address)
145290931Srodrigc	    return false;
146290931Srodrigc	  gprs [ins >> 21 & 0x1F] = *p;
147290931Srodrigc	  continue;
148290931Srodrigc	}
149290931Srodrigc      if (ins >> 26 == 0x21)  /* lwzu */
150290931Srodrigc	{
151290931Srodrigc	  uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
152290931Srodrigc	  if (p == invalid_address)
153290931Srodrigc	    return false;
154290931Srodrigc	  gprs [ins >> 21 & 0x1F] = *p;
155290931Srodrigc	  continue;
156290931Srodrigc	}
157290931Srodrigc      if (ins >> 26 == 0x24)  /* stw */
158290931Srodrigc	/* What we hope this is doing is '--in_sigtramp'.  We don't want
159290931Srodrigc	   to actually store to memory, so just make a note of the
160290931Srodrigc	   address and refuse to load from it.  */
161290931Srodrigc	{
162290931Srodrigc	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
163290931Srodrigc	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
164290931Srodrigc	  if (p == NULL || invalid_address != NULL)
165290931Srodrigc	    return false;
166290931Srodrigc	  invalid_address = p;
167290931Srodrigc	  continue;
168290931Srodrigc	}
169290931Srodrigc      if (ins >> 26 == 0x2E) /* lmw */
170290931Srodrigc	{
171290931Srodrigc	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
172290931Srodrigc	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
173290931Srodrigc	  int i;
174290931Srodrigc
175290931Srodrigc	  for (i = (ins >> 21 & 0x1F); i < 32; i++)
176290931Srodrigc	    {
177290931Srodrigc	      if (p == invalid_address)
178290931Srodrigc		return false;
179290931Srodrigc	      gprs[i] = *p++;
180290931Srodrigc	    }
181290931Srodrigc	  continue;
182290931Srodrigc	}
183290931Srodrigc      if ((ins & 0xFC1FFFFF) == 0x7c0803a6)  /* mtlr */
184290931Srodrigc	{
185290931Srodrigc	  lr = gprs [ins >> 21 & 0x1F];
186290931Srodrigc	  continue;
187290931Srodrigc	}
188290931Srodrigc      if ((ins & 0xFC1FFFFF) == 0x7c0802a6)  /* mflr */
189290931Srodrigc	{
190290931Srodrigc	  gprs [ins >> 21 & 0x1F] = lr;
191290931Srodrigc	  continue;
192290931Srodrigc	}
193290931Srodrigc      if ((ins & 0xFC1FFFFF) == 0x7c0903a6)  /* mtctr */
194290931Srodrigc	{
195290931Srodrigc	  ctr = gprs [ins >> 21 & 0x1F];
196290931Srodrigc	  continue;
197290931Srodrigc	}
198290931Srodrigc      /* The PowerPC User's Manual says that bit 11 of the mtcrf
199290931Srodrigc	 instruction is reserved and should be set to zero, but it
200290931Srodrigc	 looks like the Darwin assembler doesn't do that... */
201290931Srodrigc      if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
202290931Srodrigc	{
203290931Srodrigc	  int i;
204290931Srodrigc	  uint32_t mask = 0;
205290931Srodrigc	  for (i = 0; i < 8; i++)
206290931Srodrigc	    mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
207290931Srodrigc	  cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
208290931Srodrigc	  continue;
209290931Srodrigc	}
210290931Srodrigc      if (ins == 0x429f0005)  /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
211290931Srodrigc	{
212290931Srodrigc	  lr = (reg_unit) pc;
213290931Srodrigc	  continue;
214290931Srodrigc	}
215290931Srodrigc      if (ins == 0x4e800420) /* bctr */
216290931Srodrigc	{
217290931Srodrigc	  pc = (uint32_t *) ctr;
218290934Srodrigc	  continue;
219290931Srodrigc	}
220290931Srodrigc      if (ins == 0x44000002) /* sc */
221290931Srodrigc	return true;
222290931Srodrigc
223290931Srodrigc      return false;
224290931Srodrigc    }
225290931Srodrigc}
226290931Srodrigc
227290931Srodrigc/* We used to include <ucontext.h> and <mach/thread_status.h>,
228290931Srodrigc   but they change so much between different Darwin system versions
229290931Srodrigc   that it's much easier to just write the structures involved here
230290931Srodrigc   directly.  */
231290931Srodrigc
232290931Srodrigc/* These defines are from the kernel's bsd/dev/ppc/unix_signal.c.  */
233290931Srodrigc#define UC_TRAD                 1
234290931Srodrigc#define UC_TRAD_VEC             6
235290931Srodrigc#define UC_TRAD64               20
236290931Srodrigc#define UC_TRAD64_VEC           25
237290931Srodrigc#define UC_FLAVOR               30
238290931Srodrigc#define UC_FLAVOR_VEC           35
239290931Srodrigc#define UC_FLAVOR64             40
240290931Srodrigc#define UC_FLAVOR64_VEC         45
241290931Srodrigc#define UC_DUAL                 50
242290931Srodrigc#define UC_DUAL_VEC             55
243290931Srodrigc
244290931Srodrigcstruct gcc_ucontext
245290931Srodrigc{
246290931Srodrigc  int onstack;
247290931Srodrigc  sigset_t sigmask;
248290931Srodrigc  void * stack_sp;
249290931Srodrigc  size_t stack_sz;
250290931Srodrigc  int stack_flags;
251290931Srodrigc  struct gcc_ucontext *link;
252290931Srodrigc  size_t mcsize;
253290931Srodrigc  struct gcc_mcontext32 *mcontext;
254};
255
256struct gcc_float_vector_state
257{
258  double fpregs[32];
259  uint32_t fpscr_pad;
260  uint32_t fpscr;
261  uint32_t save_vr[32][4];
262  uint32_t save_vscr[4];
263};
264
265struct gcc_mcontext32 {
266  uint32_t dar;
267  uint32_t dsisr;
268  uint32_t exception;
269  uint32_t padding1[5];
270  uint32_t srr0;
271  uint32_t srr1;
272  uint32_t gpr[32];
273  uint32_t cr;
274  uint32_t xer;
275  uint32_t lr;
276  uint32_t ctr;
277  uint32_t mq;
278  uint32_t vrsave;
279  struct gcc_float_vector_state fvs;
280};
281
282/* These are based on /usr/include/ppc/ucontext.h and
283   /usr/include/mach/ppc/thread_status.h, but rewritten to be more
284   convenient, to compile on Jaguar, and to work around Radar 3712064
285   on Panther, which is that the 'es' field of 'struct mcontext64' has
286   the wrong type (doh!).  */
287
288struct gcc_mcontext64 {
289  uint64_t dar;
290  uint32_t dsisr;
291  uint32_t exception;
292  uint32_t padding1[4];
293  uint64_t srr0;
294  uint64_t srr1;
295  uint32_t gpr[32][2];
296  uint32_t cr;
297  uint32_t xer[2];  /* These are arrays because the original structure has them misaligned.  */
298  uint32_t lr[2];
299  uint32_t ctr[2];
300  uint32_t vrsave;
301  struct gcc_float_vector_state fvs;
302};
303
304#define UC_FLAVOR_SIZE \
305  (sizeof (struct gcc_mcontext32) - 33*16)
306
307#define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32))
308
309#define UC_FLAVOR64_SIZE \
310  (sizeof (struct gcc_mcontext64) - 33*16)
311
312#define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64))
313
314/* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS
315   to represent the execution of a signal return; or, if not a signal
316   return, return false.  */
317
318static bool
319handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32],
320		_Unwind_Ptr old_cfa)
321{
322  struct gcc_ucontext *uctx;
323  bool is_64, is_vector;
324  struct gcc_float_vector_state * float_vector_state;
325  _Unwind_Ptr new_cfa;
326  int i;
327  static _Unwind_Ptr return_addr;
328
329  /* Yay!  We're in a Libc that we understand, and it's made a
330     system call.  It'll be one of two kinds: either a Jaguar-style
331     SYS_sigreturn, or a Panther-style 'syscall' call with 184, which
332     is also SYS_sigreturn.  */
333
334  if (gprs[0] == 0x67 /* SYS_SIGRETURN */)
335    {
336      uctx = (struct gcc_ucontext *) gprs[3];
337      is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
338		   || uctx->mcsize == UC_FLAVOR_VEC_SIZE);
339      is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
340	       || uctx->mcsize == UC_FLAVOR64_SIZE);
341    }
342  else if (gprs[0] == 0 && gprs[3] == 184)
343    {
344      int ctxstyle = gprs[5];
345      uctx = (struct gcc_ucontext *) gprs[4];
346      is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
347		   || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
348      is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
349	       || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
350    }
351  else
352    return false;
353
354#define set_offset(r, addr)					\
355  (fs->regs.reg[r].how = REG_SAVED_OFFSET,			\
356   fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa)
357
358  /* Restore even the registers that are not call-saved, since they
359     might be being used in the prologue to save other registers,
360     for instance GPR0 is sometimes used to save LR.  */
361
362  /* Handle the GPRs, and produce the information needed to do the rest.  */
363  if (is_64)
364    {
365      /* The context is 64-bit, but it doesn't carry any extra information
366	 for us because only the low 32 bits of the registers are
367	 call-saved.  */
368      struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext;
369      int i;
370
371      float_vector_state = &m64->fvs;
372
373      new_cfa = m64->gpr[1][1];
374
375      set_offset (CR2_REGNO, &m64->cr);
376      for (i = 0; i < 32; i++)
377	set_offset (i, m64->gpr[i] + 1);
378      set_offset (XER_REGNO, m64->xer + 1);
379      set_offset (LINK_REGISTER_REGNUM, m64->lr + 1);
380      set_offset (COUNT_REGISTER_REGNUM, m64->ctr + 1);
381      if (is_vector)
382	set_offset (VRSAVE_REGNO, &m64->vrsave);
383
384      /* Sometimes, srr0 points to the instruction that caused the exception,
385	 and sometimes to the next instruction to be executed; we want
386	 the latter.  */
387      if (m64->exception == 3 || m64->exception == 4
388	  || m64->exception == 6
389	  || (m64->exception == 7 && !(m64->srr1 & 0x10000)))
390	return_addr = m64->srr0 + 4;
391      else
392	return_addr = m64->srr0;
393    }
394  else
395    {
396      struct gcc_mcontext32 *m = uctx->mcontext;
397      int i;
398
399      float_vector_state = &m->fvs;
400
401      new_cfa = m->gpr[1];
402
403      set_offset (CR2_REGNO, &m->cr);
404      for (i = 0; i < 32; i++)
405	set_offset (i, m->gpr + i);
406      set_offset (XER_REGNO, &m->xer);
407      set_offset (LINK_REGISTER_REGNUM, &m->lr);
408      set_offset (COUNT_REGISTER_REGNUM, &m->ctr);
409
410      if (is_vector)
411	set_offset (VRSAVE_REGNO, &m->vrsave);
412
413      /* Sometimes, srr0 points to the instruction that caused the exception,
414	 and sometimes to the next instruction to be executed; we want
415	 the latter.  */
416      if (m->exception == 3 || m->exception == 4
417	  || m->exception == 6
418	  || (m->exception == 7 && !(m->srr1 & 0x10000)))
419	return_addr = m->srr0 + 4;
420      else
421	return_addr = m->srr0;
422    }
423
424  fs->cfa_how = CFA_REG_OFFSET;
425  fs->cfa_reg = STACK_POINTER_REGNUM;
426  fs->cfa_offset = new_cfa - old_cfa;;
427
428  /* The choice of column for the return address is somewhat tricky.
429     Fortunately, the actual choice is private to this file, and
430     the space it's reserved from is the GCC register space, not the
431     DWARF2 numbering.  So any free element of the right size is an OK
432     choice.  Thus: */
433  fs->retaddr_column = ARG_POINTER_REGNUM;
434  /* FIXME: this should really be done using a DWARF2 location expression,
435     not using a static variable.  In fact, this entire file should
436     be implemented in DWARF2 expressions.  */
437  set_offset (ARG_POINTER_REGNUM, &return_addr);
438
439  for (i = 0; i < 32; i++)
440    set_offset (32 + i, float_vector_state->fpregs + i);
441  set_offset (SPEFSCR_REGNO, &float_vector_state->fpscr);
442
443  if (is_vector)
444    {
445      for (i = 0; i < 32; i++)
446	set_offset (FIRST_ALTIVEC_REGNO + i, float_vector_state->save_vr + i);
447      set_offset (VSCR_REGNO, float_vector_state->save_vscr);
448    }
449
450  return true;
451}
452
453/* This is also prototyped in rs6000/darwin.h, inside the
454   MD_FALLBACK_FRAME_STATE_FOR macro.  */
455extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
456					      _Unwind_FrameState *fs);
457
458/* Implement the MD_FALLBACK_FRAME_STATE_FOR macro,
459   returning true iff the frame was a sigreturn() frame that we
460   can understand.  */
461
462bool
463_Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
464				  _Unwind_FrameState *fs)
465{
466  reg_unit gprs[32];
467
468  if (!interpret_libc (gprs, context))
469    return false;
470  return handle_syscall (fs, gprs, _Unwind_GetCFA (context));
471}
472