Skip to content

MinGW: move unwind linkage to libunwind #71001

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

Closed
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
23 changes: 2 additions & 21 deletions src/librustc_codegen_ssa/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1218,29 +1218,10 @@ fn add_user_defined_link_args(

/// Add arbitrary "late link" args defined by the target spec.
/// FIXME: Determine where exactly these args need to be inserted.
fn add_late_link_args(
cmd: &mut dyn Linker,
sess: &Session,
flavor: LinkerFlavor,
crate_type: config::CrateType,
codegen_results: &CodegenResults,
) {
fn add_late_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) {
cmd.args(args);
}
let any_dynamic_crate = crate_type == config::CrateType::Dylib
|| codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| {
*ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
if any_dynamic_crate {
if let Some(args) = sess.target.target.options.late_link_args_dynamic.get(&flavor) {
cmd.args(args);
}
} else {
if let Some(args) = sess.target.target.options.late_link_args_static.get(&flavor) {
cmd.args(args);
}
}
}

/// Add arbitrary "post-link" args defined by the target spec.
Expand Down Expand Up @@ -1581,7 +1562,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
cmd.finalize();

// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
add_late_link_args(cmd, sess, flavor, crate_type, codegen_results);
add_late_link_args(cmd, sess, flavor);

// NO-OPT-OUT, OBJECT-FILES-YES
add_post_link_objects(cmd, sess, crate_type);
Expand Down
12 changes: 0 additions & 12 deletions src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,12 +581,6 @@ pub struct TargetOptions {
/// user-defined but before post_link_objects. Standard platform
/// libraries that should be always be linked to, usually go here.
pub late_link_args: LinkArgs,
/// Linker arguments used in addition to `late_link_args` if at least one
/// Rust dependency is dynamically linked.
pub late_link_args_dynamic: LinkArgs,
/// Linker arguments used in addition to `late_link_args` if aall Rust
/// dependencies are statically linked.
pub late_link_args_static: LinkArgs,
/// Objects to link after all others, always found within the
/// sysroot folder.
pub post_link_objects: Vec<String>, // ... unconditionally
Expand Down Expand Up @@ -858,8 +852,6 @@ impl Default for TargetOptions {
post_link_objects: Vec::new(),
post_link_objects_crt: Vec::new(),
late_link_args: LinkArgs::new(),
late_link_args_dynamic: LinkArgs::new(),
late_link_args_static: LinkArgs::new(),
link_env: Vec::new(),
link_env_remove: Vec::new(),
archive_format: "gnu".to_string(),
Expand Down Expand Up @@ -1136,8 +1128,6 @@ impl Target {
key!(pre_link_objects_exe_crt, list);
key!(pre_link_objects_dll, list);
key!(late_link_args, link_args);
key!(late_link_args_dynamic, link_args);
key!(late_link_args_static, link_args);
key!(post_link_objects, list);
key!(post_link_objects_crt, list);
key!(post_link_args, link_args);
Expand Down Expand Up @@ -1363,8 +1353,6 @@ impl ToJson for Target {
target_option_val!(pre_link_objects_exe_crt);
target_option_val!(pre_link_objects_dll);
target_option_val!(link_args - late_link_args);
target_option_val!(link_args - late_link_args_dynamic);
target_option_val!(link_args - late_link_args_static);
target_option_val!(post_link_objects);
target_option_val!(post_link_objects_crt);
target_option_val!(link_args - post_link_args);
Expand Down
32 changes: 1 addition & 31 deletions src/librustc_target/spec/windows_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ pub fn opts() -> TargetOptions {
);

let mut late_link_args = LinkArgs::new();
let mut late_link_args_dynamic = LinkArgs::new();
let mut late_link_args_static = LinkArgs::new();
late_link_args.insert(
LinkerFlavor::Gcc,
vec![
"-lmingwex".to_string(),
"-lmingw32".to_string(),
"-lgcc".to_string(),
"-lmsvcrt".to_string(),
// mingw's msvcrt is a weird hybrid import library and static library.
// And it seems that the linker fails to use import symbols from msvcrt
Expand All @@ -38,33 +37,6 @@ pub fn opts() -> TargetOptions {
"-lkernel32".to_string(),
],
);
late_link_args_dynamic.insert(
LinkerFlavor::Gcc,
vec![
// If any of our crates are dynamically linked then we need to use
// the shared libgcc_s-dw2-1.dll. This is required to support
// unwinding across DLL boundaries.
"-lgcc_s".to_string(),
"-lgcc".to_string(),
"-lkernel32".to_string(),
],
);
late_link_args_static.insert(
LinkerFlavor::Gcc,
vec![
// If all of our crates are statically linked then we can get away
// with statically linking the libgcc unwinding code. This allows
// binaries to be redistributed without the libgcc_s-dw2-1.dll
// dependency, but unfortunately break unwinding across DLL
// boundaries when unwinding across FFI boundaries.
"-lgcc".to_string(),
"-lgcc_eh".to_string(),
"-lpthread".to_string(),
// libpthread depends on libmsvcrt, so we need to link it *again*.
"-lmsvcrt".to_string(),
"-lkernel32".to_string(),
],
);

TargetOptions {
// FIXME(#13846) this should be enabled for windows
Expand All @@ -90,8 +62,6 @@ pub fn opts() -> TargetOptions {
"rsbegin.o".to_string(),
],
late_link_args,
late_link_args_dynamic,
late_link_args_static,
post_link_objects: vec!["rsend.o".to_string()],
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,
Expand Down
2 changes: 1 addition & 1 deletion src/libunwind/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn main() {
} else if target.contains("dragonfly") {
println!("cargo:rustc-link-lib=gcc_pic");
} else if target.contains("pc-windows-gnu") {
// This is handled in the target spec with late_link_args_[static|dynamic]
// This is handled in lib.rs

// cfg!(bootstrap) doesn't work in build scripts
if env::var("RUSTC_STAGE").ok() == Some("0".to_string()) {
Expand Down
16 changes: 16 additions & 0 deletions src/libunwind/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,19 @@ extern "C" {}
#[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
extern "C" {}

// If any of our crates are dynamically linked then we need to use
// the shared libgcc_s-dw2-1.dll. This is required to support
// unwinding across DLL boundaries.
// If all of our crates are statically linked then we can get away
// with statically linking the libgcc unwinding code. This allows
// binaries to be redistributed without the libgcc_s-dw2-1.dll
// dependency, but unfortunately break unwinding across DLL
// boundaries when unwinding across FFI boundaries.
//
// Linking order matters a lot here!
#[cfg(all(not(bootstrap), target_os = "windows", target_env = "gnu", target_vendor = "pc"))]
#[link(name = "gcc_eh", kind = "static-nobundle")]
#[link(name = "pthread", kind = "static-nobundle")]
#[link(name = "gcc_s")]
extern "C" {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-include ../tools.mk

# only-windows

PATH=$(SYSTEMROOT)/system32

all:
$(RUSTC) hello.rs
$(TMPDIR)/hello.exe
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello World!");
}