00001 /* DWARF2 EH unwinding support for MIPS Linux. 00002 Copyright (C) 2004, 2005 Free Software Foundation, Inc. 00003 00004 This file is part of GCC. 00005 00006 GCC is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2, or (at your option) 00009 any later version. 00010 00011 In addition to the permissions in the GNU General Public License, the 00012 Free Software Foundation gives you unlimited permission to link the 00013 compiled version of this file with other programs, and to distribute 00014 those programs without any restriction coming from the use of this 00015 file. (The General Public License restrictions do apply in other 00016 respects; for example, they cover modification of the file, and 00017 distribution when not linked into another program.) 00018 00019 GCC is distributed in the hope that it will be useful, 00020 but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License 00025 along with GCC; see the file COPYING. If not, write to 00026 the Free Software Foundation, 59 Temple Place - Suite 330, 00027 Boston, MA 02111-1307, USA. */ 00028 00029 #ifndef inhibit_libc 00030 /* Do code reading to identify a signal frame, and set the frame 00031 state data appropriately. See unwind-dw2.c for the structs. */ 00032 00033 #include <signal.h> 00034 00035 /* The third parameter to the signal handler points to something with 00036 * this structure defined in asm/ucontext.h, but the name clashes with 00037 * struct ucontext from sys/ucontext.h so this private copy is used. */ 00038 typedef struct _sig_ucontext { 00039 unsigned long uc_flags; 00040 struct _sig_ucontext *uc_link; 00041 stack_t uc_stack; 00042 struct sigcontext uc_mcontext; 00043 sigset_t uc_sigmask; 00044 } _sig_ucontext_t; 00045 00046 #define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state 00047 00048 static _Unwind_Reason_Code 00049 mips_fallback_frame_state (struct _Unwind_Context *context, 00050 _Unwind_FrameState *fs) 00051 { 00052 u_int32_t *pc = (u_int32_t *) context->ra; 00053 struct sigcontext *sc; 00054 _Unwind_Ptr new_cfa; 00055 int i; 00056 00057 /* 24021061 li v0, 0x1061 (rt_sigreturn)*/ 00058 /* 0000000c syscall */ 00059 /* or */ 00060 /* 24021017 li v0, 0x1017 (sigreturn) */ 00061 /* 0000000c syscall */ 00062 if (*(pc + 1) != 0x0000000c) 00063 return _URC_END_OF_STACK; 00064 if (*(pc + 0) == 0x24021017) 00065 { 00066 struct sigframe { 00067 u_int32_t trampoline[2]; 00068 struct sigcontext sigctx; 00069 } *rt_ = context->ra; 00070 sc = &rt_->sigctx; 00071 } 00072 else if (*(pc + 0) == 0x24021061) 00073 { 00074 struct rt_sigframe { 00075 u_int32_t trampoline[2]; 00076 struct siginfo info; 00077 _sig_ucontext_t uc; 00078 } *rt_ = context->ra; 00079 sc = &rt_->uc.uc_mcontext; 00080 } 00081 else 00082 return _URC_END_OF_STACK; 00083 00084 new_cfa = (_Unwind_Ptr)sc; 00085 fs->cfa_how = CFA_REG_OFFSET; 00086 fs->cfa_reg = STACK_POINTER_REGNUM; 00087 fs->cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa; 00088 00089 #if _MIPS_SIM == _ABIO32 && defined __MIPSEB__ 00090 /* On o32 Linux, the register save slots in the sigcontext are 00091 eight bytes. We need the lower half of each register slot, 00092 so slide our view of the structure back four bytes. */ 00093 new_cfa -= 4; 00094 #endif 00095 00096 for (i = 0; i < 32; i++) { 00097 fs->regs.reg[i].how = REG_SAVED_OFFSET; 00098 fs->regs.reg[i].loc.offset 00099 = (_Unwind_Ptr)&(sc->sc_regs[i]) - new_cfa; 00100 } 00101 fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET; 00102 fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset 00103 = (_Unwind_Ptr)&(sc->sc_pc) - new_cfa; 00104 fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN; 00105 00106 return _URC_NO_REASON; 00107 } 00108 #endif
1.5.6