Skip to content

Commit be8450e

Browse files
committed
Auto merge of #85276 - Bobo1239:more_dso_local, r=nagisa
Set dso_local for more items Related to #83592. (cc `@nagisa)` Noticed that on x86_64 with `relocation-model: static` `R_X86_64_GOTPCREL` relocations were still generated in some cases. (related: Rust-for-Linux/linux#135; Rust-for-Linux needs these fixes to successfully build) First time doing anything with LLVM so not sure whether this is correct but the following are some of the things I've tried to convince myself. ## C equivalent Example from clang which also sets `dso_local` in these cases: `clang-12 -fno-PIC -S -emit-llvm test.c` ```C extern int A; int* a() { return &A; } int B; int* b() { return &B; } ``` ``` ; ModuleID = 'test.c' source_filename = "test.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" `@A` = external dso_local global i32, align 4 `@B` = dso_local global i32 0, align 4 ; Function Attrs: noinline nounwind optnone uwtable define dso_local i32* `@a()` #0 { ret i32* `@A` } ; Function Attrs: noinline nounwind optnone uwtable define dso_local i32* `@b()` #0 { ret i32* `@B` } attributes #0 = { noinline nounwind optnone uwtable "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0} !llvm.ident = !{!1} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project/ b978a93)"} ``` `clang-12 -fno-PIC -c test.c` `objdump test.o -r`: ``` test.o: file format elf64-x86-64 RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 0000000000000006 R_X86_64_64 A 0000000000000016 R_X86_64_64 B RELOCATION RECORDS FOR [.eh_frame]: OFFSET TYPE VALUE 0000000000000020 R_X86_64_PC32 .text 0000000000000040 R_X86_64_PC32 .text+0x0000000000000010 ``` ## Comparison to pre-LLVM 12 output `rustc --emit=obj,llvm-ir --target=x86_64-unknown-none-linuxkernel --crate-type rlib test.rs` ```Rust #![feature(no_core, lang_items)] #![no_core] #[lang="sized"] trait Sized {} #[lang="sync"] trait Sync {} #[lang = "drop_in_place"] pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {} impl Sync for i32 {} pub static STATIC: i32 = 32; extern { pub static EXT_STATIC: i32; } pub fn a() -> &'static i32 { &STATIC } pub fn b() -> &'static i32 { unsafe {&EXT_STATIC} } ``` `objdump test.o -r` nightly-2021-02-20 (rustc target is `x86_64-linux-kernel`): ``` RELOCATION RECORDS FOR [.text._ZN4test1a17h1024ba65f3424175E]: OFFSET TYPE VALUE 0000000000000007 R_X86_64_32S _ZN4test6STATIC17h3adc41a83746c9ffE RELOCATION RECORDS FOR [.text._ZN4test1b17h86a6a80c1190ac8dE]: OFFSET TYPE VALUE 0000000000000007 R_X86_64_32S EXT_STATIC ``` nightly-2021-05-10: ``` RELOCATION RECORDS FOR [.text._ZN4test1a17he846f03bf37b2d20E]: OFFSET TYPE VALUE 0000000000000007 R_X86_64_GOTPCREL _ZN4test6STATIC17h5a059515bf3d4968E-0x0000000000000004 RELOCATION RECORDS FOR [.text._ZN4test1b17h7e0f7f80fbd91125E]: OFFSET TYPE VALUE 0000000000000007 R_X86_64_GOTPCREL EXT_STATIC-0x0000000000000004 ``` This PR: ``` RELOCATION RECORDS FOR [.text._ZN4test1a17he846f03bf37b2d20E]: OFFSET TYPE VALUE 0000000000000007 R_X86_64_32S _ZN4test6STATIC17h5a059515bf3d4968E RELOCATION RECORDS FOR [.text._ZN4test1b17h7e0f7f80fbd91125E]: OFFSET TYPE VALUE 0000000000000007 R_X86_64_32S EXT_STATIC ```
2 parents 9f8012e + f7ed4a7 commit be8450e

File tree

4 files changed

+76
-5
lines changed

4 files changed

+76
-5
lines changed

compiler/rustc_codegen_llvm/src/base.rs

+24
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,27 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
218218
Visibility::Protected => llvm::Visibility::Protected,
219219
}
220220
}
221+
222+
pub fn linkage_from_llvm(linkage: llvm::Linkage) -> Linkage {
223+
match linkage {
224+
llvm::Linkage::ExternalLinkage => Linkage::External,
225+
llvm::Linkage::AvailableExternallyLinkage => Linkage::AvailableExternally,
226+
llvm::Linkage::LinkOnceAnyLinkage => Linkage::LinkOnceAny,
227+
llvm::Linkage::LinkOnceODRLinkage => Linkage::LinkOnceODR,
228+
llvm::Linkage::WeakAnyLinkage => Linkage::WeakAny,
229+
llvm::Linkage::WeakODRLinkage => Linkage::WeakODR,
230+
llvm::Linkage::AppendingLinkage => Linkage::Appending,
231+
llvm::Linkage::InternalLinkage => Linkage::Internal,
232+
llvm::Linkage::PrivateLinkage => Linkage::Private,
233+
llvm::Linkage::ExternalWeakLinkage => Linkage::ExternalWeak,
234+
llvm::Linkage::CommonLinkage => Linkage::Common,
235+
}
236+
}
237+
238+
pub fn visibility_from_llvm(linkage: llvm::Visibility) -> Visibility {
239+
match linkage {
240+
llvm::Visibility::Default => Visibility::Default,
241+
llvm::Visibility::Hidden => Visibility::Hidden,
242+
llvm::Visibility::Protected => Visibility::Protected,
243+
}
244+
}

compiler/rustc_codegen_llvm/src/consts.rs

+13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_middle::mir::mono::MonoItem;
1717
use rustc_middle::ty::{self, Instance, Ty};
1818
use rustc_middle::{bug, span_bug};
1919
use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size};
20+
use rustc_target::spec::RelocModel;
2021
use tracing::debug;
2122

2223
pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value {
@@ -282,6 +283,12 @@ impl CodegenCx<'ll, 'tcx> {
282283
}
283284
}
284285

286+
if self.tcx.sess.relocation_model() == RelocModel::Static {
287+
unsafe {
288+
llvm::LLVMRustSetDSOLocal(g, true);
289+
}
290+
}
291+
285292
self.instances.borrow_mut().insert(instance, g);
286293
g
287294
}
@@ -363,6 +370,12 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
363370
set_global_alignment(&self, g, self.align_of(ty));
364371
llvm::LLVMSetInitializer(g, v);
365372

373+
let linkage = base::linkage_from_llvm(llvm::LLVMRustGetLinkage(g));
374+
let visibility = base::visibility_from_llvm(llvm::LLVMRustGetVisibility(g));
375+
if self.should_assume_dso_local(linkage, visibility) {
376+
llvm::LLVMRustSetDSOLocal(g, true);
377+
}
378+
366379
// As an optimization, all shared statics which do not have interior
367380
// mutability are placed into read-only memory.
368381
if !is_mutable && self.type_is_freeze(ty) {

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub enum CallConv {
5454
}
5555

5656
/// LLVMRustLinkage
57-
#[derive(PartialEq)]
57+
#[derive(Copy, Clone, PartialEq)]
5858
#[repr(C)]
5959
pub enum Linkage {
6060
ExternalLinkage = 0,
@@ -72,6 +72,7 @@ pub enum Linkage {
7272

7373
// LLVMRustVisibility
7474
#[repr(C)]
75+
#[derive(Copy, Clone)]
7576
pub enum Visibility {
7677
Default = 0,
7778
Hidden = 1,

src/test/assembly/static-relocation-model.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// min-llvm-version: 12.0.0
22
// needs-llvm-components: aarch64 x86
3-
// revisions:X64 A64
3+
// revisions:x64 A64
44
// assembly-output: emit-asm
5-
// [X64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static
5+
// [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static
66
// [A64] compile-flags: --target aarch64-unknown-linux-gnu -Crelocation-model=static
77

88
#![feature(no_core, lang_items)]
@@ -15,14 +15,26 @@ trait Sized {}
1515
#[lang="copy"]
1616
trait Copy {}
1717

18+
#[lang="sync"]
19+
trait Sync {}
20+
21+
#[lang = "drop_in_place"]
22+
fn drop_in_place<T>(_: *mut T) {}
23+
1824
impl Copy for u8 {}
25+
impl Sync for u8 {}
26+
27+
#[no_mangle]
28+
pub static PIERIS: u8 = 42;
1929

2030
extern "C" {
31+
static EXOCHORDA: *mut u8;
32+
2133
fn chaenomeles();
2234
}
2335

2436
// CHECK-LABEL: banana:
25-
// x64: movb chaenomeles, %{{[a,z]+}}
37+
// x64: movb chaenomeles{{(\(%[a-z0-9]+\))?}}, %{{[a-z0-9]+}}
2638
// A64: adrp [[REG:[a-z0-9]+]], chaenomeles
2739
// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG]], :lo12:chaenomeles]
2840
#[no_mangle]
@@ -33,7 +45,7 @@ pub fn banana() -> u8 {
3345
}
3446

3547
// CHECK-LABEL: peach:
36-
// x64: movb banana, %{{[a,z]+}}
48+
// x64: movb banana{{(\(%[a-z0-9]+\))?}}, %{{[a-z0-9]+}}
3749
// A64: adrp [[REG2:[a-z0-9]+]], banana
3850
// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:banana]
3951
#[no_mangle]
@@ -42,3 +54,24 @@ pub fn peach() -> u8 {
4254
*(banana as *mut u8)
4355
}
4456
}
57+
58+
// CHECK-LABEL: mango:
59+
// x64: movq EXOCHORDA{{(\(%[a-z0-9]+\))?}}, %[[REG:[a-z0-9]+]]
60+
// x64-NEXT: movb (%[[REG]]), %{{[a-z0-9]+}}
61+
// A64: adrp [[REG2:[a-z0-9]+]], EXOCHORDA
62+
// A64-NEXT: ldr {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:EXOCHORDA]
63+
#[no_mangle]
64+
pub fn mango() -> u8 {
65+
unsafe {
66+
*EXOCHORDA
67+
}
68+
}
69+
70+
// CHECK-LABEL: orange:
71+
// x64: mov{{l|absq}} $PIERIS, %{{[a-z0-9]+}}
72+
// A64: adrp [[REG2:[a-z0-9]+]], PIERIS
73+
// A64-NEXT: add {{[a-z0-9]+}}, [[REG2]], :lo12:PIERIS
74+
#[no_mangle]
75+
pub fn orange() -> &'static u8 {
76+
&PIERIS
77+
}

0 commit comments

Comments
 (0)