unwind.patch 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. From dd808373aefe6247975455006bbfb89aa6410ed9 Mon Sep 17 00:00:00 2001
  2. From: Bjorn Neergaard <bjorn@neersighted.com>
  3. Date: Tue, 3 Apr 2018 19:01:07 -0600
  4. Subject: [PATCH] Fix cross-compiling i686-pc-windows-gnu from Linux
  5. This is still very rough and serves as a proof-of-concept for fixing
  6. Linux -> 32-bit MinGW cross compilation workflow. Currently, clang and
  7. GCC's MinGW targets both only support DW2 (DWARF) or SJLJ (Set Jump Long
  8. Jump) unwinding on 32-bit Windows.
  9. The default for GCC (and the way it is shipped on every major distro) is
  10. to use SJLJ on Windows, as DWARF cannot traverse non-DWARF frames. This
  11. would work fine, except for the fact that libgcc (our C runtime on the
  12. MinGW platform) exports symbols under a different name when configured
  13. to use SJLJ-style unwinding, and uses a preprocessor macro internally to
  14. alias them.
  15. Because of this, we have to detect this scenario and link to the correct
  16. symbols ourselves. Linking has been tested with a full bootstrap on both
  17. x86_64-unknown-linux-gnu and i686-pc-windows-gnu, as well as
  18. cross-compilation of some of my own projects.
  19. Obviously, the detection is a bit unrefined. Right now we
  20. unconditionally use SJLJ when compiling Linux -> MinGW. I'd like to add
  21. feature detection using compiler build flags or autotools-style
  22. compilation and object analysis. Input on the best way to proceed here
  23. is welcome.
  24. Also, currently there is copy-pasted/duplicated code in libunwind.
  25. Ideally, this could be reduced, but this would likely require a
  26. rethinking of how iOS is special-cased above, to avoid further
  27. duplication. Input on how to best structure this file is requested.
  28. diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
  29. index e6aa78fba5..624f2ccfbe 100644
  30. --- a/src/bootstrap/compile.rs
  31. +++ b/src/bootstrap/compile.rs
  32. @@ -146,6 +146,11 @@ pub fn std_cargo(build: &Builder,
  33. cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
  34. }
  35. + // FIXME: Temporary detection of SJLJ MinGW compilers.
  36. + if build.build.build.contains("linux") && target == "i686-pc-windows-gnu" {
  37. + features.push_str(" sjlj_eh");
  38. + }
  39. +
  40. // When doing a local rebuild we tell cargo that we're stage1 rather than
  41. // stage0. This works fine if the local rust and being-built rust have the
  42. // same view of what the default allocator is, but fails otherwise. Since
  43. diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
  44. index 1201759885..a06ef7e0e6 100644
  45. --- a/src/libstd/Cargo.toml
  46. +++ b/src/libstd/Cargo.toml
  47. @@ -49,3 +49,4 @@ force_alloc_system = []
  48. panic-unwind = ["panic_unwind"]
  49. profiler = ["profiler_builtins"]
  50. wasm_syscall = []
  51. +sjlj_eh = ["unwind/sjlj_eh"]
  52. diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
  53. index fbd9789d2f..15a20d7ff4 100644
  54. --- a/src/libunwind/Cargo.toml
  55. +++ b/src/libunwind/Cargo.toml
  56. @@ -14,3 +14,7 @@ doc = false
  57. [dependencies]
  58. core = { path = "../libcore" }
  59. libc = { path = "../rustc/libc_shim" }
  60. +
  61. +[features]
  62. +sjlj_eh = []
  63. +
  64. diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs
  65. index aa73b11fb3..16c21be736 100644
  66. --- a/src/libunwind/libunwind.rs
  67. +++ b/src/libunwind/libunwind.rs
  68. @@ -10,11 +10,6 @@
  69. #![allow(bad_style)]
  70. -macro_rules! cfg_if {
  71. - ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
  72. - ( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
  73. -}
  74. -
  75. use libc::{c_int, c_void, uintptr_t};
  76. #[repr(C)]
  77. @@ -85,7 +80,6 @@ pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reaso
  78. extern "C" {
  79. #[cfg_attr(stage0, unwind)]
  80. #[cfg_attr(not(stage0), unwind(allowed))]
  81. - pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
  82. pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
  83. pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
  84. pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
  85. @@ -217,28 +211,52 @@ if #[cfg(all(any(target_os = "ios", not(target_arch = "arm"))))] {
  86. pc
  87. }
  88. }
  89. +} // cfg_if!
  90. -if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
  91. - // Not 32-bit iOS
  92. +cfg_if! {
  93. +if #[cfg(all(target_os = "ios", target_arch = "arm"))] {
  94. + // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
  95. extern "C" {
  96. #[cfg_attr(stage0, unwind)]
  97. #[cfg_attr(not(stage0), unwind(allowed))]
  98. - pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
  99. - pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
  100. - trace_argument: *mut c_void)
  101. - -> _Unwind_Reason_Code;
  102. + pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
  103. + pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
  104. }
  105. -} else {
  106. - // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
  107. +
  108. + #[inline]
  109. + pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
  110. + _Unwind_SjLj_RaiseException(exc)
  111. + }
  112. +
  113. +} else if #[cfg(feature = "sjlj_eh")] {
  114. extern "C" {
  115. #[cfg_attr(stage0, unwind)]
  116. #[cfg_attr(not(stage0), unwind(allowed))]
  117. + pub fn _Unwind_SjLj_Resume(e: *mut _Unwind_Exception) -> !;
  118. pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
  119. + pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
  120. + trace_argument: *mut c_void)
  121. + -> _Unwind_Reason_Code;
  122. + }
  123. +
  124. + #[inline]
  125. + pub unsafe fn _Unwind_Resume(exc: *mut _Unwind_Exception) -> ! {
  126. + _Unwind_SjLj_Resume(exc)
  127. }
  128. #[inline]
  129. pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
  130. _Unwind_SjLj_RaiseException(exc)
  131. }
  132. +} else {
  133. + extern "C" {
  134. + #[cfg_attr(stage0, unwind)]
  135. + #[cfg_attr(not(stage0), unwind(allowed))]
  136. + pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
  137. + pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
  138. + pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
  139. + trace_argument: *mut c_void)
  140. + -> _Unwind_Reason_Code;
  141. + }
  142. }
  143. } // cfg_if!
  144. --
  145. 2.17.1