1 /**
2  * Binding for libunwind/libgc's `unwind.h`
3  *
4  * Those bindings expose the `_Unwind_*` symbols used by druntime
5  * to do exception handling.
6  *
7  * See_Also:
8  *      Itanium C++ ABI: Exception Handling ($Revision: 1.22 $)
9  * Source: $(DRUNTIMESRC core/internal/backtrace/_unwind.d)
10  */
11 module core.internal.backtrace.unwind;
12 
13 import core.stdc.stdint;
14 
15 version (ARM)
16 {
17     version (iOS) {} else version = ARM_EABI_UNWINDER;
18 }
19 version (X86)    version = X86_Any;
20 version (X86_64) version = X86_Any;
21 
22 extern (C):
23 
24 alias uintptr_t _Unwind_Word;
25 alias intptr_t _Unwind_Sword;
26 alias uintptr_t _Unwind_Ptr;
27 alias uintptr_t _Unwind_Internal_Ptr;
28 
29 alias ulong _Unwind_Exception_Class;
30 
31 alias uintptr_t _uleb128_t;
32 alias intptr_t _sleb128_t;
33 
34 alias int _Unwind_Reason_Code;
35 enum
36 {
37     _URC_NO_REASON = 0,
38     _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
39     _URC_FATAL_PHASE2_ERROR = 2,
40     _URC_FATAL_PHASE1_ERROR = 3,
41     _URC_NORMAL_STOP = 4,
42     _URC_END_OF_STACK = 5,
43     _URC_HANDLER_FOUND = 6,
44     _URC_INSTALL_CONTEXT = 7,
45     _URC_CONTINUE_UNWIND = 8
46 }
47 version (ARM_EABI_UNWINDER)
48     enum _URC_FAILURE = 9;
49 
50 alias int _Unwind_Action;
51 enum _Unwind_Action _UA_SEARCH_PHASE  = 1;
52 enum _Unwind_Action _UA_CLEANUP_PHASE = 2;
53 enum _Unwind_Action _UA_HANDLER_FRAME = 4;
54 enum _Unwind_Action _UA_FORCE_UNWIND  = 8;
55 enum _Unwind_Action _UA_END_OF_STACK  = 16;
56 
57 alias _Unwind_Exception_Cleanup_Fn = void function(
58         _Unwind_Reason_Code reason,
59         _Unwind_Exception *exc);
60 
61 version (ARM_EABI_UNWINDER)
62 {
63     align(8) struct _Unwind_Control_Block
64     {
65         ulong exception_class;
66         void function(_Unwind_Reason_Code, _Unwind_Control_Block *) exception_cleanup;
67 
68         /* Unwinder cache, private fields for the unwinder's use */
69         struct unwinder_cache_t
70         {
71             uint reserved1; /* init reserved1 to 0, then don't touch */
72             uint reserved2;
73             uint reserved3;
74             uint reserved4;
75             uint reserved5;
76         }
77         unwinder_cache_t unwinder_cache;
78 
79         /* Propagation barrier cache (valid after phase 1): */
80         struct barrier_cache_t
81         {
82             uint sp;
83             uint[5] bitpattern;
84         }
85         barrier_cache_t barrier_cache;
86 
87         /* Cleanup cache (preserved over cleanup): */
88         struct cleanup_cache_t
89         {
90             uint[4] bitpattern;
91         }
92         cleanup_cache_t cleanup_cache;
93 
94         /* Pr cache (for pr's benefit): */
95         struct pr_cache_t
96         {
97             uint fnstart; /* function start address */
98             void* ehtp; /* pointer to EHT entry header word */
99             uint additional;
100             uint reserved1;
101         }
102         pr_cache_t pr_cache;
103     }
104 
105     alias _Unwind_Exception = _Unwind_Control_Block;
106 }
107 else version (X86_Any)
108 {
109     align(16) struct _Unwind_Exception
110     {
111         _Unwind_Exception_Class exception_class;
112         _Unwind_Exception_Cleanup_Fn exception_cleanup;
113         _Unwind_Word private_1;
114         _Unwind_Word private_2;
115     }
116 }
117 else
118 {
119     align(8) struct _Unwind_Exception
120     {
121         _Unwind_Exception_Class exception_class;
122         _Unwind_Exception_Cleanup_Fn exception_cleanup;
123         _Unwind_Word private_1;
124         _Unwind_Word private_2;
125     }
126 }
127 
128 struct _Unwind_Context;
129 
130 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object);
131 
132 alias _Unwind_Stop_Fn = _Unwind_Reason_Code function(
133         int _version,
134         _Unwind_Action actions,
135         _Unwind_Exception_Class exceptionClass,
136         _Unwind_Exception* exceptionObject,
137         _Unwind_Context* context,
138         void* stop_parameter);
139 
140 _Unwind_Reason_Code _Unwind_ForcedUnwind(
141         _Unwind_Exception* exception_object,
142         _Unwind_Stop_Fn stop,
143         void* stop_parameter);
144 
145 alias _Unwind_Trace_Fn = _Unwind_Reason_Code function(_Unwind_Context*, void*);
146 
147 void _Unwind_DeleteException(_Unwind_Exception* exception_object);
148 void _Unwind_Resume(_Unwind_Exception* exception_object);
149 _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception* exception_object);
150 _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*);
151 
152 version (ARM_EABI_UNWINDER)
153 {
154     _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception* exception_object, _Unwind_Context* context);
155     void _Unwind_Complete(_Unwind_Exception* exception_object);
156 }
157 
158 _Unwind_Word _Unwind_GetGR(_Unwind_Context* context, int index);
159 void _Unwind_SetGR(_Unwind_Context* context, int index, _Unwind_Word new_value);
160 _Unwind_Ptr _Unwind_GetIP(_Unwind_Context* context);
161 _Unwind_Ptr _Unwind_GetIPInfo(_Unwind_Context* context, int*);
162 void _Unwind_SetIP(_Unwind_Context* context, _Unwind_Ptr new_value);
163 _Unwind_Word _Unwind_GetCFA(_Unwind_Context*);
164 _Unwind_Word _Unwind_GetBSP(_Unwind_Context*);
165 void* _Unwind_GetLanguageSpecificData(_Unwind_Context*);
166 _Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context* context);
167 void* _Unwind_FindEnclosingFunction(void* pc);
168 
169 version (X68_64)
170 {
171     _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context* context)
172     {
173         return _Unwind_GetGR(context, 1);
174     }
175 
176     _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context* context)
177     {
178         assert(0);
179     }
180 }
181 else
182 {
183     _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context* context);
184     _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context* context);
185 }
186 
187 
188 alias _Unwind_Personality_Fn = _Unwind_Reason_Code function(
189         int _version,
190         _Unwind_Action actions,
191         _Unwind_Exception_Class exceptionClass,
192         _Unwind_Exception* exceptionObject,
193         _Unwind_Context* context);
194 
195 struct SjLj_Function_Context;
196 void _Unwind_SjLj_Register(SjLj_Function_Context *);
197 void _Unwind_SjLj_Unregister(SjLj_Function_Context *);
198 _Unwind_Reason_Code _Unwind_SjLj_RaiseException(_Unwind_Exception*);
199 _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(_Unwind_Exception , _Unwind_Stop_Fn, void*);
200 void _Unwind_SjLj_Resume(_Unwind_Exception*);
201 _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception*);