diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4d6bc8381300abb100379893f4267da0d78701ca..e7938fe8af968b2966746e029f2d599c145e9314 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1651,6 +1651,12 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.add_eh_frame_header(); } + // NO-OPT-OUT, OBJECT-FILES-NO + // Avoid linking to dynamic libraries unless they satisfy some undefined symbols + // at the point at which they are specified on the command line. + // Must be passed before any dynamic libraries. + cmd.add_as_needed(); + // NO-OPT-OUT, OBJECT-FILES-NO if crt_objects_fallback { cmd.no_crt_objects(); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index bb35e7ec8943955f45f67c955f9989ea735e1083..592675d916a2e5c953112a7169ed3549195c4d6e 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -130,6 +130,7 @@ pub trait Linker { fn group_end(&mut self); fn linker_plugin_lto(&mut self); fn add_eh_frame_header(&mut self) {} + fn add_as_needed(&mut self) {} fn finalize(&mut self); } @@ -641,6 +642,12 @@ fn linker_plugin_lto(&mut self) { fn add_eh_frame_header(&mut self) { self.linker_arg("--eh-frame-hdr"); } + + fn add_as_needed(&mut self) { + if self.sess.target.linker_is_gnu { + self.linker_arg("--as-needed"); + } + } } pub struct MsvcLinker<'a> { diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index 67a7684da2c70434bc917388fb3cfd1e7865dde5..df4389b8165a8f22e9b4b4be25ebe9b07b9b5fdd 100644 --- a/compiler/rustc_target/src/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs @@ -21,22 +21,9 @@ pub fn target(target_cpu: String) -> Target { has_rpath: false, position_independent_executables: false, eh_frame_header: false, - pre_link_args: vec![( - LinkerFlavor::Gcc, - vec![ - format!("-mmcu={}", target_cpu), - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), - ], - )] - .into_iter() - .collect(), + pre_link_args: vec![(LinkerFlavor::Gcc, vec![format!("-mmcu={}", target_cpu)])] + .into_iter() + .collect(), late_link_args: vec![(LinkerFlavor::Gcc, vec!["-lgcc".to_owned()])] .into_iter() .collect(), diff --git a/compiler/rustc_target/src/spec/dragonfly_base.rs b/compiler/rustc_target/src/spec/dragonfly_base.rs index b96de7ab1ed19b2ca4b6b95836f59dea48cabe6a..41d372cc6db406cd20b3197785f3ca03721e3d5b 100644 --- a/compiler/rustc_target/src/spec/dragonfly_base.rs +++ b/compiler/rustc_target/src/spec/dragonfly_base.rs @@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs index c70c492716b30e1a09324570a2e4a9cd9dffeb6c..86db2bf8eed0b0be90246b2bf2c4345b50df6ed6 100644 --- a/compiler/rustc_target/src/spec/freebsd_base.rs +++ b/compiler/rustc_target/src/spec/freebsd_base.rs @@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index c4d11bfb13ece496999e9151256ef35f61a127d9..e020264ad7af25f6b7f830f376465cffceaf1ebc 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index ec8a2493b4e42434a6e4ff64e53553772bb919e3..e596eca86b0d757e289feac1747296876100ca0e 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs index 0631644ad63555d868180a5a1affe9a62585d320..aa2ff7bb3993f7fcc5c46a5037f8f365d4665383 100644 --- a/compiler/rustc_target/src/spec/linux_base.rs +++ b/compiler/rustc_target/src/spec/linux_base.rs @@ -5,14 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index 522015689536715b922fd310aafadae958f497e9..e71c80e556e8a0aebd19e2061e0243cc1e04e620 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -4,10 +4,7 @@ pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert( - LinkerFlavor::Gcc, - vec!["-Wl,--as-needed".to_string(), "-Wl,-z,noexecstack".to_string()], - ); + pre_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-z,noexecstack".to_string()]); TargetOptions { env: "gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/netbsd_base.rs b/compiler/rustc_target/src/spec/netbsd_base.rs index a77d60bd9d74705ead46c79c000ce186eed72ff6..680cd60788bdea8d158e960e757b2c73c677f2eb 100644 --- a/compiler/rustc_target/src/spec/netbsd_base.rs +++ b/compiler/rustc_target/src/spec/netbsd_base.rs @@ -1,18 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; +use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), - ], - ); - TargetOptions { os: "netbsd".to_string(), dynamic_linking: true, @@ -21,7 +9,6 @@ pub fn opts() -> TargetOptions { linker_is_gnu: true, no_default_libraries: false, has_rpath: true, - pre_link_args: args, position_independent_executables: true, relro_level: RelroLevel::Full, use_ctors_section: true, diff --git a/compiler/rustc_target/src/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs index 2b40a1ed945cf8f713cb2964543402a3758f392e..0aeefba3647d1bb72ca56680bda0161d1b151b7f 100644 --- a/compiler/rustc_target/src/spec/openbsd_base.rs +++ b/compiler/rustc_target/src/spec/openbsd_base.rs @@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index 2f28a8562472d8d4d49ffb358cea6020fa0580b0..3ebc5469e0a8b3d897e800f280066ad58659d300 100644 --- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "ppc64".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index 1245098329aee407b05e843d291639fbeb41d993..4cc5224fae30d1328cbfa6ce8f2bcc488582cc15 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs @@ -3,7 +3,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index bb943a8825c6c794d10a6422c8b205ace60c0709..2f0a6ca44a008ae8752de8e8a66a8558b6a57c66 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs @@ -3,8 +3,8 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index 4b4f118ba49bd4731f7b89f70460061cf39f11fa..215f1a36227d79571181aa2739c3ef987d0f03f6 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs @@ -3,8 +3,8 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/redox_base.rs b/compiler/rustc_target/src/spec/redox_base.rs index 5ef705878a8ff98fa5805e4827d801d91350734e..20c91708faadf9c35e507cec4c35d899d15ee66f 100644 --- a/compiler/rustc_target/src/spec/redox_base.rs +++ b/compiler/rustc_target/src/spec/redox_base.rs @@ -5,14 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs index 7d685c83100d3a40d462a19377c257ea94bdcee2..b4286dfd88f1105abd6f62b07282284604d3385f 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "v9".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/vxworks_base.rs b/compiler/rustc_target/src/spec/vxworks_base.rs index 70bc9ce3e0e2d7d0389feeac856dd340f0bcc9e4..8396d0463d931adee5800080e2660644b92d03b9 100644 --- a/compiler/rustc_target/src/spec/vxworks_base.rs +++ b/compiler/rustc_target/src/spec/vxworks_base.rs @@ -1,21 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), - ], - ); - TargetOptions { os: "vxworks".to_string(), env: "gnu".to_string(), @@ -27,7 +12,6 @@ pub fn opts() -> TargetOptions { os_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: args, position_independent_executables: false, has_elf_tls: true, crt_static_default: true, diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs index 74fb6f0a8341ca45a8dcdffe717210aea26cbd9c..aacbdbdeefbef7d22b283d596ee5b26cd878a0bd 100644 --- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs @@ -4,7 +4,6 @@ pub fn target() -> Target { const PRE_LINK_ARGS: &[&str] = &[ - "--as-needed", "-z", "noexecstack", "-e", diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index 6d19dec00b411aea1db0d91da8a4d5337ae6ae4c..54e7ceee82e8aa02edc1f41e59f41c5ef808d557 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 1b35e813fcd8f1406033dfb4fcab3543800c81ab..f9fa9d9384304580c29abd3984c5d1ce44707a1d 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.disable_redzone = true;