Skip to content

Commit 8de4b13

Browse files
committed
Auto merge of #104679 - dvdhrm:rw/dso, r=petrochenkov
codegen-llvm: never combine DSOLocal and DllImport Prevent DllImport from being attached to DSOLocal definitions in the LLVM IR. The combination makes no sense, since definitions local to the compilation unit will never be imported from external objects. Additionally, LLVM will refuse the IR if it encounters the combination (introduced in [1]): ``` if (GV.hasDLLImportStorageClass()) Assert(!GV.isDSOLocal(), "GlobalValue with DLLImport Storage is dso_local!", &GV); ``` Right now, codegen-llvm will only apply DllImport to constants and rely on call-stubs for functions. Hence, we simply extend the codegen of constants to skip DllImport for any local definitions. This was discovered when switching the EFI targets to the static relocation model [2]. With this fixed, we can start another attempt at this. [1] https://smlnj-gitlab.cs.uchicago.edu/manticore/llvm/commit/509132b368efed10bbdad825403f45e9cf1d6e38 [2] #101656
2 parents d38a990 + 7b9e1a9 commit 8de4b13

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

compiler/rustc_codegen_llvm/src/consts.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,18 @@ impl<'ll> CodegenCx<'ll, '_> {
295295
llvm::set_thread_local_mode(g, self.tls_model);
296296
}
297297

298+
let dso_local = unsafe { self.should_assume_dso_local(g, true) };
299+
if dso_local {
300+
unsafe {
301+
llvm::LLVMRustSetDSOLocal(g, true);
302+
}
303+
}
304+
298305
if !def_id.is_local() {
299306
let needs_dll_storage_attr = self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) &&
307+
// Local definitions can never be imported, so we must not apply
308+
// the DLLImport annotation.
309+
!dso_local &&
300310
// ThinLTO can't handle this workaround in all cases, so we don't
301311
// emit the attrs. Instead we make them unnecessary by disallowing
302312
// dynamic linking when linker plugin based LTO is enabled.
@@ -340,12 +350,6 @@ impl<'ll> CodegenCx<'ll, '_> {
340350
}
341351
}
342352

343-
unsafe {
344-
if self.should_assume_dso_local(g, true) {
345-
llvm::LLVMRustSetDSOLocal(g, true);
346-
}
347-
}
348-
349353
self.instances.borrow_mut().insert(instance, g);
350354
g
351355
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Auxiliary crate that exports a function and static. Both always
2+
// evaluate to `71`. We force mutability on the static to prevent
3+
// it from being inlined as constant.
4+
5+
#![crate_type = "lib"]
6+
7+
#[no_mangle]
8+
pub fn extern_fn() -> u8 { unsafe { extern_static } }
9+
10+
#[no_mangle]
11+
pub static mut extern_static: u8 = 71;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Verify linkage of external symbols in the static relocation model on MSVC.
2+
//
3+
// compile-flags: -O -C relocation-model=static
4+
// aux-build: extern_decl.rs
5+
// only-x86_64-pc-windows-msvc
6+
7+
#![crate_type = "rlib"]
8+
9+
extern crate extern_decl;
10+
11+
// The `extern_decl` definitions are imported from a statically linked rust
12+
// crate, thus they are expected to be marked `dso_local` without `dllimport`.
13+
//
14+
// The `access_extern()` symbol is from this compilation unit, thus we expect
15+
// it to be marked `dso_local` as well, given the static relocation model.
16+
//
17+
// CHECK: @extern_static = external dso_local local_unnamed_addr global i8
18+
// CHECK: define dso_local i8 @access_extern() {{.*}}
19+
// CHECK: declare dso_local i8 @extern_fn() {{.*}}
20+
21+
#[no_mangle]
22+
pub fn access_extern() -> u8 {
23+
unsafe {
24+
extern_decl::extern_fn() + extern_decl::extern_static
25+
}
26+
}

0 commit comments

Comments
 (0)