Skip to content
Open
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
48 changes: 28 additions & 20 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1292,7 +1292,8 @@ fn embed_bitcode(
}
}

// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
// Create a `__imp_<symbol> = &symbol` global for each externally visible
// static data symbol, including aliases to static data.
// This is required to satisfy `dllimport` references to static data in .rlibs
// when using MSVC linker. We do this only for data, as linker can fix up
// code references on its own.
Expand All @@ -1305,31 +1306,38 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M
// names, so we need an extra underscore on x86. There's also a leading
// '\x01' here which disables LLVM's symbol mangling (e.g., no extra
// underscores added in front).
let prefix = if cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" };
let prefix: &[u8] = if cgcx.target_arch == "x86" { b"\x01__imp__" } else { b"\x01__imp_" };

let ptr_ty = llvm_type_ptr(llcx);
let globals = base::iter_globals(llmod)
.filter(|&val| {
llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage && !llvm::is_declaration(val)
})
.filter_map(|val| {
// Exclude some symbols that we know are not Rust symbols.
let name = llvm::get_value_name(val);
if ignored(&name) { None } else { Some((val, name)) }
})
.map(move |(val, name)| {
let mut imp_name = prefix.as_bytes().to_vec();
imp_name.extend(name);
let imp_name = CString::new(imp_name).unwrap();
(imp_name, val)
})
.collect::<Vec<_>>();
let symbols = std::iter::chain(
base::iter_globals(llmod),
base::iter_global_aliases(llmod).filter(|&val| {
llvm::LLVMGetTypeKind(unsafe { llvm::LLVMGlobalGetValueType(val) }).to_rust()
!= llvm::TypeKind::Function
}),
)
.map(|val| (val, llvm::get_linkage(val)))
.filter(|&(val, linkage)| {
matches!(linkage, llvm::Linkage::ExternalLinkage | llvm::Linkage::WeakAnyLinkage)
&& !llvm::is_declaration(val)
})
.collect::<Vec<_>>();

for (val, linkage) in symbols {
let name = llvm::get_value_name(val);
// Exclude some symbols that we know are not Rust symbols.
if ignored(&name) {
continue;
}

let mut imp_name = prefix.to_vec();
imp_name.extend(name);
let imp_name = CString::new(imp_name).unwrap();

for (imp_name, val) in globals {
let imp = llvm::add_global(llmod, ptr_ty, &imp_name);

llvm::set_initializer(imp, val);
llvm::set_linkage(imp, llvm::Linkage::ExternalLinkage);
llvm::set_linkage(imp, linkage);
}

// Use this function to exclude certain symbols from `__imp` generation.
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ pub(crate) fn iter_globals(llmod: &llvm::Module) -> ValueIter<'_> {
unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), step: llvm::LLVMGetNextGlobal } }
}

pub(crate) fn iter_global_aliases(llmod: &llvm::Module) -> ValueIter<'_> {
unsafe {
ValueIter { cur: llvm::LLVMGetFirstGlobalAlias(llmod), step: llvm::LLVMGetNextGlobalAlias }
}
}

pub(crate) fn compile_codegen_unit(
tcx: TyCtxt<'_>,
cgu_name: Symbol,
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_codegen_llvm/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,11 @@ impl<'ll> CodegenCx<'ll, '_> {
let dso_local = self.assume_dso_local(g, true);

if !def_id.is_local() {
let is_eii = fn_attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM);
let needs_dll_storage_attr = self.use_dll_storage_attrs
&& !self.tcx.is_foreign_item(def_id)
// EII static declarations are encoded as foreign items, but their symbols are
// resolved by Rust crates, not native libraries.
&& (!self.tcx.is_foreign_item(def_id) || is_eii)
// Local definitions can never be imported, so we must not apply
// the DLLImport annotation.
&& !dso_local
Expand All @@ -446,10 +449,11 @@ impl<'ll> CodegenCx<'ll, '_> {

if needs_dll_storage_attr {
// This item is external but not foreign, i.e., it originates from an external Rust
// crate. Since we don't know whether this crate will be linked dynamically or
// statically in the final application, we always mark such symbols as 'dllimport'.
// If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs
// to make things work.
// crate. EII static declarations are handled the same way, even though they are
// represented as foreign items. Since we don't know whether this crate will be
// linked dynamically or statically in the final application, we always mark such
// symbols as 'dllimport'. If final linkage happens to be static, we rely on
// compiler-emitted __imp_ stubs to make things work.
//
// However, in some scenarios we defer emission of statics to downstream
// crates, so there are cases where a static with an upstream DefId
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,17 @@ unsafe extern "C" {
pub(crate) safe fn LLVMSetTailCallKind(CallInst: &Value, kind: TailCallKind);
pub(crate) safe fn LLVMSetExternallyInitialized(GlobalVar: &Value, IsExtInit: Bool);

// Operations on global aliases
pub(crate) fn LLVMAddAlias2<'ll>(
M: &'ll Module,
ValueTy: &Type,
AddressSpace: c_uint,
Aliasee: &Value,
Name: *const c_char,
) -> &'ll Value;
pub(crate) fn LLVMGetFirstGlobalAlias(M: &Module) -> Option<&Value>;
pub(crate) fn LLVMGetNextGlobalAlias(GlobalAlias: &Value) -> Option<&Value>;

// Operations on attributes
pub(crate) fn LLVMCreateStringAttribute(
C: &Context,
Expand Down Expand Up @@ -2640,14 +2651,6 @@ unsafe extern "C" {
pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value);
pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);

pub(crate) fn LLVMAddAlias2<'ll>(
M: &'ll Module,
ValueTy: &Type,
AddressSpace: c_uint,
Aliasee: &Value,
Name: *const c_char,
) -> &'ll Value;

pub(crate) fn LLVMRustConstPtrAuth(
ptr: *const Value,
key: u32,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_monomorphize/src/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,17 @@ fn static_visibility<'tcx>(
*can_be_internalized = false;
default_visibility(tcx, def_id, false)
} else {
if tcx.def_kind(def_id).has_codegen_attrs() {
// Prevent EII and `rustc_std_internal_symbol` statics being internalized.
let attrs = tcx.codegen_fn_attrs(def_id);
if attrs.flags.intersects(
CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
| CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM,
) {
*can_be_internalized = false;
}
}

Visibility::Hidden
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/default/call_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests EIIs with default implementations.
// When there's no explicit declaration, the default should be called from the declaring crate.

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/default/call_default_panics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//@ needs-unwind
//@ exec-env:RUST_BACKTRACE=1
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// A small test to make sure that unwinding works properly.
//
// Functions can have target-cpu applied. On apple-darwin this is super important,
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/default/call_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests EIIs with default implementations.
// When an explicit implementation is given in one dependency, and the declaration is in another,
// the explicit implementation is preferred.
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/default/local_crate.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests EIIs with default implementations.
// In the same crate, when there's no explicit declaration, the default should be called.
#![feature(extern_item_impls)]
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/default/local_crate_explicit.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests EIIs with default implementations.
// In the same crate, the explicit implementation should get priority.
#![feature(extern_item_impls)]
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/duplicate/duplicate1.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ aux-build: impl1.rs
//@ aux-build: impl2.rs
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// tests that EIIs error properly, even if the conflicting implementations live in another crate.
#![feature(extern_item_impls)]

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/duplicate/duplicate2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//@ aux-build: impl2.rs
//@ aux-build: impl3.rs
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests the error message when there are multiple implementations of an EII in many crates.
#![feature(extern_item_impls)]

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/duplicate/duplicate3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//@ aux-build: impl3.rs
//@ aux-build: impl4.rs
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests the error message when there are multiple implementations of an EII in many crates.
#![feature(extern_item_impls)]

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/duplicate/multiple_impls.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether one function could implement two EIIs.
#![feature(extern_item_impls)]

Expand Down
3 changes: 2 additions & 1 deletion tests/ui/eii/eii_impl_with_contract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//@ run-pass
//@ ignore-backends: gcc
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu

#![feature(extern_item_impls)]
#![feature(contracts)]
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/linking/codegen_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//@ aux-build: codegen_cross_crate_other_crate.rs
//@ compile-flags: -O
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether calling EIIs works with the declaration in another crate.

extern crate codegen_cross_crate_other_crate as codegen;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/linking/codegen_single_crate.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether calling EIIs works with the declaration in the same crate.
#![feature(extern_item_impls)]

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/linking/same-symbol.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
#![feature(extern_item_impls)]

pub mod a {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/privacy1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//@ check-run-results
//@ aux-build: other_crate_privacy1.rs
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether re-exports work.

extern crate other_crate_privacy1 as codegen;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/shadow_builtin.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether calling EIIs works with the declaration in the same crate.
#![feature(extern_item_impls)]

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/static/argument_required.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether EIIs work on statics
#![feature(extern_item_impls)]

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/static/cross_crate_decl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//@ aux-build: cross_crate_decl.rs
//@ compile-flags: -O
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether calling EIIs works with the declaration in another crate.

extern crate cross_crate_decl as codegen;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/static/cross_crate_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//@ aux-build: cross_crate_def.rs
//@ compile-flags: -O
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// Tests whether calling EIIs works with the declaration and definition in another crate.

extern crate cross_crate_def as codegen;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/static/default.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// FIXME(#157649): static EII defaults currently fail to link on Apple targets.
//@ ignore-apple
// Tests static EIIs with default implementations.
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/static/default_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// FIXME(#157649): static EII defaults currently fail to link on Apple targets.
//@ ignore-apple
// Tests that a static EII default can be used from another crate.
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/static/default_cross_crate_explicit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// FIXME(#157649): static EII defaults currently fail to link on Apple targets.
//@ ignore-apple
// Tests that an explicit static EII implementation overrides a cross-crate default.
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/eii/static/default_explicit.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ run-pass
//@ check-run-results
//@ ignore-backends: gcc
// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
//@ ignore-windows
// FIXME(#125418): linking on Windows GNU targets is not yet supported.
//@ ignore-windows-gnu
// FIXME(#157649): static EII defaults currently fail to link on Apple targets.
//@ ignore-apple
// Tests that an explicit static EII implementation overrides a local default.
Expand Down
Loading
Loading