diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 27879d817b208..20ba542fe063b 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -30,7 +30,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileNameDisplayPreference, RealFileName, Span, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{ - CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, + CodeModel, DebuginfoKind, LinkerFeatures, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target, TargetTriple, TlsModel, }; @@ -622,11 +622,20 @@ impl Session { /// Returns the default symbol visibility. pub fn default_visibility(&self) -> SymbolVisibility { + // For now, we default to using protected only if the LLD linker features is enabled. This + // is to avoid link errors that are likely if using protected visibility with GNU ld < 2.40. + let fallback = + if self.opts.unstable_opts.linker_features.enabled.contains(LinkerFeatures::LLD) { + SymbolVisibility::Protected + } else { + SymbolVisibility::Interposable + }; + self.opts .unstable_opts .default_visibility .or(self.target.options.default_visibility) - .unwrap_or(SymbolVisibility::Interposable) + .unwrap_or(fallback) } } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 2519ace92b9e0..e86fb9506e963 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -428,7 +428,7 @@ pub fn linker_flags( ) -> Vec { let mut args = vec![]; if !builder.is_lld_direct_linker(target) && builder.config.lld_mode.is_used() { - args.push(String::from("-Clink-arg=-fuse-ld=lld")); + args.push(String::from("-Zlinker-features=+lld")); if matches!(lld_threads, LldThreads::No) { args.push(format!( diff --git a/src/doc/unstable-book/src/compiler-flags/default-visibility.md b/src/doc/unstable-book/src/compiler-flags/default-visibility.md index ad9e5d84bba80..d72a3c33dc2ad 100644 --- a/src/doc/unstable-book/src/compiler-flags/default-visibility.md +++ b/src/doc/unstable-book/src/compiler-flags/default-visibility.md @@ -10,12 +10,15 @@ setting. This option only affects building of shared objects and should have no effect on executables. -Visibility an be set to one of three options: +Visibility can be set to one of three options: * protected * hidden * interposable +The default value for this flag is `interposable` unless `-Zlinker-features=+lld` is specified, in +which case the default is `protected`. + ## Hidden visibility Using `-Zdefault-visibility=hidden` is roughly equivalent to Clang's diff --git a/tests/codegen/default-visibility.rs b/tests/codegen/default-visibility.rs index 88ff9fee25447..a0352da53b5fd 100644 --- a/tests/codegen/default-visibility.rs +++ b/tests/codegen/default-visibility.rs @@ -3,10 +3,12 @@ // also https://github.com/rust-lang/rust/issues/73295 and // https://github.com/rust-lang/rust/issues/37530. -//@ revisions:DEFAULT HIDDEN PROTECTED INTERPOSABLE +//@ revisions:NO_LLD LLD HIDDEN PROTECTED INTERPOSABLE //@[HIDDEN] compile-flags: -Zdefault-visibility=hidden //@[PROTECTED] compile-flags: -Zdefault-visibility=protected //@[INTERPOSABLE] compile-flags: -Zdefault-visibility=interposable +//@[NO_LLD] compile-flags: -Zlinker-features=-lld +//@[LLD] compile-flags: -Zlinker-features=+lld // The test scenario is specifically about visibility of symbols exported out of dynamically linked // libraries. @@ -30,7 +32,8 @@ pub static tested_symbol: [u8; 6] = *b"foobar"; // HIDDEN: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = hidden constant // PROTECTED: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = protected constant // INTERPOSABLE: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant -// DEFAULT: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant +// NO_LLD: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant +// LLD: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = protected constant pub fn do_memcmp(left: &[u8], right: &[u8]) -> i32 { left.cmp(right) as i32 @@ -46,4 +49,5 @@ pub fn do_memcmp(left: &[u8], right: &[u8]) -> i32 { // HIDDEN: declare i32 @memcmp // PROTECTED: declare i32 @memcmp // INTERPOSABLE: declare i32 @memcmp -// DEFAULT: declare i32 @memcmp +// NO_LLD: declare i32 @memcmp +// LLD: declare i32 @memcmp