1*67e74705SXin Li /*===---- unwind.h - Stack unwinding ----------------------------------------===
2*67e74705SXin Li *
3*67e74705SXin Li * Permission is hereby granted, free of charge, to any person obtaining a copy
4*67e74705SXin Li * of this software and associated documentation files (the "Software"), to deal
5*67e74705SXin Li * in the Software without restriction, including without limitation the rights
6*67e74705SXin Li * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*67e74705SXin Li * copies of the Software, and to permit persons to whom the Software is
8*67e74705SXin Li * furnished to do so, subject to the following conditions:
9*67e74705SXin Li *
10*67e74705SXin Li * The above copyright notice and this permission notice shall be included in
11*67e74705SXin Li * all copies or substantial portions of the Software.
12*67e74705SXin Li *
13*67e74705SXin Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14*67e74705SXin Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15*67e74705SXin Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16*67e74705SXin Li * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17*67e74705SXin Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18*67e74705SXin Li * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19*67e74705SXin Li * THE SOFTWARE.
20*67e74705SXin Li *
21*67e74705SXin Li *===-----------------------------------------------------------------------===
22*67e74705SXin Li */
23*67e74705SXin Li
24*67e74705SXin Li /* See "Data Definitions for libgcc_s" in the Linux Standard Base.*/
25*67e74705SXin Li
26*67e74705SXin Li #ifndef __CLANG_UNWIND_H
27*67e74705SXin Li #define __CLANG_UNWIND_H
28*67e74705SXin Li
29*67e74705SXin Li #if defined(__APPLE__) && __has_include_next(<unwind.h>)
30*67e74705SXin Li /* Darwin (from 11.x on) provide an unwind.h. If that's available,
31*67e74705SXin Li * use it. libunwind wraps some of its definitions in #ifdef _GNU_SOURCE,
32*67e74705SXin Li * so define that around the include.*/
33*67e74705SXin Li # ifndef _GNU_SOURCE
34*67e74705SXin Li # define _SHOULD_UNDEFINE_GNU_SOURCE
35*67e74705SXin Li # define _GNU_SOURCE
36*67e74705SXin Li # endif
37*67e74705SXin Li // libunwind's unwind.h reflects the current visibility. However, Mozilla
38*67e74705SXin Li // builds with -fvisibility=hidden and relies on gcc's unwind.h to reset the
39*67e74705SXin Li // visibility to default and export its contents. gcc also allows users to
40*67e74705SXin Li // override its override by #defining HIDE_EXPORTS (but note, this only obeys
41*67e74705SXin Li // the user's -fvisibility setting; it doesn't hide any exports on its own). We
42*67e74705SXin Li // imitate gcc's header here:
43*67e74705SXin Li # ifdef HIDE_EXPORTS
44*67e74705SXin Li # include_next <unwind.h>
45*67e74705SXin Li # else
46*67e74705SXin Li # pragma GCC visibility push(default)
47*67e74705SXin Li # include_next <unwind.h>
48*67e74705SXin Li # pragma GCC visibility pop
49*67e74705SXin Li # endif
50*67e74705SXin Li # ifdef _SHOULD_UNDEFINE_GNU_SOURCE
51*67e74705SXin Li # undef _GNU_SOURCE
52*67e74705SXin Li # undef _SHOULD_UNDEFINE_GNU_SOURCE
53*67e74705SXin Li # endif
54*67e74705SXin Li #else
55*67e74705SXin Li
56*67e74705SXin Li #include <stdint.h>
57*67e74705SXin Li
58*67e74705SXin Li #ifdef __cplusplus
59*67e74705SXin Li extern "C" {
60*67e74705SXin Li #endif
61*67e74705SXin Li
62*67e74705SXin Li /* It is a bit strange for a header to play with the visibility of the
63*67e74705SXin Li symbols it declares, but this matches gcc's behavior and some programs
64*67e74705SXin Li depend on it */
65*67e74705SXin Li #ifndef HIDE_EXPORTS
66*67e74705SXin Li #pragma GCC visibility push(default)
67*67e74705SXin Li #endif
68*67e74705SXin Li
69*67e74705SXin Li typedef uintptr_t _Unwind_Word;
70*67e74705SXin Li typedef intptr_t _Unwind_Sword;
71*67e74705SXin Li typedef uintptr_t _Unwind_Ptr;
72*67e74705SXin Li typedef uintptr_t _Unwind_Internal_Ptr;
73*67e74705SXin Li typedef uint64_t _Unwind_Exception_Class;
74*67e74705SXin Li
75*67e74705SXin Li typedef intptr_t _sleb128_t;
76*67e74705SXin Li typedef uintptr_t _uleb128_t;
77*67e74705SXin Li
78*67e74705SXin Li struct _Unwind_Context;
79*67e74705SXin Li struct _Unwind_Exception;
80*67e74705SXin Li typedef enum {
81*67e74705SXin Li _URC_NO_REASON = 0,
82*67e74705SXin Li #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
83*67e74705SXin Li !defined(__ARM_DWARF_EH__)
84*67e74705SXin Li _URC_OK = 0, /* used by ARM EHABI */
85*67e74705SXin Li #endif
86*67e74705SXin Li _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
87*67e74705SXin Li
88*67e74705SXin Li _URC_FATAL_PHASE2_ERROR = 2,
89*67e74705SXin Li _URC_FATAL_PHASE1_ERROR = 3,
90*67e74705SXin Li _URC_NORMAL_STOP = 4,
91*67e74705SXin Li
92*67e74705SXin Li _URC_END_OF_STACK = 5,
93*67e74705SXin Li _URC_HANDLER_FOUND = 6,
94*67e74705SXin Li _URC_INSTALL_CONTEXT = 7,
95*67e74705SXin Li _URC_CONTINUE_UNWIND = 8,
96*67e74705SXin Li #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
97*67e74705SXin Li !defined(__ARM_DWARF_EH__)
98*67e74705SXin Li _URC_FAILURE = 9 /* used by ARM EHABI */
99*67e74705SXin Li #endif
100*67e74705SXin Li } _Unwind_Reason_Code;
101*67e74705SXin Li
102*67e74705SXin Li typedef enum {
103*67e74705SXin Li _UA_SEARCH_PHASE = 1,
104*67e74705SXin Li _UA_CLEANUP_PHASE = 2,
105*67e74705SXin Li
106*67e74705SXin Li _UA_HANDLER_FRAME = 4,
107*67e74705SXin Li _UA_FORCE_UNWIND = 8,
108*67e74705SXin Li _UA_END_OF_STACK = 16 /* gcc extension to C++ ABI */
109*67e74705SXin Li } _Unwind_Action;
110*67e74705SXin Li
111*67e74705SXin Li typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
112*67e74705SXin Li struct _Unwind_Exception *);
113*67e74705SXin Li
114*67e74705SXin Li struct _Unwind_Exception {
115*67e74705SXin Li _Unwind_Exception_Class exception_class;
116*67e74705SXin Li _Unwind_Exception_Cleanup_Fn exception_cleanup;
117*67e74705SXin Li _Unwind_Word private_1;
118*67e74705SXin Li _Unwind_Word private_2;
119*67e74705SXin Li /* The Itanium ABI requires that _Unwind_Exception objects are "double-word
120*67e74705SXin Li * aligned". GCC has interpreted this to mean "use the maximum useful
121*67e74705SXin Li * alignment for the target"; so do we. */
122*67e74705SXin Li } __attribute__((__aligned__));
123*67e74705SXin Li
124*67e74705SXin Li typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action,
125*67e74705SXin Li _Unwind_Exception_Class,
126*67e74705SXin Li struct _Unwind_Exception *,
127*67e74705SXin Li struct _Unwind_Context *,
128*67e74705SXin Li void *);
129*67e74705SXin Li
130*67e74705SXin Li typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(
131*67e74705SXin Li int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
132*67e74705SXin Li struct _Unwind_Context *);
133*67e74705SXin Li typedef _Unwind_Personality_Fn __personality_routine;
134*67e74705SXin Li
135*67e74705SXin Li typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
136*67e74705SXin Li void *);
137*67e74705SXin Li
138*67e74705SXin Li #if defined(__arm__) && !defined(__APPLE__)
139*67e74705SXin Li
140*67e74705SXin Li typedef enum {
141*67e74705SXin Li _UVRSC_CORE = 0, /* integer register */
142*67e74705SXin Li _UVRSC_VFP = 1, /* vfp */
143*67e74705SXin Li _UVRSC_WMMXD = 3, /* Intel WMMX data register */
144*67e74705SXin Li _UVRSC_WMMXC = 4 /* Intel WMMX control register */
145*67e74705SXin Li } _Unwind_VRS_RegClass;
146*67e74705SXin Li
147*67e74705SXin Li typedef enum {
148*67e74705SXin Li _UVRSD_UINT32 = 0,
149*67e74705SXin Li _UVRSD_VFPX = 1,
150*67e74705SXin Li _UVRSD_UINT64 = 3,
151*67e74705SXin Li _UVRSD_FLOAT = 4,
152*67e74705SXin Li _UVRSD_DOUBLE = 5
153*67e74705SXin Li } _Unwind_VRS_DataRepresentation;
154*67e74705SXin Li
155*67e74705SXin Li typedef enum {
156*67e74705SXin Li _UVRSR_OK = 0,
157*67e74705SXin Li _UVRSR_NOT_IMPLEMENTED = 1,
158*67e74705SXin Li _UVRSR_FAILED = 2
159*67e74705SXin Li } _Unwind_VRS_Result;
160*67e74705SXin Li
161*67e74705SXin Li #if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__ARM_DWARF_EH__)
162*67e74705SXin Li typedef uint32_t _Unwind_State;
163*67e74705SXin Li #define _US_VIRTUAL_UNWIND_FRAME ((_Unwind_State)0)
164*67e74705SXin Li #define _US_UNWIND_FRAME_STARTING ((_Unwind_State)1)
165*67e74705SXin Li #define _US_UNWIND_FRAME_RESUME ((_Unwind_State)2)
166*67e74705SXin Li #define _US_ACTION_MASK ((_Unwind_State)3)
167*67e74705SXin Li #define _US_FORCE_UNWIND ((_Unwind_State)8)
168*67e74705SXin Li #endif
169*67e74705SXin Li
170*67e74705SXin Li _Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context,
171*67e74705SXin Li _Unwind_VRS_RegClass __regclass,
172*67e74705SXin Li uint32_t __regno,
173*67e74705SXin Li _Unwind_VRS_DataRepresentation __representation,
174*67e74705SXin Li void *__valuep);
175*67e74705SXin Li
176*67e74705SXin Li _Unwind_VRS_Result _Unwind_VRS_Set(struct _Unwind_Context *__context,
177*67e74705SXin Li _Unwind_VRS_RegClass __regclass,
178*67e74705SXin Li uint32_t __regno,
179*67e74705SXin Li _Unwind_VRS_DataRepresentation __representation,
180*67e74705SXin Li void *__valuep);
181*67e74705SXin Li
182*67e74705SXin Li static __inline__
_Unwind_GetGR(struct _Unwind_Context * __context,int __index)183*67e74705SXin Li _Unwind_Word _Unwind_GetGR(struct _Unwind_Context *__context, int __index) {
184*67e74705SXin Li _Unwind_Word __value;
185*67e74705SXin Li _Unwind_VRS_Get(__context, _UVRSC_CORE, __index, _UVRSD_UINT32, &__value);
186*67e74705SXin Li return __value;
187*67e74705SXin Li }
188*67e74705SXin Li
189*67e74705SXin Li static __inline__
_Unwind_SetGR(struct _Unwind_Context * __context,int __index,_Unwind_Word __value)190*67e74705SXin Li void _Unwind_SetGR(struct _Unwind_Context *__context, int __index,
191*67e74705SXin Li _Unwind_Word __value) {
192*67e74705SXin Li _Unwind_VRS_Set(__context, _UVRSC_CORE, __index, _UVRSD_UINT32, &__value);
193*67e74705SXin Li }
194*67e74705SXin Li
195*67e74705SXin Li static __inline__
_Unwind_GetIP(struct _Unwind_Context * __context)196*67e74705SXin Li _Unwind_Word _Unwind_GetIP(struct _Unwind_Context *__context) {
197*67e74705SXin Li _Unwind_Word __ip = _Unwind_GetGR(__context, 15);
198*67e74705SXin Li return __ip & ~(_Unwind_Word)(0x1); /* Remove thumb mode bit. */
199*67e74705SXin Li }
200*67e74705SXin Li
201*67e74705SXin Li static __inline__
_Unwind_SetIP(struct _Unwind_Context * __context,_Unwind_Word __value)202*67e74705SXin Li void _Unwind_SetIP(struct _Unwind_Context *__context, _Unwind_Word __value) {
203*67e74705SXin Li _Unwind_Word __thumb_mode_bit = _Unwind_GetGR(__context, 15) & 0x1;
204*67e74705SXin Li _Unwind_SetGR(__context, 15, __value | __thumb_mode_bit);
205*67e74705SXin Li }
206*67e74705SXin Li #else
207*67e74705SXin Li _Unwind_Word _Unwind_GetGR(struct _Unwind_Context *, int);
208*67e74705SXin Li void _Unwind_SetGR(struct _Unwind_Context *, int, _Unwind_Word);
209*67e74705SXin Li
210*67e74705SXin Li _Unwind_Word _Unwind_GetIP(struct _Unwind_Context *);
211*67e74705SXin Li void _Unwind_SetIP(struct _Unwind_Context *, _Unwind_Word);
212*67e74705SXin Li #endif
213*67e74705SXin Li
214*67e74705SXin Li
215*67e74705SXin Li _Unwind_Word _Unwind_GetIPInfo(struct _Unwind_Context *, int *);
216*67e74705SXin Li
217*67e74705SXin Li _Unwind_Word _Unwind_GetCFA(struct _Unwind_Context *);
218*67e74705SXin Li
219*67e74705SXin Li _Unwind_Word _Unwind_GetBSP(struct _Unwind_Context *);
220*67e74705SXin Li
221*67e74705SXin Li void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context *);
222*67e74705SXin Li
223*67e74705SXin Li _Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *);
224*67e74705SXin Li
225*67e74705SXin Li /* DWARF EH functions; currently not available on Darwin/ARM */
226*67e74705SXin Li #if !defined(__APPLE__) || !defined(__arm__)
227*67e74705SXin Li
228*67e74705SXin Li _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *);
229*67e74705SXin Li _Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *,
230*67e74705SXin Li _Unwind_Stop_Fn, void *);
231*67e74705SXin Li void _Unwind_DeleteException(struct _Unwind_Exception *);
232*67e74705SXin Li void _Unwind_Resume(struct _Unwind_Exception *);
233*67e74705SXin Li _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *);
234*67e74705SXin Li
235*67e74705SXin Li #endif
236*67e74705SXin Li
237*67e74705SXin Li _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
238*67e74705SXin Li
239*67e74705SXin Li /* setjmp(3)/longjmp(3) stuff */
240*67e74705SXin Li typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t;
241*67e74705SXin Li
242*67e74705SXin Li void _Unwind_SjLj_Register(_Unwind_FunctionContext_t);
243*67e74705SXin Li void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t);
244*67e74705SXin Li _Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *);
245*67e74705SXin Li _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *,
246*67e74705SXin Li _Unwind_Stop_Fn, void *);
247*67e74705SXin Li void _Unwind_SjLj_Resume(struct _Unwind_Exception *);
248*67e74705SXin Li _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *);
249*67e74705SXin Li
250*67e74705SXin Li void *_Unwind_FindEnclosingFunction(void *);
251*67e74705SXin Li
252*67e74705SXin Li #ifdef __APPLE__
253*67e74705SXin Li
254*67e74705SXin Li _Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *)
255*67e74705SXin Li __attribute__((__unavailable__));
256*67e74705SXin Li _Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *)
257*67e74705SXin Li __attribute__((__unavailable__));
258*67e74705SXin Li
259*67e74705SXin Li /* Darwin-specific functions */
260*67e74705SXin Li void __register_frame(const void *);
261*67e74705SXin Li void __deregister_frame(const void *);
262*67e74705SXin Li
263*67e74705SXin Li struct dwarf_eh_bases {
264*67e74705SXin Li uintptr_t tbase;
265*67e74705SXin Li uintptr_t dbase;
266*67e74705SXin Li uintptr_t func;
267*67e74705SXin Li };
268*67e74705SXin Li void *_Unwind_Find_FDE(const void *, struct dwarf_eh_bases *);
269*67e74705SXin Li
270*67e74705SXin Li void __register_frame_info_bases(const void *, void *, void *, void *)
271*67e74705SXin Li __attribute__((__unavailable__));
272*67e74705SXin Li void __register_frame_info(const void *, void *) __attribute__((__unavailable__));
273*67e74705SXin Li void __register_frame_info_table_bases(const void *, void*, void *, void *)
274*67e74705SXin Li __attribute__((__unavailable__));
275*67e74705SXin Li void __register_frame_info_table(const void *, void *)
276*67e74705SXin Li __attribute__((__unavailable__));
277*67e74705SXin Li void __register_frame_table(const void *) __attribute__((__unavailable__));
278*67e74705SXin Li void __deregister_frame_info(const void *) __attribute__((__unavailable__));
279*67e74705SXin Li void __deregister_frame_info_bases(const void *)__attribute__((__unavailable__));
280*67e74705SXin Li
281*67e74705SXin Li #else
282*67e74705SXin Li
283*67e74705SXin Li _Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *);
284*67e74705SXin Li _Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *);
285*67e74705SXin Li
286*67e74705SXin Li #endif
287*67e74705SXin Li
288*67e74705SXin Li
289*67e74705SXin Li #ifndef HIDE_EXPORTS
290*67e74705SXin Li #pragma GCC visibility pop
291*67e74705SXin Li #endif
292*67e74705SXin Li
293*67e74705SXin Li #ifdef __cplusplus
294*67e74705SXin Li }
295*67e74705SXin Li #endif
296*67e74705SXin Li
297*67e74705SXin Li #endif
298*67e74705SXin Li
299*67e74705SXin Li #endif /* __CLANG_UNWIND_H */
300