diff options
author | Alan Modra <amodra@bigpond.net.au> | 2004-09-08 00:17:19 +0000 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2004-09-08 09:47:19 +0930 |
commit | 8662eb14c0ef6531d7086ec08f5e52b87c472ede (patch) | |
tree | f6927bd90fe84c682dd04619d255d6355aac36d5 /gcc/config/mips | |
parent | a9e10feb68d5cbc371f581ebca229043b7854fe5 (diff) | |
download | gcc-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.h | 93 | ||||
-rw-r--r-- | gcc/config/mips/linux.h | 72 |
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" |