1/* Fallback frame-state unwinder for Darwin.
2   Copyright (C) 2004-2020 Free Software Foundation, Inc.
3
4   This file is part of GCC.
5
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 3, or (at your option)
9   any later version.
10
11   GCC is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14   License for more details.
15
16   Under Section 7 of GPL version 3, you are granted additional
17   permissions described in the GCC Runtime Library Exception, version
18   3.1, as published by the Free Software Foundation.
19
20   You should have received a copy of the GNU General Public License and
21   a copy of the GCC Runtime Library Exception along with this program;
22   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   <http://www.gnu.org/licenses/>.  */
24
25#ifdef __ppc__
26
27#include "tconfig.h"
28#include "tsystem.h"
29#include "coretypes.h"
30#include "tm.h"
31#include "libgcc_tm.h"
32#include "dwarf2.h"
33#include "unwind.h"
34#include "unwind-dw2.h"
35#include <stdint.h>
36#include <stdbool.h>
37#include <sys/types.h>
38#include <signal.h>
39
40#define R_LR		65
41#define R_CTR		66
42#define R_CR2		70
43#define R_XER		76
44#define R_VR0		77
45#define R_VRSAVE	109
46#define R_VSCR		110
47#define R_SPEFSCR	112
48
49typedef unsigned long reg_unit;
50
51/* Place in GPRS the parameters to the first 'sc' instruction that would
52   have been executed if we were returning from this CONTEXT, or
53   return false if an unexpected instruction is encountered.  */
54
55static bool
56interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
57{
58  uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
59  uint32_t cr;
60  reg_unit lr = (reg_unit) pc;
61  reg_unit ctr = 0;
62  uint32_t *invalid_address = NULL;
63
64  int i;
65
66  for (i = 0; i < 13; i++)
67    gprs[i] = 1;
68  gprs[1] = _Unwind_GetCFA (context);
69  for (; i < 32; i++)
70    gprs[i] = _Unwind_GetGR (context, i);
71  cr = _Unwind_GetGR (context, R_CR2);
72
73  /* For each supported Libc, we have to track the code flow
74     all the way back into the kernel.
75
76     This code is believed to support all released Libc/Libsystem builds since
77     Jaguar 6C115, including all the security updates.  To be precise,
78
79     Libc	Libsystem	Build(s)
80     262~1	60~37		6C115
81     262~1	60.2~4		6D52
82     262~1	61~3		6F21-6F22
83     262~1	63~24		6G30-6G37
84     262~1	63~32		6I34-6I35
85     262~1	63~64		6L29-6L60
86     262.4.1~1	63~84		6L123-6R172
87
88     320~1	71~101		7B85-7D28
89     320~1	71~266		7F54-7F56
90     320~1	71~288		7F112
91     320~1	71~289		7F113
92     320.1.3~1	71.1.1~29	7H60-7H105
93     320.1.3~1	71.1.1~30	7H110-7H113
94     320.1.3~1	71.1.1~31	7H114
95
96     That's a big table!  It would be insane to try to keep track of
97     every little detail, so we just read the code itself and do what
98     it would do.
99  */
100
101  for (;;)
102    {
103      uint32_t ins = *pc++;
104
105      if ((ins & 0xFC000003) == 0x48000000)  /* b instruction */
106	{
107	  pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
108	  continue;
109	}
110      if ((ins & 0xFC600000) == 0x2C000000)  /* cmpwi */
111	{
112	  int32_t val1 = (int16_t) ins;
113	  int32_t val2 = gprs[ins >> 16 & 0x1F];
114	  /* Only beq and bne instructions are supported, so we only
115	     need to set the EQ bit.  */
116	  uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
117	  if (val1 == val2)
118	    cr |= mask;
119	  else
120	    cr &= ~mask;
121	  continue;
122	}
123      if ((ins & 0xFEC38003) == 0x40820000)  /* forwards beq/bne */
124	{
125	  if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
126	    pc += (ins & 0x7FFC) / 4 - 1;
127	  continue;
128	}
129      if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
130	{
131	  gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
132				     | gprs [ins >> 21 & 0x1F]);
133	  continue;
134	}
135      if (ins >> 26 == 0x0E)  /* addi, including li */
136	{
137	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
138	  gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
139	  continue;
140	}
141      if (ins >> 26 == 0x0F)  /* addis, including lis */
142	{
143	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
144	  gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
145	  continue;
146	}
147      if (ins >> 26 == 0x20)  /* lwz */
148	{
149	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
150	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
151	  if (p == invalid_address)
152	    return false;
153	  gprs [ins >> 21 & 0x1F] = *p;
154	  continue;
155	}
156      if (ins >> 26 == 0x21)  /* lwzu */
157	{
158	  uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
159	  if (p == invalid_address)
160	    return false;
161	  gprs [ins >> 21 & 0x1F] = *p;
162	  continue;
163	}
164      if (ins >> 26 == 0x24)  /* stw */
165	/* What we hope this is doing is '--in_sigtramp'.  We don't want
166	   to actually store to memory, so just make a note of the
167	   address and refuse to load from it.  */
168	{
169	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
170	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
171	  if (p == NULL || invalid_address != NULL)
172	    return false;
173	  invalid_address = p;
174	  continue;
175	}
176      if (ins >> 26 == 0x2E) /* lmw */
177	{
178	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
179	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
180	  int i;
181
182	  for (i = (ins >> 21 & 0x1F); i < 32; i++)
183	    {
184	      if (p == invalid_address)
185		return false;
186	      gprs[i] = *p++;
187	    }
188	  continue;
189	}
190      if ((ins & 0xFC1FFFFF) == 0x7c0803a6)  /* mtlr */
191	{
192	  lr = gprs [ins >> 21 & 0x1F];
193	  continue;
194	}
195      if ((ins & 0xFC1FFFFF) == 0x7c0802a6)  /* mflr */
196	{
197	  gprs [ins >> 21 & 0x1F] = lr;
198	  continue;
199	}
200      if ((ins & 0xFC1FFFFF) == 0x7c0903a6)  /* mtctr */
201	{
202	  ctr = gprs [ins >> 21 & 0x1F];
203	  continue;
204	}
205      /* The PowerPC User's Manual says that bit 11 of the mtcrf
206	 instruction is reserved and should be set to zero, but it
207	 looks like the Darwin assembler doesn't do that... */
208      if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
209	{
210	  int i;
211	  uint32_t mask = 0;
212	  for (i = 0; i < 8; i++)
213	    mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
214	  cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
215	  continue;
216	}
217      if (ins == 0x429f0005)  /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
218	{
219	  lr = (reg_unit) pc;
220	  continue;
221	}
222      if (ins == 0x4e800420) /* bctr */
223	{
224	  pc = (uint32_t *) ctr;
225	  continue;
226	}
227      if (ins == 0x44000002) /* sc */
228	return true;
229
230      return false;
231    }
232}
233
234/* We used to include <ucontext.h> and <mach/thread_status.h>,
235   but they change so much between different Darwin system versions
236   that it's much easier to just write the structures involved here
237   directly.  */
238
239/* These defines are from the kernel's bsd/dev/ppc/unix_signal.c.  */
240#define UC_TRAD                 1
241#define UC_TRAD_VEC             6
242#define UC_TRAD64               20
243#define UC_TRAD64_VEC           25
244#define UC_FLAVOR               30
245#define UC_FLAVOR_VEC           35
246#define UC_FLAVOR64             40
247#define UC_FLAVOR64_VEC         45
248#define UC_DUAL                 50
249#define UC_DUAL_VEC             55
250
251struct gcc_ucontext
252{
253  int onstack;
254  sigset_t sigmask;
255  void * stack_sp;
256  size_t stack_sz;
257  int stack_flags;
258  struct gcc_ucontext *link;
259  size_t mcsize;
260  struct gcc_mcontext32 *mcontext;
261};
262
263struct gcc_float_vector_state
264{
265  double fpregs[32];
266  uint32_t fpscr_pad;
267  uint32_t fpscr;
268  uint32_t save_vr[32][4];
269  uint32_t save_vscr[4];
270};
271
272struct gcc_mcontext32 {
273  uint32_t dar;
274  uint32_t dsisr;
275  uint32_t exception;
276  uint32_t padding1[5];
277  uint32_t srr0;
278  uint32_t srr1;
279  uint32_t gpr[32];
280  uint32_t cr;
281  uint32_t xer;
282  uint32_t lr;
283  uint32_t ctr;
284  uint32_t mq;
285  uint32_t vrsave;
286  struct gcc_float_vector_state fvs;
287};
288
289/* These are based on /usr/include/ppc/ucontext.h and
290   /usr/include/mach/ppc/thread_status.h, but rewritten to be more
291   convenient, to compile on Jaguar, and to work around Radar 3712064
292   on Panther, which is that the 'es' field of 'struct mcontext64' has
293   the wrong type (doh!).  */
294
295struct gcc_mcontext64 {
296  uint64_t dar;
297  uint32_t dsisr;
298  uint32_t exception;
299  uint32_t padding1[4];
300  uint64_t srr0;
301  uint64_t srr1;
302  uint32_t gpr[32][2];
303  uint32_t cr;
304  uint32_t xer[2];  /* These are arrays because the original structure has them misaligned.  */
305  uint32_t lr[2];
306  uint32_t ctr[2];
307  uint32_t vrsave;
308  struct gcc_float_vector_state fvs;
309};
310
311#define UC_FLAVOR_SIZE \
312  (sizeof (struct gcc_mcontext32) - 33*16)
313
314#define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32))
315
316#define UC_FLAVOR64_SIZE \
317  (sizeof (struct gcc_mcontext64) - 33*16)
318
319#define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64))
320
321/* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS
322   to represent the execution of a signal return; or, if not a signal
323   return, return false.  */
324
325static bool
326handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32],
327		_Unwind_Ptr old_cfa)
328{
329  struct gcc_ucontext *uctx;
330  bool is_64, is_vector;
331  struct gcc_float_vector_state * float_vector_state;
332  _Unwind_Ptr new_cfa;
333  int i;
334  static _Unwind_Ptr return_addr;
335
336  /* Yay!  We're in a Libc that we understand, and it's made a
337     system call.  In Jaguar, this is a direct system call with value 103;
338     in Panther and Tiger it is a SYS_syscall call for system call number 184,
339     and in Leopard it is a direct syscall with number 184.  */
340
341  if (gprs[0] == 0x67 /* SYS_SIGRETURN */)
342    {
343      uctx = (struct gcc_ucontext *) gprs[3];
344      is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
345		   || uctx->mcsize == UC_FLAVOR_VEC_SIZE);
346      is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
347	       || uctx->mcsize == UC_FLAVOR64_SIZE);
348    }
349  else if (gprs[0] == 0 /* SYS_syscall */ && gprs[3] == 184)
350    {
351      int ctxstyle = gprs[5];
352      uctx = (struct gcc_ucontext *) gprs[4];
353      is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
354		   || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
355      is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
356	       || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
357    }
358  else if (gprs[0] == 184 /* SYS_sigreturn */)
359    {
360      int ctxstyle = gprs[4];
361      uctx = (struct gcc_ucontext *) gprs[3];
362      is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
363		   || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
364      is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
365	       || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
366    }
367  else
368    return false;
369
370#define set_offset(r, addr)					\
371  (fs->regs.reg[r].how = REG_SAVED_OFFSET,			\
372   fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa)
373
374  /* Restore even the registers that are not call-saved, since they
375     might be being used in the prologue to save other registers,
376     for instance GPR0 is sometimes used to save LR.  */
377
378  /* Handle the GPRs, and produce the information needed to do the rest.  */
379  if (is_64)
380    {
381      /* The context is 64-bit, but it doesn't carry any extra information
382	 for us because only the low 32 bits of the registers are
383	 call-saved.  */
384      struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext;
385      int i;
386
387      float_vector_state = &m64->fvs;
388
389      new_cfa = m64->gpr[1][1];
390
391      set_offset (R_CR2, &m64->cr);
392      for (i = 0; i < 32; i++)
393	set_offset (i, m64->gpr[i] + 1);
394      set_offset (R_XER, m64->xer + 1);
395      set_offset (R_LR, m64->lr + 1);
396      set_offset (R_CTR, m64->ctr + 1);
397      if (is_vector)
398	set_offset (R_VRSAVE, &m64->vrsave);
399
400      /* Sometimes, srr0 points to the instruction that caused the exception,
401	 and sometimes to the next instruction to be executed; we want
402	 the latter.  */
403      if (m64->exception == 3 || m64->exception == 4
404	  || m64->exception == 6
405	  || (m64->exception == 7 && !(m64->srr1 & 0x10000)))
406	return_addr = m64->srr0 + 4;
407      else
408	return_addr = m64->srr0;
409    }
410  else
411    {
412      struct gcc_mcontext32 *m = uctx->mcontext;
413      int i;
414
415      float_vector_state = &m->fvs;
416
417      new_cfa = m->gpr[1];
418
419      set_offset (R_CR2, &m->cr);
420      for (i = 0; i < 32; i++)
421	set_offset (i, m->gpr + i);
422      set_offset (R_XER, &m->xer);
423      set_offset (R_LR, &m->lr);
424      set_offset (R_CTR, &m->ctr);
425
426      if (is_vector)
427	set_offset (R_VRSAVE, &m->vrsave);
428
429      /* Sometimes, srr0 points to the instruction that caused the exception,
430	 and sometimes to the next instruction to be executed; we want
431	 the latter.  */
432      if (m->exception == 3 || m->exception == 4
433	  || m->exception == 6
434	  || (m->exception == 7 && !(m->srr1 & 0x10000)))
435	return_addr = m->srr0 + 4;
436      else
437	return_addr = m->srr0;
438    }
439
440  fs->regs.cfa_how = CFA_REG_OFFSET;
441  fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__;
442  fs->regs.cfa_offset = new_cfa - old_cfa;;
443
444  /* The choice of column for the return address is somewhat tricky.
445     Fortunately, the actual choice is private to this file, and
446     the space it's reserved from is the GCC register space, not the
447     DWARF2 numbering.  So any free element of the right size is an OK
448     choice.  Thus: */
449  fs->retaddr_column = ARG_POINTER_REGNUM;
450  /* FIXME: this should really be done using a DWARF2 location expression,
451     not using a static variable.  In fact, this entire file should
452     be implemented in DWARF2 expressions.  */
453  set_offset (ARG_POINTER_REGNUM, &return_addr);
454
455  for (i = 0; i < 32; i++)
456    set_offset (32 + i, float_vector_state->fpregs + i);
457  set_offset (R_SPEFSCR, &float_vector_state->fpscr);
458
459  if (is_vector)
460    {
461      for (i = 0; i < 32; i++)
462	set_offset (R_VR0 + i, float_vector_state->save_vr + i);
463      set_offset (R_VSCR, float_vector_state->save_vscr);
464    }
465
466  return true;
467}
468
469/* This is also prototyped in rs6000/darwin.h, inside the
470   MD_FALLBACK_FRAME_STATE_FOR macro.  */
471extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
472					      _Unwind_FrameState *fs);
473
474/* Implement the MD_FALLBACK_FRAME_STATE_FOR macro,
475   returning true iff the frame was a sigreturn() frame that we
476   can understand.  */
477
478bool
479_Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
480				  _Unwind_FrameState *fs)
481{
482  reg_unit gprs[32];
483
484  if (!interpret_libc (gprs, context))
485    return false;
486  return handle_syscall (fs, gprs, _Unwind_GetCFA (context));
487}
488#endif
489