Fix ARM unwinding.
This commit is contained in:
parent
8bfd2a84cf
commit
cefb2c7e45
@ -157,6 +157,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-l
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_x86_64-unknown-linux-gnu := .linux.def
|
||||
CFG_LLC_FLAGS_x86_64-unknown-linux-gnu :=
|
||||
CFG_INSTALL_NAME_x86_64-unknown-linux-gnu =
|
||||
CFG_LIBUV_LINK_FLAGS_x86_64-unknown-linux-gnu =
|
||||
CFG_LLVM_BUILD_ENV_x86_64-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
|
||||
@ -184,6 +185,7 @@ CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-lis
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
|
||||
CFG_LLC_FLAGS_i686-unknown-linux-gnu :=
|
||||
CFG_INSTALL_NAME_i686-unknown-linux-gnu =
|
||||
CFG_LIBUV_LINK_FLAGS_i686-unknown-linux-gnu =
|
||||
CFG_LLVM_BUILD_ENV_i686-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
|
||||
@ -213,6 +215,7 @@ CFG_GCCISH_DEF_FLAG_arm-apple-darwin := -Wl,-exported_symbols_list,
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-darwin :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_arm-apple-darwin :=
|
||||
CFG_DEF_SUFFIX_arm-apple-darwin := .darwin.def
|
||||
CFG_LLC_FLAGS_arm-apple-darwin := -arm-enable-ehabi -arm-enable-ehabi-descriptors
|
||||
CFG_INSTALL_NAME_arm-apple-darwin = -Wl,-install_name,@rpath/$(1)
|
||||
CFG_LIBUV_LINK_FLAGS_arm-apple-darwin =
|
||||
CFG_EXE_SUFFIX_arm-apple-darwin :=
|
||||
@ -240,6 +243,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
|
||||
CFG_DEF_SUFFIX_x86_64-apple-darwin := .darwin.def
|
||||
CFG_LLC_FLAGS_x86_64-apple-darwin :=
|
||||
CFG_INSTALL_NAME_x86_64-apple-darwin = -Wl,-install_name,@rpath/$(1)
|
||||
CFG_LIBUV_LINK_FLAGS_x86_64-apple-darwin =
|
||||
CFG_EXE_SUFFIX_x86_64-apple-darwin :=
|
||||
@ -266,6 +270,7 @@ CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
|
||||
CFG_DEF_SUFFIX_i686-apple-darwin := .darwin.def
|
||||
CFG_LLC_FLAGS_i686-apple-darwin :=
|
||||
CFG_INSTALL_NAME_i686-apple-darwin = -Wl,-install_name,@rpath/$(1)
|
||||
CFG_LIBUV_LINK_FLAGS_i686-apple-darwin =
|
||||
CFG_EXE_SUFFIX_i686-apple-darwin :=
|
||||
@ -292,6 +297,7 @@ CFG_GCCISH_DEF_FLAG_arm-linux-androideabi := -Wl,--export-dynamic,--dynamic-list
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_arm-linux-androideabi := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_arm-linux-androideabi := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_arm-linux-androideabi := .android.def
|
||||
CFG_LLC_FLAGS_arm-linux-androideabi := -arm-enable-ehabi -arm-enable-ehabi-descriptors
|
||||
CFG_INSTALL_NAME_arm-linux-androideabi =
|
||||
CFG_LIBUV_LINK_FLAGS_arm-linux-androideabi =
|
||||
CFG_EXE_SUFFIX_arm-linux-androideabi :=
|
||||
@ -321,6 +327,7 @@ CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynami
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def
|
||||
CFG_LLC_FLAGS_arm-unknown-linux-gnueabihf := -arm-enable-ehabi -arm-enable-ehabi-descriptors
|
||||
CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf =
|
||||
CFG_LIBUV_LINK_FLAGS_arm-unknown-linux-gnueabihf =
|
||||
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf :=
|
||||
@ -350,6 +357,7 @@ CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabi := .linux.def
|
||||
CFG_LLC_FLAGS_arm-unknown-linux-gnueabi := -arm-enable-ehabi -arm-enable-ehabi-descriptors
|
||||
CFG_INSTALL_NAME_arm-unknown-linux-gnueabi =
|
||||
CFG_LIBUV_LINK_FLAGS_arm-unknown-linux-gnueabi =
|
||||
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabi :=
|
||||
@ -378,6 +386,7 @@ CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-lis
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
|
||||
CFG_LLC_FLAGS_mips-unknown-linux-gnu :=
|
||||
CFG_INSTALL_NAME_mips-unknown-linux-gnu =
|
||||
CFG_LIBUV_LINK_FLAGS_mips-unknown-linux-gnu =
|
||||
CFG_EXE_SUFFIX_mips-unknown-linux-gnu :=
|
||||
@ -405,6 +414,7 @@ CFG_GCCISH_DEF_FLAG_i686-pc-mingw32 :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-mingw32 :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i686-pc-mingw32 :=
|
||||
CFG_DEF_SUFFIX_i686-pc-mingw32 := .mingw32.def
|
||||
CFG_LLC_FLAGS_i686-pc-mingw32 :=
|
||||
CFG_INSTALL_NAME_i686-pc-mingw32 =
|
||||
CFG_LIBUV_LINK_FLAGS_i686-pc-mingw32 := -lws2_32 -lpsapi -liphlpapi
|
||||
CFG_LLVM_BUILD_ENV_i686-pc-mingw32 := CPATH=$(CFG_SRC_DIR)src/etc/mingw-fix-include
|
||||
@ -432,6 +442,7 @@ CFG_GCCISH_DEF_FLAG_i586-mingw32msvc :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i586-mingw32msvc :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i586-mingw32msvc :=
|
||||
CFG_DEF_SUFFIX_i586-mingw32msvc := .mingw32.def
|
||||
CFG_LLC_FLAGS_i586-mingw32msvc :=
|
||||
CFG_INSTALL_NAME_i586-mingw32msvc =
|
||||
CFG_LIBUV_LINK_FLAGS_i586-mingw32msvc := -L$(CFG_MINGW32_CROSS_PATH)/i586-mingw32msvc/lib -lws2_32 -lpsapi -liphlpapi
|
||||
CFG_EXE_SUFFIX_i586-mingw32msvc := .exe
|
||||
@ -461,6 +472,7 @@ CFG_GCCISH_DEF_FLAG_i686-w64-mingw32 :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i686-w64-mingw32 :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i686-w64-mingw32 :=
|
||||
CFG_DEF_SUFFIX_i686-w64-mingw32 := .mingw32.def
|
||||
CFG_LLC_FLAGS_i686-w64-mingw32 :=
|
||||
CFG_INSTALL_NAME_i686-w64-mingw32 =
|
||||
CFG_LIBUV_LINK_FLAGS_i686-w64-mingw32 := -lws2_32 -lpsapi -liphlpapi
|
||||
CFG_EXE_SUFFIX_i686-w64-mingw32 := .exe
|
||||
@ -489,6 +501,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-w64-mingw32 :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-w64-mingw32 :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_x86_64-w64-mingw32 :=
|
||||
CFG_DEF_SUFFIX_x86_64-w64-mingw32 := .mingw32.def
|
||||
CFG_LLC_FLAGS_x86_64-w64-mingw32 :=
|
||||
CFG_INSTALL_NAME_x86_64-w64-mingw32 =
|
||||
CFG_LIBUV_LINK_FLAGS_x86_64-w64-mingw32 := -lws2_32 -lpsapi -liphlpapi
|
||||
CFG_EXE_SUFFIX_x86_64-w64-mingw32 := .exe
|
||||
@ -515,6 +528,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-lis
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_x86_64-unknown-freebsd := .bsd.def
|
||||
CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
|
||||
CFG_INSTALL_NAME_x86_64-unknown-freebsd =
|
||||
CFG_LIBUV_LINK_FLAGS_x86_64-unknown-freebsd := -pthread -lkvm
|
||||
CFG_EXE_SUFFIX_x86_64-unknown-freebsd :=
|
||||
|
2
mk/rt.mk
2
mk/rt.mk
@ -116,7 +116,7 @@ $$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.S $$(MKFILE_DEPS) \
|
||||
$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.ll $$(MKFILE_DEPS) \
|
||||
$$(LLVM_CONFIG_$$(CFG_BUILD))
|
||||
@$$(call E, compile: $$@)
|
||||
$$(Q)$(LLC_$(CFG_BUILD)) -filetype=obj -mtriple=$(1) -relocation-model=pic -o $$@ $$<
|
||||
$$(Q)$(LLC_$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) -filetype=obj -mtriple=$(1) -relocation-model=pic -o $$@ $$<
|
||||
|
||||
$$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJS_$(1)_$(2))
|
||||
@$$(call E, link: $$@)
|
||||
|
@ -59,8 +59,7 @@ use any::{Any, AnyRefExt};
|
||||
use c_str::CString;
|
||||
use cast;
|
||||
use kinds::Send;
|
||||
use libc::{c_char, size_t};
|
||||
use libc::{c_void, c_int};
|
||||
use libc::{c_void, c_char, size_t};
|
||||
use option::{Some, None, Option};
|
||||
use result::{Err, Ok};
|
||||
use rt::local::Local;
|
||||
@ -78,6 +77,7 @@ mod libunwind {
|
||||
|
||||
use libc::{uintptr_t, uint64_t};
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
#[repr(C)]
|
||||
pub enum _Unwind_Action
|
||||
{
|
||||
@ -88,6 +88,18 @@ mod libunwind {
|
||||
_UA_END_OF_STACK = 16,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
#[repr(C)]
|
||||
pub enum _Unwind_State
|
||||
{
|
||||
_US_VIRTUAL_UNWIND_FRAME = 0,
|
||||
_US_UNWIND_FRAME_STARTING = 1,
|
||||
_US_UNWIND_FRAME_RESUME = 2,
|
||||
_US_ACTION_MASK = 3,
|
||||
_US_FORCE_UNWIND = 8,
|
||||
_US_END_OF_STACK = 16
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub enum _Unwind_Reason_Code {
|
||||
_URC_NO_REASON = 0,
|
||||
@ -99,6 +111,7 @@ mod libunwind {
|
||||
_URC_HANDLER_FOUND = 6,
|
||||
_URC_INSTALL_CONTEXT = 7,
|
||||
_URC_CONTINUE_UNWIND = 8,
|
||||
_URC_FAILURE = 9, // used only by ARM EABI
|
||||
}
|
||||
|
||||
pub type _Unwind_Exception_Class = uint64_t;
|
||||
@ -108,8 +121,7 @@ mod libunwind {
|
||||
pub struct _Unwind_Exception {
|
||||
exception_class: _Unwind_Exception_Class,
|
||||
exception_cleanup: _Unwind_Exception_Cleanup_Fn,
|
||||
private_1: _Unwind_Word,
|
||||
private_2: _Unwind_Word,
|
||||
private: [_Unwind_Word, ..20],
|
||||
}
|
||||
|
||||
pub enum _Unwind_Context {}
|
||||
@ -148,7 +160,7 @@ impl Unwinder {
|
||||
let ep = rust_try(try_fn, closure.code as *c_void,
|
||||
closure.env as *c_void);
|
||||
if !ep.is_null() {
|
||||
rtdebug!("Caught {}", (*ep).exception_class);
|
||||
rtdebug!("caught {}", (*ep).exception_class);
|
||||
uw::_Unwind_DeleteException(ep);
|
||||
}
|
||||
}
|
||||
@ -190,8 +202,7 @@ impl Unwinder {
|
||||
let exception = ~uw::_Unwind_Exception {
|
||||
exception_class: rust_exception_class(),
|
||||
exception_cleanup: exception_cleanup,
|
||||
private_1: 0,
|
||||
private_2: 0
|
||||
private: [0, ..20],
|
||||
};
|
||||
let error = uw::_Unwind_RaiseException(cast::transmute(exception));
|
||||
rtabort!("Could not unwind stack, error = {}", error as int)
|
||||
@ -242,51 +253,107 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
|
||||
// This is achieved by overriding the return value in search phase to always
|
||||
// say "catch!".
|
||||
|
||||
extern "C" {
|
||||
fn __gcc_personality_v0(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
}
|
||||
#[cfg(not(target_os = "android"))]
|
||||
pub mod eabi {
|
||||
use uw = super::libunwind;
|
||||
use libc::c_int;
|
||||
|
||||
#[lang="eh_personality"]
|
||||
#[no_mangle] // so we can reference it by name from middle/trans/base.rs
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(test))]
|
||||
pub extern "C" fn rust_eh_personality(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
unsafe {
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
extern "C" {
|
||||
fn __gcc_personality_v0(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle] // referenced from rust_try.ll
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(test))]
|
||||
pub extern "C" fn rust_eh_personality_catch(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
|
||||
uw::_URC_HANDLER_FOUND // catch!
|
||||
}
|
||||
else { // cleanup phase
|
||||
#[lang="eh_personality"]
|
||||
#[no_mangle] // so we can reference it by name from middle/trans/base.rs
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(test))]
|
||||
pub extern "C" fn rust_eh_personality(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
unsafe {
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle] // referenced from rust_try.ll
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(test))]
|
||||
pub extern "C" fn rust_eh_personality_catch(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
|
||||
uw::_URC_HANDLER_FOUND // catch!
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ARM EHABI uses a slightly different personality routine signature,
|
||||
// but otherwise works the same.
|
||||
#[cfg(target_os = "android")]
|
||||
pub mod eabi {
|
||||
use uw = super::libunwind;
|
||||
use libc::c_int;
|
||||
|
||||
extern "C" {
|
||||
fn __gcc_personality_v0(state: uw::_Unwind_State,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
}
|
||||
|
||||
#[lang="eh_personality"]
|
||||
#[no_mangle] // so we can reference it by name from middle/trans/base.rs
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(test))]
|
||||
pub extern "C" fn rust_eh_personality(
|
||||
state: uw::_Unwind_State,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
unsafe {
|
||||
__gcc_personality_v0(state, ue_header, context)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle] // referenced from rust_try.ll
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(test))]
|
||||
pub extern "C" fn rust_eh_personality_catch(
|
||||
state: uw::_Unwind_State,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
if (state as c_int & uw::_US_ACTION_MASK as c_int)
|
||||
== uw::_US_VIRTUAL_UNWIND_FRAME as c_int { // search phase
|
||||
uw::_URC_HANDLER_FOUND // catch!
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_v0(state, ue_header, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user