Skip to content

Commit 003e996

Browse files
committed
Fix build on ARM
1 parent 857fb3e commit 003e996

File tree

1 file changed

+75
-68
lines changed

1 file changed

+75
-68
lines changed

src/libpanic_unwind/gcc.rs

Lines changed: 75 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -133,46 +133,6 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1
133133
// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
134134
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
135135

136-
// Shared version of the default personality routine, which is used directly on
137-
// most targets and indirectly on Windows x86_64 via SEH.
138-
#[allow(unused)]
139-
unsafe extern "C" fn rust_eh_personality_impl(version: c_int,
140-
actions: uw::_Unwind_Action,
141-
exception_class: uw::_Unwind_Exception_Class,
142-
exception_object: *mut uw::_Unwind_Exception,
143-
context: *mut uw::_Unwind_Context)
144-
-> uw::_Unwind_Reason_Code {
145-
if version != 1 {
146-
return uw::_URC_FATAL_PHASE1_ERROR;
147-
}
148-
let foreign_exception = exception_class != rust_exception_class();
149-
let eh_action = match find_eh_action(context, foreign_exception) {
150-
Ok(action) => action,
151-
Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
152-
};
153-
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
154-
match eh_action {
155-
EHAction::None |
156-
EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
157-
EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
158-
EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
159-
}
160-
} else {
161-
match eh_action {
162-
EHAction::None => uw::_URC_CONTINUE_UNWIND,
163-
EHAction::Cleanup(lpad) |
164-
EHAction::Catch(lpad) => {
165-
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, exception_object as uintptr_t);
166-
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
167-
uw::_Unwind_SetIP(context, lpad);
168-
uw::_URC_INSTALL_CONTEXT
169-
}
170-
EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
171-
}
172-
}
173-
}
174-
175-
176136
cfg_if::cfg_if! {
177137
if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "netbsd")))] {
178138
// ARM EHABI personality routine.
@@ -217,7 +177,7 @@ cfg_if::cfg_if! {
217177
// _Unwind_Context in our libunwind bindings and fetch the required data from there
218178
// directly, bypassing DWARF compatibility functions.
219179

220-
let exception_class = unsafe { (*exception_object).exception_class };
180+
let exception_class = (*exception_object).exception_class;
221181
let foreign_exception = exception_class != rust_exception_class();
222182
let eh_action = match find_eh_action(context, foreign_exception) {
223183
Ok(action) => action,
@@ -263,34 +223,81 @@ cfg_if::cfg_if! {
263223
-> uw::_Unwind_Reason_Code;
264224
}
265225
}
266-
} else if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
267-
// On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
268-
// handler data (aka LSDA) uses GCC-compatible encoding.
269-
#[lang = "eh_personality"]
270-
#[no_mangle]
271-
#[allow(nonstandard_style)]
272-
unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut uw::EXCEPTION_RECORD,
273-
establisherFrame: uw::LPVOID,
274-
contextRecord: *mut uw::CONTEXT,
275-
dispatcherContext: *mut uw::DISPATCHER_CONTEXT)
276-
-> uw::EXCEPTION_DISPOSITION {
277-
uw::_GCC_specific_handler(exceptionRecord,
278-
establisherFrame,
279-
contextRecord,
280-
dispatcherContext,
281-
rust_eh_personality_impl)
282-
}
283226
} else {
284-
// The personality routine for most of our targets.
285-
#[lang = "eh_personality"]
286-
#[no_mangle]
287-
unsafe extern "C" fn rust_eh_personality(version: c_int,
288-
actions: uw::_Unwind_Action,
289-
exception_class: uw::_Unwind_Exception_Class,
290-
exception_object: *mut uw::_Unwind_Exception,
291-
context: *mut uw::_Unwind_Context)
292-
-> uw::_Unwind_Reason_Code {
293-
rust_eh_personality_impl(version, actions, exception_class, exception_object, context)
227+
// Default personality routine, which is used directly on most targets
228+
// and indirectly on Windows x86_64 via SEH.
229+
unsafe extern "C" fn rust_eh_personality_impl(version: c_int,
230+
actions: uw::_Unwind_Action,
231+
exception_class: uw::_Unwind_Exception_Class,
232+
exception_object: *mut uw::_Unwind_Exception,
233+
context: *mut uw::_Unwind_Context)
234+
-> uw::_Unwind_Reason_Code {
235+
if version != 1 {
236+
return uw::_URC_FATAL_PHASE1_ERROR;
237+
}
238+
let foreign_exception = exception_class != rust_exception_class();
239+
let eh_action = match find_eh_action(context, foreign_exception) {
240+
Ok(action) => action,
241+
Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
242+
};
243+
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
244+
match eh_action {
245+
EHAction::None |
246+
EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
247+
EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
248+
EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
249+
}
250+
} else {
251+
match eh_action {
252+
EHAction::None => uw::_URC_CONTINUE_UNWIND,
253+
EHAction::Cleanup(lpad) |
254+
EHAction::Catch(lpad) => {
255+
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0,
256+
exception_object as uintptr_t);
257+
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
258+
uw::_Unwind_SetIP(context, lpad);
259+
uw::_URC_INSTALL_CONTEXT
260+
}
261+
EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
262+
}
263+
}
264+
}
265+
266+
cfg_if::cfg_if! {
267+
if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
268+
// On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
269+
// handler data (aka LSDA) uses GCC-compatible encoding.
270+
#[lang = "eh_personality"]
271+
#[no_mangle]
272+
#[allow(nonstandard_style)]
273+
unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut uw::EXCEPTION_RECORD,
274+
establisherFrame: uw::LPVOID,
275+
contextRecord: *mut uw::CONTEXT,
276+
dispatcherContext: *mut uw::DISPATCHER_CONTEXT)
277+
-> uw::EXCEPTION_DISPOSITION {
278+
uw::_GCC_specific_handler(exceptionRecord,
279+
establisherFrame,
280+
contextRecord,
281+
dispatcherContext,
282+
rust_eh_personality_impl)
283+
}
284+
} else {
285+
// The personality routine for most of our targets.
286+
#[lang = "eh_personality"]
287+
#[no_mangle]
288+
unsafe extern "C" fn rust_eh_personality(version: c_int,
289+
actions: uw::_Unwind_Action,
290+
exception_class: uw::_Unwind_Exception_Class,
291+
exception_object: *mut uw::_Unwind_Exception,
292+
context: *mut uw::_Unwind_Context)
293+
-> uw::_Unwind_Reason_Code {
294+
rust_eh_personality_impl(version,
295+
actions,
296+
exception_class,
297+
exception_object,
298+
context)
299+
}
300+
}
294301
}
295302
}
296303
}

0 commit comments

Comments
 (0)