aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2004-09-08 00:17:19 +0000
committerAlan Modra <amodra@gcc.gnu.org>2004-09-08 09:47:19 +0930
commit8662eb14c0ef6531d7086ec08f5e52b87c472ede (patch)
treef6927bd90fe84c682dd04619d255d6355aac36d5 /gcc/config/mips
parenta9e10feb68d5cbc371f581ebca229043b7854fe5 (diff)
downloadgcc-8662eb14c0ef6531d7086ec08f5e52b87c472ede.zip
gcc-8662eb14c0ef6531d7086ec08f5e52b87c472ede.tar.gz
gcc-8662eb14c0ef6531d7086ec08f5e52b87c472ede.tar.bz2
tm.texi (MD_UNWIND_SUPPORT): Document.
* doc/tm.texi (MD_UNWIND_SUPPORT): Document. (MD_FALLBACK_FRAME_STATE_FOR): Update. * unwind-dw2.c (MD_UNWIND_SUPPORT): #include if defined. (uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation. (MD_FROB_UPDATE_CONTEXT): Remove default. (uw_update_context_1): Instead #ifdef invocation. * config/ia64/unwind-ia64.c (MD_UNWIND_SUPPORT): #include if defined. (uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation. * config/alpha/gnu.h (MD_FALLBACK_FRAME_STATE_FOR): Don't undef. (MD_UNWIND_SUPPORT): Undefine this instead. * config/i386/gnu.h: Likewise. * config/alpha/linux-unwind.h: New file, macro converted to function, extracted from.. * config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): ..this. (MD_UNWIND_SUPPORT): Define. * config/alpha/vms-unwind.h, config/alpha/vms.h: Likewise. * config/i386/linux-unwind.h, config/i386/linux.h, config/i386/linux64.h: Likewise. * config/ia64/linux-unwind.h, config/ia64/linux.h: Likewise. MD_HANDLE_UNWABI too. * config/mips/linux-unwind.h, config/mips/linux.h: Likewise. * config/pa/linux-unwind.h, config/pa/pa32-linux.h: Likewise. * config/rs6000/darwin-unwind.h, config/rs6000/darwin.h: Likewise. * config/s390/linux-unwind.h, config/s390/linux.h: Likewise. * config/sparc/linux-unwind.h, config/sparc/linux.h, config/sparc/linux64.h: Likewise. * config/sh/linux-unwind.h, config/sh/linux.h: Likewise, but merge SH_FALLBACK_FRAME_FLOAT_STATE into sh_fallback_frame_state. * config/rs6000/linux-unwind.h, config/rs6000/linux.h, config/rs6000/linux64.h: Likewise. Split out get_sigcontext function. Use ARG_POINTER_REGNUM for 32-bit temp reg too. From-SVN: r87167
Diffstat (limited to 'gcc/config/mips')
-rw-r--r--gcc/config/mips/linux-unwind.h93
-rw-r--r--gcc/config/mips/linux.h72
2 files changed, 94 insertions, 71 deletions
diff --git a/gcc/config/mips/linux-unwind.h b/gcc/config/mips/linux-unwind.h
new file mode 100644
index 0000000..5c136c1
--- /dev/null
+++ b/gcc/config/mips/linux-unwind.h
@@ -0,0 +1,93 @@
+/* DWARF2 EH unwinding support for MIPS Linux.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef inhibit_libc
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs. */
+
+#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;
+
+#define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state
+
+static _Unwind_Reason_Code
+mips_fallback_frame_state (struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ 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)
+ return _URC_END_OF_STACK;
+ 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
+ return _URC_END_OF_STACK;
+
+ 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;
+
+ return _URC_NO_REASON;
+}
+#endif
diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h
index a4765d4..be5c8d4 100644
--- a/gcc/config/mips/linux.h
+++ b/gcc/config/mips/linux.h
@@ -183,74 +183,4 @@ Boston, MA 02111-1307, USA. */
%{!shared: %{pthread:-lpthread} \
%{profile:-lc_p} %{!profile: -lc}}"
-#ifndef inhibit_libc
-/* 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)
-#endif
+#define MD_UNWIND_SUPPORT "config/mips/linux-unwind.h"