[tor-commits] [tor-browser-build/master] Bug 26329: Fix Rust cross-compilation for 32bit Windows

boklm at torproject.org boklm at torproject.org
Thu Jun 14 13:31:47 UTC 2018


commit 3751474686ba0d2cc7b8a4086114332cbc36e29c
Author: Georg Koppen <gk at torproject.org>
Date:   Thu Jun 14 11:26:47 2018 +0000

    Bug 26329: Fix Rust cross-compilation for 32bit Windows
---
 projects/rust/build             |   4 +-
 projects/rust/config            |   2 +-
 projects/rust/panic-abort.patch |  36 ----------
 projects/rust/unwind.patch      | 154 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 157 insertions(+), 39 deletions(-)

diff --git a/projects/rust/build b/projects/rust/build
index 74ce74a..af0f62b 100644
--- a/projects/rust/build
+++ b/projects/rust/build
@@ -65,8 +65,8 @@ cd /var/tmp/build/rustc-[% c('version') %]-src
   # toolchains on Linux, targeting Windows 32bit, use SjLj unwinding.
   # See: https://github.com/rust-lang/rust/issues/12859 for discussion about
   # that and https://github.com/rust-lang/rust/pull/49633 for a newer attempt to
-  # fix this problem.
-  patch -p1 < $rootdir/panic-abort.patch
+  # fix this problem. We backport and apply the patch from neersighted.
+  patch -p1 < $rootdir/unwind.patch
 [% END %]
 
 mkdir build
diff --git a/projects/rust/config b/projects/rust/config
index 9d3030d..771b50b 100644
--- a/projects/rust/config
+++ b/projects/rust/config
@@ -73,5 +73,5 @@ input_files:
     gpg_keyring: rust.gpg
   - filename: binaryen.patch
     enable: '[% c("var/linux") %]'
-  - filename: panic-abort.patch
+  - filename: unwind.patch
     enable: '[% c("var/windows-i686") %]'
diff --git a/projects/rust/panic-abort.patch b/projects/rust/panic-abort.patch
deleted file mode 100644
index 1711ff7..0000000
--- a/projects/rust/panic-abort.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 2fe471643721f3967f1bdf28907b0a7247fdb705 Mon Sep 17 00:00:00 2001
-From: Georg Koppen <gk at torproject.org>
-Date: Thu, 26 Apr 2018 13:18:27 +0000
-Subject: [PATCH] Avoid cross-compilation breakage due to unwinding
- incompatibilities
-
-
-diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
-index 55d104b182..85330f973b 100644
---- a/src/bootstrap/bin/rustc.rs
-+++ b/src/bootstrap/bin/rustc.rs
-@@ -143,7 +143,8 @@ fn main() {
-         // workaround undefined references to `rust_eh_unwind_resume` generated
-         // otherwise, see issue https://github.com/rust-lang/rust/issues/43095.
-         if crate_name == "panic_abort" ||
--           crate_name == "compiler_builtins" && stage != "0" {
-+           crate_name == "compiler_builtins" && stage != "0" ||
-+           target == "i686-pc-windows-gnu" {
-             cmd.arg("-C").arg("panic=abort");
-         }
- 
-diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
-index 9ea5f39b71..bb689120af 100644
---- a/src/libtest/lib.rs
-+++ b/src/libtest/lib.rs
-@@ -45,7 +45,6 @@ extern crate getopts;
- extern crate term;
- #[cfg(any(unix, target_os = "cloudabi"))]
- extern crate libc;
--extern crate panic_unwind;
- 
- pub use self::TestFn::*;
- pub use self::ColorConfig::*;
--- 
-2.17.0
-
diff --git a/projects/rust/unwind.patch b/projects/rust/unwind.patch
new file mode 100644
index 0000000..8e2e0fc
--- /dev/null
+++ b/projects/rust/unwind.patch
@@ -0,0 +1,154 @@
+From f967c575e502e507ed51b7ed8d1e2a08525e6ae6 Mon Sep 17 00:00:00 2001
+From: Bjorn Neergaard <bjorn at neersighted.com>
+Date: Tue, 3 Apr 2018 19:01:07 -0600
+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 c85b04ddc0..2f58f0d9fa 100644
+--- a/src/bootstrap/compile.rs
++++ b/src/bootstrap/compile.rs
+@@ -145,6 +145,11 @@ pub fn std_cargo(build: &Build,
+         cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
+     }
+ 
++    // FIXME: Temporary detection of SJLJ MinGW compilers.
++    if build.build.contains("linux") && target == "i686-pc-windows-gnu" {
++        features.push_str(" sjlj_eh");
++    }
++
+     // When doing a local rebuild we tell cargo that we're stage1 rather than
+     // stage0. This works fine if the local rust and being-built rust have the
+     // same view of what the default allocator is, but fails otherwise. Since
+diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
+index c1fe4a89d6..6c8cb330d8 100644
+--- a/src/libstd/Cargo.toml
++++ b/src/libstd/Cargo.toml
+@@ -49,3 +49,4 @@ force_alloc_system = []
+ panic-unwind = ["panic_unwind"]
+ profiler = ["profiler_builtins"]
+ wasm_syscall = []
++sjlj_eh = ["unwind/sjlj_eh"]
+diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
+index fbd9789d2f..5e319c67fa 100644
+--- a/src/libunwind/Cargo.toml
++++ b/src/libunwind/Cargo.toml
+@@ -14,3 +14,6 @@ doc = false
+ [dependencies]
+ core = { path = "../libcore" }
+ libc = { path = "../rustc/libc_shim" }
++
++[features]
++sjlj_eh = []
+diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs
+index e6fff7963f..6a57cf7c93 100644
+--- a/src/libunwind/libunwind.rs
++++ b/src/libunwind/libunwind.rs
+@@ -10,11 +10,6 @@
+ 
+ #![allow(bad_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)]
+@@ -84,7 +79,6 @@ pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reaso
+                                                       exception: *mut _Unwind_Exception);
+ extern "C" {
+     #[unwind]
+-    pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
+     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;
+@@ -216,26 +210,49 @@ if #[cfg(all(any(target_os = "ios", 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]
+-        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;
++        pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
++        pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
+     }
+-} else {
+-    // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
++
++    #[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" {
+         #[unwind]
++        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;
++    }
++
++    #[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" {
++        #[unwind]
++        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.17.1
+



More information about the tor-commits mailing list