diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 17baec6c137..01a4e4d02fd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2001-05-17 Andrew Haley + + * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New. + 2001-05-21 Richard Henderson * dwarf2out.c (DEBUG_FRAME_SECTION): Rename from FRAME_SECTION. diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h index f0cf9d18c34..285cf55e5c1 100644 --- a/gcc/config/rs6000/linux.h +++ b/gcc/config/rs6000/linux.h @@ -66,3 +66,56 @@ Boston, MA 02111-1307, USA. */ #ifndef USE_GNULIBC_1 #define DEFAULT_VTABLE_THUNKS 1 #endif + +/* Do code reading to identify a signal frame, and set the frame + state data appropriately. See unwind-dw2.c for the structs. */ + +#ifdef IN_LIBGCC2 +#include +#include +#endif + +#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ + do { \ + unsigned char *pc_ = (CONTEXT)->ra; \ + struct sigcontext *sc_; \ + long new_cfa_; \ + int i_; \ + \ + /* li r0, 0x7777; sc (rt_sigreturn) */ \ + /* li r0, 0x6666; sc (sigreturn) */ \ + if (((*(unsigned int *) (pc_+0) == 0x38007777) \ + || (*(unsigned int *) (pc_+0) == 0x38006666)) \ + && (*(unsigned int *) (pc_+4) == 0x44000002)) \ + sc_ = (CONTEXT)->cfa + __SIGNAL_FRAMESIZE; \ + 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. */ \ + sc_->regs->nip += 4; \ + (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \ + (FS)->regs.reg[CR0_REGNO].loc.offset \ + = (long)&(sc_->regs->nip) - new_cfa_; \ + (FS)->retaddr_column = CR0_REGNO; \ + goto SUCCESS; \ + } while (0) +