From 3ad8c8858e93020416edef421d489c15e46a0365 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 02:52:34 +0300 Subject: [PATCH 1/9] rustc_target: Make sure lld-link is treated as link.exe by default The differences if they are discovered will need to be explicitly documented --- src/librustc_codegen_ssa/back/link.rs | 6 +- .../spec/i686_pc_windows_msvc.rs | 24 ++++--- src/librustc_target/spec/mod.rs | 35 ++++++++++- .../spec/thumbv7a_pc_windows_msvc.rs | 9 ++- src/librustc_target/spec/uefi_base.rs | 62 +++++++++---------- src/librustc_target/spec/windows_msvc_base.rs | 10 +-- .../spec/windows_uwp_msvc_base.rs | 24 +++---- 7 files changed, 106 insertions(+), 64 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 20e64f0c48851..5f7a1938a3304 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -12,7 +12,7 @@ use rustc_session::search_paths::PathKind; /// need out of the shared crate context before we get rid of it. use rustc_session::{filesearch, Session}; use rustc_span::symbol::Symbol; -use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; +use rustc_target::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelroLevel}; use super::archive::ArchiveBuilder; use super::command::Command; @@ -182,7 +182,9 @@ fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command { // To comply with the Windows App Certification Kit, // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). let t = &sess.target.target; - if flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" { + if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link)) + && t.target_vendor == "uwp" + { if let Some(ref tool) = msvc_tool { let original_path = tool.path(); if let Some(ref root_lib_path) = original_path.ancestors().nth(4) { diff --git a/src/librustc_target/spec/i686_pc_windows_msvc.rs b/src/librustc_target/spec/i686_pc_windows_msvc.rs index ffb66afc76182..9d0922b8ce5a9 100644 --- a/src/librustc_target/spec/i686_pc_windows_msvc.rs +++ b/src/librustc_target/spec/i686_pc_windows_msvc.rs @@ -1,18 +1,24 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - // Mark all dynamic libraries and executables as compatible with the larger 4GiB address - // space available to x86 Windows binaries on x86_64. - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/LARGEADDRESSAWARE".to_string()); - - // Ensure the linker will only produce an image if it can also produce a table of - // the image's safe exception handlers. - // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/SAFESEH".to_string()); + let pre_link_args_msvc = vec![ + // Mark all dynamic libraries and executables as compatible with the larger 4GiB address + // space available to x86 Windows binaries on x86_64. + "/LARGEADDRESSAWARE".to_string(), + // Ensure the linker will only produce an image if it can also produce a table of + // the image's safe exception handlers. + // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers + "/SAFESEH".to_string(), + ]; + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + base.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .extend(pre_link_args_msvc); Ok(Target { llvm_target: "i686-pc-windows-msvc".to_string(), diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1bc2bf12fad9e..a1b9974826085 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -322,6 +322,7 @@ macro_rules! supported_targets { // Target on this testing platform (i.e., checking the iOS targets // only on a Mac test platform). let _ = $module::target().map(|original| { + original.check_consistency(); let as_json = original.to_json(); let parsed = Target::from_json(as_json).unwrap(); assert_eq!(original, parsed); @@ -538,7 +539,8 @@ pub struct Target { pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, - /// Linker flavor + /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed + /// on the command line. pub linker_flavor: LinkerFlavor, /// Optional settings with defaults. pub options: TargetOptions, @@ -566,7 +568,8 @@ pub struct TargetOptions { /// Linker to invoke pub linker: Option, - /// LLD flavor + /// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker + /// without clarifying its flavor in any way. pub lld_flavor: LldFlavor, /// Linker arguments that are passed *before* any user-defined libraries. @@ -1286,6 +1289,34 @@ impl Target { } } } + + #[cfg(test)] + fn check_consistency(&self) { + // Check that LLD with the given flavor is treated identically to the linker it emulates. + // If you target really needs to deviate from the rules below, whitelist it + // and document the reasons. + assert_eq!( + self.linker_flavor == LinkerFlavor::Msvc + || self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link), + self.options.lld_flavor == LldFlavor::Link, + ); + for args in &[ + &self.options.pre_link_args, + &self.options.pre_link_args_crt, + &self.options.late_link_args, + &self.options.late_link_args_dynamic, + &self.options.late_link_args_static, + &self.options.post_link_args, + ] { + assert_eq!( + args.get(&LinkerFlavor::Msvc), + args.get(&LinkerFlavor::Lld(LldFlavor::Link)), + ); + if args.contains_key(&LinkerFlavor::Msvc) { + assert_eq!(self.options.lld_flavor, LldFlavor::Link); + } + } + } } impl ToJson for Target { diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs index ab0f7791e2cda..21d62d252e09a 100644 --- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs +++ b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); @@ -10,7 +10,12 @@ pub fn target() -> TargetResult { // should be smart enough to insert branch islands only // where necessary, but this is not the observed behavior. // Disabling the LBR optimization works around the issue. - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/OPT:NOLBR".to_string()); + let pre_link_args_msvc = "/OPT:NOLBR".to_string(); + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push(pre_link_args_msvc.clone()); + base.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .push(pre_link_args_msvc); // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is // implemented for windows/arm in LLVM diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs index d09da9478fb2b..030eb12eb0ec5 100644 --- a/src/librustc_target/spec/uefi_base.rs +++ b/src/librustc_target/spec/uefi_base.rs @@ -13,39 +13,37 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOption use std::default::Default; pub fn opts() -> TargetOptions { + let pre_link_args_msvc = vec![ + // Suppress the verbose logo and authorship debugging output, which would needlessly + // clog any log files. + "/NOLOGO".to_string(), + // UEFI is fully compatible to non-executable data pages. Tell the compiler that + // non-code sections can be marked as non-executable, including stack pages. In fact, + // firmware might enforce this, so we better let the linker know about this, so it + // will fail if the compiler ever tries placing code on the stack (e.g., trampoline + // constructs and alike). + "/NXCOMPAT".to_string(), + // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets + // must be freestanding. + "/nodefaultlib".to_string(), + // Non-standard subsystems have no default entry-point in PE+ files. We have to define + // one. "efi_main" seems to be a common choice amongst other implementations and the + // spec. + "/entry:efi_main".to_string(), + // COFF images have a "Subsystem" field in their header, which defines what kind of + // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION, + // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION, + // which is very likely the most common option. Individual projects can override this + // with custom linker flags. + // The subsystem-type only has minor effects on the application. It defines the memory + // regions the application is loaded into (runtime-drivers need to be put into + // reserved areas), as well as whether a return from the entry-point is treated as + // exit (default for applications). + "/subsystem:efi_application".to_string(), + ]; let mut pre_link_args = LinkArgs::new(); - - pre_link_args.insert( - LinkerFlavor::Lld(LldFlavor::Link), - vec![ - // Suppress the verbose logo and authorship debugging output, which would needlessly - // clog any log files. - "/NOLOGO".to_string(), - // UEFI is fully compatible to non-executable data pages. Tell the compiler that - // non-code sections can be marked as non-executable, including stack pages. In fact, - // firmware might enforce this, so we better let the linker know about this, so it - // will fail if the compiler ever tries placing code on the stack (e.g., trampoline - // constructs and alike). - "/NXCOMPAT".to_string(), - // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets - // must be freestanding. - "/nodefaultlib".to_string(), - // Non-standard subsystems have no default entry-point in PE+ files. We have to define - // one. "efi_main" seems to be a common choice amongst other implementations and the - // spec. - "/entry:efi_main".to_string(), - // COFF images have a "Subsystem" field in their header, which defines what kind of - // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION, - // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION, - // which is very likely the most common option. Individual projects can override this - // with custom linker flags. - // The subsystem-type only has minor effects on the application. It defines the memory - // regions the application is loaded into (runtime-drivers need to be put into - // reserved areas), as well as whether a return from the entry-point is treated as - // exit (default for applications). - "/subsystem:efi_application".to_string(), - ], - ); + pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); TargetOptions { dynamic_linking: false, diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index 52b166df93996..78567a4382bed 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -2,10 +2,10 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { - let pre_args = vec!["/NOLOGO".to_string(), "/NXCOMPAT".to_string()]; - let mut args = LinkArgs::new(); - args.insert(LinkerFlavor::Msvc, pre_args.clone()); - args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_args); + let pre_link_args_msvc = vec!["/NOLOGO".to_string(), "/NXCOMPAT".to_string()]; + let mut pre_link_args = LinkArgs::new(); + pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); TargetOptions { function_sections: true, @@ -24,7 +24,7 @@ pub fn opts() -> TargetOptions { // messages if a link error occurred. link_env: vec![("VSLANG".to_string(), "1033".to_string())], lld_flavor: LldFlavor::Link, - pre_link_args: args, + pre_link_args, crt_static_allows_dylibs: true, crt_static_respected: true, abi_return_struct_as_int: true, diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs index 3d639b6b628b3..9497e525dd97c 100644 --- a/src/librustc_target/spec/windows_uwp_msvc_base.rs +++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs @@ -1,17 +1,16 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Msvc, - vec![ - "/NOLOGO".to_string(), - "/NXCOMPAT".to_string(), - "/APPCONTAINER".to_string(), - "mincore.lib".to_string(), - ], - ); + let pre_link_args_msvc = vec![ + "/NOLOGO".to_string(), + "/NXCOMPAT".to_string(), + "/APPCONTAINER".to_string(), + "mincore.lib".to_string(), + ]; + let mut pre_link_args = LinkArgs::new(); + pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); TargetOptions { function_sections: true, @@ -25,12 +24,13 @@ pub fn opts() -> TargetOptions { target_family: Some("windows".to_string()), is_like_windows: true, is_like_msvc: true, - pre_link_args: args, + pre_link_args, crt_static_allows_dylibs: true, crt_static_respected: true, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, requires_uwtable: true, + lld_flavor: LldFlavor::Link, ..Default::default() } From 7a4f059add44699af6d24abdcfd39f429dd54084 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 13:53:12 +0300 Subject: [PATCH 2/9] rustc_target: Move tests into a separate unconfigured file as much as possible. --- src/librustc_target/spec/mod.rs | 48 ++------------------ src/librustc_target/spec/tests/tests_impl.rs | 43 ++++++++++++++++++ 2 files changed, 48 insertions(+), 43 deletions(-) create mode 100644 src/librustc_target/spec/tests/tests_impl.rs diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index a1b9974826085..91fd3f8e18ed2 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -309,24 +309,14 @@ macro_rules! supported_targets { } #[cfg(test)] - mod test_json_encode_decode { - use rustc_serialize::json::ToJson; - use super::Target; - $(use super::$module;)+ + mod tests { + mod tests_impl; + // Cannot put this into a separate file without duplication, make an exception. $( - #[test] // `#[test]` - this is hard to put into a separate file, make an exception + #[test] // `#[test]` fn $module() { - // Grab the TargetResult struct. If we successfully retrieved - // a Target, then the test JSON encoding/decoding can run for this - // Target on this testing platform (i.e., checking the iOS targets - // only on a Mac test platform). - let _ = $module::target().map(|original| { - original.check_consistency(); - let as_json = original.to_json(); - let parsed = Target::from_json(as_json).unwrap(); - assert_eq!(original, parsed); - }); + tests_impl::test_target(super::$module::target()); } )+ } @@ -1289,34 +1279,6 @@ impl Target { } } } - - #[cfg(test)] - fn check_consistency(&self) { - // Check that LLD with the given flavor is treated identically to the linker it emulates. - // If you target really needs to deviate from the rules below, whitelist it - // and document the reasons. - assert_eq!( - self.linker_flavor == LinkerFlavor::Msvc - || self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link), - self.options.lld_flavor == LldFlavor::Link, - ); - for args in &[ - &self.options.pre_link_args, - &self.options.pre_link_args_crt, - &self.options.late_link_args, - &self.options.late_link_args_dynamic, - &self.options.late_link_args_static, - &self.options.post_link_args, - ] { - assert_eq!( - args.get(&LinkerFlavor::Msvc), - args.get(&LinkerFlavor::Lld(LldFlavor::Link)), - ); - if args.contains_key(&LinkerFlavor::Msvc) { - assert_eq!(self.options.lld_flavor, LldFlavor::Link); - } - } - } } impl ToJson for Target { diff --git a/src/librustc_target/spec/tests/tests_impl.rs b/src/librustc_target/spec/tests/tests_impl.rs new file mode 100644 index 0000000000000..4cf186bdd7c1a --- /dev/null +++ b/src/librustc_target/spec/tests/tests_impl.rs @@ -0,0 +1,43 @@ +use super::super::*; + +pub(super) fn test_target(target: TargetResult) { + // Grab the TargetResult struct. If we successfully retrieved + // a Target, then the test JSON encoding/decoding can run for this + // Target on this testing platform (i.e., checking the iOS targets + // only on a Mac test platform). + if let Ok(original) = target { + original.check_consistency(); + let as_json = original.to_json(); + let parsed = Target::from_json(as_json).unwrap(); + assert_eq!(original, parsed); + } +} + +impl Target { + fn check_consistency(&self) { + // Check that LLD with the given flavor is treated identically to the linker it emulates. + // If you target really needs to deviate from the rules below, whitelist it + // and document the reasons. + assert_eq!( + self.linker_flavor == LinkerFlavor::Msvc + || self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link), + self.options.lld_flavor == LldFlavor::Link, + ); + for args in &[ + &self.options.pre_link_args, + &self.options.pre_link_args_crt, + &self.options.late_link_args, + &self.options.late_link_args_dynamic, + &self.options.late_link_args_static, + &self.options.post_link_args, + ] { + assert_eq!( + args.get(&LinkerFlavor::Msvc), + args.get(&LinkerFlavor::Lld(LldFlavor::Link)), + ); + if args.contains_key(&LinkerFlavor::Msvc) { + assert_eq!(self.options.lld_flavor, LldFlavor::Link); + } + } + } +} From cfe90ebfe3599bebf301dbac3e74ed557f7ecf24 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 14:53:39 +0300 Subject: [PATCH 3/9] linker: Pass `/NODEFAULTLIB` in a more regular way --- src/librustc_codegen_ssa/back/link.rs | 9 ++------- src/librustc_codegen_ssa/back/linker.rs | 10 +--------- src/librustc_target/spec/uefi_base.rs | 3 --- src/librustc_target/spec/windows_msvc_base.rs | 10 ++++++++++ src/librustc_target/spec/windows_uwp_msvc_base.rs | 10 ++++++++++ 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 5f7a1938a3304..d58d9b91c73ac 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1532,13 +1532,8 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.debuginfo(); // OBJECT-FILES-NO, AUDIT-ORDER - // We want to, by default, prevent the compiler from accidentally leaking in - // any system libraries, so we may explicitly ask linkers to not link to any - // libraries by default. Note that this does not happen for windows because - // windows pulls in some large number of libraries and I couldn't quite - // figure out which subset we wanted. - // - // This is all naturally configurable via the standard methods as well. + // We want to prevent the compiler from accidentally leaking in any system libraries, + // so by default we tell linkers not to link to any default libraries. if !sess.opts.cg.default_linker_libraries.unwrap_or(false) && sess.target.target.options.no_default_libraries { diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 0baa37ae9f1ab..d8c5ddf586f45 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -631,15 +631,7 @@ impl<'a> Linker for MsvcLinker<'a> { } fn no_default_libraries(&mut self) { - // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC - // as there's been trouble in the past of linking the C++ standard - // library required by LLVM. This likely needs to happen one day, but - // in general Windows is also a more controlled environment than - // Unix, so it's not necessarily as critical that this be implemented. - // - // Note that there are also some licensing worries about statically - // linking some libraries which require a specific agreement, so it may - // not ever be possible for us to pass this flag. + self.cmd.arg("/NODEFAULTLIB"); } fn include_path(&mut self, path: &Path) { diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs index 030eb12eb0ec5..6f5e1badfb662 100644 --- a/src/librustc_target/spec/uefi_base.rs +++ b/src/librustc_target/spec/uefi_base.rs @@ -23,9 +23,6 @@ pub fn opts() -> TargetOptions { // will fail if the compiler ever tries placing code on the stack (e.g., trampoline // constructs and alike). "/NXCOMPAT".to_string(), - // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets - // must be freestanding. - "/nodefaultlib".to_string(), // Non-standard subsystems have no default entry-point in PE+ files. We have to define // one. "efi_main" seems to be a common choice amongst other implementations and the // spec. diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index 78567a4382bed..dc56dd916ff0b 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -30,6 +30,16 @@ pub fn opts() -> TargetOptions { abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, requires_uwtable: true, + // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC + // as there's been trouble in the past of linking the C++ standard + // library required by LLVM. This likely needs to happen one day, but + // in general Windows is also a more controlled environment than + // Unix, so it's not necessarily as critical that this be implemented. + // + // Note that there are also some licensing worries about statically + // linking some libraries which require a specific agreement, so it may + // not ever be possible for us to pass this flag. + no_default_libraries: false, ..Default::default() } diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs index 9497e525dd97c..2c70ba7abe262 100644 --- a/src/librustc_target/spec/windows_uwp_msvc_base.rs +++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs @@ -31,6 +31,16 @@ pub fn opts() -> TargetOptions { emit_debug_gdb_scripts: false, requires_uwtable: true, lld_flavor: LldFlavor::Link, + // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC + // as there's been trouble in the past of linking the C++ standard + // library required by LLVM. This likely needs to happen one day, but + // in general Windows is also a more controlled environment than + // Unix, so it's not necessarily as critical that this be implemented. + // + // Note that there are also some licensing worries about statically + // linking some libraries which require a specific agreement, so it may + // not ever be possible for us to pass this flag. + no_default_libraries: false, ..Default::default() } From 6580ceb9e1d8c0afcb0a53677c6b633c43a7068d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 16:04:18 +0300 Subject: [PATCH 4/9] rustc_target: `windows(_uwp)_base` -> `windows(_uwp)_gnu_base` The old naming is from ancient times when there was no MSVC support. Also `uefi_base` -> `uefi_msvc_base`. It will inherit from `msvc_base` in a future commit, plus a GNU UEFI target is also potentially possible. --- src/librustc_target/spec/i686_pc_windows_gnu.rs | 2 +- src/librustc_target/spec/i686_unknown_uefi.rs | 2 +- src/librustc_target/spec/i686_uwp_windows_gnu.rs | 2 +- src/librustc_target/spec/mod.rs | 6 +++--- .../spec/{uefi_base.rs => uefi_msvc_base.rs} | 0 .../spec/{windows_base.rs => windows_gnu_base.rs} | 0 .../spec/{windows_uwp_base.rs => windows_uwp_gnu_base.rs} | 0 src/librustc_target/spec/x86_64_pc_windows_gnu.rs | 2 +- src/librustc_target/spec/x86_64_unknown_uefi.rs | 2 +- src/librustc_target/spec/x86_64_uwp_windows_gnu.rs | 2 +- 10 files changed, 9 insertions(+), 9 deletions(-) rename src/librustc_target/spec/{uefi_base.rs => uefi_msvc_base.rs} (100%) rename src/librustc_target/spec/{windows_base.rs => windows_gnu_base.rs} (100%) rename src/librustc_target/spec/{windows_uwp_base.rs => windows_uwp_gnu_base.rs} (100%) diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/src/librustc_target/spec/i686_pc_windows_gnu.rs index 2091902d7ce21..d12afe5a40bcc 100644 --- a/src/librustc_target/spec/i686_pc_windows_gnu.rs +++ b/src/librustc_target/spec/i686_pc_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_base::opts(); + let mut base = super::windows_gnu_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.eliminate_frame_pointer = false; // Required for backtraces diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/src/librustc_target/spec/i686_unknown_uefi.rs index e299f92fdeb63..bf3064f437ff1 100644 --- a/src/librustc_target/spec/i686_unknown_uefi.rs +++ b/src/librustc_target/spec/i686_unknown_uefi.rs @@ -8,7 +8,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::uefi_base::opts(); + let mut base = super::uefi_msvc_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); diff --git a/src/librustc_target/spec/i686_uwp_windows_gnu.rs b/src/librustc_target/spec/i686_uwp_windows_gnu.rs index 93f396de0a051..4e582fb8c63ab 100644 --- a/src/librustc_target/spec/i686_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/i686_uwp_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_uwp_base::opts(); + let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.eliminate_frame_pointer = false; // Required for backtraces diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 91fd3f8e18ed2..d29b1dcdf8a44 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -66,12 +66,12 @@ mod redox_base; mod riscv_base; mod solaris_base; mod thumb_base; -mod uefi_base; +mod uefi_msvc_base; mod vxworks_base; mod wasm32_base; -mod windows_base; +mod windows_gnu_base; mod windows_msvc_base; -mod windows_uwp_base; +mod windows_uwp_gnu_base; mod windows_uwp_msvc_base; #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_msvc_base.rs similarity index 100% rename from src/librustc_target/spec/uefi_base.rs rename to src/librustc_target/spec/uefi_msvc_base.rs diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_gnu_base.rs similarity index 100% rename from src/librustc_target/spec/windows_base.rs rename to src/librustc_target/spec/windows_gnu_base.rs diff --git a/src/librustc_target/spec/windows_uwp_base.rs b/src/librustc_target/spec/windows_uwp_gnu_base.rs similarity index 100% rename from src/librustc_target/spec/windows_uwp_base.rs rename to src/librustc_target/spec/windows_uwp_gnu_base.rs diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs index 3d3acc682dea4..eb97fa56814d8 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_base::opts(); + let mut base = super::windows_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs index 7660b68aae62e..588de409d4519 100644 --- a/src/librustc_target/spec/x86_64_unknown_uefi.rs +++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs @@ -8,7 +8,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::uefi_base::opts(); + let mut base = super::uefi_msvc_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); diff --git a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs index 48366e24a39e4..ad6002f6b89e4 100644 --- a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_uwp_base::opts(); + let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); From 9c9db3ab4b5fcb3349ec744c4f168dd3e753d57b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 16:35:25 +0300 Subject: [PATCH 5/9] rustc_target: Remove some useless imports --- src/librustc_target/spec/armebv7r_none_eabi.rs | 1 - src/librustc_target/spec/armebv7r_none_eabihf.rs | 1 - src/librustc_target/spec/armv7r_none_eabi.rs | 1 - src/librustc_target/spec/armv7r_none_eabihf.rs | 1 - src/librustc_target/spec/dragonfly_base.rs | 1 - src/librustc_target/spec/freebsd_base.rs | 1 - src/librustc_target/spec/fuchsia_base.rs | 1 - src/librustc_target/spec/haiku_base.rs | 1 - src/librustc_target/spec/hermit_base.rs | 1 - src/librustc_target/spec/hermit_kernel_base.rs | 1 - src/librustc_target/spec/l4re_base.rs | 1 - src/librustc_target/spec/linux_base.rs | 1 - src/librustc_target/spec/linux_kernel_base.rs | 1 - src/librustc_target/spec/mod.rs | 1 - src/librustc_target/spec/netbsd_base.rs | 1 - src/librustc_target/spec/openbsd_base.rs | 1 - src/librustc_target/spec/redox_base.rs | 1 - src/librustc_target/spec/solaris_base.rs | 1 - src/librustc_target/spec/thumb_base.rs | 1 - src/librustc_target/spec/uefi_msvc_base.rs | 1 - src/librustc_target/spec/vxworks_base.rs | 1 - src/librustc_target/spec/windows_gnu_base.rs | 1 - src/librustc_target/spec/windows_msvc_base.rs | 1 - src/librustc_target/spec/windows_uwp_gnu_base.rs | 1 - src/librustc_target/spec/windows_uwp_msvc_base.rs | 1 - 25 files changed, 25 deletions(-) diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/src/librustc_target/spec/armebv7r_none_eabi.rs index 3a5957892b59c..ebe901e4f274d 100644 --- a/src/librustc_target/spec/armebv7r_none_eabi.rs +++ b/src/librustc_target/spec/armebv7r_none_eabi.rs @@ -1,7 +1,6 @@ // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/src/librustc_target/spec/armebv7r_none_eabihf.rs index 9f95a1a6f44fc..8652d1051ad05 100644 --- a/src/librustc_target/spec/armebv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armebv7r_none_eabihf.rs @@ -1,7 +1,6 @@ // Targets the Cortex-R4F/R5F processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/src/librustc_target/spec/armv7r_none_eabi.rs index 517368e6a23e9..b7fcda63db00b 100644 --- a/src/librustc_target/spec/armv7r_none_eabi.rs +++ b/src/librustc_target/spec/armv7r_none_eabi.rs @@ -1,7 +1,6 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/src/librustc_target/spec/armv7r_none_eabihf.rs index 6363469d92925..340090fd43b7c 100644 --- a/src/librustc_target/spec/armv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armv7r_none_eabihf.rs @@ -1,7 +1,6 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/dragonfly_base.rs b/src/librustc_target/spec/dragonfly_base.rs index e26d0ae50b26d..c7062e1ca5196 100644 --- a/src/librustc_target/spec/dragonfly_base.rs +++ b/src/librustc_target/spec/dragonfly_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/freebsd_base.rs b/src/librustc_target/spec/freebsd_base.rs index fc252b6d43d26..d2a087ab62f9f 100644 --- a/src/librustc_target/spec/freebsd_base.rs +++ b/src/librustc_target/spec/freebsd_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs index 046388e9be8f4..4060b126cddb7 100644 --- a/src/librustc_target/spec/fuchsia_base.rs +++ b/src/librustc_target/spec/fuchsia_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/haiku_base.rs b/src/librustc_target/spec/haiku_base.rs index 1ddab7be180e0..3d7ae6c302d9c 100644 --- a/src/librustc_target/spec/haiku_base.rs +++ b/src/librustc_target/spec/haiku_base.rs @@ -1,5 +1,4 @@ use crate::spec::{RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { TargetOptions { diff --git a/src/librustc_target/spec/hermit_base.rs b/src/librustc_target/spec/hermit_base.rs index 3f9dad689fd59..b9f94023e7a79 100644 --- a/src/librustc_target/spec/hermit_base.rs +++ b/src/librustc_target/spec/hermit_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/hermit_kernel_base.rs b/src/librustc_target/spec/hermit_kernel_base.rs index 650219c21ac40..1f9b195e2e698 100644 --- a/src/librustc_target/spec/hermit_kernel_base.rs +++ b/src/librustc_target/spec/hermit_kernel_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/l4re_base.rs b/src/librustc_target/spec/l4re_base.rs index b712dcae89970..5caad10161d8e 100644 --- a/src/librustc_target/spec/l4re_base.rs +++ b/src/librustc_target/spec/l4re_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; //use std::process::Command; // Use GCC to locate code for crt* libraries from the host, not from L4Re. Note diff --git a/src/librustc_target/spec/linux_base.rs b/src/librustc_target/spec/linux_base.rs index a5d7f8e07c443..52892fc35924e 100644 --- a/src/librustc_target/spec/linux_base.rs +++ b/src/librustc_target/spec/linux_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/src/librustc_target/spec/linux_kernel_base.rs index fae44836fa821..4a900d1b02cbf 100644 --- a/src/librustc_target/spec/linux_kernel_base.rs +++ b/src/librustc_target/spec/linux_kernel_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index d29b1dcdf8a44..d0129b2cdd37e 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -37,7 +37,6 @@ use crate::spec::abi::{lookup as lookup_abi, Abi}; use rustc_serialize::json::{Json, ToJson}; use std::collections::BTreeMap; -use std::default::Default; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{fmt, io}; diff --git a/src/librustc_target/spec/netbsd_base.rs b/src/librustc_target/spec/netbsd_base.rs index eb359b920463b..95c4749f9c74c 100644 --- a/src/librustc_target/spec/netbsd_base.rs +++ b/src/librustc_target/spec/netbsd_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/openbsd_base.rs b/src/librustc_target/spec/openbsd_base.rs index b66c56e1a7aea..cadd14df69352 100644 --- a/src/librustc_target/spec/openbsd_base.rs +++ b/src/librustc_target/spec/openbsd_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/redox_base.rs b/src/librustc_target/spec/redox_base.rs index 6398fa91f0253..18cafe654d17f 100644 --- a/src/librustc_target/spec/redox_base.rs +++ b/src/librustc_target/spec/redox_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/solaris_base.rs b/src/librustc_target/spec/solaris_base.rs index 98a2a0fbc9cc1..8d3a3563f4164 100644 --- a/src/librustc_target/spec/solaris_base.rs +++ b/src/librustc_target/spec/solaris_base.rs @@ -1,5 +1,4 @@ use crate::spec::TargetOptions; -use std::default::Default; pub fn opts() -> TargetOptions { TargetOptions { diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs index 99ab996be959d..eca095b594289 100644 --- a/src/librustc_target/spec/thumb_base.rs +++ b/src/librustc_target/spec/thumb_base.rs @@ -28,7 +28,6 @@ // build scripts / gcc flags. use crate::spec::{PanicStrategy, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { // See rust-lang/rfcs#1645 for a discussion about these defaults diff --git a/src/librustc_target/spec/uefi_msvc_base.rs b/src/librustc_target/spec/uefi_msvc_base.rs index 6f5e1badfb662..148658f4abb92 100644 --- a/src/librustc_target/spec/uefi_msvc_base.rs +++ b/src/librustc_target/spec/uefi_msvc_base.rs @@ -10,7 +10,6 @@ // code runs in the same environment, no process separation is supported. use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let pre_link_args_msvc = vec![ diff --git a/src/librustc_target/spec/vxworks_base.rs b/src/librustc_target/spec/vxworks_base.rs index 1763c9139b1bf..1b25c51278d4a 100644 --- a/src/librustc_target/spec/vxworks_base.rs +++ b/src/librustc_target/spec/vxworks_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args_crt = LinkArgs::new(); diff --git a/src/librustc_target/spec/windows_gnu_base.rs b/src/librustc_target/spec/windows_gnu_base.rs index 097ee09f1ea8c..33ecb1d0d48ce 100644 --- a/src/librustc_target/spec/windows_gnu_base.rs +++ b/src/librustc_target/spec/windows_gnu_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index dc56dd916ff0b..328cdec5492ee 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let pre_link_args_msvc = vec!["/NOLOGO".to_string(), "/NXCOMPAT".to_string()]; diff --git a/src/librustc_target/spec/windows_uwp_gnu_base.rs b/src/librustc_target/spec/windows_uwp_gnu_base.rs index f19bd10dc0bbd..bd1e0bc5eba94 100644 --- a/src/librustc_target/spec/windows_uwp_gnu_base.rs +++ b/src/librustc_target/spec/windows_uwp_gnu_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs index 2c70ba7abe262..3372da857feec 100644 --- a/src/librustc_target/spec/windows_uwp_msvc_base.rs +++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let pre_link_args_msvc = vec![ From fd0e2987eda697cfa1ec754021477f54a46645aa Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 16:38:36 +0300 Subject: [PATCH 6/9] rustc_target: Inherit `windows_uwp_msvc_base` from `windows_msvc_base` --- .../spec/windows_uwp_msvc_base.rs | 50 ++++--------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs index 3372da857feec..04ffa1a0addbe 100644 --- a/src/librustc_target/spec/windows_uwp_msvc_base.rs +++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs @@ -1,46 +1,14 @@ -use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; +use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions}; pub fn opts() -> TargetOptions { - let pre_link_args_msvc = vec![ - "/NOLOGO".to_string(), - "/NXCOMPAT".to_string(), - "/APPCONTAINER".to_string(), - "mincore.lib".to_string(), - ]; - let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); - pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); + let mut opts = super::windows_msvc_base::opts(); - TargetOptions { - function_sections: true, - dynamic_linking: true, - executables: true, - dll_prefix: String::new(), - dll_suffix: ".dll".to_string(), - exe_suffix: ".exe".to_string(), - staticlib_prefix: String::new(), - staticlib_suffix: ".lib".to_string(), - target_family: Some("windows".to_string()), - is_like_windows: true, - is_like_msvc: true, - pre_link_args, - crt_static_allows_dylibs: true, - crt_static_respected: true, - abi_return_struct_as_int: true, - emit_debug_gdb_scripts: false, - requires_uwtable: true, - lld_flavor: LldFlavor::Link, - // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC - // as there's been trouble in the past of linking the C++ standard - // library required by LLVM. This likely needs to happen one day, but - // in general Windows is also a more controlled environment than - // Unix, so it's not necessarily as critical that this be implemented. - // - // Note that there are also some licensing worries about statically - // linking some libraries which require a specific agreement, so it may - // not ever be possible for us to pass this flag. - no_default_libraries: false, + let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()]; + opts.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + opts.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .extend(pre_link_args_msvc); - ..Default::default() - } + opts } From 88c480279b9da4487aa779c26f0445aaaf268834 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 17:07:39 +0300 Subject: [PATCH 7/9] rustc_target: Inherit `windows_uwp_gnu_base` from `windows_gnu_base` --- .../spec/windows_uwp_gnu_base.rs | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/librustc_target/spec/windows_uwp_gnu_base.rs b/src/librustc_target/spec/windows_uwp_gnu_base.rs index bd1e0bc5eba94..aa99c3f7d95e5 100644 --- a/src/librustc_target/spec/windows_uwp_gnu_base.rs +++ b/src/librustc_target/spec/windows_uwp_gnu_base.rs @@ -1,6 +1,9 @@ use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { + let base = super::windows_gnu_base::opts(); + + // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`. let mut pre_link_args = LinkArgs::new(); pre_link_args.insert( LinkerFlavor::Gcc, @@ -13,7 +16,10 @@ pub fn opts() -> TargetOptions { ], ); + // FIXME: Should UWP target be updated for the exception machinery changes from #67502? let mut late_link_args = LinkArgs::new(); + let late_link_args_dynamic = LinkArgs::new(); + let late_link_args_static = LinkArgs::new(); late_link_args.insert( LinkerFlavor::Gcc, vec![ @@ -32,31 +38,17 @@ pub fn opts() -> TargetOptions { ); TargetOptions { - // FIXME(#13846) this should be enabled for windows - function_sections: false, - linker: Some("gcc".to_string()), - dynamic_linking: true, executables: false, - dll_prefix: String::new(), - dll_suffix: ".dll".to_string(), - exe_suffix: ".exe".to_string(), - staticlib_prefix: "lib".to_string(), - staticlib_suffix: ".a".to_string(), - target_family: Some("windows".to_string()), - is_like_windows: true, - allows_weak_linkage: false, + limit_rdylib_exports: false, pre_link_args, - pre_link_objects_exe: vec![ - "rsbegin.o".to_string(), // Rust compiler runtime initialization, see rsbegin.rs - ], + // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`. + pre_link_objects_exe: vec!["rsbegin.o".to_string()], + // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`. pre_link_objects_dll: vec!["rsbegin.o".to_string()], late_link_args, - post_link_objects: vec!["rsend.o".to_string()], - abi_return_struct_as_int: true, - emit_debug_gdb_scripts: false, - requires_uwtable: true, - limit_rdylib_exports: false, + late_link_args_dynamic, + late_link_args_static, - ..Default::default() + ..base } } From 57870ea2ca2f9795e875d55d60df57d47e4a3eba Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Apr 2020 17:30:09 +0300 Subject: [PATCH 8/9] rustc_target: Introduce `msvc_base` and inherit both `windows_msvc_base` and `uefi_msvc_base` from it. --- src/librustc_target/spec/i686_unknown_uefi.rs | 5 --- src/librustc_target/spec/mod.rs | 1 + src/librustc_target/spec/msvc_base.rs | 38 +++++++++++++++++++ src/librustc_target/spec/uefi_msvc_base.rs | 37 +++++++++--------- src/librustc_target/spec/windows_msvc_base.rs | 21 ++-------- .../spec/x86_64_unknown_uefi.rs | 5 --- 6 files changed, 59 insertions(+), 48 deletions(-) create mode 100644 src/librustc_target/spec/msvc_base.rs diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/src/librustc_target/spec/i686_unknown_uefi.rs index bf3064f437ff1..221d5f0785cd2 100644 --- a/src/librustc_target/spec/i686_unknown_uefi.rs +++ b/src/librustc_target/spec/i686_unknown_uefi.rs @@ -23,11 +23,6 @@ pub fn target() -> TargetResult { // arguments, thus giving you access to full MMX/SSE acceleration. base.features = "-mmx,-sse,+soft-float".to_string(); - // UEFI mirrors the calling-conventions used on windows. In case of i686 this means small - // structs will be returned as int. This shouldn't matter much, since the restrictions placed - // by the UEFI specifications forbid any ABI to return structures. - base.abi_return_struct_as_int = true; - // Use -GNU here, because of the reason below: // Background and Problem: // If we use i686-unknown-windows, the LLVM IA32 MSVC generates compiler intrinsic diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index d0129b2cdd37e..6ff812754aa7d 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -59,6 +59,7 @@ mod l4re_base; mod linux_base; mod linux_kernel_base; mod linux_musl_base; +mod msvc_base; mod netbsd_base; mod openbsd_base; mod redox_base; diff --git a/src/librustc_target/spec/msvc_base.rs b/src/librustc_target/spec/msvc_base.rs new file mode 100644 index 0000000000000..4d921b5d5fe10 --- /dev/null +++ b/src/librustc_target/spec/msvc_base.rs @@ -0,0 +1,38 @@ +use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; + +pub fn opts() -> TargetOptions { + let pre_link_args_msvc = vec![ + // Suppress the verbose logo and authorship debugging output, which would needlessly + // clog any log files. + "/NOLOGO".to_string(), + // Tell the compiler that non-code sections can be marked as non-executable, + // including stack pages. + // UEFI is fully compatible to non-executable data pages. + // In fact, firmware might enforce this, so we better let the linker know about this, + // so it will fail if the compiler ever tries placing code on the stack + // (e.g., trampoline constructs and alike). + "/NXCOMPAT".to_string(), + ]; + let mut pre_link_args = LinkArgs::new(); + pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); + + TargetOptions { + executables: true, + is_like_windows: true, + is_like_msvc: true, + // set VSLANG to 1033 can prevent link.exe from using + // language packs, and avoid generating Non-UTF-8 error + // messages if a link error occurred. + link_env: vec![("VSLANG".to_string(), "1033".to_string())], + lld_flavor: LldFlavor::Link, + pre_link_args, + // UEFI mirrors the calling-conventions used on windows. In case of x86-64 and i686 this + // means small structs will be returned as int. This shouldn't matter much, since the + // restrictions placed by the UEFI specifications forbid any ABI to return structures. + abi_return_struct_as_int: true, + emit_debug_gdb_scripts: false, + + ..Default::default() + } +} diff --git a/src/librustc_target/spec/uefi_msvc_base.rs b/src/librustc_target/spec/uefi_msvc_base.rs index 148658f4abb92..3f7c78c8e7d47 100644 --- a/src/librustc_target/spec/uefi_msvc_base.rs +++ b/src/librustc_target/spec/uefi_msvc_base.rs @@ -9,19 +9,12 @@ // the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all // code runs in the same environment, no process separation is supported. -use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; pub fn opts() -> TargetOptions { + let mut base = super::msvc_base::opts(); + let pre_link_args_msvc = vec![ - // Suppress the verbose logo and authorship debugging output, which would needlessly - // clog any log files. - "/NOLOGO".to_string(), - // UEFI is fully compatible to non-executable data pages. Tell the compiler that - // non-code sections can be marked as non-executable, including stack pages. In fact, - // firmware might enforce this, so we better let the linker know about this, so it - // will fail if the compiler ever tries placing code on the stack (e.g., trampoline - // constructs and alike). - "/NXCOMPAT".to_string(), // Non-standard subsystems have no default entry-point in PE+ files. We have to define // one. "efi_main" seems to be a common choice amongst other implementations and the // spec. @@ -37,25 +30,29 @@ pub fn opts() -> TargetOptions { // exit (default for applications). "/subsystem:efi_application".to_string(), ]; - let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); - pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + base.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .extend(pre_link_args_msvc); TargetOptions { - dynamic_linking: false, - executables: true, disable_redzone: true, exe_suffix: ".efi".to_string(), allows_weak_linkage: false, panic_strategy: PanicStrategy::Abort, stack_probes: true, singlethread: true, - emit_debug_gdb_scripts: false, - linker: Some("rust-lld".to_string()), - lld_flavor: LldFlavor::Link, - pre_link_args, + // FIXME: This should likely be `true` inherited from `msvc_base` + // because UEFI follows Windows ABI and uses PE/COFF. + // The `false` is probably causing ABI bugs right now. + is_like_windows: false, + // FIXME: This should likely be `true` inherited from `msvc_base` + // because UEFI follows Windows ABI and uses PE/COFF. + // The `false` is probably causing ABI bugs right now. + is_like_msvc: false, - ..Default::default() + ..base } } diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index 328cdec5492ee..77171f8672e8a 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -1,33 +1,18 @@ -use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; +use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { - let pre_link_args_msvc = vec!["/NOLOGO".to_string(), "/NXCOMPAT".to_string()]; - let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); - pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); + let base = super::msvc_base::opts(); TargetOptions { - function_sections: true, dynamic_linking: true, - executables: true, dll_prefix: String::new(), dll_suffix: ".dll".to_string(), exe_suffix: ".exe".to_string(), staticlib_prefix: String::new(), staticlib_suffix: ".lib".to_string(), target_family: Some("windows".to_string()), - is_like_windows: true, - is_like_msvc: true, - // set VSLANG to 1033 can prevent link.exe from using - // language packs, and avoid generating Non-UTF-8 error - // messages if a link error occurred. - link_env: vec![("VSLANG".to_string(), "1033".to_string())], - lld_flavor: LldFlavor::Link, - pre_link_args, crt_static_allows_dylibs: true, crt_static_respected: true, - abi_return_struct_as_int: true, - emit_debug_gdb_scripts: false, requires_uwtable: true, // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC // as there's been trouble in the past of linking the C++ standard @@ -40,6 +25,6 @@ pub fn opts() -> TargetOptions { // not ever be possible for us to pass this flag. no_default_libraries: false, - ..Default::default() + ..base } } diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs index 588de409d4519..12edc29330a49 100644 --- a/src/librustc_target/spec/x86_64_unknown_uefi.rs +++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs @@ -28,11 +28,6 @@ pub fn target() -> TargetResult { // places no locality-restrictions, so it fits well here. base.code_model = Some("large".to_string()); - // UEFI mirrors the calling-conventions used on windows. In case of x86-64 this means small - // structs will be returned as int. This shouldn't matter much, since the restrictions placed - // by the UEFI specifications forbid any ABI to return structures. - base.abi_return_struct_as_int = true; - Ok(Target { llvm_target: "x86_64-unknown-windows".to_string(), target_endian: "little".to_string(), From 8392e477e73c12566803411396b0ff18a0864c81 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 12 Apr 2020 23:36:37 +0300 Subject: [PATCH 9/9] Address review comments --- src/librustc_target/spec/msvc_base.rs | 3 --- src/librustc_target/spec/windows_uwp_gnu_base.rs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc_target/spec/msvc_base.rs b/src/librustc_target/spec/msvc_base.rs index 4d921b5d5fe10..817a322a9e4da 100644 --- a/src/librustc_target/spec/msvc_base.rs +++ b/src/librustc_target/spec/msvc_base.rs @@ -27,9 +27,6 @@ pub fn opts() -> TargetOptions { link_env: vec![("VSLANG".to_string(), "1033".to_string())], lld_flavor: LldFlavor::Link, pre_link_args, - // UEFI mirrors the calling-conventions used on windows. In case of x86-64 and i686 this - // means small structs will be returned as int. This shouldn't matter much, since the - // restrictions placed by the UEFI specifications forbid any ABI to return structures. abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/src/librustc_target/spec/windows_uwp_gnu_base.rs b/src/librustc_target/spec/windows_uwp_gnu_base.rs index aa99c3f7d95e5..dd3b60344be22 100644 --- a/src/librustc_target/spec/windows_uwp_gnu_base.rs +++ b/src/librustc_target/spec/windows_uwp_gnu_base.rs @@ -16,7 +16,7 @@ pub fn opts() -> TargetOptions { ], ); - // FIXME: Should UWP target be updated for the exception machinery changes from #67502? + // FIXME: This should be updated for the exception machinery changes from #67502. let mut late_link_args = LinkArgs::new(); let late_link_args_dynamic = LinkArgs::new(); let late_link_args_static = LinkArgs::new();