1146895Skan/* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux. 2169689Skan Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 3146895Skan 4146895Skan This file is part of GCC. 5146895Skan 6146895Skan GCC is free software; you can redistribute it and/or modify it 7146895Skan under the terms of the GNU General Public License as published 8146895Skan by the Free Software Foundation; either version 2, or (at your 9146895Skan option) any later version. 10146895Skan 11146895Skan In addition to the permissions in the GNU General Public License, 12146895Skan the Free Software Foundation gives you unlimited permission to link 13146895Skan the compiled version of this file with other programs, and to 14146895Skan distribute those programs without any restriction coming from the 15146895Skan use of this file. (The General Public License restrictions do 16146895Skan apply in other respects; for example, they cover modification of 17146895Skan the file, and distribution when not linked into another program.) 18146895Skan 19146895Skan GCC is distributed in the hope that it will be useful, but WITHOUT 20146895Skan ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 21146895Skan or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22146895Skan License for more details. 23146895Skan 24146895Skan You should have received a copy of the GNU General Public License 25146895Skan along with GCC; see the file COPYING. If not, write to the 26169689Skan Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 27169689Skan MA 02110-1301, USA. */ 28146895Skan 29146895Skan/* This file defines our own versions of various kernel and user 30146895Skan structs, so that system headers are not needed, which otherwise 31146895Skan can make bootstrapping a new toolchain difficult. Do not use 32146895Skan these structs elsewhere; Many fields are missing, particularly 33146895Skan from the end of the structures. */ 34146895Skan 35146895Skanstruct gcc_vregs 36146895Skan{ 37146895Skan __attribute__ ((vector_size (16))) int vr[32]; 38146895Skan#ifdef __powerpc64__ 39146895Skan unsigned int pad1[3]; 40146895Skan unsigned int vscr; 41146895Skan unsigned int vsave; 42146895Skan unsigned int pad2[3]; 43146895Skan#else 44146895Skan unsigned int vsave; 45146895Skan unsigned int pad[2]; 46146895Skan unsigned int vscr; 47146895Skan#endif 48146895Skan}; 49146895Skan 50146895Skanstruct gcc_regs 51146895Skan{ 52146895Skan unsigned long gpr[32]; 53146895Skan unsigned long nip; 54146895Skan unsigned long msr; 55146895Skan unsigned long orig_gpr3; 56146895Skan unsigned long ctr; 57146895Skan unsigned long link; 58146895Skan unsigned long xer; 59146895Skan unsigned long ccr; 60146895Skan unsigned long softe; 61146895Skan unsigned long trap; 62146895Skan unsigned long dar; 63146895Skan unsigned long dsisr; 64146895Skan unsigned long result; 65146895Skan unsigned long pad1[4]; 66146895Skan double fpr[32]; 67146895Skan unsigned int pad2; 68146895Skan unsigned int fpscr; 69146895Skan#ifdef __powerpc64__ 70146895Skan struct gcc_vregs *vp; 71146895Skan#else 72146895Skan unsigned int pad3[2]; 73146895Skan#endif 74146895Skan struct gcc_vregs vregs; 75146895Skan}; 76146895Skan 77146895Skanstruct gcc_ucontext 78146895Skan{ 79146895Skan#ifdef __powerpc64__ 80146895Skan unsigned long pad[28]; 81146895Skan#else 82146895Skan unsigned long pad[12]; 83146895Skan#endif 84146895Skan struct gcc_regs *regs; 85146895Skan struct gcc_regs rsave; 86146895Skan}; 87146895Skan 88146895Skan#ifdef __powerpc64__ 89146895Skan 90146895Skanenum { SIGNAL_FRAMESIZE = 128 }; 91146895Skan 92146895Skan/* If PC is at a sigreturn trampoline, return a pointer to the 93146895Skan regs. Otherwise return NULL. */ 94146895Skan 95169689Skanstatic struct gcc_regs * 96169689Skanget_regs (struct _Unwind_Context *context) 97169689Skan{ 98169689Skan const unsigned char *pc = context->ra; 99146895Skan 100169689Skan /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ 101169689Skan /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ 102169689Skan if (*(unsigned int *) (pc + 0) != 0x38210000 + SIGNAL_FRAMESIZE 103169689Skan || *(unsigned int *) (pc + 8) != 0x44000002) 104169689Skan return NULL; 105169689Skan if (*(unsigned int *) (pc + 4) == 0x38000077) 106169689Skan { 107169689Skan struct sigframe { 108169689Skan char gap[SIGNAL_FRAMESIZE]; 109169689Skan unsigned long pad[7]; 110169689Skan struct gcc_regs *regs; 111169689Skan } *frame = (struct sigframe *) context->cfa; 112169689Skan return frame->regs; 113169689Skan } 114169689Skan else if (*(unsigned int *) (pc + 4) == 0x380000AC) 115169689Skan { 116169689Skan /* This works for 2.4 kernels, but not for 2.6 kernels with vdso 117169689Skan because pc isn't pointing into the stack. Can be removed when 118169689Skan no one is running 2.4.19 or 2.4.20, the first two ppc64 119169689Skan kernels released. */ 120169689Skan struct rt_sigframe_24 { 121169689Skan int tramp[6]; 122169689Skan void *pinfo; 123169689Skan struct gcc_ucontext *puc; 124169689Skan } *frame24 = (struct rt_sigframe_24 *) pc; 125146895Skan 126169689Skan /* Test for magic value in *puc of vdso. */ 127169689Skan if ((long) frame24->puc != -21 * 8) 128169689Skan return frame24->puc->regs; 129169689Skan else 130169689Skan { 131169689Skan /* This works for 2.4.21 and later kernels. */ 132169689Skan struct rt_sigframe { 133169689Skan char gap[SIGNAL_FRAMESIZE]; 134169689Skan struct gcc_ucontext uc; 135169689Skan unsigned long pad[2]; 136169689Skan int tramp[6]; 137169689Skan void *pinfo; 138169689Skan struct gcc_ucontext *puc; 139169689Skan } *frame = (struct rt_sigframe *) context->cfa; 140169689Skan return frame->uc.regs; 141169689Skan } 142169689Skan } 143169689Skan return NULL; 144169689Skan} 145146895Skan 146146895Skan#else /* !__powerpc64__ */ 147146895Skan 148146895Skanenum { SIGNAL_FRAMESIZE = 64 }; 149146895Skan 150169689Skanstatic struct gcc_regs * 151169689Skanget_regs (struct _Unwind_Context *context) 152169689Skan{ 153169689Skan const unsigned char *pc = context->ra; 154146895Skan 155169689Skan /* li r0, 0x7777; sc (sigreturn old) */ 156169689Skan /* li r0, 0x0077; sc (sigreturn new) */ 157169689Skan /* li r0, 0x6666; sc (rt_sigreturn old) */ 158169689Skan /* li r0, 0x00AC; sc (rt_sigreturn new) */ 159169689Skan if (*(unsigned int *) (pc + 4) != 0x44000002) 160169689Skan return NULL; 161169689Skan if (*(unsigned int *) (pc + 0) == 0x38007777 162169689Skan || *(unsigned int *) (pc + 0) == 0x38000077) 163169689Skan { 164169689Skan struct sigframe { 165169689Skan char gap[SIGNAL_FRAMESIZE]; 166169689Skan unsigned long pad[7]; 167169689Skan struct gcc_regs *regs; 168169689Skan } *frame = (struct sigframe *) context->cfa; 169169689Skan return frame->regs; 170169689Skan } 171169689Skan else if (*(unsigned int *) (pc + 0) == 0x38006666 172169689Skan || *(unsigned int *) (pc + 0) == 0x380000AC) 173169689Skan { 174169689Skan struct rt_sigframe { 175169689Skan char gap[SIGNAL_FRAMESIZE + 16]; 176169689Skan char siginfo[128]; 177169689Skan struct gcc_ucontext uc; 178169689Skan } *frame = (struct rt_sigframe *) context->cfa; 179169689Skan return frame->uc.regs; 180169689Skan } 181169689Skan return NULL; 182169689Skan} 183169689Skan#endif 184146895Skan 185169689Skan/* Find an entry in the process auxiliary vector. The canonical way to 186169689Skan test for VMX is to look at AT_HWCAP. */ 187146895Skan 188169689Skanstatic long 189169689Skanppc_linux_aux_vector (long which) 190169689Skan{ 191169689Skan /* __libc_stack_end holds the original stack passed to a process. */ 192169689Skan extern long *__libc_stack_end; 193169689Skan long argc; 194169689Skan char **argv; 195169689Skan char **envp; 196169689Skan struct auxv 197169689Skan { 198169689Skan long a_type; 199169689Skan long a_val; 200169689Skan } *auxp; 201146895Skan 202169689Skan /* The Linux kernel puts argc first on the stack. */ 203169689Skan argc = __libc_stack_end[0]; 204169689Skan /* Followed by argv, NULL terminated. */ 205169689Skan argv = (char **) __libc_stack_end + 1; 206169689Skan /* Followed by environment string pointers, NULL terminated. */ 207169689Skan envp = argv + argc + 1; 208169689Skan while (*envp++) 209169689Skan continue; 210169689Skan /* Followed by the aux vector, zero terminated. */ 211169689Skan for (auxp = (struct auxv *) envp; auxp->a_type != 0; ++auxp) 212169689Skan if (auxp->a_type == which) 213169689Skan return auxp->a_val; 214169689Skan return 0; 215169689Skan} 216169689Skan 217146895Skan/* Do code reading to identify a signal frame, and set the frame 218146895Skan state data appropriately. See unwind-dw2.c for the structs. */ 219146895Skan 220169689Skan#define MD_FALLBACK_FRAME_STATE_FOR ppc_fallback_frame_state 221169689Skan 222169689Skanstatic _Unwind_Reason_Code 223169689Skanppc_fallback_frame_state (struct _Unwind_Context *context, 224169689Skan _Unwind_FrameState *fs) 225169689Skan{ 226169689Skan static long hwcap = 0; 227169689Skan struct gcc_regs *regs = get_regs (context); 228169689Skan long new_cfa; 229169689Skan int i; 230169689Skan 231169689Skan if (regs == NULL) 232169689Skan return _URC_END_OF_STACK; 233169689Skan 234169689Skan new_cfa = regs->gpr[STACK_POINTER_REGNUM]; 235169689Skan fs->cfa_how = CFA_REG_OFFSET; 236169689Skan fs->cfa_reg = STACK_POINTER_REGNUM; 237169689Skan fs->cfa_offset = new_cfa - (long) context->cfa; 238169689Skan 239169689Skan for (i = 0; i < 32; i++) 240169689Skan if (i != STACK_POINTER_REGNUM) 241169689Skan { 242169689Skan fs->regs.reg[i].how = REG_SAVED_OFFSET; 243169689Skan fs->regs.reg[i].loc.offset = (long) ®s->gpr[i] - new_cfa; 244169689Skan } 245169689Skan 246169689Skan fs->regs.reg[CR2_REGNO].how = REG_SAVED_OFFSET; 247169689Skan fs->regs.reg[CR2_REGNO].loc.offset = (long) ®s->ccr - new_cfa; 248169689Skan 249169689Skan fs->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; 250169689Skan fs->regs.reg[LINK_REGISTER_REGNUM].loc.offset = (long) ®s->link - new_cfa; 251169689Skan 252169689Skan fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET; 253169689Skan fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) ®s->nip - new_cfa; 254169689Skan fs->retaddr_column = ARG_POINTER_REGNUM; 255169689Skan fs->signal_frame = 1; 256169689Skan 257169689Skan if (hwcap == 0) 258169689Skan { 259169689Skan hwcap = ppc_linux_aux_vector (16); 260169689Skan /* These will already be set if we found AT_HWCAP. A nonzero 261169689Skan value stops us looking again if for some reason we couldn't 262169689Skan find AT_HWCAP. */ 263169689Skan#ifdef __powerpc64__ 264169689Skan hwcap |= 0xc0000000; 265169689Skan#else 266169689Skan hwcap |= 0x80000000; 267169689Skan#endif 268169689Skan } 269169689Skan 270169689Skan /* If we have a FPU... */ 271169689Skan if (hwcap & 0x08000000) 272169689Skan for (i = 0; i < 32; i++) 273169689Skan { 274169689Skan fs->regs.reg[i + 32].how = REG_SAVED_OFFSET; 275169689Skan fs->regs.reg[i + 32].loc.offset = (long) ®s->fpr[i] - new_cfa; 276169689Skan } 277169689Skan 278169689Skan /* If we have a VMX unit... */ 279169689Skan if (hwcap & 0x10000000) 280169689Skan { 281169689Skan struct gcc_vregs *vregs; 282169689Skan#ifdef __powerpc64__ 283169689Skan vregs = regs->vp; 284169689Skan#else 285169689Skan vregs = ®s->vregs; 286169689Skan#endif 287169689Skan if (regs->msr & (1 << 25)) 288169689Skan { 289169689Skan for (i = 0; i < 32; i++) 290169689Skan { 291169689Skan fs->regs.reg[i + FIRST_ALTIVEC_REGNO].how = REG_SAVED_OFFSET; 292169689Skan fs->regs.reg[i + FIRST_ALTIVEC_REGNO].loc.offset 293169689Skan = (long) &vregs[i] - new_cfa; 294169689Skan } 295169689Skan 296169689Skan fs->regs.reg[VSCR_REGNO].how = REG_SAVED_OFFSET; 297169689Skan fs->regs.reg[VSCR_REGNO].loc.offset = (long) &vregs->vscr - new_cfa; 298169689Skan } 299169689Skan 300169689Skan fs->regs.reg[VRSAVE_REGNO].how = REG_SAVED_OFFSET; 301169689Skan fs->regs.reg[VRSAVE_REGNO].loc.offset = (long) &vregs->vsave - new_cfa; 302169689Skan } 303169689Skan 304169689Skan return _URC_NO_REASON; 305169689Skan} 306169689Skan 307169689Skan#define MD_FROB_UPDATE_CONTEXT frob_update_context 308169689Skan 309169689Skanstatic void 310169689Skanfrob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATTRIBUTE_UNUSED) 311169689Skan{ 312169689Skan const unsigned int *pc = (const unsigned int *) context->ra; 313169689Skan 314169689Skan /* Fix up for 2.6.12 - 2.6.16 Linux kernels that have vDSO, but don't 315169689Skan have S flag in it. */ 316169689Skan#ifdef __powerpc64__ 317169689Skan /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ 318169689Skan /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ 319169689Skan if (pc[0] == 0x38210000 + SIGNAL_FRAMESIZE 320169689Skan && (pc[1] == 0x38000077 || pc[1] == 0x380000AC) 321169689Skan && pc[2] == 0x44000002) 322169689Skan _Unwind_SetSignalFrame (context, 1); 323169689Skan#else 324169689Skan /* li r0, 0x7777; sc (sigreturn old) */ 325169689Skan /* li r0, 0x0077; sc (sigreturn new) */ 326169689Skan /* li r0, 0x6666; sc (rt_sigreturn old) */ 327169689Skan /* li r0, 0x00AC; sc (rt_sigreturn new) */ 328169689Skan if ((pc[0] == 0x38007777 || pc[0] == 0x38000077 329169689Skan || pc[0] == 0x38006666 || pc[0] == 0x380000AC) 330169689Skan && pc[1] == 0x44000002) 331169689Skan _Unwind_SetSignalFrame (context, 1); 332169689Skan#endif 333169689Skan 334169689Skan#ifdef __powerpc64__ 335169689Skan if (fs->regs.reg[2].how == REG_UNSAVED) 336169689Skan { 337169689Skan /* If the current unwind info (FS) does not contain explicit info 338169689Skan saving R2, then we have to do a minor amount of code reading to 339169689Skan figure out if it was saved. The big problem here is that the 340169689Skan code that does the save/restore is generated by the linker, so 341169689Skan we have no good way to determine at compile time what to do. */ 342169689Skan unsigned int *insn 343169689Skan = (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM); 344169689Skan if (*insn == 0xE8410028) 345169689Skan _Unwind_SetGRPtr (context, 2, context->cfa + 40); 346169689Skan } 347169689Skan#endif 348169689Skan} 349