summaryrefslogtreecommitdiff
path: root/gcc/config/mips/linux-unwind.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mips/linux-unwind.h')
-rw-r--r--gcc/config/mips/linux-unwind.h11
1 files changed, 8 insertions, 3 deletions
diff --git a/gcc/config/mips/linux-unwind.h b/gcc/config/mips/linux-unwind.h
index bbb2445b539..e10fc769830 100644
--- a/gcc/config/mips/linux-unwind.h
+++ b/gcc/config/mips/linux-unwind.h
@@ -1,5 +1,5 @@
/* DWARF2 EH unwinding support for MIPS Linux.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@@ -51,6 +51,7 @@ mips_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
u_int32_t *pc = (u_int32_t *) context->ra;
+ u_int32_t t;
struct sigcontext *sc;
_Unwind_Ptr new_cfa;
int i;
@@ -102,9 +103,13 @@ mips_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[i].loc.offset
= (_Unwind_Ptr)&(sc->sc_regs[i]) - new_cfa;
}
- fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET;
+ /* The PC points to the faulting instruction, but the unwind tables
+ expect it point to the following instruction. We compensate by
+ reporting a return address at the next instruction. */
+ fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_VAL_OFFSET;
+ t = (*(u_int32_t *)(void *)&sc->sc_pc) + 4;
fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset
- = (_Unwind_Ptr)&(sc->sc_pc) - new_cfa;
+ = (_Unwind_Ptr)t - new_cfa;
fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;
return _URC_NO_REASON;