1 1.1 mrg /* Fallback frame-state unwinder for Darwin. 2 1.1.1.11 mrg Copyright (C) 2004-2024 Free Software Foundation, Inc. 3 1.1 mrg 4 1.1 mrg This file is part of GCC. 5 1.1 mrg 6 1.1 mrg GCC is free software; you can redistribute it and/or modify it 7 1.1 mrg under the terms of the GNU General Public License as published by 8 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg any later version. 10 1.1 mrg 11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT 12 1.1 mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 1.1 mrg License for more details. 15 1.1 mrg 16 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg You should have received a copy of the GNU General Public License and 21 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg <http://www.gnu.org/licenses/>. */ 24 1.1 mrg 25 1.1 mrg #ifdef __ppc__ 26 1.1 mrg 27 1.1 mrg #include "tconfig.h" 28 1.1 mrg #include "tsystem.h" 29 1.1 mrg #include "coretypes.h" 30 1.1 mrg #include "tm.h" 31 1.1 mrg #include "libgcc_tm.h" 32 1.1 mrg #include "dwarf2.h" 33 1.1 mrg #include "unwind.h" 34 1.1 mrg #include "unwind-dw2.h" 35 1.1 mrg #include <stdint.h> 36 1.1 mrg #include <stdbool.h> 37 1.1 mrg #include <sys/types.h> 38 1.1 mrg #include <signal.h> 39 1.1 mrg 40 1.1 mrg #define R_LR 65 41 1.1 mrg #define R_CTR 66 42 1.1 mrg #define R_CR2 70 43 1.1 mrg #define R_XER 76 44 1.1 mrg #define R_VR0 77 45 1.1 mrg #define R_VRSAVE 109 46 1.1 mrg #define R_VSCR 110 47 1.1 mrg #define R_SPEFSCR 112 48 1.1 mrg 49 1.1 mrg typedef unsigned long reg_unit; 50 1.1 mrg 51 1.1 mrg /* Place in GPRS the parameters to the first 'sc' instruction that would 52 1.1 mrg have been executed if we were returning from this CONTEXT, or 53 1.1 mrg return false if an unexpected instruction is encountered. */ 54 1.1 mrg 55 1.1 mrg static bool 56 1.1 mrg interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context) 57 1.1 mrg { 58 1.1 mrg uint32_t *pc = (uint32_t *)_Unwind_GetIP (context); 59 1.1 mrg uint32_t cr; 60 1.1 mrg reg_unit lr = (reg_unit) pc; 61 1.1 mrg reg_unit ctr = 0; 62 1.1 mrg uint32_t *invalid_address = NULL; 63 1.1 mrg 64 1.1 mrg int i; 65 1.1 mrg 66 1.1 mrg for (i = 0; i < 13; i++) 67 1.1 mrg gprs[i] = 1; 68 1.1 mrg gprs[1] = _Unwind_GetCFA (context); 69 1.1 mrg for (; i < 32; i++) 70 1.1 mrg gprs[i] = _Unwind_GetGR (context, i); 71 1.1 mrg cr = _Unwind_GetGR (context, R_CR2); 72 1.1 mrg 73 1.1 mrg /* For each supported Libc, we have to track the code flow 74 1.1 mrg all the way back into the kernel. 75 1.1 mrg 76 1.1 mrg This code is believed to support all released Libc/Libsystem builds since 77 1.1 mrg Jaguar 6C115, including all the security updates. To be precise, 78 1.1 mrg 79 1.1 mrg Libc Libsystem Build(s) 80 1.1 mrg 262~1 60~37 6C115 81 1.1 mrg 262~1 60.2~4 6D52 82 1.1 mrg 262~1 61~3 6F21-6F22 83 1.1 mrg 262~1 63~24 6G30-6G37 84 1.1 mrg 262~1 63~32 6I34-6I35 85 1.1 mrg 262~1 63~64 6L29-6L60 86 1.1 mrg 262.4.1~1 63~84 6L123-6R172 87 1.1 mrg 88 1.1 mrg 320~1 71~101 7B85-7D28 89 1.1 mrg 320~1 71~266 7F54-7F56 90 1.1 mrg 320~1 71~288 7F112 91 1.1 mrg 320~1 71~289 7F113 92 1.1 mrg 320.1.3~1 71.1.1~29 7H60-7H105 93 1.1 mrg 320.1.3~1 71.1.1~30 7H110-7H113 94 1.1 mrg 320.1.3~1 71.1.1~31 7H114 95 1.1 mrg 96 1.1 mrg That's a big table! It would be insane to try to keep track of 97 1.1 mrg every little detail, so we just read the code itself and do what 98 1.1 mrg it would do. 99 1.1 mrg */ 100 1.1 mrg 101 1.1 mrg for (;;) 102 1.1 mrg { 103 1.1 mrg uint32_t ins = *pc++; 104 1.1 mrg 105 1.1 mrg if ((ins & 0xFC000003) == 0x48000000) /* b instruction */ 106 1.1 mrg { 107 1.1 mrg pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4; 108 1.1 mrg continue; 109 1.1 mrg } 110 1.1 mrg if ((ins & 0xFC600000) == 0x2C000000) /* cmpwi */ 111 1.1 mrg { 112 1.1 mrg int32_t val1 = (int16_t) ins; 113 1.1 mrg int32_t val2 = gprs[ins >> 16 & 0x1F]; 114 1.1 mrg /* Only beq and bne instructions are supported, so we only 115 1.1 mrg need to set the EQ bit. */ 116 1.1 mrg uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C); 117 1.1 mrg if (val1 == val2) 118 1.1 mrg cr |= mask; 119 1.1 mrg else 120 1.1 mrg cr &= ~mask; 121 1.1 mrg continue; 122 1.1 mrg } 123 1.1 mrg if ((ins & 0xFEC38003) == 0x40820000) /* forwards beq/bne */ 124 1.1 mrg { 125 1.1 mrg if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1)) 126 1.1 mrg pc += (ins & 0x7FFC) / 4 - 1; 127 1.1 mrg continue; 128 1.1 mrg } 129 1.1 mrg if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */ 130 1.1 mrg { 131 1.1 mrg gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F] 132 1.1 mrg | gprs [ins >> 21 & 0x1F]); 133 1.1 mrg continue; 134 1.1 mrg } 135 1.1 mrg if (ins >> 26 == 0x0E) /* addi, including li */ 136 1.1 mrg { 137 1.1 mrg reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 138 1.1 mrg gprs [ins >> 21 & 0x1F] = src + (int16_t) ins; 139 1.1 mrg continue; 140 1.1 mrg } 141 1.1 mrg if (ins >> 26 == 0x0F) /* addis, including lis */ 142 1.1 mrg { 143 1.1 mrg reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 144 1.1 mrg gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16); 145 1.1 mrg continue; 146 1.1 mrg } 147 1.1 mrg if (ins >> 26 == 0x20) /* lwz */ 148 1.1 mrg { 149 1.1 mrg reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 150 1.1 mrg uint32_t *p = (uint32_t *)(src + (int16_t) ins); 151 1.1 mrg if (p == invalid_address) 152 1.1 mrg return false; 153 1.1 mrg gprs [ins >> 21 & 0x1F] = *p; 154 1.1 mrg continue; 155 1.1 mrg } 156 1.1 mrg if (ins >> 26 == 0x21) /* lwzu */ 157 1.1 mrg { 158 1.1 mrg uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins); 159 1.1 mrg if (p == invalid_address) 160 1.1 mrg return false; 161 1.1 mrg gprs [ins >> 21 & 0x1F] = *p; 162 1.1 mrg continue; 163 1.1 mrg } 164 1.1 mrg if (ins >> 26 == 0x24) /* stw */ 165 1.1 mrg /* What we hope this is doing is '--in_sigtramp'. We don't want 166 1.1 mrg to actually store to memory, so just make a note of the 167 1.1 mrg address and refuse to load from it. */ 168 1.1 mrg { 169 1.1 mrg reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 170 1.1 mrg uint32_t *p = (uint32_t *)(src + (int16_t) ins); 171 1.1 mrg if (p == NULL || invalid_address != NULL) 172 1.1 mrg return false; 173 1.1 mrg invalid_address = p; 174 1.1 mrg continue; 175 1.1 mrg } 176 1.1 mrg if (ins >> 26 == 0x2E) /* lmw */ 177 1.1 mrg { 178 1.1 mrg reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; 179 1.1 mrg uint32_t *p = (uint32_t *)(src + (int16_t) ins); 180 1.1 mrg int i; 181 1.1 mrg 182 1.1 mrg for (i = (ins >> 21 & 0x1F); i < 32; i++) 183 1.1 mrg { 184 1.1 mrg if (p == invalid_address) 185 1.1 mrg return false; 186 1.1 mrg gprs[i] = *p++; 187 1.1 mrg } 188 1.1 mrg continue; 189 1.1 mrg } 190 1.1 mrg if ((ins & 0xFC1FFFFF) == 0x7c0803a6) /* mtlr */ 191 1.1 mrg { 192 1.1 mrg lr = gprs [ins >> 21 & 0x1F]; 193 1.1 mrg continue; 194 1.1 mrg } 195 1.1 mrg if ((ins & 0xFC1FFFFF) == 0x7c0802a6) /* mflr */ 196 1.1 mrg { 197 1.1 mrg gprs [ins >> 21 & 0x1F] = lr; 198 1.1 mrg continue; 199 1.1 mrg } 200 1.1 mrg if ((ins & 0xFC1FFFFF) == 0x7c0903a6) /* mtctr */ 201 1.1 mrg { 202 1.1 mrg ctr = gprs [ins >> 21 & 0x1F]; 203 1.1 mrg continue; 204 1.1 mrg } 205 1.1 mrg /* The PowerPC User's Manual says that bit 11 of the mtcrf 206 1.1 mrg instruction is reserved and should be set to zero, but it 207 1.1 mrg looks like the Darwin assembler doesn't do that... */ 208 1.1 mrg if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */ 209 1.1 mrg { 210 1.1 mrg int i; 211 1.1 mrg uint32_t mask = 0; 212 1.1 mrg for (i = 0; i < 8; i++) 213 1.1 mrg mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i; 214 1.1 mrg cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask); 215 1.1 mrg continue; 216 1.1 mrg } 217 1.1 mrg if (ins == 0x429f0005) /* bcl- 20,4*cr7+so,.+4, loads pc into LR */ 218 1.1 mrg { 219 1.1 mrg lr = (reg_unit) pc; 220 1.1 mrg continue; 221 1.1 mrg } 222 1.1 mrg if (ins == 0x4e800420) /* bctr */ 223 1.1 mrg { 224 1.1 mrg pc = (uint32_t *) ctr; 225 1.1 mrg continue; 226 1.1 mrg } 227 1.1 mrg if (ins == 0x44000002) /* sc */ 228 1.1 mrg return true; 229 1.1 mrg 230 1.1 mrg return false; 231 1.1 mrg } 232 1.1 mrg } 233 1.1 mrg 234 1.1 mrg /* We used to include <ucontext.h> and <mach/thread_status.h>, 235 1.1 mrg but they change so much between different Darwin system versions 236 1.1 mrg that it's much easier to just write the structures involved here 237 1.1 mrg directly. */ 238 1.1 mrg 239 1.1 mrg /* These defines are from the kernel's bsd/dev/ppc/unix_signal.c. */ 240 1.1 mrg #define UC_TRAD 1 241 1.1 mrg #define UC_TRAD_VEC 6 242 1.1 mrg #define UC_TRAD64 20 243 1.1 mrg #define UC_TRAD64_VEC 25 244 1.1 mrg #define UC_FLAVOR 30 245 1.1 mrg #define UC_FLAVOR_VEC 35 246 1.1 mrg #define UC_FLAVOR64 40 247 1.1 mrg #define UC_FLAVOR64_VEC 45 248 1.1 mrg #define UC_DUAL 50 249 1.1 mrg #define UC_DUAL_VEC 55 250 1.1 mrg 251 1.1 mrg struct gcc_ucontext 252 1.1 mrg { 253 1.1 mrg int onstack; 254 1.1 mrg sigset_t sigmask; 255 1.1 mrg void * stack_sp; 256 1.1 mrg size_t stack_sz; 257 1.1 mrg int stack_flags; 258 1.1 mrg struct gcc_ucontext *link; 259 1.1 mrg size_t mcsize; 260 1.1 mrg struct gcc_mcontext32 *mcontext; 261 1.1 mrg }; 262 1.1 mrg 263 1.1 mrg struct gcc_float_vector_state 264 1.1 mrg { 265 1.1 mrg double fpregs[32]; 266 1.1 mrg uint32_t fpscr_pad; 267 1.1 mrg uint32_t fpscr; 268 1.1 mrg uint32_t save_vr[32][4]; 269 1.1 mrg uint32_t save_vscr[4]; 270 1.1 mrg }; 271 1.1 mrg 272 1.1 mrg struct gcc_mcontext32 { 273 1.1 mrg uint32_t dar; 274 1.1 mrg uint32_t dsisr; 275 1.1 mrg uint32_t exception; 276 1.1 mrg uint32_t padding1[5]; 277 1.1 mrg uint32_t srr0; 278 1.1 mrg uint32_t srr1; 279 1.1 mrg uint32_t gpr[32]; 280 1.1 mrg uint32_t cr; 281 1.1 mrg uint32_t xer; 282 1.1 mrg uint32_t lr; 283 1.1 mrg uint32_t ctr; 284 1.1 mrg uint32_t mq; 285 1.1 mrg uint32_t vrsave; 286 1.1 mrg struct gcc_float_vector_state fvs; 287 1.1 mrg }; 288 1.1 mrg 289 1.1 mrg /* These are based on /usr/include/ppc/ucontext.h and 290 1.1 mrg /usr/include/mach/ppc/thread_status.h, but rewritten to be more 291 1.1 mrg convenient, to compile on Jaguar, and to work around Radar 3712064 292 1.1 mrg on Panther, which is that the 'es' field of 'struct mcontext64' has 293 1.1 mrg the wrong type (doh!). */ 294 1.1 mrg 295 1.1 mrg struct gcc_mcontext64 { 296 1.1 mrg uint64_t dar; 297 1.1 mrg uint32_t dsisr; 298 1.1 mrg uint32_t exception; 299 1.1 mrg uint32_t padding1[4]; 300 1.1 mrg uint64_t srr0; 301 1.1 mrg uint64_t srr1; 302 1.1 mrg uint32_t gpr[32][2]; 303 1.1 mrg uint32_t cr; 304 1.1 mrg uint32_t xer[2]; /* These are arrays because the original structure has them misaligned. */ 305 1.1 mrg uint32_t lr[2]; 306 1.1 mrg uint32_t ctr[2]; 307 1.1 mrg uint32_t vrsave; 308 1.1 mrg struct gcc_float_vector_state fvs; 309 1.1 mrg }; 310 1.1 mrg 311 1.1 mrg #define UC_FLAVOR_SIZE \ 312 1.1 mrg (sizeof (struct gcc_mcontext32) - 33*16) 313 1.1 mrg 314 1.1 mrg #define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32)) 315 1.1 mrg 316 1.1 mrg #define UC_FLAVOR64_SIZE \ 317 1.1 mrg (sizeof (struct gcc_mcontext64) - 33*16) 318 1.1 mrg 319 1.1 mrg #define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64)) 320 1.1 mrg 321 1.1 mrg /* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS 322 1.1 mrg to represent the execution of a signal return; or, if not a signal 323 1.1 mrg return, return false. */ 324 1.1 mrg 325 1.1 mrg static bool 326 1.1 mrg handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32], 327 1.1 mrg _Unwind_Ptr old_cfa) 328 1.1 mrg { 329 1.1 mrg struct gcc_ucontext *uctx; 330 1.1 mrg bool is_64, is_vector; 331 1.1 mrg struct gcc_float_vector_state * float_vector_state; 332 1.1 mrg _Unwind_Ptr new_cfa; 333 1.1 mrg int i; 334 1.1 mrg static _Unwind_Ptr return_addr; 335 1.1 mrg 336 1.1 mrg /* Yay! We're in a Libc that we understand, and it's made a 337 1.1 mrg system call. In Jaguar, this is a direct system call with value 103; 338 1.1 mrg in Panther and Tiger it is a SYS_syscall call for system call number 184, 339 1.1 mrg and in Leopard it is a direct syscall with number 184. */ 340 1.1 mrg 341 1.1 mrg if (gprs[0] == 0x67 /* SYS_SIGRETURN */) 342 1.1 mrg { 343 1.1 mrg uctx = (struct gcc_ucontext *) gprs[3]; 344 1.1 mrg is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE 345 1.1 mrg || uctx->mcsize == UC_FLAVOR_VEC_SIZE); 346 1.1 mrg is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE 347 1.1 mrg || uctx->mcsize == UC_FLAVOR64_SIZE); 348 1.1 mrg } 349 1.1 mrg else if (gprs[0] == 0 /* SYS_syscall */ && gprs[3] == 184) 350 1.1 mrg { 351 1.1 mrg int ctxstyle = gprs[5]; 352 1.1 mrg uctx = (struct gcc_ucontext *) gprs[4]; 353 1.1 mrg is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC 354 1.1 mrg || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC); 355 1.1 mrg is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC 356 1.1 mrg || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64); 357 1.1 mrg } 358 1.1 mrg else if (gprs[0] == 184 /* SYS_sigreturn */) 359 1.1 mrg { 360 1.1 mrg int ctxstyle = gprs[4]; 361 1.1 mrg uctx = (struct gcc_ucontext *) gprs[3]; 362 1.1 mrg is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC 363 1.1 mrg || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC); 364 1.1 mrg is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC 365 1.1 mrg || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64); 366 1.1 mrg } 367 1.1 mrg else 368 1.1 mrg return false; 369 1.1 mrg 370 1.1 mrg #define set_offset(r, addr) \ 371 1.1.1.11 mrg (fs->regs.how[r] = REG_SAVED_OFFSET, \ 372 1.1 mrg fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa) 373 1.1 mrg 374 1.1 mrg /* Restore even the registers that are not call-saved, since they 375 1.1 mrg might be being used in the prologue to save other registers, 376 1.1 mrg for instance GPR0 is sometimes used to save LR. */ 377 1.1 mrg 378 1.1 mrg /* Handle the GPRs, and produce the information needed to do the rest. */ 379 1.1 mrg if (is_64) 380 1.1 mrg { 381 1.1 mrg /* The context is 64-bit, but it doesn't carry any extra information 382 1.1 mrg for us because only the low 32 bits of the registers are 383 1.1 mrg call-saved. */ 384 1.1 mrg struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext; 385 1.1 mrg int i; 386 1.1 mrg 387 1.1 mrg float_vector_state = &m64->fvs; 388 1.1 mrg 389 1.1 mrg new_cfa = m64->gpr[1][1]; 390 1.1 mrg 391 1.1 mrg set_offset (R_CR2, &m64->cr); 392 1.1 mrg for (i = 0; i < 32; i++) 393 1.1 mrg set_offset (i, m64->gpr[i] + 1); 394 1.1 mrg set_offset (R_XER, m64->xer + 1); 395 1.1 mrg set_offset (R_LR, m64->lr + 1); 396 1.1 mrg set_offset (R_CTR, m64->ctr + 1); 397 1.1 mrg if (is_vector) 398 1.1 mrg set_offset (R_VRSAVE, &m64->vrsave); 399 1.1 mrg 400 1.1 mrg /* Sometimes, srr0 points to the instruction that caused the exception, 401 1.1 mrg and sometimes to the next instruction to be executed; we want 402 1.1 mrg the latter. */ 403 1.1 mrg if (m64->exception == 3 || m64->exception == 4 404 1.1 mrg || m64->exception == 6 405 1.1 mrg || (m64->exception == 7 && !(m64->srr1 & 0x10000))) 406 1.1 mrg return_addr = m64->srr0 + 4; 407 1.1 mrg else 408 1.1 mrg return_addr = m64->srr0; 409 1.1 mrg } 410 1.1 mrg else 411 1.1 mrg { 412 1.1 mrg struct gcc_mcontext32 *m = uctx->mcontext; 413 1.1 mrg int i; 414 1.1 mrg 415 1.1 mrg float_vector_state = &m->fvs; 416 1.1 mrg 417 1.1 mrg new_cfa = m->gpr[1]; 418 1.1 mrg 419 1.1 mrg set_offset (R_CR2, &m->cr); 420 1.1 mrg for (i = 0; i < 32; i++) 421 1.1 mrg set_offset (i, m->gpr + i); 422 1.1 mrg set_offset (R_XER, &m->xer); 423 1.1 mrg set_offset (R_LR, &m->lr); 424 1.1 mrg set_offset (R_CTR, &m->ctr); 425 1.1 mrg 426 1.1 mrg if (is_vector) 427 1.1 mrg set_offset (R_VRSAVE, &m->vrsave); 428 1.1 mrg 429 1.1 mrg /* Sometimes, srr0 points to the instruction that caused the exception, 430 1.1 mrg and sometimes to the next instruction to be executed; we want 431 1.1 mrg the latter. */ 432 1.1 mrg if (m->exception == 3 || m->exception == 4 433 1.1 mrg || m->exception == 6 434 1.1 mrg || (m->exception == 7 && !(m->srr1 & 0x10000))) 435 1.1 mrg return_addr = m->srr0 + 4; 436 1.1 mrg else 437 1.1 mrg return_addr = m->srr0; 438 1.1 mrg } 439 1.1 mrg 440 1.1 mrg fs->regs.cfa_how = CFA_REG_OFFSET; 441 1.1.1.2 mrg fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__; 442 1.1 mrg fs->regs.cfa_offset = new_cfa - old_cfa;; 443 1.1 mrg 444 1.1 mrg /* The choice of column for the return address is somewhat tricky. 445 1.1 mrg Fortunately, the actual choice is private to this file, and 446 1.1 mrg the space it's reserved from is the GCC register space, not the 447 1.1 mrg DWARF2 numbering. So any free element of the right size is an OK 448 1.1 mrg choice. Thus: */ 449 1.1 mrg fs->retaddr_column = ARG_POINTER_REGNUM; 450 1.1 mrg /* FIXME: this should really be done using a DWARF2 location expression, 451 1.1 mrg not using a static variable. In fact, this entire file should 452 1.1 mrg be implemented in DWARF2 expressions. */ 453 1.1 mrg set_offset (ARG_POINTER_REGNUM, &return_addr); 454 1.1 mrg 455 1.1 mrg for (i = 0; i < 32; i++) 456 1.1 mrg set_offset (32 + i, float_vector_state->fpregs + i); 457 1.1 mrg set_offset (R_SPEFSCR, &float_vector_state->fpscr); 458 1.1 mrg 459 1.1 mrg if (is_vector) 460 1.1 mrg { 461 1.1 mrg for (i = 0; i < 32; i++) 462 1.1 mrg set_offset (R_VR0 + i, float_vector_state->save_vr + i); 463 1.1 mrg set_offset (R_VSCR, float_vector_state->save_vscr); 464 1.1 mrg } 465 1.1 mrg 466 1.1 mrg return true; 467 1.1 mrg } 468 1.1 mrg 469 1.1 mrg /* This is also prototyped in rs6000/darwin.h, inside the 470 1.1 mrg MD_FALLBACK_FRAME_STATE_FOR macro. */ 471 1.1 mrg extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context, 472 1.1 mrg _Unwind_FrameState *fs); 473 1.1 mrg 474 1.1 mrg /* Implement the MD_FALLBACK_FRAME_STATE_FOR macro, 475 1.1 mrg returning true iff the frame was a sigreturn() frame that we 476 1.1 mrg can understand. */ 477 1.1 mrg 478 1.1 mrg bool 479 1.1 mrg _Unwind_fallback_frame_state_for (struct _Unwind_Context *context, 480 1.1 mrg _Unwind_FrameState *fs) 481 1.1 mrg { 482 1.1 mrg reg_unit gprs[32]; 483 1.1 mrg 484 1.1 mrg if (!interpret_libc (gprs, context)) 485 1.1 mrg return false; 486 1.1 mrg return handle_syscall (fs, gprs, _Unwind_GetCFA (context)); 487 1.1 mrg } 488 1.1 mrg #endif 489