diff --git a/mk/cfg/i686-pc-windows-gnu.mk b/mk/cfg/i686-pc-windows-gnu.mk index 3426b30aeeb85..9c55fdbb05fa4 100644 --- a/mk/cfg/i686-pc-windows-gnu.mk +++ b/mk/cfg/i686-pc-windows-gnu.mk @@ -22,6 +22,5 @@ CFG_LDPATH_i686-pc-windows-gnu := CFG_RUN_i686-pc-windows-gnu=$(2) CFG_RUN_TARG_i686-pc-windows-gnu=$(call CFG_RUN_i686-pc-windows-gnu,,$(2)) CFG_GNU_TRIPLE_i686-pc-windows-gnu := i686-w64-mingw32 -CFG_THIRD_PARTY_OBJECTS_i686-pc-windows-gnu := crt2.o dllcrt2.o -CFG_INSTALLED_OBJECTS_i686-pc-windows-gnu := crt2.o dllcrt2.o rsbegin.o rsend.o -CFG_RUSTRT_HAS_STARTUP_OBJS_i686-pc-windows-gnu := 1 +CFG_THIRD_PARTY_OBJECTS_i686-pc-windows-gnu := +CFG_INSTALLED_OBJECTS_i686-pc-windows-gnu := diff --git a/mk/cfg/x86_64-pc-windows-gnu.mk b/mk/cfg/x86_64-pc-windows-gnu.mk index f0732d08c71ea..b69c84cd4ff72 100644 --- a/mk/cfg/x86_64-pc-windows-gnu.mk +++ b/mk/cfg/x86_64-pc-windows-gnu.mk @@ -22,6 +22,5 @@ CFG_LDPATH_x86_64-pc-windows-gnu := CFG_RUN_x86_64-pc-windows-gnu=$(2) CFG_RUN_TARG_x86_64-pc-windows-gnu=$(call CFG_RUN_x86_64-pc-windows-gnu,,$(2)) CFG_GNU_TRIPLE_x86_64-pc-windows-gnu := x86_64-w64-mingw32 -CFG_THIRD_PARTY_OBJECTS_x86_64-pc-windows-gnu := crt2.o dllcrt2.o -CFG_INSTALLED_OBJECTS_x86_64-pc-windows-gnu := crt2.o dllcrt2.o rsbegin.o rsend.o -CFG_RUSTRT_HAS_STARTUP_OBJS_x86_64-pc-windows-gnu := 1 +CFG_THIRD_PARTY_OBJECTS_x86_64-pc-windows-gnu := +CFG_INSTALLED_OBJECTS_x86_64-pc-windows-gnu := diff --git a/mk/dist.mk b/mk/dist.mk index 685fb2b5b4679..929b6c39952e9 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -58,7 +58,6 @@ PKG_FILES := \ libcoretest \ libbacktrace \ rt \ - rtstartup \ rustllvm \ snapshots.txt \ rust-installer \ diff --git a/mk/rt.mk b/mk/rt.mk index cfb210952bcfb..798913fe8a5ad 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -291,10 +291,8 @@ BACKTRACE_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),backtrace) BACKTRACE_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(BACKTRACE_NAME_$(1)) BACKTRACE_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/libbacktrace -# We don't use this on platforms that aren't linux-based (with the exception of -# msys2/mingw builds on windows, which use it to read the dwarf debug -# information) so just make the file available, the compilation of libstd won't -# actually build it. +# We don't use this on platforms that aren't linux-based so just make the file +# available, the compilation of libstd won't actually build it. ifeq ($$(findstring darwin,$$(OSTYPE_$(1))),darwin) # See comment above $$(BACKTRACE_LIB_$(1)): @@ -307,7 +305,7 @@ $$(BACKTRACE_LIB_$(1)): touch $$@ else -ifeq ($$(findstring msvc,$(1)),msvc) +ifeq ($$(findstring windows,$(1)),windows) # See comment above $$(BACKTRACE_LIB_$(1)): touch $$@ @@ -382,10 +380,6 @@ endif # endif for darwin ifeq ($$(findstring musl,$(1)),musl) $$(RT_OUTPUT_DIR_$(1))/%: $$(CFG_MUSL_ROOT)/lib/% cp $$^ $$@ -else -# Ask gcc where it is -$$(RT_OUTPUT_DIR_$(1))/%: - cp $$(shell $$(CC_$(1)) -print-file-name=$$(@F)) $$@ endif endef diff --git a/mk/target.mk b/mk/target.mk index 32a3eb5c20d28..62114dbc7d172 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -126,34 +126,6 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \ endef -# Macro for building runtime startup/shutdown object files; -# these are Rust's equivalent of crti.o, crtn.o -# -# $(1) - stage -# $(2) - target triple -# $(3) - host triple -# $(4) - object basename -define TARGET_RUSTRT_STARTUP_OBJ - -$$(TLIB$(1)_T_$(2)_H_$(3))/$(4).o: \ - $(S)src/rtstartup/$(4).rs \ - $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.core \ - $$(HSREQ$(1)_T_$(2)_H_$(3)) \ - | $$(TBIN$(1)_T_$(2)_H_$(3))/ - @$$(call E, rustc: $$@) - $$(STAGE$(1)_T_$(2)_H_$(3)) --emit=obj -o $$@ $$< - -ifeq ($$(CFG_RUSTRT_HAS_STARTUP_OBJS_$(2)), 1) -# Add dependencies on Rust startup objects to all crates that depend on core. -# This ensures that they are built after core (since they depend on it), -# but before everything else (since they are needed for linking dylib crates). -$$(foreach crate, $$(TARGET_CRATES), \ - $$(if $$(findstring core,$$(DEPS_$$(crate))), \ - $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate))) : $$(TLIB$(1)_T_$(2)_H_$(3))/$(4).o -endif - -endef - # Every recipe in RUST_TARGET_STAGE_N outputs to $$(TLIB$(1)_T_$(2)_H_$(3), # a directory that can be cleaned out during the middle of a run of # the get-snapshot.py script. Therefore, every recipe needs to have @@ -166,7 +138,10 @@ SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD))/rustc$(X_$(CFG_BUILD)) define TARGET_HOST_RULES -$$(TLIB$(1)_T_$(2)_H_$(3))/: +$$(TLIB$(1)_T_$(2)_H_$(3))/: | $$(SNAPSHOT_RUSTC_POST_CLEANUP) + mkdir -p $$@ + +$$(TBIN$(1)_T_$(2)_H_$(3))/: | $$(SNAPSHOT_RUSTC_POST_CLEANUP) mkdir -p $$@ $$(TLIB$(1)_T_$(2)_H_$(3))/%: $$(RT_OUTPUT_DIR_$(2))/% \ @@ -197,8 +172,33 @@ $(foreach host,$(CFG_HOST), \ $(foreach tool,$(TOOLS), \ $(eval $(call TARGET_TOOL,$(stage),$(target),$(host),$(tool))))))) +# FIXME(stage0) - remove everything here after a snapshot +# +# The stage0 compiler requires the rsend.o, rsbegin.o, crt2.o, and dllcrt2.o +# startup objects on the pc-windows-gnu targets, but that's no longer the case. +# Hack in support to the makefiles to ensure that these objects all exist. +# +# Note that the rs*.o files can just be blank object files. +define STARTUP_OBJS_COMPAT +ifeq ($$(findstring pc-windows-gnu,$(2)),pc-windows-gnu) +DUMMY_DEPS_$(2)_H_$(3) := \ + $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.core \ + $$(HSREQ$(1)_T_$(2)_H_$(3))/stamp.core +$$(TLIB$(1)_T_$(2)_H_$(3))/rsend.o $$(TLIB$(1)_T_$(2)_H_$(3))/rsbegin.o: \ + $$(DUMMY_DEPS_$(2)_H_$(3) \ + | $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP) + $$(CC_$(2)) $$(CFG_GCCISH_CFLAGS_$(2)) -c -x c - -o $$@ < /dev/null +$$(TLIB$(1)_T_$(2)_H_$(3))/dllcrt2.o $$(TLIB$(1)_T_$(2)_H_$(3))/crt2.o: \ + $$(DUMMY_DEPS_$(2)_H_$(3) \ + | $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP) + cp $$(shell $$(CC_$(2)) -print-file-name=$$(@F)) $$@ +$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.std: \ + $$(TLIB$(1)_T_$(2)_H_$(3))/rsend.o \ + $$(TLIB$(1)_T_$(2)_H_$(3))/rsbegin.o \ + $$(TLIB$(1)_T_$(2)_H_$(3))/dllcrt2.o \ + $$(TLIB$(1)_T_$(2)_H_$(3))/crt2.o +endif +endef $(foreach host,$(CFG_HOST), \ $(foreach target,$(CFG_TARGET), \ - $(foreach stage,$(STAGES), \ - $(foreach obj,rsbegin rsend, \ - $(eval $(call TARGET_RUSTRT_STARTUP_OBJ,$(stage),$(target),$(host),$(obj))))))) + $(eval $(call STARTUP_OBJS_COMPAT,0,$(target),$(host))))) diff --git a/src/doc/book/custom-allocators.md b/src/doc/book/custom-allocators.md index d69ef6cf7e83a..7b43aeb4de2ab 100644 --- a/src/doc/book/custom-allocators.md +++ b/src/doc/book/custom-allocators.md @@ -138,9 +138,6 @@ pub extern fn __rust_usable_size(size: usize, _align: usize) -> usize { # fn main() {} # #[lang = "panic_fmt"] fn panic_fmt() {} # #[lang = "eh_personality"] fn eh_personality() {} -# #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} -# #[no_mangle] pub extern fn rust_eh_register_frames () {} -# #[no_mangle] pub extern fn rust_eh_unregister_frames () {} ``` After we compile this crate, it can be used as follows: diff --git a/src/doc/book/lang-items.md b/src/doc/book/lang-items.md index b948567ac5b74..78f84a50b4124 100644 --- a/src/doc/book/lang-items.md +++ b/src/doc/book/lang-items.md @@ -59,9 +59,6 @@ fn main(argc: isize, argv: *const *const u8) -> isize { #[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } -# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} -# #[no_mangle] pub extern fn rust_eh_register_frames () {} -# #[no_mangle] pub extern fn rust_eh_unregister_frames () {} ``` Note the use of `abort`: the `exchange_malloc` lang item is assumed to diff --git a/src/doc/book/no-stdlib.md b/src/doc/book/no-stdlib.md index 610940cde95e6..7f21761ef4e6a 100644 --- a/src/doc/book/no-stdlib.md +++ b/src/doc/book/no-stdlib.md @@ -39,9 +39,6 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize { // provided by libstd. #[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } -# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} -# #[no_mangle] pub extern fn rust_eh_register_frames () {} -# #[no_mangle] pub extern fn rust_eh_unregister_frames () {} # // fn main() {} tricked you, rustdoc! ``` @@ -66,9 +63,6 @@ pub extern fn main(argc: i32, argv: *const *const u8) -> i32 { #[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } -# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} -# #[no_mangle] pub extern fn rust_eh_register_frames () {} -# #[no_mangle] pub extern fn rust_eh_unregister_frames () {} # // fn main() {} tricked you, rustdoc! ``` diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index a22ad7a0707c2..d472d469024f7 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -340,7 +340,6 @@ lets_do_this! { EhPersonalityLangItem, "eh_personality", eh_personality; EhPersonalityCatchLangItem, "eh_personality_catch", eh_personality_catch; - EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume; MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter; OwnedBoxLangItem, "owned_box", owned_box; diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 6059d7ee74e39..391b6664faa52 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -43,10 +43,6 @@ pub fn check_crate(krate: &hir::Crate, if items.eh_personality().is_none() { items.missing.push(lang_items::EhPersonalityLangItem); } - if sess.target.target.options.custom_unwind_resume & - items.eh_unwind_resume().is_none() { - items.missing.push(lang_items::EhUnwindResumeLangItem); - } { let mut cx = Context { sess: sess, items: items }; @@ -123,5 +119,4 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { weak_lang_items! { panic_fmt, PanicFmtLangItem, rust_begin_unwind; eh_personality, EhPersonalityLangItem, rust_eh_personality; - eh_unwind_resume, EhUnwindResumeLangItem, rust_eh_unwind_resume; } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index c61ae547a2254..2e0cca0e8dc1e 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -191,11 +191,6 @@ pub struct TargetOptions { pub archive_format: String, /// Is asm!() allowed? Defaults to true. pub allow_asm: bool, - /// Whether the target uses a custom unwind resumption routine. - /// By default LLVM lowers `resume` instructions into calls to `_Unwind_Resume` - /// defined in libgcc. If this option is enabled, the target must provide - /// `eh_unwind_resume` lang item. - pub custom_unwind_resume: bool, /// Default crate for allocation symbols to link against pub lib_allocation_crate: String, @@ -250,7 +245,6 @@ impl Default for TargetOptions { post_link_objects: Vec::new(), late_link_args: Vec::new(), archive_format: String::new(), - custom_unwind_resume: false, lib_allocation_crate: "alloc_system".to_string(), exe_allocation_crate: "alloc_system".to_string(), allow_asm: true, @@ -365,7 +359,6 @@ impl Target { key!(post_link_args, list); key!(archive_format); key!(allow_asm, bool); - key!(custom_unwind_resume, bool); base } diff --git a/src/librustc_back/target/windows_base.rs b/src/librustc_back/target/windows_base.rs index 4eacea3fcd9a9..1c1c2355e13c2 100644 --- a/src/librustc_back/target/windows_base.rs +++ b/src/librustc_back/target/windows_base.rs @@ -23,7 +23,7 @@ pub fn opts() -> TargetOptions { exe_suffix: ".exe".to_string(), staticlib_prefix: "".to_string(), staticlib_suffix: ".lib".to_string(), - no_default_libraries: true, + no_default_libraries: false, is_like_windows: true, archive_format: "gnu".to_string(), pre_link_args: vec!( @@ -60,30 +60,7 @@ pub fn opts() -> TargetOptions { // Always enable DEP (NX bit) when it is available "-Wl,--nxcompat".to_string(), - - // Do not use the standard system startup files or libraries when linking - "-nostdlib".to_string(), - ), - pre_link_objects_exe: vec!( - "crt2.o".to_string(), // mingw C runtime initialization for executables - "rsbegin.o".to_string(), // Rust compiler runtime initialization, see rsbegin.rs - ), - pre_link_objects_dll: vec!( - "dllcrt2.o".to_string(), // mingw C runtime initialization for dlls - "rsbegin.o".to_string(), - ), - late_link_args: vec!( - "-lmingwex".to_string(), - "-lmingw32".to_string(), - "-lgcc".to_string(), // alas, mingw* libraries above depend on libgcc - "-lmsvcrt".to_string(), - "-luser32".to_string(), - "-lkernel32".to_string(), - ), - post_link_objects: vec!( - "rsend.o".to_string() ), - custom_unwind_resume: true, .. Default::default() } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 2ddc803fe493f..83b0a582eea52 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -2490,3 +2490,17 @@ impl Drop for OperandBundleDef { mod llvmdeps { include! { env!("CFG_LLVM_LINKAGE_FILE") } } + +// Currenty when compiling LLVM for i686-pc-windows-gnu it will think that it's +// got "ehtable support", and these two symbols here will be referenced from +// RTDyldMemoryManager. This class is, however, only really used from jits, so +// we don't really need it to work. For now just define two dummy symbols, but +// ideally we'd upstream some patch or configure LLVM in such a way that it +// doesn't even need these symbols defined. +#[cfg(all(windows, target_env = "gnu", target_arch = "x86"))] +pub mod __dummy_llvm_required_symbols { + #[no_mangle] + pub extern fn __register_frame(_ptr: *mut u8) {} + #[no_mangle] + pub extern fn __deregister_frame(_ptr: *mut u8) {} +} diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 2fc585c7c795e..5710ef9017b8d 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -980,11 +980,9 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// Returns whether this session's target will use SEH-based unwinding. /// -/// This is only true for MSVC targets, and even then the 64-bit MSVC target -/// currently uses SEH-ish unwinding with DWARF info tables to the side (same as -/// 64-bit MinGW) instead of "full SEH". +/// This is currentlyt true for all Windows targets. pub fn wants_msvc_seh(sess: &Session) -> bool { - sess.target.target.options.is_like_msvc + sess.target.target.options.is_like_windows } pub fn avoid_invoke(bcx: Block) -> bool { @@ -1220,19 +1218,6 @@ pub fn call_lifetime_end(cx: Block, ptr: ValueRef) { }) } -// Generates code for resumption of unwind at the end of a landing pad. -pub fn trans_unwind_resume(bcx: Block, lpval: ValueRef) { - if !bcx.sess().target.target.options.custom_unwind_resume { - Resume(bcx, lpval); - } else { - let exc_ptr = ExtractValue(bcx, lpval, 0); - let llunwresume = bcx.fcx.eh_unwind_resume(); - Call(bcx, llunwresume, &[exc_ptr], None, DebugLoc::None); - Unreachable(bcx); - } -} - - pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { let _icx = push_ctxt("call_memcpy"); let ccx = cx.ccx(); @@ -1981,7 +1966,9 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, record_translation_item_as_generated(ccx, fn_ast_id, param_substs); let _icx = push_ctxt("trans_closure"); - attributes::emit_uwtable(llfndecl, true); + if !wants_msvc_seh(ccx.sess()) { + attributes::emit_uwtable(llfndecl, true); + } debug!("trans_closure(..., param_substs={:?})", param_substs); diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 7c98868dfe7c6..0d262fbd033d0 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -747,7 +747,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx .unwrap(); let lp = build::Load(bcx, addr); base::call_lifetime_end(bcx, addr); - base::trans_unwind_resume(bcx, lp); + build::Resume(bcx, lp); } UnwindKind::CleanupPad(_) => { let pad = build::CleanupPad(bcx, None, &[]); diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 303fc17ce81b4..86ca9d46cc45f 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -534,35 +534,6 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { } } } - - // Returns a ValueRef of the "eh_unwind_resume" lang item if one is defined, - // otherwise declares it as an external funtion. - pub fn eh_unwind_resume(&self) -> ValueRef { - use trans::attributes; - assert!(self.ccx.sess().target.target.options.custom_unwind_resume); - match self.ccx.tcx().lang_items.eh_unwind_resume() { - Some(def_id) => { - callee::trans_fn_ref(self.ccx, def_id, ExprId(0), - self.param_substs).val - } - None => { - let mut unwresume = self.ccx.eh_unwind_resume().borrow_mut(); - match *unwresume { - Some(llfn) => llfn, - None => { - let fty = Type::func(&[Type::i8p(self.ccx)], &Type::void(self.ccx)); - let llfn = declare::declare_fn(self.ccx, - "rust_eh_unwind_resume", - llvm::CCallConv, - fty, ty::FnDiverging); - attributes::unwind(llfn, true); - *unwresume = Some(llfn); - llfn - } - } - } - } - } } // Basic block context. We create a block context for each basic block diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index 38459c1ec3cb7..65b100476b2dc 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -153,7 +153,6 @@ pub struct LocalCrateContext<'tcx> { dbg_cx: Option>, eh_personality: RefCell>, - eh_unwind_resume: RefCell>, rust_try_fn: RefCell>, intrinsics: RefCell>, @@ -493,7 +492,6 @@ impl<'tcx> LocalCrateContext<'tcx> { closure_vals: RefCell::new(FnvHashMap()), dbg_cx: dbg_cx, eh_personality: RefCell::new(None), - eh_unwind_resume: RefCell::new(None), rust_try_fn: RefCell::new(None), intrinsics: RefCell::new(FnvHashMap()), n_llvm_insns: Cell::new(0), @@ -758,10 +756,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local.eh_personality } - pub fn eh_unwind_resume<'a>(&'a self) -> &'a RefCell> { - &self.local.eh_unwind_resume - } - pub fn rust_try_fn<'a>(&'a self) -> &'a RefCell> { &self.local.rust_try_fn } diff --git a/src/librustc_trans/trans/mir/block.rs b/src/librustc_trans/trans/mir/block.rs index 5be585c4189e1..c7961e723ffaf 100644 --- a/src/librustc_trans/trans/mir/block.rs +++ b/src/librustc_trans/trans/mir/block.rs @@ -87,7 +87,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { let ps = self.get_personality_slot(bcx); let lp = build::Load(bcx, ps); base::call_lifetime_end(bcx, ps); - base::trans_unwind_resume(bcx, lp); + build::Resume(bcx, lp); } mir::Terminator::Return => { diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index fcd827e2a8b72..3a362cd766469 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -27,11 +27,6 @@ // Reexport some of our utilities which are expected by other crates. pub use sys_common::unwind::{begin_unwind, begin_unwind_fmt}; -// Rust runtime's startup objects depend on these symbols, so they must be public. -// Since sys_common isn't public, we have to re-export them here. -#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] -pub use sys_common::unwind::imp::eh_frame_registry::*; - #[cfg(not(test))] #[lang = "start"] fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize { diff --git a/src/libstd/sys/common/dwarf/eh.rs b/src/libstd/sys/common/dwarf/eh.rs deleted file mode 100644 index 319be245bde98..0000000000000 --- a/src/libstd/sys/common/dwarf/eh.rs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Parsing of GCC-style Language-Specific Data Area (LSDA) -//! For details see: -//! http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html -//! http://mentorembedded.github.io/cxx-abi/exceptions.pdf -//! http://www.airs.com/blog/archives/460 -//! http://www.airs.com/blog/archives/464 -//! -//! A reference implementation may be found in the GCC source tree -//! (/libgcc/unwind-c.c as of this writing) - -#![allow(non_upper_case_globals)] -#![allow(unused)] - -use prelude::v1::*; -use sys_common::dwarf::DwarfReader; -use core::mem; - -pub const DW_EH_PE_omit : u8 = 0xFF; -pub const DW_EH_PE_absptr : u8 = 0x00; - -pub const DW_EH_PE_uleb128 : u8 = 0x01; -pub const DW_EH_PE_udata2 : u8 = 0x02; -pub const DW_EH_PE_udata4 : u8 = 0x03; -pub const DW_EH_PE_udata8 : u8 = 0x04; -pub const DW_EH_PE_sleb128 : u8 = 0x09; -pub const DW_EH_PE_sdata2 : u8 = 0x0A; -pub const DW_EH_PE_sdata4 : u8 = 0x0B; -pub const DW_EH_PE_sdata8 : u8 = 0x0C; - -pub const DW_EH_PE_pcrel : u8 = 0x10; -pub const DW_EH_PE_textrel : u8 = 0x20; -pub const DW_EH_PE_datarel : u8 = 0x30; -pub const DW_EH_PE_funcrel : u8 = 0x40; -pub const DW_EH_PE_aligned : u8 = 0x50; - -pub const DW_EH_PE_indirect : u8 = 0x80; - -#[derive(Copy, Clone)] -pub struct EHContext { - pub ip: usize, // Current instruction pointer - pub func_start: usize, // Address of the current function - pub text_start: usize, // Address of the code section - pub data_start: usize, // Address of the data section -} - -pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext) - -> Option { - if lsda.is_null() { - return None; - } - - let func_start = context.func_start; - let mut reader = DwarfReader::new(lsda); - - let start_encoding = reader.read::(); - // base address for landing pad offsets - let lpad_base = if start_encoding != DW_EH_PE_omit { - read_encoded_pointer(&mut reader, context, start_encoding) - } else { - func_start - }; - - let ttype_encoding = reader.read::(); - if ttype_encoding != DW_EH_PE_omit { - // Rust doesn't analyze exception types, so we don't care about the type table - reader.read_uleb128(); - } - - let call_site_encoding = reader.read::(); - let call_site_table_length = reader.read_uleb128(); - let action_table = reader.ptr.offset(call_site_table_length as isize); - // Return addresses point 1 byte past the call instruction, which could - // be in the next IP range. - let ip = context.ip-1; - - while reader.ptr < action_table { - let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding); - let cs_len = read_encoded_pointer(&mut reader, context, call_site_encoding); - let cs_lpad = read_encoded_pointer(&mut reader, context, call_site_encoding); - let cs_action = reader.read_uleb128(); - // Callsite table is sorted by cs_start, so if we've passed the ip, we - // may stop searching. - if ip < func_start + cs_start { - break - } - if ip < func_start + cs_start + cs_len { - if cs_lpad != 0 { - return Some(lpad_base + cs_lpad); - } else { - return None; - } - } - } - // IP range not found: gcc's C++ personality calls terminate() here, - // however the rest of the languages treat this the same as cs_lpad == 0. - // We follow this suit. - None -} - -#[inline] -fn round_up(unrounded: usize, align: usize) -> usize { - assert!(align.is_power_of_two()); - (unrounded + align - 1) & !(align - 1) -} - -unsafe fn read_encoded_pointer(reader: &mut DwarfReader, - context: &EHContext, - encoding: u8) -> usize { - assert!(encoding != DW_EH_PE_omit); - - // DW_EH_PE_aligned implies it's an absolute pointer value - if encoding == DW_EH_PE_aligned { - reader.ptr = round_up(reader.ptr as usize, - mem::size_of::()) as *const u8; - return reader.read::(); - } - - let mut result = match encoding & 0x0F { - DW_EH_PE_absptr => reader.read::(), - DW_EH_PE_uleb128 => reader.read_uleb128() as usize, - DW_EH_PE_udata2 => reader.read::() as usize, - DW_EH_PE_udata4 => reader.read::() as usize, - DW_EH_PE_udata8 => reader.read::() as usize, - DW_EH_PE_sleb128 => reader.read_sleb128() as usize, - DW_EH_PE_sdata2 => reader.read::() as usize, - DW_EH_PE_sdata4 => reader.read::() as usize, - DW_EH_PE_sdata8 => reader.read::() as usize, - _ => panic!() - }; - - result += match encoding & 0x70 { - DW_EH_PE_absptr => 0, - // relative to address of the encoded value, despite the name - DW_EH_PE_pcrel => reader.ptr as usize, - DW_EH_PE_textrel => { assert!(context.text_start != 0); - context.text_start }, - DW_EH_PE_datarel => { assert!(context.data_start != 0); - context.data_start }, - DW_EH_PE_funcrel => { assert!(context.func_start != 0); - context.func_start }, - _ => panic!() - }; - - if encoding & DW_EH_PE_indirect != 0 { - result = *(result as *const usize); - } - - result -} diff --git a/src/libstd/sys/common/dwarf/mod.rs b/src/libstd/sys/common/dwarf/mod.rs deleted file mode 100644 index 822826bcc837f..0000000000000 --- a/src/libstd/sys/common/dwarf/mod.rs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Utilities for parsing DWARF-encoded data streams. -//! See http://www.dwarfstd.org, -//! DWARF-4 standard, Section 7 - "Data Representation" - -// This module is used only by x86_64-pc-windows-gnu for now, but we -// are compiling it everywhere to avoid regressions. -#![allow(unused)] - -pub mod eh; - -use prelude::v1::*; -use core::mem; - -pub struct DwarfReader { - pub ptr : *const u8 -} - -#[repr(C,packed)] -struct Unaligned(T); - -impl DwarfReader { - - pub fn new(ptr : *const u8) -> DwarfReader { - DwarfReader { - ptr : ptr - } - } - - // DWARF streams are packed, so e.g. a u32 would not necessarily be aligned - // on a 4-byte boundary. This may cause problems on platforms with strict - // alignment requirements. By wrapping data in a "packed" struct, we are - // telling the backend to generate "misalignment-safe" code. - pub unsafe fn read(&mut self) -> T { - let Unaligned(result) = *(self.ptr as *const Unaligned); - self.ptr = self.ptr.offset(mem::size_of::() as isize); - result - } - - // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable - // Length Data". - pub unsafe fn read_uleb128(&mut self) -> u64 { - let mut shift : usize = 0; - let mut result : u64 = 0; - let mut byte : u8; - loop { - byte = self.read::(); - result |= ((byte & 0x7F) as u64) << shift; - shift += 7; - if byte & 0x80 == 0 { - break; - } - } - result - } - - pub unsafe fn read_sleb128(&mut self) -> i64 { - let mut shift : usize = 0; - let mut result : u64 = 0; - let mut byte : u8; - loop { - byte = self.read::(); - result |= ((byte & 0x7F) as u64) << shift; - shift += 7; - if byte & 0x80 == 0 { - break; - } - } - // sign-extend - if shift < 8 * mem::size_of::() && (byte & 0x40) != 0 { - result |= (!0 as u64) << shift; - } - result as i64 - } -} - -#[test] -fn dwarf_reader() { - let encoded: &[u8] = &[1, - 2, 3, - 4, 5, 6, 7, - 0xE5, 0x8E, 0x26, - 0x9B, 0xF1, 0x59, - 0xFF, 0xFF]; - - let mut reader = DwarfReader::new(encoded.as_ptr()); - - unsafe { - assert!(reader.read::() == u8::to_be(1u8)); - assert!(reader.read::() == u16::to_be(0x0203)); - assert!(reader.read::() == u32::to_be(0x04050607)); - - assert!(reader.read_uleb128() == 624485); - assert!(reader.read_sleb128() == -624485); - - assert!(reader.read::() == i8::to_be(-1)); - } -} diff --git a/src/libstd/sys/common/gnu/mod.rs b/src/libstd/sys/common/gnu/mod.rs deleted file mode 100644 index 3a8cf2d842591..0000000000000 --- a/src/libstd/sys/common/gnu/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] - -pub mod libbacktrace; diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index 56628a4c7545e..0195ab2004b43 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -30,9 +30,7 @@ pub mod args; pub mod at_exit_imp; pub mod backtrace; pub mod condvar; -pub mod dwarf; pub mod io; -pub mod libunwind; pub mod mutex; pub mod net; pub mod poison; @@ -45,10 +43,6 @@ pub mod unwind; pub mod util; pub mod wtf8; -#[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))), - all(windows, target_env = "gnu")))] -pub mod gnu; - // common error constructors /// A trait for viewing representations from std types diff --git a/src/libstd/sys/common/unwind/mod.rs b/src/libstd/sys/common/unwind.rs similarity index 61% rename from src/libstd/sys/common/unwind/mod.rs rename to src/libstd/sys/common/unwind.rs index d9641e63760e5..7ff898b7b1d89 100644 --- a/src/libstd/sys/common/unwind/mod.rs +++ b/src/libstd/sys/common/unwind.rs @@ -8,95 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Implementation of Rust stack unwinding +//! Common unwinding support to all platforms. //! -//! For background on exception handling and stack unwinding please see -//! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and -//! documents linked from it. -//! These are also good reads: -//! http://mentorembedded.github.io/cxx-abi/abi-eh.html -//! http://monoinfinito.wordpress.com/series/exception-handling-in-c/ -//! http://www.airs.com/blog/index.php?s=exception+frames +//! This module does not contain the lowest-level implementation of unwinding +//! itself, but rather contains some of the Rust APIs used as entry points to +//! unwinding itself. For example this is the location of the lang item +//! `panic_fmt` which is the entry point of all panics from libcore. //! -//! ## A brief summary -//! -//! Exception handling happens in two phases: a search phase and a cleanup phase. -//! -//! In both phases the unwinder walks stack frames from top to bottom using -//! information from the stack frame unwind sections of the current process's -//! modules ("module" here refers to an OS module, i.e. an executable or a -//! dynamic library). -//! -//! For each stack frame, it invokes the associated "personality routine", whose -//! address is also stored in the unwind info section. -//! -//! In the search phase, the job of a personality routine is to examine exception -//! object being thrown, and to decide whether it should be caught at that stack -//! frame. Once the handler frame has been identified, cleanup phase begins. -//! -//! In the cleanup phase, the unwinder invokes each personality routine again. -//! This time it decides which (if any) cleanup code needs to be run for -//! the current stack frame. If so, the control is transferred to a special branch -//! in the function body, the "landing pad", which invokes destructors, frees memory, -//! etc. At the end of the landing pad, control is transferred back to the unwinder -//! and unwinding resumes. -//! -//! Once stack has been unwound down to the handler frame level, unwinding stops -//! and the last personality routine transfers control to the catch block. -//! -//! ## `eh_personality` and `eh_unwind_resume` -//! -//! These language items are used by the compiler when generating unwind info. -//! The first one is the personality routine described above. The second one -//! allows compilation target to customize the process of resuming unwind at the -//! end of the landing pads. `eh_unwind_resume` is used only if `custom_unwind_resume` -//! flag in the target options is set. -//! -//! ## Frame unwind info registration -//! -//! Each module's image contains a frame unwind info section (usually ".eh_frame"). -//! When a module is loaded/unloaded into the process, the unwinder must be informed -//! about the location of this section in memory. The methods of achieving that vary -//! by the platform. -//! On some (e.g. Linux), the unwinder can discover unwind info sections on its own -//! (by dynamically enumerating currently loaded modules via the dl_iterate_phdr() API -//! and finding their ".eh_frame" sections); -//! Others, like Windows, require modules to actively register their unwind info -//! sections via unwinder API (see `rust_eh_register_frames`/`rust_eh_unregister_frames`). - -#![allow(dead_code)] -#![allow(unused_imports)] +//! For details on how each platform implements unwinding, see the +//! platform-specific `sys::unwind` module. use prelude::v1::*; use any::Any; -use boxed; -use cmp; use panicking::{self,PANIC_COUNT}; use fmt; use intrinsics; -use mem; -use sync::atomic::{self, Ordering}; -use sys_common::mutex::Mutex; - -// The actual unwinding implementation is cfg'd here, and we've got two current -// implementations. One goes through SEH on Windows and the other goes through -// libgcc via the libunwind-like API. - -// *-pc-windows-msvc -#[cfg(target_env = "msvc")] -#[path = "seh.rs"] #[doc(hidden)] -pub mod imp; - -// x86_64-pc-windows-gnu -#[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] -#[path = "seh64_gnu.rs"] #[doc(hidden)] -pub mod imp; - -// i686-pc-windows-gnu and all others -#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))] -#[path = "gcc.rs"] #[doc(hidden)] -pub mod imp; +use sys::unwind; /// Invoke a closure, capturing the cause of panic if one occurs. /// @@ -140,18 +68,19 @@ unsafe fn inner_try(f: fn(*mut u8), data: *mut u8) // the point-of-throw back to this location. // // A pointer to this data is passed to the `try` intrinsic itself, - // allowing this function, the `try` intrinsic, imp::payload(), and - // imp::cleanup() to all work in concert to transmit this information. + // allowing this function, the `try` intrinsic, unwind::payload(), and + // unwind::cleanup() to all work in concert to transmit this + // information. // // More information about what this pointer actually is can be found in // each implementation as well as browsing the compiler source itself. - let mut payload = imp::payload(); + let mut payload = unwind::payload(); let r = intrinsics::try(f, data, &mut payload as *mut _ as *mut _); s.set(prev); if r == 0 { Ok(()) } else { - Err(imp::cleanup(payload)) + Err(unwind::cleanup(payload)) } }) } @@ -167,7 +96,7 @@ unsafe fn inner_try(f: fn(*mut u8), data: *mut u8) if ep.is_null() { Ok(()) } else { - Err(imp::cleanup(ep)) + Err(unwind::cleanup(ep)) } }) } @@ -183,7 +112,7 @@ pub fn panicking() -> bool { #[allow(private_no_mangle_fns)] pub fn rust_panic(cause: Box) -> ! { unsafe { - imp::panic(cause) + unwind::panic(cause) } } diff --git a/src/libstd/sys/common/unwind/seh64_gnu.rs b/src/libstd/sys/common/unwind/seh64_gnu.rs deleted file mode 100644 index 8afef081673d0..0000000000000 --- a/src/libstd/sys/common/unwind/seh64_gnu.rs +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Unwinding implementation of top of native Win64 SEH, -//! however the unwind handler data (aka LSDA) uses GCC-compatible encoding. - -#![allow(bad_style)] -#![allow(private_no_mangle_fns)] - -use prelude::v1::*; - -use any::Any; -use sys_common::dwarf::eh; -use core::mem; -use core::ptr; -use sys::c; - -// Define our exception codes: -// according to http://msdn.microsoft.com/en-us/library/het71c37(v=VS.80).aspx, -// [31:30] = 3 (error), 2 (warning), 1 (info), 0 (success) -// [29] = 1 (user-defined) -// [28] = 0 (reserved) -// we define bits: -// [24:27] = type -// [0:23] = magic -const ETYPE: c::DWORD = 0b1110_u32 << 28; -const MAGIC: c::DWORD = 0x525354; // "RST" - -const RUST_PANIC: c::DWORD = ETYPE | (1 << 24) | MAGIC; - -#[repr(C)] -struct PanicData { - data: Box -} - -pub unsafe fn panic(data: Box) -> ! { - let panic_ctx = Box::new(PanicData { data: data }); - let params = [Box::into_raw(panic_ctx) as c::ULONG_PTR]; - c::RaiseException(RUST_PANIC, - c::EXCEPTION_NONCONTINUABLE, - params.len() as c::DWORD, - ¶ms as *const c::ULONG_PTR); - rtabort!("could not unwind stack"); -} - -#[cfg(not(stage0))] -pub fn payload() -> *mut u8 { - 0 as *mut u8 -} - -pub unsafe fn cleanup(ptr: *mut u8) -> Box { - let panic_ctx = Box::from_raw(ptr as *mut PanicData); - return panic_ctx.data; -} - -// SEH doesn't support resuming unwinds after calling a landing pad like -// libunwind does. For this reason, MSVC compiler outlines landing pads into -// separate functions that can be called directly from the personality function -// but are nevertheless able to find and modify stack frame of the "parent" -// function. -// -// Since this cannot be done with libdwarf-style landing pads, -// rust_eh_personality instead catches RUST_PANICs, runs the landing pad, then -// reraises the exception. -// -// Note that it makes certain assumptions about the exception: -// -// 1. That RUST_PANIC is non-continuable, so no lower stack frame may choose to -// resume execution. -// 2. That the first parameter of the exception is a pointer to an extra data -// area (PanicData). -// Since these assumptions do not generally hold true for foreign exceptions -// (system faults, C++ exceptions, etc), we make no attempt to invoke our -// landing pads (and, thus, destructors!) for anything other than RUST_PANICs. -// This is considered acceptable, because the behavior of throwing exceptions -// through a C ABI boundary is undefined. - -#[lang = "eh_personality_catch"] -#[cfg(not(test))] -unsafe extern fn rust_eh_personality_catch( - exceptionRecord: *mut c::EXCEPTION_RECORD, - establisherFrame: c::LPVOID, - contextRecord: *mut c::CONTEXT, - dispatcherContext: *mut c::DISPATCHER_CONTEXT -) -> c::EXCEPTION_DISPOSITION -{ - rust_eh_personality(exceptionRecord, establisherFrame, - contextRecord, dispatcherContext) -} - -#[lang = "eh_personality"] -#[cfg(not(test))] -unsafe extern fn rust_eh_personality( - exceptionRecord: *mut c::EXCEPTION_RECORD, - establisherFrame: c::LPVOID, - contextRecord: *mut c::CONTEXT, - dispatcherContext: *mut c::DISPATCHER_CONTEXT -) -> c::EXCEPTION_DISPOSITION -{ - let er = &*exceptionRecord; - let dc = &*dispatcherContext; - - if er.ExceptionFlags & c::EXCEPTION_UNWIND == 0 { // we are in the dispatch phase - if er.ExceptionCode == RUST_PANIC { - if let Some(lpad) = find_landing_pad(dc) { - c::RtlUnwindEx(establisherFrame, - lpad as c::LPVOID, - exceptionRecord, - er.ExceptionInformation[0] as c::LPVOID, // pointer to PanicData - contextRecord, - dc.HistoryTable); - rtabort!("could not unwind"); - } - } - } - c::ExceptionContinueSearch -} - -#[cfg(not(test))] -#[lang = "eh_unwind_resume"] -#[unwind] -unsafe extern fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! { - let params = [panic_ctx as c::ULONG_PTR]; - c::RaiseException(RUST_PANIC, - c::EXCEPTION_NONCONTINUABLE, - params.len() as c::DWORD, - ¶ms as *const c::ULONG_PTR); - rtabort!("could not resume unwind"); -} - -unsafe fn find_landing_pad(dc: &c::DISPATCHER_CONTEXT) -> Option { - let eh_ctx = eh::EHContext { - ip: dc.ControlPc as usize, - func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize, - text_start: dc.ImageBase as usize, - data_start: 0 - }; - eh::find_landing_pad(dc.HandlerData, &eh_ctx) -} diff --git a/src/libstd/sys/unix/backtrace/printing/gnu.rs b/src/libstd/sys/unix/backtrace/printing/gnu.rs deleted file mode 100644 index fb06fbedaf57b..0000000000000 --- a/src/libstd/sys/unix/backtrace/printing/gnu.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub use sys_common::gnu::libbacktrace::print; diff --git a/src/libstd/sys/common/gnu/libbacktrace.rs b/src/libstd/sys/unix/backtrace/printing/libbacktrace.rs similarity index 100% rename from src/libstd/sys/common/gnu/libbacktrace.rs rename to src/libstd/sys/unix/backtrace/printing/libbacktrace.rs diff --git a/src/libstd/sys/unix/backtrace/printing/mod.rs b/src/libstd/sys/unix/backtrace/printing/mod.rs index 02e53854727f7..7c9fb9cf71c68 100644 --- a/src/libstd/sys/unix/backtrace/printing/mod.rs +++ b/src/libstd/sys/unix/backtrace/printing/mod.rs @@ -17,5 +17,5 @@ mod imp; #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))] -#[path = "gnu.rs"] +#[path = "libbacktrace.rs"] mod imp; diff --git a/src/libstd/sys/common/libunwind.rs b/src/libstd/sys/unix/libunwind.rs similarity index 97% rename from src/libstd/sys/common/libunwind.rs rename to src/libstd/sys/unix/libunwind.rs index 3f70afe6ad76e..13c8622a2622f 100644 --- a/src/libstd/sys/common/libunwind.rs +++ b/src/libstd/sys/unix/libunwind.rs @@ -120,9 +120,7 @@ pub type _Unwind_Exception_Cleanup_Fn = link(name = "gcc_pic"))] #[cfg_attr(target_os = "bitrig", link(name = "c++abi"))] -#[cfg_attr(all(target_os = "windows", target_env="gnu"), - link(name = "gcc_eh"))] -extern "C" { +extern { // iOS on armv7 uses SjLj exceptions and requires to link // against corresponding routine (..._SjLj_...) #[cfg(not(all(target_os = "ios", target_arch = "arm")))] diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 9cae36fb7260b..7429fb33cf433 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -36,6 +36,7 @@ pub mod condvar; pub mod ext; pub mod fd; pub mod fs; +pub mod libunwind; pub mod mutex; pub mod net; pub mod os; @@ -44,10 +45,11 @@ pub mod pipe; pub mod process; pub mod rwlock; pub mod stack_overflow; +pub mod stdio; pub mod thread; pub mod thread_local; pub mod time; -pub mod stdio; +pub mod unwind; #[cfg(not(test))] pub fn init() { diff --git a/src/libstd/sys/common/unwind/gcc.rs b/src/libstd/sys/unix/unwind.rs similarity index 60% rename from src/libstd/sys/common/unwind/gcc.rs rename to src/libstd/sys/unix/unwind.rs index 12cd07a4f4f18..61169499dd2a6 100644 --- a/src/libstd/sys/common/unwind/gcc.rs +++ b/src/libstd/sys/unix/unwind.rs @@ -8,21 +8,105 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! # Implementation of Rust stack unwinding +//! +//! Also might be known as itanium exceptions, libunwind-based unwinding, +//! libgcc unwinding, etc. Unwinding on Unix currently always happens through +//! the libunwind support library, although we don't always link to libunwind +//! directly as it's often bundled directly into libgcc (or libgcc_s). +//! +//! For background on exception handling and stack unwinding please see +//! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and +//! documents linked from it. +//! +//! These are also good reads: +//! +//! * http://mentorembedded.github.io/cxx-abi/abi-eh.html +//! * http://monoinfinito.wordpress.com/series/exception-handling-in-c/ +//! * http://www.airs.com/blog/index.php?s=exception+frames +//! +//! The basic premise here is that we're going to literally throw an exception, +//! only with library support rather than language support. This interacts with +//! LLVM by using the `invoke` instruction all over the place instead of a +//! typical `call` instruction. As a reminder, when LLVM translates an `invoke` +//! instruction it requires that the surrounding function is attached with a +//! **personality** function. The major purpose of this module is to define +//! these personality functions. +//! +//! First, though, let's take a look at how unwinding works: +//! +//! ## A brief summary +//! +//! Exception handling happens in two phases: a search phase and a cleanup +//! phase. +//! +//! In both phases the unwinder walks stack frames from top to bottom using +//! information from the stack frame unwind sections of the current process's +//! modules ("module" here refers to an OS module, i.e. an executable or a +//! dynamic library). +//! +//! For each stack frame, it invokes the associated "personality routine", whose +//! address is also stored in the unwind info section. +//! +//! In the search phase, the job of a personality routine is to examine +//! exception object being thrown, and to decide whether it should be caught at +//! that stack frame. Once the handler frame has been identified, cleanup phase +//! begins. +//! +//! In the cleanup phase, the unwinder invokes each personality routine again. +//! This time it decides which (if any) cleanup code needs to be run for +//! the current stack frame. If so, the control is transferred to a special +//! branch in the function body, the "landing pad", which invokes destructors, +//! frees memory, etc. At the end of the landing pad, control is transferred +//! back to the unwinder and unwinding resumes. +//! +//! Once stack has been unwound down to the handler frame level, unwinding stops +//! and the last personality routine transfers control to the catch block. +//! +//! ## `eh_personality` and `eh_personality_catch` +//! +//! The main personality function, `eh_personality`, is used by almost all Rust +//! functions that are translated. This personality indicates that no exceptions +//! should be caught, but cleanups should always be run. The second personality +//! function, `eh_personality_catch`, is distinct in that it indicates that +//! exceptions should be caught (no cleanups are run). The compiler will +//! annotate all generated functions with these two personalities, and then +//! we're just left to implement them over here! +//! +//! We could implement our personality routine in pure Rust, however exception +//! info decoding is tedious. More importantly, personality routines have to +//! handle various platform quirks, which are not fun to maintain. For this +//! reason, we attempt to reuse personality routine of the C language. This +//! comes under a number of names and ABIs, including `__gcc_personality_v0` and +//! `__gcc_personality_sj0`. +//! +//! Since C does not support exception catching, this personality function +//! simply always returns `_URC_CONTINUE_UNWIND` in search phase, and always +//! returns `_URC_INSTALL_CONTEXT` (i.e. "invoke cleanup code") in cleanup +//! phase. +//! +//! To implement the `eh_personality_catch` function, however, we detect when +//! the search phase is occurring and return `_URC_HANDLER_FOUND` to indicate +//! that we want to catch the exception. +//! +//! See also: `rustc_trans::trans::intrinsic::trans_gnu_try` + #![allow(private_no_mangle_fns)] use prelude::v1::*; use any::Any; -use sys_common::libunwind as uw; +use sys::libunwind as uw; +#[repr(C)] struct Exception { - uwe: uw::_Unwind_Exception, + _uwe: uw::_Unwind_Exception, cause: Option>, } pub unsafe fn panic(data: Box) -> ! { let exception: Box<_> = box Exception { - uwe: uw::_Unwind_Exception { + _uwe: uw::_Unwind_Exception { exception_class: rust_exception_class(), exception_cleanup: exception_cleanup, private: [0; uw::unwinder_private_data_size], @@ -60,30 +144,9 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class { 0x4d4f5a_00_52555354 } -// We could implement our personality routine in pure Rust, however exception -// info decoding is tedious. More importantly, personality routines have to -// handle various platform quirks, which are not fun to maintain. For this -// reason, we attempt to reuse personality routine of the C language: -// __gcc_personality_v0. -// -// Since C does not support exception catching, __gcc_personality_v0 simply -// always returns _URC_CONTINUE_UNWIND in search phase, and always returns -// _URC_INSTALL_CONTEXT (i.e. "invoke cleanup code") in cleanup phase. -// -// This is pretty close to Rust's exception handling approach, except that Rust -// does have a single "catch-all" handler at the bottom of each thread's stack. -// So we have two versions of the personality routine: -// - rust_eh_personality, used by all cleanup landing pads, which never catches, -// so the behavior of __gcc_personality_v0 is perfectly adequate there, and -// - rust_eh_personality_catch, used only by rust_try(), which always catches. -// -// See also: rustc_trans::trans::intrinsic::trans_gnu_try - -#[cfg(all(not(target_arch = "arm"), - not(all(windows, target_arch = "x86_64")), - not(test)))] +#[cfg(all(not(target_arch = "arm"), not(test)))] pub mod eabi { - use sys_common::libunwind as uw; + use sys::libunwind as uw; use libc::c_int; extern { @@ -139,7 +202,7 @@ pub mod eabi { #[cfg(all(target_os = "ios", target_arch = "arm", not(test)))] pub mod eabi { - use sys_common::libunwind as uw; + use sys::libunwind as uw; use libc::c_int; extern { @@ -194,7 +257,7 @@ pub mod eabi { // but otherwise works the same. #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(test)))] pub mod eabi { - use sys_common::libunwind as uw; + use sys::libunwind as uw; use libc::c_int; extern { @@ -236,38 +299,3 @@ pub mod eabi { } } } - -// See docs in the `unwind` module. -#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu", not(test)))] -#[lang = "eh_unwind_resume"] -#[unwind] -unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! { - uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception); -} - -#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] -pub mod eh_frame_registry { - // The implementation of stack unwinding is (for now) deferred to libgcc_eh, however Rust - // crates use these Rust-specific entry points to avoid potential clashes with GCC runtime. - // See also: rtbegin.rs, `unwind` module. - - #[link(name = "gcc_eh")] - extern { - fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8); - fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8); - } - #[cfg(not(test))] - #[no_mangle] - #[unstable(feature = "libstd_sys_internals", issue = "0")] - pub unsafe extern fn rust_eh_register_frames(eh_frame_begin: *const u8, - object: *mut u8) { - __register_frame_info(eh_frame_begin, object); - } - #[cfg(not(test))] - #[no_mangle] - #[unstable(feature = "libstd_sys_internals", issue = "0")] - pub unsafe extern fn rust_eh_unregister_frames(eh_frame_begin: *const u8, - object: *mut u8) { - __deregister_frame_info(eh_frame_begin, object); - } -} diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index d106bc3285cb1..0b6aa66b3accb 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -27,29 +27,25 @@ use io::prelude::*; use dynamic_lib::DynamicLibrary; +use ffi::CStr; use io; -use libc::c_void; +use libc::{c_ulong, c_int, c_char, c_void}; use mem; use path::Path; use ptr; use sync::StaticMutex; use sys::c; - -macro_rules! sym{ ($lib:expr, $e:expr, $t:ident) => (unsafe { - let lib = $lib; - match lib.symbol($e) { - Ok(f) => $crate::mem::transmute::<*mut u8, $t>(f), - Err(..) => return Ok(()) - } -}) } - -#[cfg(target_env = "msvc")] -#[path = "printing/msvc.rs"] -mod printing; - -#[cfg(target_env = "gnu")] -#[path = "printing/gnu.rs"] -mod printing; +use sys_common::backtrace::{output, output_fileline}; + +macro_rules! sym { + ($lib:expr, $e:expr, $t:ident) => (unsafe { + let lib = $lib; + match lib.symbol($e) { + Ok(f) => $crate::mem::transmute::<*mut u8, $t>(f), + Err(..) => return Ok(()) + } + }) +} type SymFromAddrFn = extern "system" fn(c::HANDLE, u64, *mut u64, @@ -151,9 +147,49 @@ pub fn write(w: &mut Write) -> io::Result<()> { i += 1; if i >= 0 { - try!(printing::print(w, i, addr-1, &dbghelp, process)); + try!(print(w, i, addr-1, &dbghelp, process)); } } Ok(()) } + +fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, + process: c::HANDLE) -> io::Result<()> { + let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn); + let SymGetLineFromAddr64 = sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn); + + let mut info: c::SYMBOL_INFO = unsafe { mem::zeroed() }; + info.MaxNameLen = c::MAX_SYM_NAME as c_ulong; + // the struct size in C. the value is different to + // `size_of::() - MAX_SYM_NAME + 1` (== 81) + // due to struct alignment. + info.SizeOfStruct = 88; + + let mut displacement = 0u64; + let ret = SymFromAddr(process, addr, &mut displacement, &mut info); + + let name = if ret == c::TRUE { + let ptr = info.Name.as_ptr() as *const c_char; + Some(unsafe { CStr::from_ptr(ptr).to_bytes() }) + } else { + None + }; + + try!(output(w, i, addr as usize as *mut c_void, name)); + + // Now find out the filename and line number + let mut line: c::IMAGEHLP_LINE64 = unsafe { mem::zeroed() }; + line.SizeOfStruct = ::mem::size_of::() as u32; + + let mut displacement = 0u32; + let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line); + if ret == c::TRUE { + output_fileline(w, + unsafe { CStr::from_ptr(line.Filename).to_bytes() }, + line.LineNumber as c_int, + false) + } else { + Ok(()) + } +} diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 9ecef5ee92c71..684ad9bd6c045 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -35,10 +35,11 @@ pub mod pipe; pub mod process; pub mod rwlock; pub mod stack_overflow; +pub mod stdio; pub mod thread; pub mod thread_local; pub mod time; -pub mod stdio; +pub mod unwind; #[cfg(not(test))] pub fn init() { diff --git a/src/libstd/sys/windows/printing/gnu.rs b/src/libstd/sys/windows/printing/gnu.rs deleted file mode 100644 index c1367d5381da1..0000000000000 --- a/src/libstd/sys/windows/printing/gnu.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![allow(deprecated)] - -use dynamic_lib::DynamicLibrary; -use io::prelude::*; -use io; -use sys::c; -use libc::c_void; - -use sys_common::gnu::libbacktrace; - -pub fn print(w: &mut Write, i: isize, addr: u64, _: &DynamicLibrary, _: c::HANDLE) - -> io::Result<()> { - let addr = addr as usize as *mut c_void; - libbacktrace::print(w, i, addr, addr) -} diff --git a/src/libstd/sys/windows/printing/msvc.rs b/src/libstd/sys/windows/printing/msvc.rs deleted file mode 100644 index d04691a6a4783..0000000000000 --- a/src/libstd/sys/windows/printing/msvc.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![allow(deprecated)] - -use dynamic_lib::DynamicLibrary; -use ffi::CStr; -use io::prelude::*; -use io; -use libc::{c_ulong, c_int, c_char, c_void}; -use mem; -use super::{SymFromAddrFn, SymGetLineFromAddr64Fn}; -use sys::c; -use sys_common::backtrace::{output, output_fileline}; - -pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, - process: c::HANDLE) -> io::Result<()> { - let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn); - let SymGetLineFromAddr64 = sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn); - - let mut info: c::SYMBOL_INFO = unsafe { mem::zeroed() }; - info.MaxNameLen = c::MAX_SYM_NAME as c_ulong; - // the struct size in C. the value is different to - // `size_of::() - MAX_SYM_NAME + 1` (== 81) - // due to struct alignment. - info.SizeOfStruct = 88; - - let mut displacement = 0u64; - let ret = SymFromAddr(process, addr, &mut displacement, &mut info); - - let name = if ret == c::TRUE { - let ptr = info.Name.as_ptr() as *const c_char; - Some(unsafe { CStr::from_ptr(ptr).to_bytes() }) - } else { - None - }; - - try!(output(w, i, addr as usize as *mut c_void, name)); - - // Now find out the filename and line number - let mut line: c::IMAGEHLP_LINE64 = unsafe { mem::zeroed() }; - line.SizeOfStruct = ::mem::size_of::() as u32; - - let mut displacement = 0u32; - let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line); - if ret == c::TRUE { - output_fileline(w, - unsafe { CStr::from_ptr(line.Filename).to_bytes() }, - line.LineNumber as c_int, - false) - } else { - Ok(()) - } -} diff --git a/src/libstd/sys/common/unwind/seh.rs b/src/libstd/sys/windows/unwind.rs similarity index 96% rename from src/libstd/sys/common/unwind/seh.rs rename to src/libstd/sys/windows/unwind.rs index f8d3a92b3b65b..96fc5d69d2ab6 100644 --- a/src/libstd/sys/common/unwind/seh.rs +++ b/src/libstd/sys/windows/unwind.rs @@ -56,13 +56,6 @@ //! [win64]: http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx //! [llvm]: http://llvm.org/docs/ExceptionHandling.html#background-on-windows-exceptions -use sys::c; - -// A code which indicates panics that originate from Rust. Note that some of the -// upper bits are used by the system so we just set them to 0 and ignore them. -// 0x 0 R S T -const RUST_PANIC: c::DWORD = 0x00525354; - pub use self::imp::*; #[cfg(stage0)] @@ -100,9 +93,14 @@ mod imp { use any::Any; use mem; use raw; - use super::RUST_PANIC; use sys::c; + // A code which indicates panics that originate from Rust. Note that some of + // the upper bits are used by the system so we just set them to 0 and ignore + // them. + // 0x 0 R S T + const RUST_PANIC: c::DWORD = 0x00525354; + pub unsafe fn panic(data: Box) -> ! { // As mentioned above, the call stack here is preserved while the filter // functions are running, so it's ok to pass stack-local arrays into diff --git a/src/rtstartup/rsbegin.rs b/src/rtstartup/rsbegin.rs deleted file mode 100644 index d1b6fe6655ac6..0000000000000 --- a/src/rtstartup/rsbegin.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// rsbegin.o and rsend.o are the so called "compiler runtime startup objects". -// They contain code needed to correctly initialize the compiler runtime. -// -// When an executable or dylib image is linked, all user code and libraries are -// "sandwiched" between these two object files, so code or data from rsbegin.o -// become first in the respective sections of the image, whereas code and data -// from rsend.o become the last ones. This effect can be used to place symbols -// at the beginning or at the end of a section, as well as to insert any required -// headers or footers. -// -// Note that the actual module entry point is located in the C runtime startup -// object (usually called `crtX.o), which then invokes initialization callbacks -// of other runtime components (registered via yet another special image section). - -#![crate_type="rlib"] -#![no_std] -#![allow(non_camel_case_types)] - -#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] -pub mod eh_frames -{ - #[no_mangle] - #[link_section = ".eh_frame"] - // Marks beginning of the stack frame unwind info section - pub static __EH_FRAME_BEGIN__: [u8; 0] = []; - - // Scratch space for unwinder's internal book-keeping. - // This is defined as `struct object` in $GCC/libgcc/unwind-dw2-fde.h. - static mut obj: [isize; 6] = [0; 6]; - - // Unwind info registration/deregistration routines. - // See the docs of `unwind` module in libstd. - extern { - fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8); - fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8); - } - - unsafe fn init() { - // register unwind info on module startup - rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8, - &mut obj as *mut _ as *mut u8); - } - - unsafe fn uninit() { - // unregister on shutdown - rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8, - &mut obj as *mut _ as *mut u8); - } - - // MSVC-specific init/uninit routine registration - pub mod ms_init - { - // .CRT$X?? sections are roughly analogous to ELF's .init_array and .fini_array, - // except that they exploit the fact that linker will sort them alphabitically, - // so e.g. sections with names between .CRT$XIA and .CRT$XIZ are guaranteed to be - // placed between those two, without requiring any ordering of objects on the linker - // command line. - // Note that ordering of same-named sections from different objects is not guaranteed. - // Since .CRT$XIA contains init array's header symbol, which must always come first, - // we place our initialization callback into .CRT$XIB. - - #[link_section = ".CRT$XIB"] // .CRT$XI? : C initialization callbacks - pub static P_INIT: unsafe fn() = super::init; - - #[link_section = ".CRT$XTY"] // .CRT$XT? : C termination callbacks - pub static P_UNINIT: unsafe fn() = super::uninit; - } -} diff --git a/src/rtstartup/rsend.rs b/src/rtstartup/rsend.rs deleted file mode 100644 index 5e4e13ebd05e4..0000000000000 --- a/src/rtstartup/rsend.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// See rsbegin.rs for details. - -#![crate_type="rlib"] -#![no_std] - -#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] -pub mod eh_frames -{ - // Terminate the frame unwind info section with a 0 as a sentinel; - // this would be the 'length' field in a real FDE. - #[no_mangle] - #[link_section = ".eh_frame"] - pub static __EH_FRAME_END__: u32 = 0; -} diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index 41ceb924ab306..5c9d2e53a6468 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -18,9 +18,6 @@ extern crate libc; #[lang = "eh_personality"] extern fn eh_personality() {} -#[lang = "eh_unwind_resume"] -extern fn eh_unwind_resume() {} - #[lang = "panic_fmt"] extern fn rust_begin_unwind(msg: core::fmt::Arguments, file: &'static str, line: u32) -> ! { diff --git a/src/test/compile-fail/no_owned_box_lang_item.rs b/src/test/compile-fail/no_owned_box_lang_item.rs index 72eb687adc602..1f42245765d0c 100644 --- a/src/test/compile-fail/no_owned_box_lang_item.rs +++ b/src/test/compile-fail/no_owned_box_lang_item.rs @@ -20,5 +20,4 @@ fn main() { } #[lang = "eh_personality"] extern fn eh_personality() {} -#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } diff --git a/src/test/run-fail/mir_trans_calls_converging_drops.rs b/src/test/run-fail/mir_trans_calls_converging_drops.rs index eb399e07d859d..7f595f2c4655d 100644 --- a/src/test/run-fail/mir_trans_calls_converging_drops.rs +++ b/src/test/run-fail/mir_trans_calls_converging_drops.rs @@ -10,7 +10,7 @@ #![feature(rustc_attrs)] -// ignore-msvc: FIXME(#30941) +// ignore-windows: FIXME(#30941) // error-pattern:converging_fn called // error-pattern:0 dropped // error-pattern:exit diff --git a/src/test/run-fail/mir_trans_calls_converging_drops_2.rs b/src/test/run-fail/mir_trans_calls_converging_drops_2.rs index df4ead387b91f..97c47cc43fccc 100644 --- a/src/test/run-fail/mir_trans_calls_converging_drops_2.rs +++ b/src/test/run-fail/mir_trans_calls_converging_drops_2.rs @@ -10,7 +10,7 @@ #![feature(rustc_attrs)] -// ignore-msvc: FIXME(#30941) +// ignore-windows: FIXME(#30941) // error-pattern:complex called // error-pattern:dropped // error-pattern:exit diff --git a/src/test/run-fail/mir_trans_calls_diverging_drops.rs b/src/test/run-fail/mir_trans_calls_diverging_drops.rs index cbe8793cceb22..c4ff228c1ac4a 100644 --- a/src/test/run-fail/mir_trans_calls_diverging_drops.rs +++ b/src/test/run-fail/mir_trans_calls_diverging_drops.rs @@ -10,7 +10,7 @@ #![feature(rustc_attrs)] -// ignore-msvc: FIXME(#30941) +// ignore-windows: FIXME(#30941) // error-pattern:diverging_fn called // error-pattern:0 dropped diff --git a/src/test/run-make/no-duplicate-libs/bar.rs b/src/test/run-make/no-duplicate-libs/bar.rs index 8a15afb328a92..65d9fddb9c8c0 100644 --- a/src/test/run-make/no-duplicate-libs/bar.rs +++ b/src/test/run-make/no-duplicate-libs/bar.rs @@ -18,7 +18,4 @@ extern crate libc; pub extern fn bar() {} #[lang = "eh_personality"] fn eh_personality() {} -#[lang = "eh_unwind_resume"] fn eh_unwind_resume() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } -#[no_mangle] pub extern fn rust_eh_register_frames () {} -#[no_mangle] pub extern fn rust_eh_unregister_frames () {} diff --git a/src/test/run-make/no-duplicate-libs/foo.rs b/src/test/run-make/no-duplicate-libs/foo.rs index ab8d2eca9363f..729153a471a90 100644 --- a/src/test/run-make/no-duplicate-libs/foo.rs +++ b/src/test/run-make/no-duplicate-libs/foo.rs @@ -18,7 +18,4 @@ extern crate libc; pub extern fn foo() {} #[lang = "eh_personality"] fn eh_personality() {} -#[lang = "eh_unwind_resume"] fn eh_unwind_resume() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } -#[no_mangle] pub extern fn rust_eh_register_frames () {} -#[no_mangle] pub extern fn rust_eh_unregister_frames () {} diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 3fb52f8c8b4dc..effc3bcf802cf 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -89,7 +89,7 @@ fn runtest(me: &str) { } fn main() { - if cfg!(windows) && cfg!(target_arch = "x86") && cfg!(target_env = "gnu") { + if cfg!(windows) && cfg!(target_env = "gnu") { return } diff --git a/src/test/run-pass/smallest-hello-world.rs b/src/test/run-pass/smallest-hello-world.rs index b11970560d59a..4298cb3be1897 100644 --- a/src/test/run-pass/smallest-hello-world.rs +++ b/src/test/run-pass/smallest-hello-world.rs @@ -21,10 +21,7 @@ extern { fn puts(s: *const u8); } extern "rust-intrinsic" { fn transmute(t: T) -> U; } #[lang = "eh_personality"] extern fn eh_personality() {} -#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } -#[no_mangle] pub extern fn rust_eh_register_frames () {} -#[no_mangle] pub extern fn rust_eh_unregister_frames () {} #[start] fn main(_: isize, _: *const *const u8) -> isize {