123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- From b3bea7008ece7a5bdf9b5a5dcc95e82febad1854 Mon Sep 17 00:00:00 2001
- From: Bjorn Neergaard <bjorn@neersighted.com>
- Date: Sat, 9 Feb 2019 19:39:23 +0000
- Subject: [PATCH] Fix cross-compiling i686-pc-windows-gnu from Linux
- This is still very rough and serves as a proof-of-concept for fixing
- Linux -> 32-bit MinGW cross compilation workflow. Currently, clang and
- GCC's MinGW targets both only support DW2 (DWARF) or SJLJ (Set Jump Long
- Jump) unwinding on 32-bit Windows.
- The default for GCC (and the way it is shipped on every major distro) is
- to use SJLJ on Windows, as DWARF cannot traverse non-DWARF frames. This
- would work fine, except for the fact that libgcc (our C runtime on the
- MinGW platform) exports symbols under a different name when configured
- to use SJLJ-style unwinding, and uses a preprocessor macro internally to
- alias them.
- Because of this, we have to detect this scenario and link to the correct
- symbols ourselves. Linking has been tested with a full bootstrap on both
- x86_64-unknown-linux-gnu and i686-pc-windows-gnu, as well as
- cross-compilation of some of my own projects.
- Obviously, the detection is a bit unrefined. Right now we
- unconditionally use SJLJ when compiling Linux -> MinGW. I'd like to add
- feature detection using compiler build flags or autotools-style
- compilation and object analysis. Input on the best way to proceed here
- is welcome.
- Also, currently there is copy-pasted/duplicated code in libunwind.
- Ideally, this could be reduced, but this would likely require a
- rethinking of how iOS is special-cased above, to avoid further
- duplication. Input on how to best structure this file is requested.
- diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
- index 249a183189..df08d6eb0c 100644
- --- a/src/bootstrap/compile.rs
- +++ b/src/bootstrap/compile.rs
- @@ -162,7 +162,12 @@ pub fn std_cargo(builder: &Builder<'_>,
- .arg("--features")
- .arg("compiler-builtins-mem");
- } else {
- - let features = builder.std_features();
- + let mut features = builder.std_features();
- +
- + // FIXME: Temporary detection of SJLJ MinGW compilers.
- + if builder.config.build.contains("linux") && target == "i686-pc-windows-gnu" {
- + features.push_str(" sjlj_eh");
- + }
-
- if compiler.stage != 0 && builder.config.sanitizers {
- // This variable is used by the sanitizer runtime crates, e.g.
- diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
- index 7d60a17042..d876d0b89a 100644
- --- a/src/libstd/Cargo.toml
- +++ b/src/libstd/Cargo.toml
- @@ -71,3 +71,4 @@ wasm-bindgen-threads = []
- # https://github.com/rust-lang-nursery/stdsimd/blob/master/crates/std_detect/Cargo.toml
- std_detect_file_io = []
- std_detect_dlsym_getauxval = []
- +sjlj_eh = ["unwind/sjlj_eh"]
- diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
- index 2378b0a315..0b5979ed62 100644
- --- a/src/libunwind/Cargo.toml
- +++ b/src/libunwind/Cargo.toml
- @@ -16,3 +16,6 @@ doc = false
- core = { path = "../libcore" }
- libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false }
- compiler_builtins = "0.1.0"
- +
- +[features]
- +sjlj_eh = []
- diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs
- index 339b554ed6..ec2f93ed60 100644
- --- a/src/libunwind/libunwind.rs
- +++ b/src/libunwind/libunwind.rs
- @@ -1,10 +1,5 @@
- #![allow(nonstandard_style)]
-
- -macro_rules! cfg_if {
- - ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
- - ( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
- -}
- -
- use libc::{c_int, c_void, uintptr_t};
-
- #[repr(C)]
- @@ -73,8 +68,8 @@ pub enum _Unwind_Context {}
- pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code,
- exception: *mut _Unwind_Exception);
- extern "C" {
- - #[unwind(allowed)]
- - pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
- + #[cfg_attr(stage0, unwind)]
- + #[cfg_attr(not(stage0), unwind(allowed))]
- pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
- pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
- pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
- @@ -206,26 +201,52 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm
- pc
- }
- }
- +} // cfg_if!
-
- -if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
- - // Not 32-bit iOS
- +cfg_if! {
- +if #[cfg(all(target_os = "ios", target_arch = "arm"))] {
- + // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
- extern "C" {
- - #[unwind(allowed)]
- - pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
- + #[cfg_attr(stage0, unwind)]
- + #[cfg_attr(not(stage0), unwind(allowed))]
- + pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
- + pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
- + }
- +
- + #[inline]
- + pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
- + _Unwind_SjLj_RaiseException(exc)
- + }
- +
- +} else if #[cfg(feature = "sjlj_eh")] {
- + extern "C" {
- + #[cfg_attr(stage0, unwind)]
- + #[cfg_attr(not(stage0), unwind(allowed))]
- + pub fn _Unwind_SjLj_Resume(e: *mut _Unwind_Exception) -> !;
- + pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
- pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
- trace_argument: *mut c_void)
- -> _Unwind_Reason_Code;
- }
- -} else {
- - // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
- - extern "C" {
- - #[unwind(allowed)]
- - pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
- +
- + #[inline]
- + pub unsafe fn _Unwind_Resume(exc: *mut _Unwind_Exception) -> ! {
- + _Unwind_SjLj_Resume(exc)
- }
-
- #[inline]
- pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
- _Unwind_SjLj_RaiseException(exc)
- }
- +} else {
- + extern "C" {
- + #[cfg_attr(stage0, unwind)]
- + #[cfg_attr(not(stage0), unwind(allowed))]
- + pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
- + pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
- + pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
- + trace_argument: *mut c_void)
- + -> _Unwind_Reason_Code;
- + }
- }
- } // cfg_if!
- --
- 2.23.0.rc0
|