• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===------------------------------- unwind.h -----------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 // C++ ABI Level 1 ABI documented at:
10 //   http://mentorembedded.github.io/cxx-abi/abi-eh.html
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef __UNWIND_H__
15 #define __UNWIND_H__
16 
17 #include <stdint.h>
18 #include <stddef.h>
19 
20 #if defined(__APPLE__)
21 #define LIBUNWIND_UNAVAIL __attribute__ (( unavailable ))
22 #else
23 #define LIBUNWIND_UNAVAIL
24 #endif
25 
26 // TODO(danakj): This is also in cxxabi.h and libunwind.h, can we consolidate?
27 #if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
28     !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
29 #define LIBCXXABI_ARM_EHABI 1
30 #else
31 #define LIBCXXABI_ARM_EHABI 0
32 #endif
33 
34 typedef enum {
35   _URC_NO_REASON = 0,
36   _URC_OK = 0,
37   _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
38   _URC_FATAL_PHASE2_ERROR = 2,
39   _URC_FATAL_PHASE1_ERROR = 3,
40   _URC_NORMAL_STOP = 4,
41   _URC_END_OF_STACK = 5,
42   _URC_HANDLER_FOUND = 6,
43   _URC_INSTALL_CONTEXT = 7,
44   _URC_CONTINUE_UNWIND = 8,
45 #if LIBCXXABI_ARM_EHABI
46   _URC_FAILURE = 9,
47 #endif
48 } _Unwind_Reason_Code;
49 
50 typedef enum {
51   _UA_SEARCH_PHASE = 1,
52   _UA_CLEANUP_PHASE = 2,
53   _UA_HANDLER_FRAME = 4,
54   _UA_FORCE_UNWIND = 8,
55   _UA_END_OF_STACK = 16 // gcc extension to C++ ABI
56 } _Unwind_Action;
57 
58 typedef struct _Unwind_Context _Unwind_Context;   // opaque
59 
60 #if LIBCXXABI_ARM_EHABI
61 typedef uint32_t _Unwind_State;
62 
63 static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME   = 0;
64 static const _Unwind_State _US_UNWIND_FRAME_STARTING  = 1;
65 static const _Unwind_State _US_UNWIND_FRAME_RESUME    = 2;
66 
67 typedef uint32_t _Unwind_EHT_Header;
68 
69 struct _Unwind_Control_Block;
70 typedef struct _Unwind_Control_Block _Unwind_Control_Block;
71 typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
72 
73 struct _Unwind_Control_Block {
74   uint64_t exception_class;
75   void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*);
76   /* Unwinder cache, private fields for the unwinder's use */
77   struct {
78     uint32_t reserved1; /* init reserved1 to 0, then don't touch */
79     uint32_t reserved2;
80     uint32_t reserved3;
81     uint32_t reserved4;
82     uint32_t reserved5;
83   } unwinder_cache;
84   /* Propagation barrier cache (valid after phase 1): */
85   struct {
86     uint32_t sp;
87     uint32_t bitpattern[5];
88   } barrier_cache;
89   /* Cleanup cache (preserved over cleanup): */
90   struct {
91     uint32_t bitpattern[4];
92   } cleanup_cache;
93   /* Pr cache (for pr's benefit): */
94   struct {
95     uint32_t fnstart; /* function start address */
96     _Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */
97     uint32_t additional; /* additional data */
98     uint32_t reserved1;
99   } pr_cache;
100 
101   long long int :0; /* Enforce the 8-byte alignment */
102 };
103 
104 typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
105       (_Unwind_State state,
106        _Unwind_Exception* exceptionObject,
107        struct _Unwind_Context* context);
108 
109 typedef _Unwind_Reason_Code (*__personality_routine)
110       (_Unwind_State state,
111        _Unwind_Exception* exceptionObject,
112        struct _Unwind_Context* context);
113 #else
114 struct _Unwind_Context;   // opaque
115 struct _Unwind_Exception; // forward declaration
116 typedef struct _Unwind_Exception _Unwind_Exception;
117 
118 struct _Unwind_Exception {
119   uint64_t exception_class;
120   void (*exception_cleanup)(_Unwind_Reason_Code reason,
121                             _Unwind_Exception *exc);
122   uintptr_t private_1; // non-zero means forced unwind
123   uintptr_t private_2; // holds sp that phase1 found for phase2 to use
124 #if !__LP64__
125   // The gcc implementation of _Unwind_Exception used attribute mode on the
126   // above fields which had the side effect of causing this whole struct to
127   // round up to 32 bytes in size. To be more explicit, we add pad fields
128   // added for binary compatibility.
129   uint32_t reserved[3];
130 #endif
131 };
132 
133 typedef _Unwind_Reason_Code (*__personality_routine)
134       (int version,
135        _Unwind_Action actions,
136        uint64_t exceptionClass,
137        _Unwind_Exception* exceptionObject,
138        struct _Unwind_Context* context);
139 
140 typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
141         (int version,
142          _Unwind_Action actions,
143          uint64_t exceptionClass,
144          struct _Unwind_Exception *exceptionObject,
145          struct _Unwind_Context *context,
146          void *stop_parameter );
147 
148 #endif
149 
150 #ifdef __cplusplus
151 extern "C" {
152 #endif
153 
154 //
155 // The following are the base functions documented by the C++ ABI
156 //
157 #if __USING_SJLJ_EXCEPTIONS__
158 extern _Unwind_Reason_Code
159     _Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object);
160 extern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object);
161 #else
162 extern _Unwind_Reason_Code
163     _Unwind_RaiseException(_Unwind_Exception *exception_object);
164 extern void _Unwind_Resume(_Unwind_Exception *exception_object);
165 #endif
166 extern void _Unwind_DeleteException(_Unwind_Exception *exception_object);
167 
168 #if LIBCXXABI_ARM_EHABI
169 typedef enum {
170   _UVRSC_CORE = 0, /* integer register */
171   _UVRSC_VFP = 1, /* vfp */
172   _UVRSC_WMMXD = 3, /* Intel WMMX data register */
173   _UVRSC_WMMXC = 4 /* Intel WMMX control register */
174 } _Unwind_VRS_RegClass;
175 
176 typedef enum {
177   _UVRSD_UINT32 = 0,
178   _UVRSD_VFPX = 1,
179   _UVRSD_UINT64 = 3,
180   _UVRSD_FLOAT = 4,
181   _UVRSD_DOUBLE = 5
182 } _Unwind_VRS_DataRepresentation;
183 
184 typedef enum {
185   _UVRSR_OK = 0,
186   _UVRSR_NOT_IMPLEMENTED = 1,
187   _UVRSR_FAILED = 2
188 } _Unwind_VRS_Result;
189 
190 extern void _Unwind_Complete(_Unwind_Exception* exception_object);
191 
192 extern _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context* context,
193                                           _Unwind_VRS_RegClass regclass,
194                                           uint32_t regno,
195                                           _Unwind_VRS_DataRepresentation representation,
196                                           void *valuep);
197 
198 extern _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context* context,
199                                           _Unwind_VRS_RegClass regclass,
200                                           uint32_t regno,
201                                           _Unwind_VRS_DataRepresentation representation,
202                                           void *valuep);
203 
204 extern _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *context,
205                                           _Unwind_VRS_RegClass regclass,
206                                           uint32_t discriminator,
207                                           _Unwind_VRS_DataRepresentation representation);
208 
209 // TODO(ajwong): This is not part of the EHABI. Decide if the name is right.
210 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context* context,
211                                                  uint32_t* data,
212                                                  size_t offset,
213                                                  size_t len);
214 
215 // TODO(ajwong) Should these {Set,Get}/{GR,IP} be removed in favor of
216 // VRS_Get/VRS_Set? Is the thumb bit inference in SetIP correct?
_Unwind_GetGR(struct _Unwind_Context * context,int index)217 static inline uintptr_t _Unwind_GetGR(struct _Unwind_Context* context,
218                                       int index) {
219   uintptr_t value = 0;
220   _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
221   return value;
222 }
223 
_Unwind_SetGR(struct _Unwind_Context * context,int index,uintptr_t new_value)224 static inline void _Unwind_SetGR(struct _Unwind_Context* context, int index,
225                                  uintptr_t new_value) {
226   _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index,
227                   _UVRSD_UINT32, &new_value);
228 }
229 
_Unwind_GetIP(struct _Unwind_Context * context)230 static inline uintptr_t _Unwind_GetIP(struct _Unwind_Context* context) {
231   // remove the thumb-bit before returning
232   return (_Unwind_GetGR(context, 15) & (~(uintptr_t)0x1));
233 }
234 
_Unwind_SetIP(struct _Unwind_Context * context,uintptr_t new_value)235 static inline void _Unwind_SetIP(struct _Unwind_Context* context,
236                                  uintptr_t new_value) {
237   uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
238   _Unwind_SetGR(context, 15, new_value | thumb_bit);
239 }
240 #else // LIBCXXABI_ARM_EHABI
241 extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
242 extern void _Unwind_SetGR(struct _Unwind_Context *context, int index,
243                           uintptr_t new_value);
244 extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context);
245 extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value);
246 #endif // LIBCXXABI_ARM_EHABI
247 
248 extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
249 extern uintptr_t
250     _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);
251 #if __USING_SJLJ_EXCEPTIONS__
252 extern _Unwind_Reason_Code
253     _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object,
254                               _Unwind_Stop_Fn stop, void *stop_parameter);
255 #else // !__USING_SJLJ_EXCEPTIONS__
256 extern _Unwind_Reason_Code
257     _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
258                          _Unwind_Stop_Fn stop, void *stop_parameter);
259 #endif // !__USING_SJLJ_EXCEPTIONS__
260 
261 #if __USING_SJLJ_EXCEPTIONS__
262 typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t;
263 extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc);
264 extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc);
265 #endif
266 
267 //
268 // The following are semi-suppoted extensions to the C++ ABI
269 //
270 
271 //
272 //  called by __cxa_rethrow().
273 //
274 #if __USING_SJLJ_EXCEPTIONS__
275 extern _Unwind_Reason_Code
276     _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object);
277 #else
278 extern _Unwind_Reason_Code
279     _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object);
280 #endif
281 
282 // _Unwind_Backtrace() is a gcc extension that walks the stack and calls the
283 // _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack
284 // or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON.
285 typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
286                                                 void *);
287 extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
288 
289 // _Unwind_GetCFA is a gcc extension that can be called from within a
290 // personality handler to get the CFA (stack pointer before call) of
291 // current frame.
292 extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *);
293 
294 
295 // _Unwind_GetIPInfo is a gcc extension that can be called from within a
296 // personality handler.  Similar to _Unwind_GetIP() but also returns in
297 // *ipBefore a non-zero value if the instruction pointer is at or before the
298 // instruction causing the unwind. Normally, in a function call, the IP returned
299 // is the return address which is after the call instruction and may be past the
300 // end of the function containing the call instruction.
301 extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
302                                    int *ipBefore);
303 
304 
305 // __register_frame() is used with dynamically generated code to register the
306 // FDE for a generated (JIT) code.  The FDE must use pc-rel addressing to point
307 // to its function and optional LSDA.
308 // __register_frame() has existed in all versions of Mac OS X, but in 10.4 and
309 // 10.5 it was buggy and did not actually register the FDE with the unwinder.
310 // In 10.6 and later it does register properly.
311 extern void __register_frame(const void *fde);
312 extern void __deregister_frame(const void *fde);
313 
314 // _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has
315 // an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind
316 // info" which the runtime uses in preference to dwarf unwind info.  This
317 // function will only work if the target function has an FDE but no compact
318 // unwind info.
319 struct dwarf_eh_bases {
320   uintptr_t tbase;
321   uintptr_t dbase;
322   uintptr_t func;
323 };
324 extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *);
325 
326 
327 // This function attempts to find the start (address of first instruction) of
328 // a function given an address inside the function.  It only works if the
329 // function has an FDE (dwarf unwind info).
330 // This function is unimplemented on Mac OS X 10.6 and later.  Instead, use
331 // _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result.
332 extern void *_Unwind_FindEnclosingFunction(void *pc);
333 
334 // Mac OS X does not support text-rel and data-rel addressing so these functions
335 // are unimplemented
336 extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context)
337     LIBUNWIND_UNAVAIL;
338 extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context)
339     LIBUNWIND_UNAVAIL;
340 
341 // Mac OS X 10.4 and 10.5 had implementations of these functions in
342 // libgcc_s.dylib, but they never worked.
343 /// These functions are no longer available on Mac OS X.
344 extern void __register_frame_info_bases(const void *fde, void *ob, void *tb,
345                                         void *db) LIBUNWIND_UNAVAIL;
346 extern void __register_frame_info(const void *fde, void *ob)
347     LIBUNWIND_UNAVAIL;
348 extern void __register_frame_info_table_bases(const void *fde, void *ob,
349                                               void *tb, void *db)
350     LIBUNWIND_UNAVAIL;
351 extern void __register_frame_info_table(const void *fde, void *ob)
352     LIBUNWIND_UNAVAIL;
353 extern void __register_frame_table(const void *fde)
354     LIBUNWIND_UNAVAIL;
355 extern void *__deregister_frame_info(const void *fde)
356     LIBUNWIND_UNAVAIL;
357 extern void *__deregister_frame_info_bases(const void *fde)
358     LIBUNWIND_UNAVAIL;
359 
360 #ifdef __cplusplus
361 }
362 #endif
363 
364 #endif // __UNWIND_H__
365