1 /* Fallback frame-state unwinder for Darwin.
2    Copyright (C) 2004, 2005 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 2, or (at your option)
9    any later version.
10 
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
18    executable.)
19 
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.
24 
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
28    02110-1301, USA.  */
29 
30 #include "tconfig.h"
31 #include "tsystem.h"
32 #include "coretypes.h"
33 #include "tm.h"
34 #include "dwarf2.h"
35 #include "unwind.h"
36 #include "unwind-dw2.h"
37 #include <stdint.h>
38 #include <stdbool.h>
39 #include <sys/types.h>
40 #include <signal.h>
41 
42 typedef unsigned long reg_unit;
43 
44 /* Place in GPRS the parameters to the first 'sc' instruction that would
45    have been executed if we were returning from this CONTEXT, or
46    return false if an unexpected instruction is encountered.  */
47 
48 static bool
interpret_libc(reg_unit gprs[32],struct _Unwind_Context * context)49 interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
50 {
51   uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
52   uint32_t cr;
53   reg_unit lr = (reg_unit) pc;
54   reg_unit ctr = 0;
55   uint32_t *invalid_address = NULL;
56 
57   int i;
58 
59   for (i = 0; i < 13; i++)
60     gprs[i] = 1;
61   gprs[1] = _Unwind_GetCFA (context);
62   for (; i < 32; i++)
63     gprs[i] = _Unwind_GetGR (context, i);
64   cr = _Unwind_GetGR (context, CR2_REGNO);
65 
66   /* For each supported Libc, we have to track the code flow
67      all the way back into the kernel.
68 
69      This code is believed to support all released Libc/Libsystem builds since
70      Jaguar 6C115, including all the security updates.  To be precise,
71 
72      Libc	Libsystem	Build(s)
73      262~1	60~37		6C115
74      262~1	60.2~4		6D52
75      262~1	61~3		6F21-6F22
76      262~1	63~24		6G30-6G37
77      262~1	63~32		6I34-6I35
78      262~1	63~64		6L29-6L60
79      262.4.1~1	63~84		6L123-6R172
80 
81      320~1	71~101		7B85-7D28
82      320~1	71~266		7F54-7F56
83      320~1	71~288		7F112
84      320~1	71~289		7F113
85      320.1.3~1	71.1.1~29	7H60-7H105
86      320.1.3~1	71.1.1~30	7H110-7H113
87      320.1.3~1	71.1.1~31	7H114
88 
89      That's a big table!  It would be insane to try to keep track of
90      every little detail, so we just read the code itself and do what
91      it would do.
92   */
93 
94   for (;;)
95     {
96       uint32_t ins = *pc++;
97 
98       if ((ins & 0xFC000003) == 0x48000000)  /* b instruction */
99 	{
100 	  pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
101 	  continue;
102 	}
103       if ((ins & 0xFC600000) == 0x2C000000)  /* cmpwi */
104 	{
105 	  int32_t val1 = (int16_t) ins;
106 	  int32_t val2 = gprs[ins >> 16 & 0x1F];
107 	  /* Only beq and bne instructions are supported, so we only
108 	     need to set the EQ bit.  */
109 	  uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
110 	  if (val1 == val2)
111 	    cr |= mask;
112 	  else
113 	    cr &= ~mask;
114 	  continue;
115 	}
116       if ((ins & 0xFEC38003) == 0x40820000)  /* forwards beq/bne */
117 	{
118 	  if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
119 	    pc += (ins & 0x7FFC) / 4 - 1;
120 	  continue;
121 	}
122       if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
123 	{
124 	  gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
125 				     | gprs [ins >> 21 & 0x1F]);
126 	  continue;
127 	}
128       if (ins >> 26 == 0x0E)  /* addi, including li */
129 	{
130 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
131 	  gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
132 	  continue;
133 	}
134       if (ins >> 26 == 0x0F)  /* addis, including lis */
135 	{
136 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
137 	  gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
138 	  continue;
139 	}
140       if (ins >> 26 == 0x20)  /* lwz */
141 	{
142 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
143 	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
144 	  if (p == invalid_address)
145 	    return false;
146 	  gprs [ins >> 21 & 0x1F] = *p;
147 	  continue;
148 	}
149       if (ins >> 26 == 0x21)  /* lwzu */
150 	{
151 	  uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
152 	  if (p == invalid_address)
153 	    return false;
154 	  gprs [ins >> 21 & 0x1F] = *p;
155 	  continue;
156 	}
157       if (ins >> 26 == 0x24)  /* stw */
158 	/* What we hope this is doing is '--in_sigtramp'.  We don't want
159 	   to actually store to memory, so just make a note of the
160 	   address and refuse to load from it.  */
161 	{
162 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
163 	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
164 	  if (p == NULL || invalid_address != NULL)
165 	    return false;
166 	  invalid_address = p;
167 	  continue;
168 	}
169       if (ins >> 26 == 0x2E) /* lmw */
170 	{
171 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
172 	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
173 	  int i;
174 
175 	  for (i = (ins >> 21 & 0x1F); i < 32; i++)
176 	    {
177 	      if (p == invalid_address)
178 		return false;
179 	      gprs[i] = *p++;
180 	    }
181 	  continue;
182 	}
183       if ((ins & 0xFC1FFFFF) == 0x7c0803a6)  /* mtlr */
184 	{
185 	  lr = gprs [ins >> 21 & 0x1F];
186 	  continue;
187 	}
188       if ((ins & 0xFC1FFFFF) == 0x7c0802a6)  /* mflr */
189 	{
190 	  gprs [ins >> 21 & 0x1F] = lr;
191 	  continue;
192 	}
193       if ((ins & 0xFC1FFFFF) == 0x7c0903a6)  /* mtctr */
194 	{
195 	  ctr = gprs [ins >> 21 & 0x1F];
196 	  continue;
197 	}
198       /* The PowerPC User's Manual says that bit 11 of the mtcrf
199 	 instruction is reserved and should be set to zero, but it
200 	 looks like the Darwin assembler doesn't do that... */
201       if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
202 	{
203 	  int i;
204 	  uint32_t mask = 0;
205 	  for (i = 0; i < 8; i++)
206 	    mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
207 	  cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
208 	  continue;
209 	}
210       if (ins == 0x429f0005)  /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
211 	{
212 	  lr = (reg_unit) pc;
213 	  continue;
214 	}
215       if (ins == 0x4e800420) /* bctr */
216 	{
217 	  pc = (uint32_t *) ctr;
218 	  continue;
219 	}
220       if (ins == 0x44000002) /* sc */
221 	return true;
222 
223       return false;
224     }
225 }
226 
227 /* We used to include <ucontext.h> and <mach/thread_status.h>,
228    but they change so much between different Darwin system versions
229    that it's much easier to just write the structures involved here
230    directly.  */
231 
232 /* These defines are from the kernel's bsd/dev/ppc/unix_signal.c.  */
233 #define UC_TRAD                 1
234 #define UC_TRAD_VEC             6
235 #define UC_TRAD64               20
236 #define UC_TRAD64_VEC           25
237 #define UC_FLAVOR               30
238 #define UC_FLAVOR_VEC           35
239 #define UC_FLAVOR64             40
240 #define UC_FLAVOR64_VEC         45
241 #define UC_DUAL                 50
242 #define UC_DUAL_VEC             55
243 
244 struct gcc_ucontext
245 {
246   int onstack;
247   sigset_t sigmask;
248   void * stack_sp;
249   size_t stack_sz;
250   int stack_flags;
251   struct gcc_ucontext *link;
252   size_t mcsize;
253   struct gcc_mcontext32 *mcontext;
254 };
255 
256 struct 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 
265 struct 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 
288 struct 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 
318 static bool
handle_syscall(_Unwind_FrameState * fs,const reg_unit gprs[32],_Unwind_Ptr old_cfa)319 handle_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.  */
455 extern 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 
462 bool
_Unwind_fallback_frame_state_for(struct _Unwind_Context * context,_Unwind_FrameState * fs)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