diff options
author | David Daney <daney@gcc.gnu.org> | 2003-10-15 22:24:56 +0000 |
---|---|---|
committer | David Daney <daney@gcc.gnu.org> | 2003-10-15 22:24:56 +0000 |
commit | 1f3d066157f480765d8f1c97bcfe614607abb52c (patch) | |
tree | 1676c66a6731dde19d97a0e826f6952a0f4fac10 /gcc | |
parent | 6492b8d80d97923f61dc12869ddf0d732d203ecb (diff) | |
download | gcc-1f3d066157f480765d8f1c97bcfe614607abb52c.zip gcc-1f3d066157f480765d8f1c97bcfe614607abb52c.tar.gz gcc-1f3d066157f480765d8f1c97bcfe614607abb52c.tar.bz2 |
linux.h (MD_FALLBACK_FRAME_STATE_FOR): New
* config/mips/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New
* config/mips/mips.h (DWARF_FRAME_REGNUM): Fixed to allow unwind
from leaf functions.
(DWARF_FRAME_RETURN_COLUMN): Ditto.
(SIGNAL_UNWIND_RETURN_COLUMN): New, used
by MD_FALLBACK_FRAME_STATE_FOR.
* testsuite/gcc.dg/cleanup-9.c: Added mips*-*-linux* target.
From-SVN: r72536
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/mips/linux.h | 70 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cleanup-9.c | 2 |
3 files changed, 77 insertions, 4 deletions
diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h index 851f048..8712242 100644 --- a/gcc/config/mips/linux.h +++ b/gcc/config/mips/linux.h @@ -190,3 +190,73 @@ Boston, MA 02111-1307, USA. */ %{!static:-rpath-link %R/lib:%R/usr/lib} \ %{!shared: %{pthread:-lpthread} \ %{profile:-lc_p} %{!profile: -lc}}" + +/* 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 <signal.h> + +/* The third parameter to the signal handler points to something with + * this structure defined in asm/ucontext.h, but the name clashes with + * struct ucontext from sys/ucontext.h so this private copy is used. */ +typedef struct _sig_ucontext { + unsigned long uc_flags; + struct _sig_ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; +} _sig_ucontext_t; + +#endif /* IN_LIBGCC2 */ + +#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ + do { \ + u_int32_t *pc_ = (u_int32_t *) (CONTEXT)->ra; \ + struct sigcontext *sc_; \ + _Unwind_Ptr new_cfa_; \ + int i_; \ + \ + /* 24021061 li v0, 0x1061 (rt_sigreturn)*/ \ + /* 0000000c syscall */ \ + /* or */ \ + /* 24021017 li v0, 0x1017 (sigreturn) */ \ + /* 0000000c syscall */ \ + if (*(pc_ + 1) != 0x0000000c) \ + break; \ + if (*(pc_ + 0) == 0x24021017) \ + { \ + struct sigframe { \ + u_int32_t trampoline[2]; \ + struct sigcontext sigctx; \ + } *rt_ = (CONTEXT)->ra; \ + sc_ = &rt_->sigctx; \ + } \ + else if (*(pc_ + 0) == 0x24021061) \ + { \ + struct rt_sigframe { \ + u_int32_t trampoline[2]; \ + struct siginfo info; \ + _sig_ucontext_t uc; \ + } *rt_ = (CONTEXT)->ra; \ + sc_ = &rt_->uc.uc_mcontext; \ + } \ + else \ + break; \ + \ + new_cfa_ = (_Unwind_Ptr)sc_; \ + (FS)->cfa_how = CFA_REG_OFFSET; \ + (FS)->cfa_reg = STACK_POINTER_REGNUM; \ + (FS)->cfa_offset = new_cfa_ - (_Unwind_Ptr) (CONTEXT)->cfa; \ + \ + for (i_ = 0; i_ < 32; i_++) { \ + (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \ + (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; \ + (FS)->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset \ + = (_Unwind_Ptr)&(sc_->sc_pc) - new_cfa_; \ + (FS)->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN; \ + \ + goto SUCCESS; \ + } while (0) diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 2e5fb7a..23fe285 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1216,11 +1216,14 @@ extern const struct mips_cpu_info *mips_tune_info; #define DBX_REGISTER_NUMBER(REGNO) mips_dbx_regno[ (REGNO) ] /* The mapping from gcc register number to DWARF 2 CFA column number. */ -#define DWARF_FRAME_REGNUM(REG) \ - (REG == GP_REG_FIRST + 31 ? DWARF_FRAME_RETURN_COLUMN : REG) +#define DWARF_FRAME_REGNUM(REG) (REG) /* The DWARF 2 CFA column which tracks the return address. */ -#define DWARF_FRAME_RETURN_COLUMN (FP_REG_LAST + 1) +#define DWARF_FRAME_RETURN_COLUMN (GP_REG_FIRST + 31) + +/* The DWARF 2 CFA column which tracks the return address from a + signal handler context. */ +#define SIGNAL_UNWIND_RETURN_COLUMN (FP_REG_LAST + 1) /* Before the prologue, RA lives in r31. */ #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31) diff --git a/gcc/testsuite/gcc.dg/cleanup-9.c b/gcc/testsuite/gcc.dg/cleanup-9.c index 0c17f25..29048d2 100644 --- a/gcc/testsuite/gcc.dg/cleanup-9.c +++ b/gcc/testsuite/gcc.dg/cleanup-9.c @@ -1,4 +1,4 @@ -/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* alpha*-*-linux* powerpc*-*-linux* s390*-*-linux* sparc*-*-linux* } } */ +/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* alpha*-*-linux* powerpc*-*-linux* s390*-*-linux* sparc*-*-linux* mips*-*-linux* } } */ /* { dg-options "-fasynchronous-unwind-tables -fexceptions -O2" } */ /* Verify that cleanups work with exception handling through realtime signal frames. */ |