-#ifdef __powerpc64__
-
-/* If the current unwind info (FS) does not contain explicit info
- saving R2, then we have to do a minor amount of code reading to
- figure out if it was saved. The big problem here is that the
- code that does the save/restore is generated by the linker, so
- we have no good way to determine at compile time what to do. */
-
-#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
- do { \
- if ((FS)->regs.reg[2].how == REG_UNSAVED) \
- { \
- unsigned int *insn \
- = (unsigned int *) \
- _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
- if (*insn == 0xE8410028) \
- _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
- } \
- } while (0)
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
- do { \
- unsigned char *pc_ = (CONTEXT)->ra; \
- struct sigcontext *sc_; \
- long new_cfa_; \
- int i_; \
- \
- /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ \
- /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ \
- if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE \
- || *(unsigned int *) (pc_+8) != 0x44000002) \
- break; \
- if (*(unsigned int *) (pc_+4) == 0x38000077) \
- { \
- struct sigframe { \
- char gap[SIGNAL_FRAMESIZE]; \
- struct sigcontext sigctx; \
- } *rt_ = (CONTEXT)->cfa; \
- sc_ = &rt_->sigctx; \
- } \
- else if (*(unsigned int *) (pc_+4) == 0x380000AC) \
- { \
- struct rt_sigframe { \
- int tramp[6]; \
- struct siginfo *pinfo; \
- struct ucontext *puc; \
- } *rt_ = (struct rt_sigframe *) pc_; \
- sc_ = &rt_->puc->uc_mcontext; \
- } \
- else \
- break; \
- \
- new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
- (FS)->cfa_how = CFA_REG_OFFSET; \
- (FS)->cfa_reg = STACK_POINTER_REGNUM; \
- (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
- \
- for (i_ = 0; i_ < 32; i_++) \
- if (i_ != STACK_POINTER_REGNUM) \
- { \
- (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[i_].loc.offset \
- = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
- } \
- \
- (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
- = (long)&(sc_->regs->link) - new_cfa_; \
- \
- /* The unwinder expects the IP to point to the following insn, \
- whereas the kernel returns the address of the actual \
- faulting insn. We store NIP+4 in an unused register slot to \
- get the same result for multiple evaluation of the same signal \
- frame. */ \
- sc_->regs->gpr[47] = sc_->regs->nip + 4; \
- (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[CR0_REGNO].loc.offset \
- = (long)&(sc_->regs->gpr[47]) - new_cfa_; \
- (FS)->retaddr_column = CR0_REGNO; \
- goto SUCCESS; \
- } while (0)