]>
Commit | Line | Data |
---|---|---|
02a9f771 | 1 | /* Header file for the ARM EABI unwinder |
bfff8b1b | 2 | Copyright (C) 2003-2017 Free Software Foundation, Inc. |
02a9f771 DJ |
3 | Contributed by Paul Brook |
4 | ||
5 | This file is free software; you can redistribute it and/or modify it | |
6 | under the terms of the GNU General Public License as published by the | |
7 | Free Software Foundation; either version 2, or (at your option) any | |
8 | later version. | |
9 | ||
10 | In addition to the permissions in the GNU General Public License, the | |
11 | Free Software Foundation gives you unlimited permission to link the | |
12 | compiled version of this file into combinations with other programs, | |
13 | and to distribute those combinations without any restriction coming | |
14 | from the use of this file. (The General Public License restrictions | |
15 | do apply in other respects; for example, they cover modification of | |
16 | the file, and distribution when not linked into a combine | |
17 | executable.) | |
18 | ||
19 | This file is distributed in the hope that it will be useful, but | |
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
22 | General Public License for more details. | |
23 | ||
24 | You should have received a copy of the GNU General Public License | |
ab84e3ff PE |
25 | along with this program. If not, see |
26 | <http://www.gnu.org/licenses/>. */ | |
02a9f771 DJ |
27 | |
28 | /* Language-independent unwinder header public defines. This contains both | |
29 | ABI defined objects, and GNU support routines. */ | |
30 | ||
31 | #ifndef UNWIND_ARM_H | |
32 | #define UNWIND_ARM_H | |
33 | ||
34 | #define __ARM_EABI_UNWINDER__ 1 | |
35 | ||
36 | #ifdef __cplusplus | |
37 | extern "C" { | |
38 | #endif | |
39 | typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); | |
40 | typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); | |
41 | typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); | |
42 | typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); | |
43 | typedef _Unwind_Word _uw; | |
44 | typedef unsigned _uw64 __attribute__((mode(__DI__))); | |
45 | typedef unsigned _uw16 __attribute__((mode(__HI__))); | |
46 | typedef unsigned _uw8 __attribute__((mode(__QI__))); | |
47 | ||
48 | typedef enum | |
49 | { | |
50 | _URC_OK = 0, /* operation completed successfully */ | |
51 | _URC_FOREIGN_EXCEPTION_CAUGHT = 1, | |
52 | _URC_END_OF_STACK = 5, | |
53 | _URC_HANDLER_FOUND = 6, | |
54 | _URC_INSTALL_CONTEXT = 7, | |
55 | _URC_CONTINUE_UNWIND = 8, | |
56 | _URC_FAILURE = 9 /* unspecified failure of some kind */ | |
57 | } | |
58 | _Unwind_Reason_Code; | |
59 | ||
60 | typedef enum | |
61 | { | |
62 | _US_VIRTUAL_UNWIND_FRAME = 0, | |
63 | _US_UNWIND_FRAME_STARTING = 1, | |
64 | _US_UNWIND_FRAME_RESUME = 2, | |
65 | _US_ACTION_MASK = 3, | |
66 | _US_FORCE_UNWIND = 8, | |
67 | _US_END_OF_STACK = 16 | |
68 | } | |
69 | _Unwind_State; | |
70 | ||
71 | /* Provided only for for compatibility with existing code. */ | |
72 | typedef int _Unwind_Action; | |
73 | #define _UA_SEARCH_PHASE 1 | |
74 | #define _UA_CLEANUP_PHASE 2 | |
75 | #define _UA_HANDLER_FRAME 4 | |
76 | #define _UA_FORCE_UNWIND 8 | |
77 | #define _UA_END_OF_STACK 16 | |
78 | #define _URC_NO_REASON _URC_OK | |
79 | ||
80 | typedef struct _Unwind_Control_Block _Unwind_Control_Block; | |
81 | typedef struct _Unwind_Context _Unwind_Context; | |
82 | typedef _uw _Unwind_EHT_Header; | |
83 | ||
84 | ||
85 | /* UCB: */ | |
86 | ||
87 | struct _Unwind_Control_Block | |
88 | { | |
89 | #ifdef _LIBC | |
90 | /* For the benefit of code which assumes this is a scalar. All | |
91 | glibc ever does is clear it. */ | |
92 | _uw64 exception_class; | |
93 | #else | |
94 | char exception_class[8]; | |
95 | #endif | |
96 | void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *); | |
97 | /* Unwinder cache, private fields for the unwinder's use */ | |
98 | struct | |
99 | { | |
100 | _uw reserved1; /* Forced unwind stop fn, 0 if not forced */ | |
101 | _uw reserved2; /* Personality routine address */ | |
102 | _uw reserved3; /* Saved callsite address */ | |
103 | _uw reserved4; /* Forced unwind stop arg */ | |
104 | _uw reserved5; | |
105 | } | |
106 | unwinder_cache; | |
107 | /* Propagation barrier cache (valid after phase 1): */ | |
108 | struct | |
109 | { | |
110 | _uw sp; | |
111 | _uw bitpattern[5]; | |
112 | } | |
113 | barrier_cache; | |
114 | /* Cleanup cache (preserved over cleanup): */ | |
115 | struct | |
116 | { | |
117 | _uw bitpattern[4]; | |
118 | } | |
119 | cleanup_cache; | |
120 | /* Pr cache (for pr's benefit): */ | |
121 | struct | |
122 | { | |
123 | _uw fnstart; /* function start address */ | |
124 | _Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */ | |
125 | _uw additional; /* additional data */ | |
126 | _uw reserved1; | |
127 | } | |
128 | pr_cache; | |
129 | long long int :0; /* Force alignment to 8-byte boundary */ | |
130 | }; | |
131 | ||
132 | /* Virtual Register Set*/ | |
133 | ||
134 | typedef enum | |
135 | { | |
136 | _UVRSC_CORE = 0, /* integer register */ | |
137 | _UVRSC_VFP = 1, /* vfp */ | |
138 | _UVRSC_FPA = 2, /* fpa */ | |
139 | _UVRSC_WMMXD = 3, /* Intel WMMX data register */ | |
140 | _UVRSC_WMMXC = 4 /* Intel WMMX control register */ | |
141 | } | |
142 | _Unwind_VRS_RegClass; | |
143 | ||
144 | typedef enum | |
145 | { | |
146 | _UVRSD_UINT32 = 0, | |
147 | _UVRSD_VFPX = 1, | |
148 | _UVRSD_FPAX = 2, | |
149 | _UVRSD_UINT64 = 3, | |
150 | _UVRSD_FLOAT = 4, | |
151 | _UVRSD_DOUBLE = 5 | |
152 | } | |
153 | _Unwind_VRS_DataRepresentation; | |
154 | ||
155 | typedef enum | |
156 | { | |
157 | _UVRSR_OK = 0, | |
158 | _UVRSR_NOT_IMPLEMENTED = 1, | |
159 | _UVRSR_FAILED = 2 | |
160 | } | |
161 | _Unwind_VRS_Result; | |
162 | ||
163 | /* Frame unwinding state. */ | |
164 | typedef struct | |
165 | { | |
166 | /* The current word (bytes packed msb first). */ | |
167 | _uw data; | |
168 | /* Pointer to the next word of data. */ | |
169 | _uw *next; | |
170 | /* The number of bytes left in this word. */ | |
171 | _uw8 bytes_left; | |
172 | /* The number of words pointed to by ptr. */ | |
173 | _uw8 words_left; | |
174 | } | |
175 | __gnu_unwind_state; | |
176 | ||
177 | typedef _Unwind_Reason_Code (*personality_routine) (_Unwind_State, | |
178 | _Unwind_Control_Block *, _Unwind_Context *); | |
179 | ||
180 | _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *, _Unwind_VRS_RegClass, | |
181 | _uw, _Unwind_VRS_DataRepresentation, | |
182 | void *); | |
183 | ||
184 | _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *, _Unwind_VRS_RegClass, | |
185 | _uw, _Unwind_VRS_DataRepresentation, | |
186 | void *); | |
187 | ||
188 | _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *, _Unwind_VRS_RegClass, | |
189 | _uw, _Unwind_VRS_DataRepresentation); | |
190 | ||
191 | ||
192 | /* Support functions for the PR. */ | |
193 | #define _Unwind_Exception _Unwind_Control_Block | |
194 | typedef char _Unwind_Exception_Class[8]; | |
195 | ||
196 | void * _Unwind_GetLanguageSpecificData (_Unwind_Context *); | |
197 | _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *); | |
198 | ||
199 | /* These two should never be used. */ | |
200 | _Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *); | |
201 | _Unwind_Ptr _Unwind_GetTextRelBase (_Unwind_Context *); | |
202 | ||
203 | /* Interface functions: */ | |
204 | _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp); | |
205 | void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp); | |
206 | _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (_Unwind_Control_Block *ucbp); | |
207 | ||
208 | typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) | |
209 | (int, _Unwind_Action, _Unwind_Exception_Class, | |
210 | _Unwind_Control_Block *, struct _Unwind_Context *, void *); | |
211 | _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *, | |
212 | _Unwind_Stop_Fn, void *); | |
213 | _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); | |
214 | void _Unwind_Complete(_Unwind_Control_Block *ucbp); | |
215 | void _Unwind_DeleteException (_Unwind_Exception *); | |
216 | ||
217 | _Unwind_Reason_Code __gnu_unwind_frame (_Unwind_Control_Block *, | |
218 | _Unwind_Context *); | |
219 | _Unwind_Reason_Code __gnu_unwind_execute (_Unwind_Context *, | |
220 | __gnu_unwind_state *); | |
221 | ||
222 | /* Decode an R_ARM_TARGET2 relocation. */ | |
223 | static inline _Unwind_Word | |
224 | _Unwind_decode_target2 (_Unwind_Word ptr) | |
225 | { | |
226 | _Unwind_Word tmp; | |
227 | ||
228 | tmp = *(_Unwind_Word *) ptr; | |
229 | /* Zero values are always NULL. */ | |
230 | if (!tmp) | |
231 | return 0; | |
232 | ||
233 | #if defined(linux) || defined(__NetBSD__) | |
234 | /* Pc-relative indirect. */ | |
235 | tmp += ptr; | |
236 | tmp = *(_Unwind_Word *) tmp; | |
237 | #elif defined(__symbian__) | |
238 | /* Absolute pointer. Nothing more to do. */ | |
239 | #else | |
240 | /* Pc-relative pointer. */ | |
241 | tmp += ptr; | |
242 | #endif | |
243 | return tmp; | |
244 | } | |
245 | ||
246 | static inline _Unwind_Word | |
247 | _Unwind_GetGR (_Unwind_Context *context, int regno) | |
248 | { | |
249 | _uw val; | |
250 | _Unwind_VRS_Get (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); | |
251 | return val; | |
252 | } | |
253 | ||
254 | /* Return the address of the instruction, not the actual IP value. */ | |
255 | #define _Unwind_GetIP(context) \ | |
256 | (_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) | |
257 | ||
258 | static inline void | |
259 | _Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val) | |
260 | { | |
261 | _Unwind_VRS_Set (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); | |
262 | } | |
263 | ||
264 | /* The dwarf unwinder doesn't understand arm/thumb state. We assume the | |
265 | landing pad uses the same instruction set as the call site. */ | |
266 | #define _Unwind_SetIP(context, val) \ | |
267 | _Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1)) | |
268 | ||
b6dec188 MK |
269 | typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) |
270 | (struct _Unwind_Context *, void *); | |
271 | ||
272 | extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); | |
273 | ||
02a9f771 DJ |
274 | #ifdef __cplusplus |
275 | } /* extern "C" */ | |
276 | #endif | |
277 | ||
278 | #endif /* defined UNWIND_ARM_H */ |