1169689Skan/* Fallback frame-state unwinder for Darwin.
2169689Skan   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3169689Skan
4169689Skan   This file is part of GCC.
5169689Skan
6169689Skan   GCC is free software; you can redistribute it and/or modify it
7169689Skan   under the terms of the GNU General Public License as published by
8169689Skan   the Free Software Foundation; either version 2, or (at your option)
9169689Skan   any later version.
10169689Skan
11169689Skan   In addition to the permissions in the GNU General Public License, the
12169689Skan   Free Software Foundation gives you unlimited permission to link the
13169689Skan   compiled version of this file into combinations with other programs,
14169689Skan   and to distribute those combinations without any restriction coming
15169689Skan   from the use of this file.  (The General Public License restrictions
16169689Skan   do apply in other respects; for example, they cover modification of
17169689Skan   the file, and distribution when not linked into a combined
18169689Skan   executable.)
19169689Skan
20169689Skan   GCC is distributed in the hope that it will be useful, but WITHOUT
21169689Skan   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22169689Skan   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
23169689Skan   License for more details.
24169689Skan
25169689Skan   You should have received a copy of the GNU General Public License
26169689Skan   along with GCC; see the file COPYING.  If not, write to the Free
27169689Skan   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
28169689Skan   02110-1301, USA.  */
29169689Skan
30169689Skan#include "tconfig.h"
31169689Skan#include "tsystem.h"
32169689Skan#include "coretypes.h"
33169689Skan#include "tm.h"
34169689Skan#include "dwarf2.h"
35169689Skan#include "unwind.h"
36169689Skan#include "unwind-dw2.h"
37169689Skan#include <stdint.h>
38169689Skan#include <stdbool.h>
39169689Skan#include <sys/types.h>
40169689Skan#include <signal.h>
41169689Skan
42169689Skantypedef unsigned long reg_unit;
43169689Skan
44169689Skan/* Place in GPRS the parameters to the first 'sc' instruction that would
45169689Skan   have been executed if we were returning from this CONTEXT, or
46169689Skan   return false if an unexpected instruction is encountered.  */
47169689Skan
48169689Skanstatic bool
49169689Skaninterpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
50169689Skan{
51169689Skan  uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
52169689Skan  uint32_t cr;
53169689Skan  reg_unit lr = (reg_unit) pc;
54169689Skan  reg_unit ctr = 0;
55169689Skan  uint32_t *invalid_address = NULL;
56169689Skan
57169689Skan  int i;
58169689Skan
59169689Skan  for (i = 0; i < 13; i++)
60169689Skan    gprs[i] = 1;
61169689Skan  gprs[1] = _Unwind_GetCFA (context);
62169689Skan  for (; i < 32; i++)
63169689Skan    gprs[i] = _Unwind_GetGR (context, i);
64169689Skan  cr = _Unwind_GetGR (context, CR2_REGNO);
65169689Skan
66169689Skan  /* For each supported Libc, we have to track the code flow
67169689Skan     all the way back into the kernel.
68169689Skan
69169689Skan     This code is believed to support all released Libc/Libsystem builds since
70169689Skan     Jaguar 6C115, including all the security updates.  To be precise,
71169689Skan
72169689Skan     Libc	Libsystem	Build(s)
73169689Skan     262~1	60~37		6C115
74169689Skan     262~1	60.2~4		6D52
75169689Skan     262~1	61~3		6F21-6F22
76169689Skan     262~1	63~24		6G30-6G37
77169689Skan     262~1	63~32		6I34-6I35
78169689Skan     262~1	63~64		6L29-6L60
79169689Skan     262.4.1~1	63~84		6L123-6R172
80169689Skan
81169689Skan     320~1	71~101		7B85-7D28
82169689Skan     320~1	71~266		7F54-7F56
83169689Skan     320~1	71~288		7F112
84169689Skan     320~1	71~289		7F113
85169689Skan     320.1.3~1	71.1.1~29	7H60-7H105
86169689Skan     320.1.3~1	71.1.1~30	7H110-7H113
87169689Skan     320.1.3~1	71.1.1~31	7H114
88169689Skan
89169689Skan     That's a big table!  It would be insane to try to keep track of
90169689Skan     every little detail, so we just read the code itself and do what
91169689Skan     it would do.
92169689Skan  */
93169689Skan
94169689Skan  for (;;)
95169689Skan    {
96169689Skan      uint32_t ins = *pc++;
97169689Skan
98169689Skan      if ((ins & 0xFC000003) == 0x48000000)  /* b instruction */
99169689Skan	{
100169689Skan	  pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
101169689Skan	  continue;
102169689Skan	}
103169689Skan      if ((ins & 0xFC600000) == 0x2C000000)  /* cmpwi */
104169689Skan	{
105169689Skan	  int32_t val1 = (int16_t) ins;
106169689Skan	  int32_t val2 = gprs[ins >> 16 & 0x1F];
107169689Skan	  /* Only beq and bne instructions are supported, so we only
108169689Skan	     need to set the EQ bit.  */
109169689Skan	  uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
110169689Skan	  if (val1 == val2)
111169689Skan	    cr |= mask;
112169689Skan	  else
113169689Skan	    cr &= ~mask;
114169689Skan	  continue;
115169689Skan	}
116169689Skan      if ((ins & 0xFEC38003) == 0x40820000)  /* forwards beq/bne */
117169689Skan	{
118169689Skan	  if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
119169689Skan	    pc += (ins & 0x7FFC) / 4 - 1;
120169689Skan	  continue;
121169689Skan	}
122169689Skan      if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
123169689Skan	{
124169689Skan	  gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
125169689Skan				     | gprs [ins >> 21 & 0x1F]);
126169689Skan	  continue;
127169689Skan	}
128169689Skan      if (ins >> 26 == 0x0E)  /* addi, including li */
129169689Skan	{
130169689Skan	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
131169689Skan	  gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
132169689Skan	  continue;
133169689Skan	}
134169689Skan      if (ins >> 26 == 0x0F)  /* addis, including lis */
135169689Skan	{
136169689Skan	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
137169689Skan	  gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
138169689Skan	  continue;
139169689Skan	}
140169689Skan      if (ins >> 26 == 0x20)  /* lwz */
141169689Skan	{
142169689Skan	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
143169689Skan	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
144169689Skan	  if (p == invalid_address)
145169689Skan	    return false;
146169689Skan	  gprs [ins >> 21 & 0x1F] = *p;
147169689Skan	  continue;
148169689Skan	}
149169689Skan      if (ins >> 26 == 0x21)  /* lwzu */
150169689Skan	{
151169689Skan	  uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
152169689Skan	  if (p == invalid_address)
153169689Skan	    return false;
154169689Skan	  gprs [ins >> 21 & 0x1F] = *p;
155169689Skan	  continue;
156169689Skan	}
157169689Skan      if (ins >> 26 == 0x24)  /* stw */
158169689Skan	/* What we hope this is doing is '--in_sigtramp'.  We don't want
159169689Skan	   to actually store to memory, so just make a note of the
160169689Skan	   address and refuse to load from it.  */
161169689Skan	{
162169689Skan	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
163169689Skan	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
164169689Skan	  if (p == NULL || invalid_address != NULL)
165169689Skan	    return false;
166169689Skan	  invalid_address = p;
167169689Skan	  continue;
168169689Skan	}
169169689Skan      if (ins >> 26 == 0x2E) /* lmw */
170169689Skan	{
171169689Skan	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
172169689Skan	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
173169689Skan	  int i;
174169689Skan
175169689Skan	  for (i = (ins >> 21 & 0x1F); i < 32; i++)
176169689Skan	    {
177169689Skan	      if (p == invalid_address)
178169689Skan		return false;
179169689Skan	      gprs[i] = *p++;
180169689Skan	    }
181169689Skan	  continue;
182169689Skan	}
183169689Skan      if ((ins & 0xFC1FFFFF) == 0x7c0803a6)  /* mtlr */
184169689Skan	{
185169689Skan	  lr = gprs [ins >> 21 & 0x1F];
186169689Skan	  continue;
187169689Skan	}
188169689Skan      if ((ins & 0xFC1FFFFF) == 0x7c0802a6)  /* mflr */
189169689Skan	{
190169689Skan	  gprs [ins >> 21 & 0x1F] = lr;
191169689Skan	  continue;
192169689Skan	}
193169689Skan      if ((ins & 0xFC1FFFFF) == 0x7c0903a6)  /* mtctr */
194169689Skan	{
195169689Skan	  ctr = gprs [ins >> 21 & 0x1F];
196169689Skan	  continue;
197169689Skan	}
198169689Skan      /* The PowerPC User's Manual says that bit 11 of the mtcrf
199169689Skan	 instruction is reserved and should be set to zero, but it
200169689Skan	 looks like the Darwin assembler doesn't do that... */
201169689Skan      if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
202169689Skan	{
203169689Skan	  int i;
204169689Skan	  uint32_t mask = 0;
205169689Skan	  for (i = 0; i < 8; i++)
206169689Skan	    mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
207169689Skan	  cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
208169689Skan	  continue;
209169689Skan	}
210169689Skan      if (ins == 0x429f0005)  /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
211169689Skan	{
212169689Skan	  lr = (reg_unit) pc;
213169689Skan	  continue;
214169689Skan	}
215169689Skan      if (ins == 0x4e800420) /* bctr */
216169689Skan	{
217169689Skan	  pc = (uint32_t *) ctr;
218169689Skan	  continue;
219169689Skan	}
220169689Skan      if (ins == 0x44000002) /* sc */
221169689Skan	return true;
222169689Skan
223169689Skan      return false;
224169689Skan    }
225169689Skan}
226169689Skan
227169689Skan/* We used to include <ucontext.h> and <mach/thread_status.h>,
228169689Skan   but they change so much between different Darwin system versions
229169689Skan   that it's much easier to just write the structures involved here
230169689Skan   directly.  */
231169689Skan
232169689Skan/* These defines are from the kernel's bsd/dev/ppc/unix_signal.c.  */
233169689Skan#define UC_TRAD                 1
234169689Skan#define UC_TRAD_VEC             6
235169689Skan#define UC_TRAD64               20
236169689Skan#define UC_TRAD64_VEC           25
237169689Skan#define UC_FLAVOR               30
238169689Skan#define UC_FLAVOR_VEC           35
239169689Skan#define UC_FLAVOR64             40
240169689Skan#define UC_FLAVOR64_VEC         45
241169689Skan#define UC_DUAL                 50
242169689Skan#define UC_DUAL_VEC             55
243169689Skan
244169689Skanstruct gcc_ucontext
245169689Skan{
246169689Skan  int onstack;
247169689Skan  sigset_t sigmask;
248169689Skan  void * stack_sp;
249169689Skan  size_t stack_sz;
250169689Skan  int stack_flags;
251169689Skan  struct gcc_ucontext *link;
252169689Skan  size_t mcsize;
253169689Skan  struct gcc_mcontext32 *mcontext;
254169689Skan};
255169689Skan
256169689Skanstruct gcc_float_vector_state
257169689Skan{
258169689Skan  double fpregs[32];
259169689Skan  uint32_t fpscr_pad;
260169689Skan  uint32_t fpscr;
261169689Skan  uint32_t save_vr[32][4];
262169689Skan  uint32_t save_vscr[4];
263169689Skan};
264169689Skan
265169689Skanstruct gcc_mcontext32 {
266169689Skan  uint32_t dar;
267169689Skan  uint32_t dsisr;
268169689Skan  uint32_t exception;
269169689Skan  uint32_t padding1[5];
270169689Skan  uint32_t srr0;
271169689Skan  uint32_t srr1;
272169689Skan  uint32_t gpr[32];
273169689Skan  uint32_t cr;
274169689Skan  uint32_t xer;
275169689Skan  uint32_t lr;
276169689Skan  uint32_t ctr;
277169689Skan  uint32_t mq;
278169689Skan  uint32_t vrsave;
279169689Skan  struct gcc_float_vector_state fvs;
280169689Skan};
281169689Skan
282169689Skan/* These are based on /usr/include/ppc/ucontext.h and
283169689Skan   /usr/include/mach/ppc/thread_status.h, but rewritten to be more
284169689Skan   convenient, to compile on Jaguar, and to work around Radar 3712064
285169689Skan   on Panther, which is that the 'es' field of 'struct mcontext64' has
286169689Skan   the wrong type (doh!).  */
287169689Skan
288169689Skanstruct gcc_mcontext64 {
289169689Skan  uint64_t dar;
290169689Skan  uint32_t dsisr;
291169689Skan  uint32_t exception;
292169689Skan  uint32_t padding1[4];
293169689Skan  uint64_t srr0;
294169689Skan  uint64_t srr1;
295169689Skan  uint32_t gpr[32][2];
296169689Skan  uint32_t cr;
297169689Skan  uint32_t xer[2];  /* These are arrays because the original structure has them misaligned.  */
298169689Skan  uint32_t lr[2];
299169689Skan  uint32_t ctr[2];
300169689Skan  uint32_t vrsave;
301169689Skan  struct gcc_float_vector_state fvs;
302169689Skan};
303169689Skan
304169689Skan#define UC_FLAVOR_SIZE \
305169689Skan  (sizeof (struct gcc_mcontext32) - 33*16)
306169689Skan
307169689Skan#define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32))
308169689Skan
309169689Skan#define UC_FLAVOR64_SIZE \
310169689Skan  (sizeof (struct gcc_mcontext64) - 33*16)
311169689Skan
312169689Skan#define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64))
313169689Skan
314169689Skan/* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS
315169689Skan   to represent the execution of a signal return; or, if not a signal
316169689Skan   return, return false.  */
317169689Skan
318169689Skanstatic bool
319169689Skanhandle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32],
320169689Skan		_Unwind_Ptr old_cfa)
321169689Skan{
322169689Skan  struct gcc_ucontext *uctx;
323169689Skan  bool is_64, is_vector;
324169689Skan  struct gcc_float_vector_state * float_vector_state;
325169689Skan  _Unwind_Ptr new_cfa;
326169689Skan  int i;
327169689Skan  static _Unwind_Ptr return_addr;
328169689Skan
329169689Skan  /* Yay!  We're in a Libc that we understand, and it's made a
330169689Skan     system call.  It'll be one of two kinds: either a Jaguar-style
331169689Skan     SYS_sigreturn, or a Panther-style 'syscall' call with 184, which
332169689Skan     is also SYS_sigreturn.  */
333169689Skan
334169689Skan  if (gprs[0] == 0x67 /* SYS_SIGRETURN */)
335169689Skan    {
336169689Skan      uctx = (struct gcc_ucontext *) gprs[3];
337169689Skan      is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
338169689Skan		   || uctx->mcsize == UC_FLAVOR_VEC_SIZE);
339169689Skan      is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
340169689Skan	       || uctx->mcsize == UC_FLAVOR64_SIZE);
341169689Skan    }
342169689Skan  else if (gprs[0] == 0 && gprs[3] == 184)
343169689Skan    {
344169689Skan      int ctxstyle = gprs[5];
345169689Skan      uctx = (struct gcc_ucontext *) gprs[4];
346169689Skan      is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
347169689Skan		   || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
348169689Skan      is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
349169689Skan	       || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
350169689Skan    }
351169689Skan  else
352169689Skan    return false;
353169689Skan
354169689Skan#define set_offset(r, addr)					\
355169689Skan  (fs->regs.reg[r].how = REG_SAVED_OFFSET,			\
356169689Skan   fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa)
357169689Skan
358169689Skan  /* Restore even the registers that are not call-saved, since they
359169689Skan     might be being used in the prologue to save other registers,
360169689Skan     for instance GPR0 is sometimes used to save LR.  */
361169689Skan
362169689Skan  /* Handle the GPRs, and produce the information needed to do the rest.  */
363169689Skan  if (is_64)
364169689Skan    {
365169689Skan      /* The context is 64-bit, but it doesn't carry any extra information
366169689Skan	 for us because only the low 32 bits of the registers are
367169689Skan	 call-saved.  */
368169689Skan      struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext;
369169689Skan      int i;
370169689Skan
371169689Skan      float_vector_state = &m64->fvs;
372169689Skan
373169689Skan      new_cfa = m64->gpr[1][1];
374169689Skan
375169689Skan      set_offset (CR2_REGNO, &m64->cr);
376169689Skan      for (i = 0; i < 32; i++)
377169689Skan	set_offset (i, m64->gpr[i] + 1);
378169689Skan      set_offset (XER_REGNO, m64->xer + 1);
379169689Skan      set_offset (LINK_REGISTER_REGNUM, m64->lr + 1);
380169689Skan      set_offset (COUNT_REGISTER_REGNUM, m64->ctr + 1);
381169689Skan      if (is_vector)
382169689Skan	set_offset (VRSAVE_REGNO, &m64->vrsave);
383169689Skan
384169689Skan      /* Sometimes, srr0 points to the instruction that caused the exception,
385169689Skan	 and sometimes to the next instruction to be executed; we want
386169689Skan	 the latter.  */
387169689Skan      if (m64->exception == 3 || m64->exception == 4
388169689Skan	  || m64->exception == 6
389169689Skan	  || (m64->exception == 7 && !(m64->srr1 & 0x10000)))
390169689Skan	return_addr = m64->srr0 + 4;
391169689Skan      else
392169689Skan	return_addr = m64->srr0;
393169689Skan    }
394169689Skan  else
395169689Skan    {
396169689Skan      struct gcc_mcontext32 *m = uctx->mcontext;
397169689Skan      int i;
398169689Skan
399169689Skan      float_vector_state = &m->fvs;
400169689Skan
401169689Skan      new_cfa = m->gpr[1];
402169689Skan
403169689Skan      set_offset (CR2_REGNO, &m->cr);
404169689Skan      for (i = 0; i < 32; i++)
405169689Skan	set_offset (i, m->gpr + i);
406169689Skan      set_offset (XER_REGNO, &m->xer);
407169689Skan      set_offset (LINK_REGISTER_REGNUM, &m->lr);
408169689Skan      set_offset (COUNT_REGISTER_REGNUM, &m->ctr);
409169689Skan
410169689Skan      if (is_vector)
411169689Skan	set_offset (VRSAVE_REGNO, &m->vrsave);
412169689Skan
413169689Skan      /* Sometimes, srr0 points to the instruction that caused the exception,
414169689Skan	 and sometimes to the next instruction to be executed; we want
415169689Skan	 the latter.  */
416169689Skan      if (m->exception == 3 || m->exception == 4
417169689Skan	  || m->exception == 6
418169689Skan	  || (m->exception == 7 && !(m->srr1 & 0x10000)))
419169689Skan	return_addr = m->srr0 + 4;
420169689Skan      else
421169689Skan	return_addr = m->srr0;
422169689Skan    }
423169689Skan
424169689Skan  fs->cfa_how = CFA_REG_OFFSET;
425169689Skan  fs->cfa_reg = STACK_POINTER_REGNUM;
426169689Skan  fs->cfa_offset = new_cfa - old_cfa;;
427169689Skan
428169689Skan  /* The choice of column for the return address is somewhat tricky.
429169689Skan     Fortunately, the actual choice is private to this file, and
430169689Skan     the space it's reserved from is the GCC register space, not the
431169689Skan     DWARF2 numbering.  So any free element of the right size is an OK
432169689Skan     choice.  Thus: */
433169689Skan  fs->retaddr_column = ARG_POINTER_REGNUM;
434169689Skan  /* FIXME: this should really be done using a DWARF2 location expression,
435169689Skan     not using a static variable.  In fact, this entire file should
436169689Skan     be implemented in DWARF2 expressions.  */
437169689Skan  set_offset (ARG_POINTER_REGNUM, &return_addr);
438169689Skan
439169689Skan  for (i = 0; i < 32; i++)
440169689Skan    set_offset (32 + i, float_vector_state->fpregs + i);
441169689Skan  set_offset (SPEFSCR_REGNO, &float_vector_state->fpscr);
442169689Skan
443169689Skan  if (is_vector)
444169689Skan    {
445169689Skan      for (i = 0; i < 32; i++)
446169689Skan	set_offset (FIRST_ALTIVEC_REGNO + i, float_vector_state->save_vr + i);
447169689Skan      set_offset (VSCR_REGNO, float_vector_state->save_vscr);
448169689Skan    }
449169689Skan
450169689Skan  return true;
451169689Skan}
452169689Skan
453169689Skan/* This is also prototyped in rs6000/darwin.h, inside the
454169689Skan   MD_FALLBACK_FRAME_STATE_FOR macro.  */
455169689Skanextern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
456169689Skan					      _Unwind_FrameState *fs);
457169689Skan
458169689Skan/* Implement the MD_FALLBACK_FRAME_STATE_FOR macro,
459169689Skan   returning true iff the frame was a sigreturn() frame that we
460169689Skan   can understand.  */
461169689Skan
462169689Skanbool
463169689Skan_Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
464169689Skan				  _Unwind_FrameState *fs)
465169689Skan{
466169689Skan  reg_unit gprs[32];
467169689Skan
468169689Skan  if (!interpret_libc (gprs, context))
469169689Skan    return false;
470169689Skan  return handle_syscall (fs, gprs, _Unwind_GetCFA (context));
471169689Skan}
472