]>
Commit | Line | Data |
---|---|---|
b7449926 | 1 | #![allow(nonstandard_style)] |
1a4d82fc | 2 | |
5bcae85e | 3 | use libc::{c_int, c_void, uintptr_t}; |
1a4d82fc JJ |
4 | |
5 | #[repr(C)] | |
8bb4bdeb | 6 | #[derive(Debug, Copy, Clone, PartialEq)] |
1a4d82fc JJ |
7 | pub enum _Unwind_Reason_Code { |
8 | _URC_NO_REASON = 0, | |
9 | _URC_FOREIGN_EXCEPTION_CAUGHT = 1, | |
10 | _URC_FATAL_PHASE2_ERROR = 2, | |
11 | _URC_FATAL_PHASE1_ERROR = 3, | |
12 | _URC_NORMAL_STOP = 4, | |
13 | _URC_END_OF_STACK = 5, | |
14 | _URC_HANDLER_FOUND = 6, | |
15 | _URC_INSTALL_CONTEXT = 7, | |
16 | _URC_CONTINUE_UNWIND = 8, | |
5bcae85e | 17 | _URC_FAILURE = 9, // used only by ARM EHABI |
1a4d82fc | 18 | } |
9fa01778 | 19 | pub use _Unwind_Reason_Code::*; |
1a4d82fc JJ |
20 | |
21 | pub type _Unwind_Exception_Class = u64; | |
5bcae85e SL |
22 | pub type _Unwind_Word = uintptr_t; |
23 | pub type _Unwind_Ptr = uintptr_t; | |
dfeec247 XL |
24 | pub type _Unwind_Trace_Fn = |
25 | extern "C" fn(ctx: *mut _Unwind_Context, arg: *mut c_void) -> _Unwind_Reason_Code; | |
26 | ||
1a4d82fc | 27 | #[cfg(target_arch = "x86")] |
c34b1796 | 28 | pub const unwinder_private_data_size: usize = 5; |
1a4d82fc | 29 | |
6522a427 EL |
30 | #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))] |
31 | pub const unwinder_private_data_size: usize = 2; | |
32 | ||
33 | #[cfg(all(target_arch = "x86_64", target_os = "windows"))] | |
c34b1796 | 34 | pub const unwinder_private_data_size: usize = 6; |
1a4d82fc | 35 | |
064997fb | 36 | #[cfg(all(target_arch = "arm", not(any(target_os = "ios", target_os = "watchos"))))] |
c34b1796 | 37 | pub const unwinder_private_data_size: usize = 20; |
1a4d82fc | 38 | |
064997fb | 39 | #[cfg(all(target_arch = "arm", any(target_os = "ios", target_os = "watchos")))] |
c34b1796 | 40 | pub const unwinder_private_data_size: usize = 5; |
1a4d82fc | 41 | |
6522a427 | 42 | #[cfg(all(target_arch = "aarch64", target_pointer_width = "64", not(target_os = "windows")))] |
c34b1796 | 43 | pub const unwinder_private_data_size: usize = 2; |
1a4d82fc | 44 | |
6522a427 EL |
45 | #[cfg(all(target_arch = "aarch64", target_pointer_width = "64", target_os = "windows"))] |
46 | pub const unwinder_private_data_size: usize = 6; | |
47 | ||
5869c6ff XL |
48 | #[cfg(all(target_arch = "aarch64", target_pointer_width = "32"))] |
49 | pub const unwinder_private_data_size: usize = 5; | |
50 | ||
5099ac24 FG |
51 | #[cfg(target_arch = "m68k")] |
52 | pub const unwinder_private_data_size: usize = 2; | |
53 | ||
7453a54e | 54 | #[cfg(target_arch = "mips")] |
c34b1796 | 55 | pub const unwinder_private_data_size: usize = 2; |
1a4d82fc | 56 | |
9e0c209e SL |
57 | #[cfg(target_arch = "mips64")] |
58 | pub const unwinder_private_data_size: usize = 2; | |
59 | ||
7453a54e | 60 | #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] |
c34b1796 | 61 | pub const unwinder_private_data_size: usize = 2; |
85aaf69f | 62 | |
9e0c209e SL |
63 | #[cfg(target_arch = "s390x")] |
64 | pub const unwinder_private_data_size: usize = 2; | |
65 | ||
1b1a35ee | 66 | #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] |
32a655c1 SL |
67 | pub const unwinder_private_data_size: usize = 2; |
68 | ||
1b1a35ee | 69 | #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] |
dfeec247 XL |
70 | pub const unwinder_private_data_size: usize = 2; |
71 | ||
c30ab7b3 | 72 | #[cfg(target_os = "emscripten")] |
7453a54e SL |
73 | pub const unwinder_private_data_size: usize = 20; |
74 | ||
416331ca XL |
75 | #[cfg(all(target_arch = "hexagon", target_os = "linux"))] |
76 | pub const unwinder_private_data_size: usize = 35; | |
77 | ||
1a4d82fc JJ |
78 | #[repr(C)] |
79 | pub struct _Unwind_Exception { | |
80 | pub exception_class: _Unwind_Exception_Class, | |
81 | pub exception_cleanup: _Unwind_Exception_Cleanup_Fn, | |
82 | pub private: [_Unwind_Word; unwinder_private_data_size], | |
83 | } | |
84 | ||
85 | pub enum _Unwind_Context {} | |
86 | ||
dfeec247 XL |
87 | pub type _Unwind_Exception_Cleanup_Fn = |
88 | extern "C" fn(unwind_code: _Unwind_Reason_Code, exception: *mut _Unwind_Exception); | |
94222f64 XL |
89 | |
90 | // FIXME: The `#[link]` attributes on `extern "C"` block marks those symbols declared in | |
6522a427 | 91 | // the block are reexported in dylib build of std. This is needed when build rustc with |
94222f64 XL |
92 | // feature `llvm-libunwind', as no other cdylib will provided those _Unwind_* symbols. |
93 | // However the `link` attribute is duplicated multiple times and does not just export symbol, | |
94 | // a better way to manually export symbol would be another attribute like `#[export]`. | |
95 | // See the logic in function rustc_codegen_ssa::src::back::exported_symbols, module | |
96 | // rustc_codegen_ssa::src::back::symbol_export, rustc_middle::middle::exported_symbols | |
97 | // and RFC 2841 | |
dfeec247 | 98 | #[cfg_attr( |
6522a427 EL |
99 | any( |
100 | all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), | |
101 | all(target_os = "windows", target_env = "gnu", target_abi = "llvm") | |
102 | ), | |
94222f64 | 103 | link(name = "unwind", kind = "static", modifiers = "-bundle") |
dfeec247 | 104 | )] |
94222f64 | 105 | extern "C-unwind" { |
5bcae85e | 106 | pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !; |
94222f64 XL |
107 | } |
108 | extern "C" { | |
1a4d82fc | 109 | pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception); |
5bcae85e SL |
110 | pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void; |
111 | pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; | |
112 | pub fn _Unwind_GetTextRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; | |
113 | pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; | |
114 | } | |
92a42be0 | 115 | |
dc9dc135 | 116 | cfg_if::cfg_if! { |
064997fb | 117 | if #[cfg(any(target_os = "ios", target_os = "watchos", target_os = "netbsd", not(target_arch = "arm")))] { |
5bcae85e SL |
118 | // Not ARM EHABI |
119 | #[repr(C)] | |
120 | #[derive(Copy, Clone, PartialEq)] | |
121 | pub enum _Unwind_Action { | |
122 | _UA_SEARCH_PHASE = 1, | |
123 | _UA_CLEANUP_PHASE = 2, | |
124 | _UA_HANDLER_FRAME = 4, | |
125 | _UA_FORCE_UNWIND = 8, | |
126 | _UA_END_OF_STACK = 16, | |
127 | } | |
9fa01778 | 128 | pub use _Unwind_Action::*; |
a7813a04 | 129 | |
94222f64 XL |
130 | #[cfg_attr( |
131 | all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), | |
132 | link(name = "unwind", kind = "static", modifiers = "-bundle") | |
133 | )] | |
5bcae85e SL |
134 | extern "C" { |
135 | pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word; | |
136 | pub fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word); | |
137 | pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> _Unwind_Word; | |
138 | pub fn _Unwind_SetIP(ctx: *mut _Unwind_Context, value: _Unwind_Word); | |
139 | pub fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, ip_before_insn: *mut c_int) | |
140 | -> _Unwind_Word; | |
141 | pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void; | |
142 | } | |
1a4d82fc | 143 | |
5bcae85e SL |
144 | } else { |
145 | // ARM EHABI | |
146 | #[repr(C)] | |
147 | #[derive(Copy, Clone, PartialEq)] | |
148 | pub enum _Unwind_State { | |
149 | _US_VIRTUAL_UNWIND_FRAME = 0, | |
150 | _US_UNWIND_FRAME_STARTING = 1, | |
151 | _US_UNWIND_FRAME_RESUME = 2, | |
152 | _US_ACTION_MASK = 3, | |
153 | _US_FORCE_UNWIND = 8, | |
154 | _US_END_OF_STACK = 16, | |
155 | } | |
9fa01778 | 156 | pub use _Unwind_State::*; |
a7813a04 | 157 | |
a7813a04 XL |
158 | #[repr(C)] |
159 | enum _Unwind_VRS_Result { | |
160 | _UVRSR_OK = 0, | |
161 | _UVRSR_NOT_IMPLEMENTED = 1, | |
162 | _UVRSR_FAILED = 2, | |
163 | } | |
164 | #[repr(C)] | |
165 | enum _Unwind_VRS_RegClass { | |
166 | _UVRSC_CORE = 0, | |
167 | _UVRSC_VFP = 1, | |
168 | _UVRSC_FPA = 2, | |
169 | _UVRSC_WMMXD = 3, | |
170 | _UVRSC_WMMXC = 4, | |
171 | } | |
9fa01778 | 172 | use _Unwind_VRS_RegClass::*; |
a7813a04 XL |
173 | #[repr(C)] |
174 | enum _Unwind_VRS_DataRepresentation { | |
175 | _UVRSD_UINT32 = 0, | |
176 | _UVRSD_VFPX = 1, | |
177 | _UVRSD_FPAX = 2, | |
178 | _UVRSD_UINT64 = 3, | |
179 | _UVRSD_FLOAT = 4, | |
180 | _UVRSD_DOUBLE = 5, | |
181 | } | |
9fa01778 | 182 | use _Unwind_VRS_DataRepresentation::*; |
5bcae85e SL |
183 | |
184 | pub const UNWIND_POINTER_REG: c_int = 12; | |
dfeec247 | 185 | pub const UNWIND_SP_REG: c_int = 13; |
5bcae85e | 186 | pub const UNWIND_IP_REG: c_int = 15; |
a7813a04 | 187 | |
94222f64 XL |
188 | #[cfg_attr( |
189 | all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), | |
190 | link(name = "unwind", kind = "static", modifiers = "-bundle") | |
191 | )] | |
3157f602 | 192 | extern "C" { |
a7813a04 | 193 | fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context, |
5bcae85e SL |
194 | regclass: _Unwind_VRS_RegClass, |
195 | regno: _Unwind_Word, | |
a7813a04 | 196 | repr: _Unwind_VRS_DataRepresentation, |
5bcae85e SL |
197 | data: *mut c_void) |
198 | -> _Unwind_VRS_Result; | |
199 | ||
200 | fn _Unwind_VRS_Set(ctx: *mut _Unwind_Context, | |
201 | regclass: _Unwind_VRS_RegClass, | |
202 | regno: _Unwind_Word, | |
203 | repr: _Unwind_VRS_DataRepresentation, | |
204 | data: *mut c_void) | |
3157f602 | 205 | -> _Unwind_VRS_Result; |
a7813a04 XL |
206 | } |
207 | ||
5bcae85e SL |
208 | // On Android or ARM/Linux, these are implemented as macros: |
209 | ||
210 | pub unsafe fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word { | |
211 | let mut val: _Unwind_Word = 0; | |
212 | _Unwind_VRS_Get(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, | |
213 | &mut val as *mut _ as *mut c_void); | |
214 | val | |
215 | } | |
216 | ||
217 | pub unsafe fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word) { | |
218 | let mut value = value; | |
219 | _Unwind_VRS_Set(ctx, _UVRSC_CORE, reg_index as _Unwind_Word, _UVRSD_UINT32, | |
220 | &mut value as *mut _ as *mut c_void); | |
221 | } | |
222 | ||
223 | pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) | |
224 | -> _Unwind_Word { | |
225 | let val = _Unwind_GetGR(ctx, UNWIND_IP_REG); | |
226 | (val & !1) as _Unwind_Word | |
227 | } | |
a7813a04 | 228 | |
5bcae85e SL |
229 | pub unsafe fn _Unwind_SetIP(ctx: *mut _Unwind_Context, |
230 | value: _Unwind_Word) { | |
231 | // Propagate thumb bit to instruction pointer | |
232 | let thumb_state = _Unwind_GetGR(ctx, UNWIND_IP_REG) & 1; | |
233 | let value = value | thumb_state; | |
234 | _Unwind_SetGR(ctx, UNWIND_IP_REG, value); | |
235 | } | |
236 | ||
237 | pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, | |
238 | ip_before_insn: *mut c_int) | |
239 | -> _Unwind_Word { | |
240 | *ip_before_insn = 0; | |
241 | _Unwind_GetIP(ctx) | |
242 | } | |
243 | ||
244 | // This function also doesn't exist on Android or ARM/Linux, so make it a no-op | |
245 | pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void { | |
246 | pc | |
247 | } | |
a7813a04 | 248 | } |
dc9dc135 | 249 | } // cfg_if! |
a7813a04 | 250 | |
dc9dc135 | 251 | cfg_if::cfg_if! { |
5bcae85e SL |
252 | if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { |
253 | // Not 32-bit iOS | |
94222f64 XL |
254 | #[cfg_attr( |
255 | all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), | |
256 | link(name = "unwind", kind = "static", modifiers = "-bundle") | |
257 | )] | |
258 | extern "C-unwind" { | |
5bcae85e | 259 | pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code; |
94222f64 | 260 | } |
5e7ed085 FG |
261 | #[cfg_attr( |
262 | all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), | |
263 | link(name = "unwind", kind = "static", modifiers = "-bundle") | |
264 | )] | |
94222f64 | 265 | extern "C" { |
5bcae85e SL |
266 | pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn, |
267 | trace_argument: *mut c_void) | |
268 | -> _Unwind_Reason_Code; | |
269 | } | |
270 | } else { | |
271 | // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace() | |
94222f64 | 272 | extern "C-unwind" { |
5bcae85e SL |
273 | pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; |
274 | } | |
275 | ||
923072b8 | 276 | pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException; |
a7813a04 | 277 | } |
5bcae85e | 278 | } // cfg_if! |
e74abb32 XL |
279 | |
280 | cfg_if::cfg_if! { | |
6522a427 | 281 | if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] { |
e74abb32 XL |
282 | // We declare these as opaque types. This is fine since you just need to |
283 | // pass them to _GCC_specific_handler and forget about them. | |
284 | pub enum EXCEPTION_RECORD {} | |
285 | pub type LPVOID = *mut c_void; | |
286 | pub enum CONTEXT {} | |
287 | pub enum DISPATCHER_CONTEXT {} | |
288 | pub type EXCEPTION_DISPOSITION = c_int; | |
289 | type PersonalityFn = unsafe extern "C" fn(version: c_int, | |
290 | actions: _Unwind_Action, | |
291 | exception_class: _Unwind_Exception_Class, | |
292 | exception_object: *mut _Unwind_Exception, | |
293 | context: *mut _Unwind_Context) | |
294 | -> _Unwind_Reason_Code; | |
295 | ||
296 | extern "C" { | |
297 | pub fn _GCC_specific_handler(exceptionRecord: *mut EXCEPTION_RECORD, | |
298 | establisherFrame: LPVOID, | |
299 | contextRecord: *mut CONTEXT, | |
300 | dispatcherContext: *mut DISPATCHER_CONTEXT, | |
301 | personality: PersonalityFn) | |
302 | -> EXCEPTION_DISPOSITION; | |
303 | } | |
304 | } | |
305 | } // cfg_if! |