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