Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unstable -Z direct-access-external-data cmdline flag for rustc #119162

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions compiler/rustc_codegen_llvm/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,30 @@ impl CodegenCx<'_, '_> {
return false;
}

// Match clang by only supporting COFF and ELF for now.
if self.tcx.sess.target.is_like_osx {
return false;
}

// With pie relocation model calls of functions defined in the translation
// unit can use copy relocations.
if self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration {
return true;
}

// Thread-local variables generally don't support copy relocations.
let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
.is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True);
if is_thread_local_var {
return false;
}

// Match clang by only supporting COFF and ELF for now.
if self.tcx.sess.target.is_like_osx {
return false;
// Respect the direct-access-external-data to override default behavior if present.
if let Some(direct) = self.tcx.sess.direct_access_external_data() {
return direct;
}

// Static relocation model should force copy relocations everywhere.
if self.tcx.sess.relocation_model() == RelocModel::Static {
return true;
}

// With pie relocation model calls of functions defined in the translation
// unit can use copy relocations.
self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration
self.tcx.sess.relocation_model() == RelocModel::Static
}
}
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(debug_macros, true);
tracked!(default_hidden_visibility, Some(true));
tracked!(dep_info_omit_d_target, true);
tracked!(direct_access_external_data, Some(true));
tracked!(dual_proc_macros, true);
tracked!(dwarf_version, Some(5));
tracked!(emit_thin_lto, false);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,8 @@ options! {
dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
"in dep-info output, omit targets for tracking dependencies of the dep-info files \
themselves (default: no)"),
direct_access_external_data: Option<bool> = (None, parse_opt_bool, [TRACKED],
"Direct or use GOT indirect to reference external data symbols"),
dual_proc_macros: bool = (false, parse_bool, [TRACKED],
"load proc macros for both target and host, but only link to the target (default: no)"),
dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,13 @@ impl Session {
self.opts.unstable_opts.tls_model.unwrap_or(self.target.tls_model)
}

pub fn direct_access_external_data(&self) -> Option<bool> {
self.opts
.unstable_opts
.direct_access_external_data
.or(self.target.direct_access_external_data)
}

pub fn split_debuginfo(&self) -> SplitDebuginfo {
self.opts.cg.split_debuginfo.unwrap_or(self.target.split_debuginfo)
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1885,6 +1885,8 @@ pub struct TargetOptions {
/// passed, and cannot be disabled even via `-C`. Corresponds to `llc
/// -mattr=$features`.
pub features: StaticCow<str>,
/// Direct or use GOT indirect to reference external data symbols
pub direct_access_external_data: Option<bool>,
/// Whether dynamic linking is available on this target. Defaults to false.
pub dynamic_linking: bool,
/// Whether dynamic linking can export TLS globals. Defaults to true.
Expand Down Expand Up @@ -2279,6 +2281,7 @@ impl Default for TargetOptions {
asm_args: cvs![],
cpu: "generic".into(),
features: "".into(),
direct_access_external_data: None,
dynamic_linking: false,
dll_tls_export: true,
only_cdylib: false,
Expand Down Expand Up @@ -2575,6 +2578,12 @@ impl Target {
base.$key_name = s as u32;
}
} );
($key_name:ident, Option<bool>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) {
base.$key_name = Some(s);
}
} );
($key_name:ident, Option<u64>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
Expand Down Expand Up @@ -3003,6 +3012,7 @@ impl Target {
key!(cpu);
key!(features);
key!(dynamic_linking, bool);
key!(direct_access_external_data, Option<bool>);
key!(dll_tls_export, bool);
key!(only_cdylib, bool);
key!(executables, bool);
Expand Down Expand Up @@ -3257,6 +3267,7 @@ impl ToJson for Target {
target_option_val!(cpu);
target_option_val!(features);
target_option_val!(dynamic_linking);
target_option_val!(direct_access_external_data);
target_option_val!(dll_tls_export);
target_option_val!(only_cdylib);
target_option_val!(executables);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn target() -> Target {
features: "+f,+d".into(),
llvm_abiname: "lp64d".into(),
max_atomic_width: Some(64),
direct_access_external_data: Some(false),
..base::linux_gnu::opts()
},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# `direct_access_external_data`

The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/707

------------------------

Option `-Z direct-access-external-data` controls how to access symbols of
external data.

Supported values for this option are:

- `yes` - Don't use GOT indirection to reference external data symbols.
- `no` - Use GOT indirection to reference external data symbols.

If the option is not explicitly specified, different targets have different
default values.
21 changes: 21 additions & 0 deletions tests/codegen/direct-access-external-data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// only-loongarch64-unknown-linux-gnu

// revisions: DEFAULT DIRECT INDIRECT
// [DEFAULT] compile-flags: -C relocation-model=static
// [DIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=yes
// [INDIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=no

#![crate_type = "rlib"]

// DEFAULT: @VAR = external {{.*}} global i32
// DIRECT: @VAR = external dso_local {{.*}} global i32
// INDIRECT: @VAR = external {{.*}} global i32

extern "C" {
static VAR: i32;
}

#[no_mangle]
pub fn get() -> i32 {
unsafe { VAR }
}
Loading