Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: Move pc-windows-gnu to SEH-based unwinding #31313

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions mk/cfg/i686-pc-windows-gnu.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 :=
5 changes: 2 additions & 3 deletions mk/cfg/x86_64-pc-windows-gnu.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 :=
1 change: 0 additions & 1 deletion mk/dist.mk
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ PKG_FILES := \
libcoretest \
libbacktrace \
rt \
rtstartup \
rustllvm \
snapshots.txt \
rust-installer \
Expand Down
12 changes: 3 additions & 9 deletions mk/rt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)):
Expand All @@ -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 $$@
Expand Down Expand Up @@ -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
Expand Down
64 changes: 32 additions & 32 deletions mk/target.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))/% \
Expand Down Expand Up @@ -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)))))
3 changes: 0 additions & 3 deletions src/doc/book/custom-allocators.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 0 additions & 3 deletions src/doc/book/lang-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 0 additions & 6 deletions src/doc/book/no-stdlib.md
Original file line number Diff line number Diff line change
Expand Up @@ -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!
```

Expand All @@ -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!
```

Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 0 additions & 5 deletions src/librustc/middle/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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;
}
7 changes: 0 additions & 7 deletions src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -365,7 +359,6 @@ impl Target {
key!(post_link_args, list);
key!(archive_format);
key!(allow_asm, bool);
key!(custom_unwind_resume, bool);

base
}
Expand Down
25 changes: 1 addition & 24 deletions src/librustc_back/target/windows_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down Expand Up @@ -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()
}
Expand Down
14 changes: 14 additions & 0 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
}
23 changes: 5 additions & 18 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

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 {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/trans/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, &[]);
Expand Down
29 changes: 0 additions & 29 deletions src/librustc_trans/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading