linker: Use --as-needed by default when linker supports it

This commit is contained in:
Vadim Petrochenkov 2021-03-28 00:02:23 +03:00
parent afaf33dcaf
commit 6615ee89be
21 changed files with 30 additions and 94 deletions

View File

@ -1651,6 +1651,12 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
cmd.add_eh_frame_header(); 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 // NO-OPT-OUT, OBJECT-FILES-NO
if crt_objects_fallback { if crt_objects_fallback {
cmd.no_crt_objects(); cmd.no_crt_objects();

View File

@ -130,6 +130,7 @@ pub trait Linker {
fn group_end(&mut self); fn group_end(&mut self);
fn linker_plugin_lto(&mut self); fn linker_plugin_lto(&mut self);
fn add_eh_frame_header(&mut self) {} fn add_eh_frame_header(&mut self) {}
fn add_as_needed(&mut self) {}
fn finalize(&mut self); fn finalize(&mut self);
} }
@ -641,6 +642,12 @@ impl<'a> Linker for GccLinker<'a> {
fn add_eh_frame_header(&mut self) { fn add_eh_frame_header(&mut self) {
self.linker_arg("--eh-frame-hdr"); 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> { pub struct MsvcLinker<'a> {

View File

@ -21,22 +21,9 @@ pub fn target(target_cpu: String) -> Target {
has_rpath: false, has_rpath: false,
position_independent_executables: false, position_independent_executables: false,
eh_frame_header: false, eh_frame_header: false,
pre_link_args: vec![( pre_link_args: vec![(LinkerFlavor::Gcc, vec![format!("-mmcu={}", target_cpu)])]
LinkerFlavor::Gcc, .into_iter()
vec![ .collect(),
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(),
late_link_args: vec![(LinkerFlavor::Gcc, vec!["-lgcc".to_owned()])] late_link_args: vec![(LinkerFlavor::Gcc, vec!["-lgcc".to_owned()])]
.into_iter() .into_iter()
.collect(), .collect(),

View File

@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions {
args.insert( args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ 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 // Always enable NX protection when it is available
"-Wl,-z,noexecstack".to_string(), "-Wl,-z,noexecstack".to_string(),
], ],

View File

@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions {
args.insert( args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ 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 // Always enable NX protection when it is available
"-Wl,-z,noexecstack".to_string(), "-Wl,-z,noexecstack".to_string(),
], ],

View File

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "pentium4".to_string(); base.cpu = "pentium4".to_string();
base.max_atomic_width = Some(64); 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) }; base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
Target { Target {

View File

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "pentium4".to_string(); base.cpu = "pentium4".to_string();
base.max_atomic_width = Some(64); 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) }; base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
Target { Target {

View File

@ -5,14 +5,6 @@ pub fn opts() -> TargetOptions {
args.insert( args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ 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 // Always enable NX protection when it is available
"-Wl,-z,noexecstack".to_string(), "-Wl,-z,noexecstack".to_string(),
], ],

View File

@ -4,10 +4,7 @@ use crate::spec::{
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut pre_link_args = LinkArgs::new(); let mut pre_link_args = LinkArgs::new();
pre_link_args.insert( pre_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-z,noexecstack".to_string()]);
LinkerFlavor::Gcc,
vec!["-Wl,--as-needed".to_string(), "-Wl,-z,noexecstack".to_string()],
);
TargetOptions { TargetOptions {
env: "gnu".to_string(), env: "gnu".to_string(),

View File

@ -1,18 +1,6 @@
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; use crate::spec::{RelroLevel, TargetOptions};
pub fn opts() -> 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 { TargetOptions {
os: "netbsd".to_string(), os: "netbsd".to_string(),
dynamic_linking: true, dynamic_linking: true,
@ -21,7 +9,6 @@ pub fn opts() -> TargetOptions {
linker_is_gnu: true, linker_is_gnu: true,
no_default_libraries: false, no_default_libraries: false,
has_rpath: true, has_rpath: true,
pre_link_args: args,
position_independent_executables: true, position_independent_executables: true,
relro_level: RelroLevel::Full, relro_level: RelroLevel::Full,
use_ctors_section: true, use_ctors_section: true,

View File

@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions {
args.insert( args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ 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 // Always enable NX protection when it is available
"-Wl,-z,noexecstack".to_string(), "-Wl,-z,noexecstack".to_string(),
], ],

View File

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "ppc64".to_string(); 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); base.max_atomic_width = Some(64);
Target { Target {

View File

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); 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); base.max_atomic_width = Some(32);
Target { Target {

View File

@ -3,8 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_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.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string()); base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".to_string());
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View File

@ -3,8 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string()); base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().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("--secure-plt".to_string());
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View File

@ -5,14 +5,6 @@ pub fn opts() -> TargetOptions {
args.insert( args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ 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 // Always enable NX protection when it is available
"-Wl,-z,noexecstack".to_string(), "-Wl,-z,noexecstack".to_string(),
], ],

View File

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "v9".to_string(); 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); base.max_atomic_width = Some(64);
Target { Target {

View File

@ -1,21 +1,6 @@
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; use crate::spec::TargetOptions;
pub fn opts() -> 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 { TargetOptions {
os: "vxworks".to_string(), os: "vxworks".to_string(),
env: "gnu".to_string(), env: "gnu".to_string(),
@ -27,7 +12,6 @@ pub fn opts() -> TargetOptions {
os_family: Some("unix".to_string()), os_family: Some("unix".to_string()),
linker_is_gnu: true, linker_is_gnu: true,
has_rpath: true, has_rpath: true,
pre_link_args: args,
position_independent_executables: false, position_independent_executables: false,
has_elf_tls: true, has_elf_tls: true,
crt_static_default: true, crt_static_default: true,

View File

@ -4,7 +4,6 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
const PRE_LINK_ARGS: &[&str] = &[ const PRE_LINK_ARGS: &[&str] = &[
"--as-needed",
"-z", "-z",
"noexecstack", "noexecstack",
"-e", "-e",

View File

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "x86-64".to_string(); base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
Target { Target {

View File

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "x86-64".to_string(); base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
base.disable_redzone = true; base.disable_redzone = true;