1/* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux.
2   Copyright (C) 2004-2022 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
8   by the Free Software Foundation; either version 3, or (at your
9   option) 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#define R_LR		65
26#define R_CR2		70
27#define R_CR3		71
28#define R_CR4		72
29#define R_VR0		77
30#define R_VRSAVE	109
31
32#ifdef __powerpc64__
33#if _CALL_ELF == 2
34#define TOC_SAVE_SLOT	24
35#else
36#define TOC_SAVE_SLOT	40
37#endif
38#endif
39
40struct gcc_vregs
41{
42  __attribute__ ((vector_size (16))) int vr[32];
43#ifdef __powerpc64__
44  unsigned int pad1[3];
45  unsigned int vscr;
46  unsigned int vsave;
47  unsigned int pad2[3];
48#else
49  unsigned int vsave;
50  unsigned int pad[2];
51  unsigned int vscr;
52#endif
53};
54
55struct gcc_regs
56{
57  unsigned long gpr[32];
58  unsigned long nip;
59  unsigned long msr;
60  unsigned long orig_gpr3;
61  unsigned long ctr;
62  unsigned long link;
63  unsigned long xer;
64  unsigned long ccr;
65  unsigned long softe;
66  unsigned long trap;
67  unsigned long dar;
68  unsigned long dsisr;
69  unsigned long result;
70  unsigned long pad1[4];
71  double fpr[32];
72  unsigned int pad2;
73  unsigned int fpscr;
74#ifdef __powerpc64__
75  struct gcc_vregs *vp;
76#else
77  unsigned int pad3[2];
78#endif
79  struct gcc_vregs vregs;
80};
81
82struct gcc_ucontext
83{
84#ifdef __powerpc64__
85  unsigned long pad[28];
86#else
87  unsigned long pad[12];
88#endif
89  struct gcc_regs *regs;
90  struct gcc_regs rsave;
91};
92
93#ifdef __powerpc64__
94
95enum { SIGNAL_FRAMESIZE = 128 };
96
97struct rt_sigframe {
98  char gap[SIGNAL_FRAMESIZE];
99  struct gcc_ucontext uc;
100  unsigned long pad[2];
101  int tramp[6];
102  void *pinfo;
103  struct gcc_ucontext *puc;
104};
105
106/* If PC is at a sigreturn trampoline, return a pointer to the
107   regs.  Otherwise return NULL.  */
108
109static struct gcc_regs *
110get_regs (struct _Unwind_Context *context)
111{
112  const unsigned int *pc = context->ra;
113
114  /* addi r1, r1, 128; li r0, 0x0077; sc  (sigreturn) */
115  /* addi r1, r1, 128; li r0, 0x00AC; sc  (rt_sigreturn) */
116  if (pc[0] != 0x38210000 + SIGNAL_FRAMESIZE || pc[2] != 0x44000002)
117    return NULL;
118  if (pc[1] == 0x38000077)
119    {
120      struct sigframe {
121	char gap[SIGNAL_FRAMESIZE];
122	unsigned long pad[7];
123	struct gcc_regs *regs;
124      } *frame = (struct sigframe *) context->cfa;
125      return frame->regs;
126    }
127  else if (pc[1] == 0x380000AC)
128    {
129#if _CALL_ELF != 2
130      /* These old kernel versions never supported ELFv2.  */
131      /* This works for 2.4 kernels, but not for 2.6 kernels with vdso
132	 because pc isn't pointing into the stack.  Can be removed when
133	 no one is running 2.4.19 or 2.4.20, the first two ppc64
134	 kernels released.  */
135      const struct rt_sigframe_24 {
136	int tramp[6];
137	void *pinfo;
138	struct gcc_ucontext *puc;
139      } *frame24 = (const struct rt_sigframe_24 *) context->ra;
140
141      /* Test for magic value in *puc of vdso.  */
142      if ((long) frame24->puc != -21 * 8)
143	return frame24->puc->regs;
144      else
145#endif
146	{
147	  /* This works for 2.4.21 and later kernels.  */
148	  struct rt_sigframe *frame = (struct rt_sigframe *) context->cfa;
149	  return frame->uc.regs;
150	}
151    }
152  return NULL;
153}
154
155#else  /* !__powerpc64__ */
156
157enum { SIGNAL_FRAMESIZE = 64 };
158
159struct rt_sigframe {
160  char gap[SIGNAL_FRAMESIZE + 16];
161  char siginfo[128];
162  struct gcc_ucontext uc;
163};
164
165static struct gcc_regs *
166get_regs (struct _Unwind_Context *context)
167{
168  const unsigned int *pc = context->ra;
169
170  /* li r0, 0x7777; sc  (sigreturn old)  */
171  /* li r0, 0x0077; sc  (sigreturn new)  */
172  /* li r0, 0x6666; sc  (rt_sigreturn old)  */
173  /* li r0, 0x00AC; sc  (rt_sigreturn new)  */
174  if (pc[1] != 0x44000002)
175    return NULL;
176  if (pc[0] == 0x38007777 || pc[0] == 0x38000077)
177    {
178      struct sigframe {
179	char gap[SIGNAL_FRAMESIZE];
180	unsigned long pad[7];
181	struct gcc_regs *regs;
182      } *frame = (struct sigframe *) context->cfa;
183      return frame->regs;
184    }
185  else if (pc[0] == 0x38006666 || pc[0] == 0x380000AC)
186    {
187      struct rt_sigframe *frame = (struct rt_sigframe *) context->cfa;
188      return frame->uc.regs;
189    }
190  return NULL;
191}
192#endif
193
194/* Do code reading to identify a signal frame, and set the frame
195   state data appropriately.  See unwind-dw2.c for the structs.  */
196
197#define MD_FALLBACK_FRAME_STATE_FOR ppc_fallback_frame_state
198
199static _Unwind_Reason_Code
200ppc_fallback_frame_state (struct _Unwind_Context *context,
201			  _Unwind_FrameState *fs)
202{
203  struct gcc_regs *regs = get_regs (context);
204  struct gcc_vregs *vregs;
205  long cr_offset;
206  long new_cfa;
207  int i;
208
209  if (regs == NULL)
210    return _URC_NORMAL_STOP;
211
212  new_cfa = regs->gpr[__LIBGCC_STACK_POINTER_REGNUM__];
213  fs->regs.cfa_how = CFA_REG_OFFSET;
214  fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__;
215  fs->regs.cfa_offset = new_cfa - (long) context->cfa;
216
217#ifdef __powerpc64__
218  fs->regs.reg[2].how = REG_SAVED_OFFSET;
219  fs->regs.reg[2].loc.offset = (long) &regs->gpr[2] - new_cfa;
220#endif
221  for (i = 14; i < 32; i++)
222    {
223      fs->regs.reg[i].how = REG_SAVED_OFFSET;
224      fs->regs.reg[i].loc.offset = (long) &regs->gpr[i] - new_cfa;
225    }
226
227  /* The CR is saved in the low 32 bits of regs->ccr.  */
228  cr_offset = (long) &regs->ccr - new_cfa;
229#ifndef __LITTLE_ENDIAN__
230  cr_offset += sizeof (long) - 4;
231#endif
232  /* In the ELFv1 ABI, CR2 stands in for the whole CR.  */
233  fs->regs.reg[R_CR2].how = REG_SAVED_OFFSET;
234  fs->regs.reg[R_CR2].loc.offset = cr_offset;
235#if _CALL_ELF == 2
236  /* In the ELFv2 ABI, every CR field has a separate CFI entry.  */
237  fs->regs.reg[R_CR3].how = REG_SAVED_OFFSET;
238  fs->regs.reg[R_CR3].loc.offset = cr_offset;
239  fs->regs.reg[R_CR4].how = REG_SAVED_OFFSET;
240  fs->regs.reg[R_CR4].loc.offset = cr_offset;
241#endif
242
243  fs->regs.reg[R_LR].how = REG_SAVED_OFFSET;
244  fs->regs.reg[R_LR].loc.offset = (long) &regs->link - new_cfa;
245
246  fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
247  fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) &regs->nip - new_cfa;
248  fs->retaddr_column = ARG_POINTER_REGNUM;
249  fs->signal_frame = 1;
250
251  /* If we have a FPU...  */
252  for (i = 14; i < 32; i++)
253    {
254      fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
255      fs->regs.reg[i + 32].loc.offset = (long) &regs->fpr[i] - new_cfa;
256    }
257
258  /* If we have a VMX unit...  */
259#ifdef __powerpc64__
260  vregs = regs->vp;
261#else
262  vregs = &regs->vregs;
263#endif
264  if (regs->msr & (1 << 25))
265    {
266      for (i = 20; i < 32; i++)
267	{
268	  fs->regs.reg[i + R_VR0].how = REG_SAVED_OFFSET;
269	  fs->regs.reg[i + R_VR0].loc.offset = (long) &vregs->vr[i] - new_cfa;
270	}
271    }
272
273  fs->regs.reg[R_VRSAVE].how = REG_SAVED_OFFSET;
274  fs->regs.reg[R_VRSAVE].loc.offset = (long) &vregs->vsave - new_cfa;
275
276  /* If we have SPE register high-parts... we check at compile-time to
277     avoid expanding the code for all other PowerPC.  */
278#ifdef __SPE__
279  for (i = 14; i < 32; i++)
280    {
281      fs->regs.reg[i + FIRST_SPE_HIGH_REGNO - 4].how = REG_SAVED_OFFSET;
282      fs->regs.reg[i + FIRST_SPE_HIGH_REGNO - 4].loc.offset
283	= (long) &regs->vregs - new_cfa + 4 * i;
284    }
285#endif
286
287  return _URC_NO_REASON;
288}
289
290#define MD_FROB_UPDATE_CONTEXT frob_update_context
291
292static void
293frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATTRIBUTE_UNUSED)
294{
295  const unsigned int *pc = (const unsigned int *) context->ra;
296
297  /* Fix up for 2.6.12 - 2.6.16 Linux kernels that have vDSO, but don't
298     have S flag in it.  */
299#ifdef __powerpc64__
300  /* addi r1, r1, 128; li r0, 0x0077; sc  (sigreturn) */
301  /* addi r1, r1, 128; li r0, 0x00AC; sc  (rt_sigreturn) */
302  if (pc[0] == 0x38210000 + SIGNAL_FRAMESIZE
303      && (pc[1] == 0x38000077 || pc[1] == 0x380000AC)
304      && pc[2] == 0x44000002)
305    _Unwind_SetSignalFrame (context, 1);
306#else
307  /* li r0, 0x7777; sc  (sigreturn old)  */
308  /* li r0, 0x0077; sc  (sigreturn new)  */
309  /* li r0, 0x6666; sc  (rt_sigreturn old)  */
310  /* li r0, 0x00AC; sc  (rt_sigreturn new)  */
311  if ((pc[0] == 0x38007777 || pc[0] == 0x38000077
312       || pc[0] == 0x38006666 || pc[0] == 0x380000AC)
313      && pc[1] == 0x44000002)
314    _Unwind_SetSignalFrame (context, 1);
315#endif
316
317#ifdef __powerpc64__
318  if (fs->regs.reg[2].how == REG_UNSAVED)
319    {
320      /* If the current unwind info (FS) does not contain explicit info
321	 saving R2, then we have to do a minor amount of code reading to
322	 figure out if it was saved.  The big problem here is that the
323	 code that does the save/restore is generated by the linker, so
324	 we have no good way to determine at compile time what to do.  */
325      if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT
326#if _CALL_ELF != 2
327	  /* The ELFv2 linker never generates the old PLT stub form.  */
328	  || ((pc[0] & 0xFFFF0000) == 0x3D820000
329	      && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)
330#endif
331	  )
332	{
333	  /* We are in a plt call stub or r2 adjusting long branch stub,
334	     before r2 has been saved.  Keep REG_UNSAVED.  */
335	}
336      else
337	{
338	  unsigned int *insn
339	    = (unsigned int *) _Unwind_GetGR (context, R_LR);
340	  if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT)
341	    _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT);
342#if _CALL_ELF != 2
343	  /* ELFv2 does not use this function pointer call sequence.  */
344	  else if (pc[0] == 0x4E800421
345		   && pc[1] == 0xE8410000 + TOC_SAVE_SLOT)
346	    {
347	      /* We are at the bctrl instruction in a call via function
348		 pointer.  gcc always emits the load of the new R2 just
349		 before the bctrl so this is the first and only place
350		 we need to use the stored R2.  */
351	      _Unwind_Word sp = _Unwind_GetGR (context, 1);
352	      _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT));
353	    }
354#endif
355	}
356    }
357#endif
358}
359
360#define MD_BACKCHAIN_FALLBACK ppc_backchain_fallback
361
362struct trace_arg
363{
364  /* Stores the list of addresses.  */
365  void **array;
366  struct unwind_link *unwind_link;
367  _Unwind_Word cfa;
368  /* Number of addresses currently stored.  */
369  int count;
370  /* Maximum number of addresses.  */
371  int size;
372};
373
374/* This is the stack layout we see with every stack frame.
375   Note that every routine is required by the ABI to lay out the stack
376   like this.
377
378	    +----------------+        +-----------------+
379    %r1  -> | previous frame--------> | previous frame--->...  --> NULL
380	    |                |        |                 |
381	    | cr save        |        | cr save	        |
382	    |                |        |                 |
383	    | (unused)       |        | lr save         |
384	    +----------------+        +-----------------+
385
386  The CR save is only present on 64-bit ABIs.
387*/
388struct frame_layout
389{
390  struct frame_layout *backchain;
391#ifdef __powerpc64__
392  long int cr_save;
393#endif
394  void *lr_save;
395};
396
397
398static void
399ppc_backchain_fallback (struct _Unwind_Context *context, void *a)
400{
401  struct frame_layout *current;
402  struct trace_arg *arg = a;
403  int count;
404
405  /* Get the last address computed.  */
406  current = context->cfa;
407
408  /* If the trace CFA is not the context CFA the backtrace is done.  */
409  if (arg == NULL || arg->cfa != current)
410	return;
411
412  /* Start with next address.  */
413  current = current->backchain;
414
415  for (count = arg->count; current != NULL; current = current->backchain)
416    {
417      arg->array[count] = current->lr_save;
418
419      /* Check if the symbol is the signal trampoline and get the interrupted
420	 symbol address from the trampoline saved area.  */
421      context->ra = current->lr_save;
422      if (current->lr_save && get_regs (context))
423	{
424	  struct rt_sigframe *sigframe = (struct rt_sigframe *) current;
425	  if (count + 1 == arg->size)
426	    break;
427	  arg->array[++count] = (void *) sigframe->uc.rsave.nip;
428	  current = (void *) sigframe->uc.rsave.gpr[1];
429	}
430      if (count++ >= arg->size)
431	break;
432    }
433
434  arg->count = count-1;
435}
436