1 /* DWARF2 EH unwinding support for SH Linux.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Do code reading to identify a signal frame, and set the frame
22 state data appropriately. See unwind-dw2.c for the structs. */
25 #include <sys/ucontext.h>
26 #include "insn-constants.h"
28 # if defined (__SH5__)
29 #define SH_DWARF_FRAME_GP0 0
30 #define SH_DWARF_FRAME_FP0 (__SH5__ == 32 ? 245 : 77)
31 #define SH_DWARF_FRAME_XD0 289
32 #define SH_DWARF_FRAME_BT0 68
33 #define SH_DWARF_FRAME_PR 241
34 #define SH_DWARF_FRAME_PR_MEDIA 18
35 #define SH_DWARF_FRAME_GBR 238
36 #define SH_DWARF_FRAME_MACH 239
37 #define SH_DWARF_FRAME_MACL 240
38 #define SH_DWARF_FRAME_PC 64
39 #define SH_DWARF_FRAME_SR 65
40 #define SH_DWARF_FRAME_FPUL 244
41 #define SH_DWARF_FRAME_FPSCR 243
43 #define SH_DWARF_FRAME_GP0 0
44 #define SH_DWARF_FRAME_FP0 25
45 #define SH_DWARF_FRAME_XD0 87
46 #define SH_DWARF_FRAME_PR 17
47 #define SH_DWARF_FRAME_GBR 19
48 #define SH_DWARF_FRAME_MACH 20
49 #define SH_DWARF_FRAME_MACL 21
50 #define SH_DWARF_FRAME_PC 16
51 #define SH_DWARF_FRAME_SR 22
52 #define SH_DWARF_FRAME_FPUL 23
53 #define SH_DWARF_FRAME_FPSCR 24
54 #endif /* defined (__SH5__) */
57 /* MD_FALLBACK_FRAME_STATE_FOR is not yet defined for SHMEDIA. */
58 #else /* defined (__SH5__) */
60 #define MD_FALLBACK_FRAME_STATE_FOR sh_fallback_frame_state
62 static _Unwind_Reason_Code
63 sh_fallback_frame_state (struct _Unwind_Context
*context
,
64 _Unwind_FrameState
*fs
)
66 unsigned char *pc
= context
->ra
;
67 struct sigcontext
*sc
;
70 #if defined (__SH3E__) || defined (__SH4__)
74 /* mov.w 1f,r3; trapa #0x10; 1: .short 0x77 (sigreturn) */
75 /* mov.w 1f,r3; trapa #0x10; 1: .short 0xad (rt_sigreturn) */
76 /* Newer kernel uses pad instructions to avoid an SH-4 core bug. */
77 /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
78 or r0,r0; 1: .short 0x77 (sigreturn) */
79 /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
80 or r0,r0; 1: .short 0xad (rt_sigreturn) */
81 if (((*(unsigned short *) (pc
+0) == 0x9300)
82 && (*(unsigned short *) (pc
+2) == 0xc310)
83 && (*(unsigned short *) (pc
+4) == 0x0077))
84 || (((*(unsigned short *) (pc
+0) == 0x9305)
85 && (*(unsigned short *) (pc
+2) == 0xc310)
86 && (*(unsigned short *) (pc
+14) == 0x0077))))
88 else if (((*(unsigned short *) (pc
+0) == 0x9300)
89 && (*(unsigned short *) (pc
+2) == 0xc310)
90 && (*(unsigned short *) (pc
+4) == 0x00ad))
91 || (((*(unsigned short *) (pc
+0) == 0x9305)
92 && (*(unsigned short *) (pc
+2) == 0xc310)
93 && (*(unsigned short *) (pc
+14) == 0x00ad))))
98 } *rt_
= context
->cfa
;
99 sc
= (struct sigcontext
*) &rt_
->uc
.uc_mcontext
;
102 return _URC_END_OF_STACK
;
104 new_cfa
= sc
->sc_regs
[15];
105 fs
->cfa_how
= CFA_REG_OFFSET
;
107 fs
->cfa_offset
= new_cfa
- (long) context
->cfa
;
109 for (i
= 0; i
< 15; i
++)
111 fs
->regs
.reg
[i
].how
= REG_SAVED_OFFSET
;
112 fs
->regs
.reg
[i
].loc
.offset
113 = (long)&(sc
->sc_regs
[i
]) - new_cfa
;
116 fs
->regs
.reg
[SH_DWARF_FRAME_PR
].how
= REG_SAVED_OFFSET
;
117 fs
->regs
.reg
[SH_DWARF_FRAME_PR
].loc
.offset
118 = (long)&(sc
->sc_pr
) - new_cfa
;
119 fs
->regs
.reg
[SH_DWARF_FRAME_SR
].how
= REG_SAVED_OFFSET
;
120 fs
->regs
.reg
[SH_DWARF_FRAME_SR
].loc
.offset
121 = (long)&(sc
->sc_sr
) - new_cfa
;
122 fs
->regs
.reg
[SH_DWARF_FRAME_GBR
].how
= REG_SAVED_OFFSET
;
123 fs
->regs
.reg
[SH_DWARF_FRAME_GBR
].loc
.offset
124 = (long)&(sc
->sc_gbr
) - new_cfa
;
125 fs
->regs
.reg
[SH_DWARF_FRAME_MACH
].how
= REG_SAVED_OFFSET
;
126 fs
->regs
.reg
[SH_DWARF_FRAME_MACH
].loc
.offset
127 = (long)&(sc
->sc_mach
) - new_cfa
;
128 fs
->regs
.reg
[SH_DWARF_FRAME_MACL
].how
= REG_SAVED_OFFSET
;
129 fs
->regs
.reg
[SH_DWARF_FRAME_MACL
].loc
.offset
130 = (long)&(sc
->sc_macl
) - new_cfa
;
132 #if defined (__SH3E__) || defined (__SH4__)
133 r
= SH_DWARF_FRAME_FP0
;
134 for (i
= 0; i
< 16; i
++)
136 fs
->regs
.reg
[r
+i
].how
= REG_SAVED_OFFSET
;
137 fs
->regs
.reg
[r
+i
].loc
.offset
138 = (long)&(sc
->sc_fpregs
[i
]) - new_cfa
;
141 r
= SH_DWARF_FRAME_XD0
;
142 for (i
= 0; i
< 8; i
++)
144 fs
->regs
.reg
[i
].how
= REG_SAVED_OFFSET
;
145 fs
->regs
.reg
[i
].loc
.offset
146 = (long)&(sc
->sc_xfpregs
[2*i
]) - new_cfa
;
149 fs
->regs
.reg
[SH_DWARF_FRAME_FPUL
].how
= REG_SAVED_OFFSET
;
150 fs
->regs
.reg
[SH_DWARF_FRAME_FPUL
].loc
.offset
151 = (long)&(sc
->sc_fpul
) - new_cfa
;
152 fs
->regs
.reg
[SH_DWARF_FRAME_FPSCR
].how
= REG_SAVED_OFFSET
;
153 fs
->regs
.reg
[SH_DWARF_FRAME_FPSCR
].loc
.offset
154 = (long)&(sc
->sc_fpscr
) - new_cfa
;
157 fs
->regs
.reg
[SH_DWARF_FRAME_PC
].how
= REG_SAVED_OFFSET
;
158 fs
->regs
.reg
[SH_DWARF_FRAME_PC
].loc
.offset
159 = (long)&(sc
->sc_pc
) - new_cfa
;
160 fs
->retaddr_column
= SH_DWARF_FRAME_PC
;
161 return _URC_NO_REASON
;
163 #endif /* defined (__SH5__) */