1169689Skan/* Fallback frame-state unwinder for Darwin. 2169689Skan Copyright (C) 2004, 2005 Free Software Foundation, Inc. 3169689Skan 4169689Skan This file is part of GCC. 5169689Skan 6169689Skan GCC is free software; you can redistribute it and/or modify it 7169689Skan under the terms of the GNU General Public License as published by 8169689Skan the Free Software Foundation; either version 2, or (at your option) 9169689Skan any later version. 10169689Skan 11169689Skan In addition to the permissions in the GNU General Public License, the 12169689Skan Free Software Foundation gives you unlimited permission to link the 13169689Skan compiled version of this file into combinations with other programs, 14169689Skan and to distribute those combinations without any restriction coming 15169689Skan from the use of this file. (The General Public License restrictions 16169689Skan do apply in other respects; for example, they cover modification of 17169689Skan the file, and distribution when not linked into a combined 18169689Skan executable.) 19169689Skan 20169689Skan GCC is distributed in the hope that it will be useful, but WITHOUT 21169689Skan ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 22169689Skan or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 23169689Skan License for more details. 24169689Skan 25169689Skan You should have received a copy of the GNU General Public License 26169689Skan along with GCC; see the file COPYING. If not, write to the Free 27169689Skan Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 28169689Skan 02110-1301, USA. */ 29169689Skan 30169689Skan#include "tconfig.h" 31169689Skan#include "tsystem.h" 32169689Skan#include "coretypes.h" 33169689Skan#include "tm.h" 34169689Skan#include "dwarf2.h" 35169689Skan#include "unwind.h" 36169689Skan#include "unwind-dw2.h" 37169689Skan#include <stdint.h> 38169689Skan#include <stdbool.h> 39169689Skan#include <sys/types.h> 40169689Skan#include <signal.h> 41169689Skan 42169689Skantypedef unsigned long reg_unit; 43169689Skan 44169689Skan/* Place in GPRS the parameters to the first 'sc' instruction that would 45169689Skan have been executed if we were returning from this CONTEXT, or 46169689Skan return false if an unexpected instruction is encountered. */ 47169689Skan 48169689Skanstatic bool 49169689Skaninterpret_libc (reg_unit gprs[32], struct _Unwind_Context *context) 50169689Skan{ 51169689Skan uint32_t *pc = (uint32_t *)_Unwind_GetIP (context); 52169689Skan uint32_t cr; 53169689Skan reg_unit lr = (reg_unit) pc; 54169689Skan reg_unit ctr = 0; 55169689Skan uint32_t *invalid_address = NULL; 56169689Skan 57169689Skan int i; 58169689Skan 59169689Skan for (i = 0; i < 13; i++) 60169689Skan gprs[i] = 1; 61169689Skan gprs[1] = _Unwind_GetCFA (context); 62169689Skan for (; i < 32; i++) 63169689Skan gprs[i] = _Unwind_GetGR (context, i); 64169689Skan cr = _Unwind_GetGR (context, CR2_REGNO); 65169689Skan 66169689Skan /* For each supported Libc, we have to track the code flow 67169689Skan all the way back into the kernel. 68169689Skan 69169689Skan This code is believed to support all released Libc/Libsystem builds since 70169689Skan Jaguar 6C115, including all the security updates. To be precise, 71169689Skan 72169689Skan Libc Libsystem Build(s) 73169689Skan 262~1 60~37 6C115 74169689Skan 262~1 60.2~4 6D52 75169689Skan 262~1 61~3 6F21-6F22 76169689Skan 262~1 63~24 6G30-6G37 77169689Skan 262~1 63~32 6I34-6I35 78169689Skan 262~1 63~64 6L29-6L60 79169689Skan 262.4.1~1 63~84 6L123-6R172 80169689Skan 81169689Skan 320~1 71~101 7B85-7D28 82169689Skan 320~1 71~266 7F54-7F56 83169689Skan 320~1 71~288 7F112 84169689Skan 320~1 71~289 7F113 85169689Skan 320.1.3~1 71.1.1~29 7H60-7H105 86169689Skan 320.1.3~1 71.1.1~30 7H110-7H113 87169689Skan 320.1.3~1 71.1.1~31 7H114 88169689Skan 89169689Skan That's a big table! It would be insane to try to keep track of 90169689Skan every little detail, so we just read the code itself and do what 91169689Skan it would do. 92169689Skan */ 93169689Skan 94169689Skan for (;;) 95169689Skan { 96169689Skan uint32_t ins = *pc++; 97169689Skan 98169689Skan if ((ins & 0xFC000003) == 0x48000000) /* b instruction */ 99169689Skan { 100169689Skan pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4; 101169689Skan continue; 102169689Skan } 103169689Skan if ((ins & 0xFC600000) == 0x2C000000) /* cmpwi */ 104169689Skan { 105169689Skan int32_t val1 = (int16_t) ins; 106169689Skan int32_t val2 = gprs[ins >> 16 & 0x1F]; 107169689Skan /* Only beq and bne instructions are supported, so we only 108169689Skan need to set the EQ bit. */ 109169689Skan uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C); 110169689Skan if (val1 == val2) 111169689Skan cr |= mask; 112169689Skan else 113169689Skan cr &= ~mask; 114169689Skan continue; 115169689Skan } 116169689Skan if ((ins & 0xFEC38003) == 0x40820000) /* forwards beq/bne */ 117169689Skan { 118169689Skan if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1)) 119169689Skan pc += (ins & 0x7FFC) / 4 - 1; 120169689Skan continue; 121169689Skan } 122169689Skan if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */ 123169689Skan { 124169689Skan gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F] 125169689Skan | gprs [ins >> 21 & 0x1F]); 126169689Skan continue; 127169689Skan } 128169689Skan if (ins >> 26 == 0x0E) /* addi, including li */ 129169689Skan { 130169689Skan reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 131169689Skan gprs [ins >> 21 & 0x1F] = src + (int16_t) ins; 132169689Skan continue; 133169689Skan } 134169689Skan if (ins >> 26 == 0x0F) /* addis, including lis */ 135169689Skan { 136169689Skan reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 137169689Skan gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16); 138169689Skan continue; 139169689Skan } 140169689Skan if (ins >> 26 == 0x20) /* lwz */ 141169689Skan { 142169689Skan reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 143169689Skan uint32_t *p = (uint32_t *)(src + (int16_t) ins); 144169689Skan if (p == invalid_address) 145169689Skan return false; 146169689Skan gprs [ins >> 21 & 0x1F] = *p; 147169689Skan continue; 148169689Skan } 149169689Skan if (ins >> 26 == 0x21) /* lwzu */ 150169689Skan { 151169689Skan uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins); 152169689Skan if (p == invalid_address) 153169689Skan return false; 154169689Skan gprs [ins >> 21 & 0x1F] = *p; 155169689Skan continue; 156169689Skan } 157169689Skan if (ins >> 26 == 0x24) /* stw */ 158169689Skan /* What we hope this is doing is '--in_sigtramp'. We don't want 159169689Skan to actually store to memory, so just make a note of the 160169689Skan address and refuse to load from it. */ 161169689Skan { 162169689Skan reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 163169689Skan uint32_t *p = (uint32_t *)(src + (int16_t) ins); 164169689Skan if (p == NULL || invalid_address != NULL) 165169689Skan return false; 166169689Skan invalid_address = p; 167169689Skan continue; 168169689Skan } 169169689Skan if (ins >> 26 == 0x2E) /* lmw */ 170169689Skan { 171169689Skan reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 172169689Skan uint32_t *p = (uint32_t *)(src + (int16_t) ins); 173169689Skan int i; 174169689Skan 175169689Skan for (i = (ins >> 21 & 0x1F); i < 32; i++) 176169689Skan { 177169689Skan if (p == invalid_address) 178169689Skan return false; 179169689Skan gprs[i] = *p++; 180169689Skan } 181169689Skan continue; 182169689Skan } 183169689Skan if ((ins & 0xFC1FFFFF) == 0x7c0803a6) /* mtlr */ 184169689Skan { 185169689Skan lr = gprs [ins >> 21 & 0x1F]; 186169689Skan continue; 187169689Skan } 188169689Skan if ((ins & 0xFC1FFFFF) == 0x7c0802a6) /* mflr */ 189169689Skan { 190169689Skan gprs [ins >> 21 & 0x1F] = lr; 191169689Skan continue; 192169689Skan } 193169689Skan if ((ins & 0xFC1FFFFF) == 0x7c0903a6) /* mtctr */ 194169689Skan { 195169689Skan ctr = gprs [ins >> 21 & 0x1F]; 196169689Skan continue; 197169689Skan } 198169689Skan /* The PowerPC User's Manual says that bit 11 of the mtcrf 199169689Skan instruction is reserved and should be set to zero, but it 200169689Skan looks like the Darwin assembler doesn't do that... */ 201169689Skan if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */ 202169689Skan { 203169689Skan int i; 204169689Skan uint32_t mask = 0; 205169689Skan for (i = 0; i < 8; i++) 206169689Skan mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i; 207169689Skan cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask); 208169689Skan continue; 209169689Skan } 210169689Skan if (ins == 0x429f0005) /* bcl- 20,4*cr7+so,.+4, loads pc into LR */ 211169689Skan { 212169689Skan lr = (reg_unit) pc; 213169689Skan continue; 214169689Skan } 215169689Skan if (ins == 0x4e800420) /* bctr */ 216169689Skan { 217169689Skan pc = (uint32_t *) ctr; 218169689Skan continue; 219169689Skan } 220169689Skan if (ins == 0x44000002) /* sc */ 221169689Skan return true; 222169689Skan 223169689Skan return false; 224169689Skan } 225169689Skan} 226169689Skan 227169689Skan/* We used to include <ucontext.h> and <mach/thread_status.h>, 228169689Skan but they change so much between different Darwin system versions 229169689Skan that it's much easier to just write the structures involved here 230169689Skan directly. */ 231169689Skan 232169689Skan/* These defines are from the kernel's bsd/dev/ppc/unix_signal.c. */ 233169689Skan#define UC_TRAD 1 234169689Skan#define UC_TRAD_VEC 6 235169689Skan#define UC_TRAD64 20 236169689Skan#define UC_TRAD64_VEC 25 237169689Skan#define UC_FLAVOR 30 238169689Skan#define UC_FLAVOR_VEC 35 239169689Skan#define UC_FLAVOR64 40 240169689Skan#define UC_FLAVOR64_VEC 45 241169689Skan#define UC_DUAL 50 242169689Skan#define UC_DUAL_VEC 55 243169689Skan 244169689Skanstruct gcc_ucontext 245169689Skan{ 246169689Skan int onstack; 247169689Skan sigset_t sigmask; 248169689Skan void * stack_sp; 249169689Skan size_t stack_sz; 250169689Skan int stack_flags; 251169689Skan struct gcc_ucontext *link; 252169689Skan size_t mcsize; 253169689Skan struct gcc_mcontext32 *mcontext; 254169689Skan}; 255169689Skan 256169689Skanstruct gcc_float_vector_state 257169689Skan{ 258169689Skan double fpregs[32]; 259169689Skan uint32_t fpscr_pad; 260169689Skan uint32_t fpscr; 261169689Skan uint32_t save_vr[32][4]; 262169689Skan uint32_t save_vscr[4]; 263169689Skan}; 264169689Skan 265169689Skanstruct gcc_mcontext32 { 266169689Skan uint32_t dar; 267169689Skan uint32_t dsisr; 268169689Skan uint32_t exception; 269169689Skan uint32_t padding1[5]; 270169689Skan uint32_t srr0; 271169689Skan uint32_t srr1; 272169689Skan uint32_t gpr[32]; 273169689Skan uint32_t cr; 274169689Skan uint32_t xer; 275169689Skan uint32_t lr; 276169689Skan uint32_t ctr; 277169689Skan uint32_t mq; 278169689Skan uint32_t vrsave; 279169689Skan struct gcc_float_vector_state fvs; 280169689Skan}; 281169689Skan 282169689Skan/* These are based on /usr/include/ppc/ucontext.h and 283169689Skan /usr/include/mach/ppc/thread_status.h, but rewritten to be more 284169689Skan convenient, to compile on Jaguar, and to work around Radar 3712064 285169689Skan on Panther, which is that the 'es' field of 'struct mcontext64' has 286169689Skan the wrong type (doh!). */ 287169689Skan 288169689Skanstruct gcc_mcontext64 { 289169689Skan uint64_t dar; 290169689Skan uint32_t dsisr; 291169689Skan uint32_t exception; 292169689Skan uint32_t padding1[4]; 293169689Skan uint64_t srr0; 294169689Skan uint64_t srr1; 295169689Skan uint32_t gpr[32][2]; 296169689Skan uint32_t cr; 297169689Skan uint32_t xer[2]; /* These are arrays because the original structure has them misaligned. */ 298169689Skan uint32_t lr[2]; 299169689Skan uint32_t ctr[2]; 300169689Skan uint32_t vrsave; 301169689Skan struct gcc_float_vector_state fvs; 302169689Skan}; 303169689Skan 304169689Skan#define UC_FLAVOR_SIZE \ 305169689Skan (sizeof (struct gcc_mcontext32) - 33*16) 306169689Skan 307169689Skan#define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32)) 308169689Skan 309169689Skan#define UC_FLAVOR64_SIZE \ 310169689Skan (sizeof (struct gcc_mcontext64) - 33*16) 311169689Skan 312169689Skan#define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64)) 313169689Skan 314169689Skan/* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS 315169689Skan to represent the execution of a signal return; or, if not a signal 316169689Skan return, return false. */ 317169689Skan 318169689Skanstatic bool 319169689Skanhandle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32], 320169689Skan _Unwind_Ptr old_cfa) 321169689Skan{ 322169689Skan struct gcc_ucontext *uctx; 323169689Skan bool is_64, is_vector; 324169689Skan struct gcc_float_vector_state * float_vector_state; 325169689Skan _Unwind_Ptr new_cfa; 326169689Skan int i; 327169689Skan static _Unwind_Ptr return_addr; 328169689Skan 329169689Skan /* Yay! We're in a Libc that we understand, and it's made a 330169689Skan system call. It'll be one of two kinds: either a Jaguar-style 331169689Skan SYS_sigreturn, or a Panther-style 'syscall' call with 184, which 332169689Skan is also SYS_sigreturn. */ 333169689Skan 334169689Skan if (gprs[0] == 0x67 /* SYS_SIGRETURN */) 335169689Skan { 336169689Skan uctx = (struct gcc_ucontext *) gprs[3]; 337169689Skan is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE 338169689Skan || uctx->mcsize == UC_FLAVOR_VEC_SIZE); 339169689Skan is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE 340169689Skan || uctx->mcsize == UC_FLAVOR64_SIZE); 341169689Skan } 342169689Skan else if (gprs[0] == 0 && gprs[3] == 184) 343169689Skan { 344169689Skan int ctxstyle = gprs[5]; 345169689Skan uctx = (struct gcc_ucontext *) gprs[4]; 346169689Skan is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC 347169689Skan || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC); 348169689Skan is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC 349169689Skan || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64); 350169689Skan } 351169689Skan else 352169689Skan return false; 353169689Skan 354169689Skan#define set_offset(r, addr) \ 355169689Skan (fs->regs.reg[r].how = REG_SAVED_OFFSET, \ 356169689Skan fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa) 357169689Skan 358169689Skan /* Restore even the registers that are not call-saved, since they 359169689Skan might be being used in the prologue to save other registers, 360169689Skan for instance GPR0 is sometimes used to save LR. */ 361169689Skan 362169689Skan /* Handle the GPRs, and produce the information needed to do the rest. */ 363169689Skan if (is_64) 364169689Skan { 365169689Skan /* The context is 64-bit, but it doesn't carry any extra information 366169689Skan for us because only the low 32 bits of the registers are 367169689Skan call-saved. */ 368169689Skan struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext; 369169689Skan int i; 370169689Skan 371169689Skan float_vector_state = &m64->fvs; 372169689Skan 373169689Skan new_cfa = m64->gpr[1][1]; 374169689Skan 375169689Skan set_offset (CR2_REGNO, &m64->cr); 376169689Skan for (i = 0; i < 32; i++) 377169689Skan set_offset (i, m64->gpr[i] + 1); 378169689Skan set_offset (XER_REGNO, m64->xer + 1); 379169689Skan set_offset (LINK_REGISTER_REGNUM, m64->lr + 1); 380169689Skan set_offset (COUNT_REGISTER_REGNUM, m64->ctr + 1); 381169689Skan if (is_vector) 382169689Skan set_offset (VRSAVE_REGNO, &m64->vrsave); 383169689Skan 384169689Skan /* Sometimes, srr0 points to the instruction that caused the exception, 385169689Skan and sometimes to the next instruction to be executed; we want 386169689Skan the latter. */ 387169689Skan if (m64->exception == 3 || m64->exception == 4 388169689Skan || m64->exception == 6 389169689Skan || (m64->exception == 7 && !(m64->srr1 & 0x10000))) 390169689Skan return_addr = m64->srr0 + 4; 391169689Skan else 392169689Skan return_addr = m64->srr0; 393169689Skan } 394169689Skan else 395169689Skan { 396169689Skan struct gcc_mcontext32 *m = uctx->mcontext; 397169689Skan int i; 398169689Skan 399169689Skan float_vector_state = &m->fvs; 400169689Skan 401169689Skan new_cfa = m->gpr[1]; 402169689Skan 403169689Skan set_offset (CR2_REGNO, &m->cr); 404169689Skan for (i = 0; i < 32; i++) 405169689Skan set_offset (i, m->gpr + i); 406169689Skan set_offset (XER_REGNO, &m->xer); 407169689Skan set_offset (LINK_REGISTER_REGNUM, &m->lr); 408169689Skan set_offset (COUNT_REGISTER_REGNUM, &m->ctr); 409169689Skan 410169689Skan if (is_vector) 411169689Skan set_offset (VRSAVE_REGNO, &m->vrsave); 412169689Skan 413169689Skan /* Sometimes, srr0 points to the instruction that caused the exception, 414169689Skan and sometimes to the next instruction to be executed; we want 415169689Skan the latter. */ 416169689Skan if (m->exception == 3 || m->exception == 4 417169689Skan || m->exception == 6 418169689Skan || (m->exception == 7 && !(m->srr1 & 0x10000))) 419169689Skan return_addr = m->srr0 + 4; 420169689Skan else 421169689Skan return_addr = m->srr0; 422169689Skan } 423169689Skan 424169689Skan fs->cfa_how = CFA_REG_OFFSET; 425169689Skan fs->cfa_reg = STACK_POINTER_REGNUM; 426169689Skan fs->cfa_offset = new_cfa - old_cfa;; 427169689Skan 428169689Skan /* The choice of column for the return address is somewhat tricky. 429169689Skan Fortunately, the actual choice is private to this file, and 430169689Skan the space it's reserved from is the GCC register space, not the 431169689Skan DWARF2 numbering. So any free element of the right size is an OK 432169689Skan choice. Thus: */ 433169689Skan fs->retaddr_column = ARG_POINTER_REGNUM; 434169689Skan /* FIXME: this should really be done using a DWARF2 location expression, 435169689Skan not using a static variable. In fact, this entire file should 436169689Skan be implemented in DWARF2 expressions. */ 437169689Skan set_offset (ARG_POINTER_REGNUM, &return_addr); 438169689Skan 439169689Skan for (i = 0; i < 32; i++) 440169689Skan set_offset (32 + i, float_vector_state->fpregs + i); 441169689Skan set_offset (SPEFSCR_REGNO, &float_vector_state->fpscr); 442169689Skan 443169689Skan if (is_vector) 444169689Skan { 445169689Skan for (i = 0; i < 32; i++) 446169689Skan set_offset (FIRST_ALTIVEC_REGNO + i, float_vector_state->save_vr + i); 447169689Skan set_offset (VSCR_REGNO, float_vector_state->save_vscr); 448169689Skan } 449169689Skan 450169689Skan return true; 451169689Skan} 452169689Skan 453169689Skan/* This is also prototyped in rs6000/darwin.h, inside the 454169689Skan MD_FALLBACK_FRAME_STATE_FOR macro. */ 455169689Skanextern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context, 456169689Skan _Unwind_FrameState *fs); 457169689Skan 458169689Skan/* Implement the MD_FALLBACK_FRAME_STATE_FOR macro, 459169689Skan returning true iff the frame was a sigreturn() frame that we 460169689Skan can understand. */ 461169689Skan 462169689Skanbool 463169689Skan_Unwind_fallback_frame_state_for (struct _Unwind_Context *context, 464169689Skan _Unwind_FrameState *fs) 465169689Skan{ 466169689Skan reg_unit gprs[32]; 467169689Skan 468169689Skan if (!interpret_libc (gprs, context)) 469169689Skan return false; 470169689Skan return handle_syscall (fs, gprs, _Unwind_GetCFA (context)); 471169689Skan} 472