1 /* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux.
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
34 __attribute__ ((vector_size (16))) int vr[32];
49 unsigned long gpr[32];
52 unsigned long orig_gpr3;
62 unsigned long pad1[4];
71 struct gcc_vregs vregs;
77 unsigned long pad[28];
79 unsigned long pad[12];
81 struct gcc_regs *regs;
82 struct gcc_regs rsave;
87 enum { SIGNAL_FRAMESIZE = 128 };
89 /* If PC is at a sigreturn trampoline, return a pointer to the
90 regs. Otherwise return NULL. */
92 static struct gcc_regs *
93 get_regs (struct _Unwind_Context *context)
95 const unsigned int *pc = context->ra;
97 /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */
98 /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */
99 if (pc[0] != 0x38210000 + SIGNAL_FRAMESIZE || pc[2] != 0x44000002)
101 if (pc[1] == 0x38000077)
104 char gap[SIGNAL_FRAMESIZE];
105 unsigned long pad[7];
106 struct gcc_regs *regs;
107 } *frame = (struct sigframe *) context->cfa;
110 else if (pc[1] == 0x380000AC)
112 /* This works for 2.4 kernels, but not for 2.6 kernels with vdso
113 because pc isn't pointing into the stack. Can be removed when
114 no one is running 2.4.19 or 2.4.20, the first two ppc64
116 const struct rt_sigframe_24 {
119 struct gcc_ucontext *puc;
120 } *frame24 = (const struct rt_sigframe_24 *) context->ra;
122 /* Test for magic value in *puc of vdso. */
123 if ((long) frame24->puc != -21 * 8)
124 return frame24->puc->regs;
127 /* This works for 2.4.21 and later kernels. */
129 char gap[SIGNAL_FRAMESIZE];
130 struct gcc_ucontext uc;
131 unsigned long pad[2];
134 struct gcc_ucontext *puc;
135 } *frame = (struct rt_sigframe *) context->cfa;
136 return frame->uc.regs;
142 #else /* !__powerpc64__ */
144 enum { SIGNAL_FRAMESIZE = 64 };
146 static struct gcc_regs *
147 get_regs (struct _Unwind_Context *context)
149 const unsigned int *pc = context->ra;
151 /* li r0, 0x7777; sc (sigreturn old) */
152 /* li r0, 0x0077; sc (sigreturn new) */
153 /* li r0, 0x6666; sc (rt_sigreturn old) */
154 /* li r0, 0x00AC; sc (rt_sigreturn new) */
155 if (pc[1] != 0x44000002)
157 if (pc[0] == 0x38007777 || pc[0] == 0x38000077)
160 char gap[SIGNAL_FRAMESIZE];
161 unsigned long pad[7];
162 struct gcc_regs *regs;
163 } *frame = (struct sigframe *) context->cfa;
166 else if (pc[0] == 0x38006666 || pc[0] == 0x380000AC)
169 char gap[SIGNAL_FRAMESIZE + 16];
171 struct gcc_ucontext uc;
172 } *frame = (struct rt_sigframe *) context->cfa;
173 return frame->uc.regs;
179 /* Find an entry in the process auxiliary vector. The canonical way to
180 test for VMX is to look at AT_HWCAP. */
183 ppc_linux_aux_vector (long which)
185 /* __libc_stack_end holds the original stack passed to a process. */
186 extern long *__libc_stack_end;
196 /* The Linux kernel puts argc first on the stack. */
197 argc = __libc_stack_end[0];
198 /* Followed by argv, NULL terminated. */
199 argv = (char **) __libc_stack_end + 1;
200 /* Followed by environment string pointers, NULL terminated. */
201 envp = argv + argc + 1;
204 /* Followed by the aux vector, zero terminated. */
205 for (auxp = (struct auxv *) envp; auxp->a_type != 0; ++auxp)
206 if (auxp->a_type == which)
211 /* Do code reading to identify a signal frame, and set the frame
212 state data appropriately. See unwind-dw2.c for the structs. */
214 #define MD_FALLBACK_FRAME_STATE_FOR ppc_fallback_frame_state
216 static _Unwind_Reason_Code
217 ppc_fallback_frame_state (struct _Unwind_Context *context,
218 _Unwind_FrameState *fs)
220 static long hwcap = 0;
221 struct gcc_regs *regs = get_regs (context);
226 return _URC_END_OF_STACK;
228 new_cfa = regs->gpr[STACK_POINTER_REGNUM];
229 fs->regs.cfa_how = CFA_REG_OFFSET;
230 fs->regs.cfa_reg = STACK_POINTER_REGNUM;
231 fs->regs.cfa_offset = new_cfa - (long) context->cfa;
233 for (i = 0; i < 32; i++)
234 if (i != STACK_POINTER_REGNUM)
236 fs->regs.reg[i].how = REG_SAVED_OFFSET;
237 fs->regs.reg[i].loc.offset = (long) ®s->gpr[i] - new_cfa;
240 fs->regs.reg[R_CR2].how = REG_SAVED_OFFSET;
241 /* CR? regs are always 32-bit and PPC is big-endian, so in 64-bit
242 libgcc loc.offset needs to point to the low 32 bits of regs->ccr. */
243 fs->regs.reg[R_CR2].loc.offset = (long) ®s->ccr - new_cfa
246 fs->regs.reg[R_LR].how = REG_SAVED_OFFSET;
247 fs->regs.reg[R_LR].loc.offset = (long) ®s->link - new_cfa;
249 fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
250 fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) ®s->nip - new_cfa;
251 fs->retaddr_column = ARG_POINTER_REGNUM;
252 fs->signal_frame = 1;
256 hwcap = ppc_linux_aux_vector (16);
257 /* These will already be set if we found AT_HWCAP. A nonzero
258 value stops us looking again if for some reason we couldn't
267 /* If we have a FPU... */
268 if (hwcap & 0x08000000)
269 for (i = 0; i < 32; i++)
271 fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
272 fs->regs.reg[i + 32].loc.offset = (long) ®s->fpr[i] - new_cfa;
275 /* If we have a VMX unit... */
276 if (hwcap & 0x10000000)
278 struct gcc_vregs *vregs;
282 vregs = ®s->vregs;
284 if (regs->msr & (1 << 25))
286 for (i = 0; i < 32; i++)
288 fs->regs.reg[i + R_VR0].how = REG_SAVED_OFFSET;
289 fs->regs.reg[i + R_VR0].loc.offset
290 = (long) &vregs->vr[i] - new_cfa;
293 fs->regs.reg[R_VSCR].how = REG_SAVED_OFFSET;
294 fs->regs.reg[R_VSCR].loc.offset = (long) &vregs->vscr - new_cfa;
297 fs->regs.reg[R_VRSAVE].how = REG_SAVED_OFFSET;
298 fs->regs.reg[R_VRSAVE].loc.offset = (long) &vregs->vsave - new_cfa;
301 /* If we have SPE register high-parts... we check at compile-time to
302 avoid expanding the code for all other PowerPC. */
304 for (i = 0; i < 32; i++)
306 fs->regs.reg[i + FIRST_PSEUDO_REGISTER - 1].how = REG_SAVED_OFFSET;
307 fs->regs.reg[i + FIRST_PSEUDO_REGISTER - 1].loc.offset
308 = (long) ®s->vregs - new_cfa + 4 * i;
312 return _URC_NO_REASON;
315 #define MD_FROB_UPDATE_CONTEXT frob_update_context
318 frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATTRIBUTE_UNUSED)
320 const unsigned int *pc = (const unsigned int *) context->ra;
322 /* Fix up for 2.6.12 - 2.6.16 Linux kernels that have vDSO, but don't
323 have S flag in it. */
325 /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */
326 /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */
327 if (pc[0] == 0x38210000 + SIGNAL_FRAMESIZE
328 && (pc[1] == 0x38000077 || pc[1] == 0x380000AC)
329 && pc[2] == 0x44000002)
330 _Unwind_SetSignalFrame (context, 1);
332 /* li r0, 0x7777; sc (sigreturn old) */
333 /* li r0, 0x0077; sc (sigreturn new) */
334 /* li r0, 0x6666; sc (rt_sigreturn old) */
335 /* li r0, 0x00AC; sc (rt_sigreturn new) */
336 if ((pc[0] == 0x38007777 || pc[0] == 0x38000077
337 || pc[0] == 0x38006666 || pc[0] == 0x380000AC)
338 && pc[1] == 0x44000002)
339 _Unwind_SetSignalFrame (context, 1);
343 if (fs->regs.reg[2].how == REG_UNSAVED)
345 /* If the current unwind info (FS) does not contain explicit info
346 saving R2, then we have to do a minor amount of code reading to
347 figure out if it was saved. The big problem here is that the
348 code that does the save/restore is generated by the linker, so
349 we have no good way to determine at compile time what to do. */
350 if (pc[0] == 0xF8410028
351 || ((pc[0] & 0xFFFF0000) == 0x3D820000
352 && pc[1] == 0xF8410028))
354 /* We are in a plt call stub or r2 adjusting long branch stub,
355 before r2 has been saved. Keep REG_UNSAVED. */
360 = (unsigned int *) _Unwind_GetGR (context, R_LR);
361 if (insn && *insn == 0xE8410028)
362 _Unwind_SetGRPtr (context, 2, context->cfa + 40);
363 else if (pc[0] == 0x4E800421
364 && pc[1] == 0xE8410028)
366 /* We are at the bctrl instruction in a call via function
367 pointer. gcc always emits the load of the new R2 just
368 before the bctrl so this is the first and only place
369 we need to use the stored R2. */
370 _Unwind_Word sp = _Unwind_GetGR (context, 1);
371 _Unwind_SetGRPtr (context, 2, sp + 40);