Skip to content

Commit df06e73

Browse files
committed
[WIP] Weak aliases for the global allocator on ELF
1 parent 7b3150e commit df06e73

File tree

18 files changed

+100
-66
lines changed

18 files changed

+100
-66
lines changed

compiler/rustc_codegen_cranelift/src/driver/aot.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ fn codegen_cgu_content(
557557
);
558558
codegened_functions.push(codegened_function);
559559
}
560+
MonoItem::WeakAlias(_, _) => todo!(),
560561
MonoItem::Static(def_id) => {
561562
let data_id = crate::constant::codegen_static(tcx, module, def_id);
562563
if let Some(debug_context) = &mut cx.debug_context {

compiler/rustc_codegen_cranelift/src/driver/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn predefine_mono_items<'tcx>(
4949
)
5050
.unwrap();
5151
}
52-
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {}
52+
MonoItem::WeakAlias(_, _) | MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {}
5353
}
5454
}
5555
});

compiler/rustc_codegen_llvm/src/allocator.rs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,6 @@ pub(crate) unsafe fn codegen(
3030
let i8 = cx.type_i8();
3131
let i8p = cx.type_ptr();
3232

33-
if kind == AllocatorKind::Default {
34-
for method in ALLOCATOR_METHODS {
35-
let mut args = Vec::with_capacity(method.inputs.len());
36-
for input in method.inputs.iter() {
37-
match input.ty {
38-
AllocatorTy::Layout => {
39-
args.push(usize); // size
40-
args.push(usize); // align
41-
}
42-
AllocatorTy::Ptr => args.push(i8p),
43-
AllocatorTy::Usize => args.push(usize),
44-
45-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
46-
}
47-
}
48-
let output = match method.output {
49-
AllocatorTy::ResultPtr => Some(i8p),
50-
AllocatorTy::Unit => None,
51-
52-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
53-
panic!("invalid allocator output")
54-
}
55-
};
56-
57-
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
58-
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
59-
60-
create_wrapper_function(tcx, &cx, &from_name, &to_name, &args, output, false);
61-
}
62-
}
63-
6433
// rust alloc error handler
6534
create_wrapper_function(
6635
tcx,

compiler/rustc_codegen_llvm/src/base.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,11 @@ pub(crate) fn compile_codegen_unit(
118118
if !cx.used_statics.is_empty() {
119119
cx.create_used_variable_impl(c"llvm.used", &cx.used_statics);
120120
}
121-
if !cx.compiler_used_statics.is_empty() {
122-
cx.create_used_variable_impl(c"llvm.compiler.used", &cx.compiler_used_statics);
121+
if !cx.compiler_used_statics.borrow().is_empty() {
122+
cx.create_used_variable_impl(
123+
c"llvm.compiler.used",
124+
&*cx.compiler_used_statics.borrow(),
125+
);
123126
}
124127

125128
// Run replace-all-uses-with for statics that need it. This must

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::borrow::{Borrow, Cow};
2+
use std::ffi::CString;
23
use std::ops::Deref;
34
use std::{iter, ptr};
45

56
pub(crate) mod autodiff;
67

78
use libc::{c_char, c_uint, size_t};
8-
use rustc_abi as abi;
9-
use rustc_abi::{Align, Size, WrappingRange};
9+
use rustc_abi::{self as abi, AddressSpace, Align, Size, WrappingRange};
1010
use rustc_codegen_ssa::MemFlags;
1111
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind};
1212
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,8 @@ impl<'ll> CodegenCx<'ll, '_> {
549549

550550
/// Add a global value to a list to be stored in the `llvm.compiler.used` variable,
551551
/// an array of ptr.
552-
pub(crate) fn add_compiler_used_global(&mut self, global: &'ll Value) {
553-
self.compiler_used_statics.push(global);
552+
pub(crate) fn add_compiler_used_global(&self, global: &'ll Value) {
553+
self.compiler_used_statics.borrow_mut().push(global);
554554
}
555555
}
556556

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub(crate) struct FullCx<'ll, 'tcx> {
121121

122122
/// Statics that will be placed in the llvm.compiler.used variable
123123
/// See <https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable> for details
124-
pub compiler_used_statics: Vec<&'ll Value>,
124+
pub compiler_used_statics: RefCell<Vec<&'ll Value>>,
125125

126126
/// Mapping of non-scalar types to llvm types.
127127
pub type_lowering: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), &'ll Type>>,
@@ -615,7 +615,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
615615
const_globals: Default::default(),
616616
statics_to_rauw: RefCell::new(Vec::new()),
617617
used_statics: Vec::new(),
618-
compiler_used_statics: Vec::new(),
618+
compiler_used_statics: RefCell::new(Vec::new()),
619619
type_lowering: Default::default(),
620620
scalar_lltypes: Default::default(),
621621
coverage_cx,

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
110110
.flat_map(|cgu| cgu.items().keys())
111111
.filter_map(|item| match item {
112112
mir::mono::MonoItem::Fn(instance) => Some(instance),
113-
mir::mono::MonoItem::Static(_) | mir::mono::MonoItem::GlobalAsm(_) => None,
113+
mir::mono::MonoItem::WeakAlias(_, _)
114+
| mir::mono::MonoItem::Static(_)
115+
| mir::mono::MonoItem::GlobalAsm(_) => None,
114116
})
115117
// We only need one arbitrary instance per definition.
116118
.filter(move |instance| def_ids_seen.insert(instance.def_id()))

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,11 +2671,11 @@ unsafe extern "C" {
26712671
pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value);
26722672
pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
26732673

2674-
pub(crate) fn LLVMAddAlias2(
2675-
M: &Module,
2674+
pub(crate) fn LLVMAddAlias2<'ll>(
2675+
M: &'ll Module,
26762676
ValueTy: &Type,
26772677
AddressSpace: c_uint,
26782678
Aliasee: &Value,
26792679
Name: *const c_char,
2680-
);
2680+
) -> &'ll Value;
26812681
}

compiler/rustc_codegen_llvm/src/llvm/mod.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -351,17 +351,14 @@ impl Intrinsic {
351351
}
352352

353353
/// Safe wrapper for `LLVMAddAlias2`
354-
pub(crate) fn add_alias(
355-
module: &Module,
354+
pub(crate) fn add_alias<'ll>(
355+
module: &'ll Module,
356356
ty: &Type,
357357
address_space: AddressSpace,
358358
aliasee: &Value,
359-
name: &[u8],
360-
) {
361-
unsafe {
362-
let data = name.as_c_char_ptr();
363-
LLVMAddAlias2(value, data, address_space, aliasee, name.len());
364-
}
359+
name: &CStr,
360+
) -> &'ll Value {
361+
unsafe { LLVMAddAlias2(module, ty, address_space.0, aliasee, name.as_ptr()) }
365362
}
366363

367364
/// Safe wrapper for `LLVMSetValueName2` from a byte slice

compiler/rustc_codegen_llvm/src/mono_item.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use std::ffi::CString;
2+
3+
use rustc_abi::AddressSpace;
14
use rustc_codegen_ssa::traits::*;
25
use rustc_hir::def::DefKind;
36
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@@ -6,6 +9,7 @@ use rustc_middle::mir::mono::{Linkage, Visibility};
69
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf};
710
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
811
use rustc_session::config::CrateType;
12+
use rustc_symbol_mangling::mangle_internal_symbol;
913
use rustc_target::spec::RelocModel;
1014
use tracing::debug;
1115

@@ -77,8 +81,36 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
7781

7882
self.assume_dso_local(lldecl, false);
7983

84+
let symbol_name = self.tcx.symbol_name(instance);
85+
if symbol_name.name.contains("__rdl_alloc") {
86+
self.weak_alias(lldecl, &mangle_internal_symbol(self.tcx, "__rust_alloc"));
87+
}
88+
if symbol_name.name.contains("__rdl_dealloc") {
89+
self.weak_alias(lldecl, &mangle_internal_symbol(self.tcx, "__rust_dealloc"));
90+
}
91+
if symbol_name.name.contains("__rdl_realloc") {
92+
self.weak_alias(lldecl, &mangle_internal_symbol(self.tcx, "__rust_realloc"));
93+
}
94+
if symbol_name.name.contains("__rdl_alloc_zeroed") {
95+
self.weak_alias(lldecl, &mangle_internal_symbol(self.tcx, "__rust_alloc_zeroed"));
96+
}
97+
8098
self.instances.borrow_mut().insert(instance, lldecl);
8199
}
100+
101+
fn weak_alias(&self, aliasee: Self::Function, name: &str) {
102+
let ty = self.get_type_of_global(aliasee);
103+
let alias = llvm::add_alias(
104+
self.llmod,
105+
ty,
106+
AddressSpace::DATA,
107+
aliasee,
108+
&CString::new(name).unwrap(),
109+
);
110+
111+
llvm::set_linkage(alias, llvm::Linkage::WeakAnyLinkage);
112+
self.add_compiler_used_global(alias);
113+
}
82114
}
83115

84116
impl CodegenCx<'_, '_> {

compiler/rustc_codegen_ssa/src/mir/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_middle::mir::{Body, Local, UnwindTerminateReason, traversal};
77
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, TyAndLayout};
88
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
99
use rustc_middle::{bug, mir, span_bug};
10+
use rustc_symbol_mangling::mangle_internal_symbol;
1011
use rustc_target::callconv::{FnAbi, PassMode};
1112
use tracing::{debug, instrument};
1213

compiler/rustc_codegen_ssa/src/mono_item.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
4040
MonoItem::GlobalAsm(item_id) => {
4141
base::codegen_global_asm(cx, item_id);
4242
}
43+
MonoItem::WeakAlias(def_id, target) => {
44+
todo!()
45+
}
4346
MonoItem::Fn(instance) => {
4447
if cx
4548
.tcx()
@@ -83,6 +86,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
8386
cx.predefine_fn(instance, linkage, visibility, symbol_name);
8487
};
8588
}
89+
MonoItem::WeakAlias(..) => {}
8690
MonoItem::GlobalAsm(..) => {}
8791
}
8892

@@ -95,6 +99,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
9599
format!("Fn({:?}, {})", instance.def, instance.args.as_ptr().addr())
96100
}
97101
MonoItem::Static(id) => format!("Static({id:?})"),
102+
MonoItem::WeakAlias(def_id, target) => format!("WeakAlias({def_id:?}, {target:?})"),
98103
MonoItem::GlobalAsm(id) => format!("GlobalAsm({id:?})"),
99104
}
100105
}

compiler/rustc_codegen_ssa/src/traits/declare.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use rustc_hir::def_id::DefId;
22
use rustc_middle::mir::mono::{Linkage, Visibility};
33
use rustc_middle::ty::Instance;
44

5-
pub trait PreDefineCodegenMethods<'tcx> {
5+
use crate::traits::BackendTypes;
6+
7+
pub trait PreDefineCodegenMethods<'tcx>: BackendTypes {
68
fn predefine_static(
79
&mut self,
810
def_id: DefId,
@@ -17,4 +19,6 @@ pub trait PreDefineCodegenMethods<'tcx> {
1719
visibility: Visibility,
1820
symbol_name: &str,
1921
);
22+
23+
fn weak_alias(&self, aliasee: Self::Function, name: &str);
2024
}

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub enum InstantiationMode {
5353
pub enum MonoItem<'tcx> {
5454
Fn(Instance<'tcx>),
5555
Static(DefId),
56+
WeakAlias(DefId, Instance<'tcx>),
5657
GlobalAsm(ItemId),
5758
}
5859

@@ -94,7 +95,7 @@ impl<'tcx> MonoItem<'tcx> {
9495
pub fn is_user_defined(&self) -> bool {
9596
match *self {
9697
MonoItem::Fn(instance) => matches!(instance.def, InstanceKind::Item(..)),
97-
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => true,
98+
MonoItem::WeakAlias(_, _) | MonoItem::Static(..) | MonoItem::GlobalAsm(..) => true,
9899
}
99100
}
100101

@@ -105,21 +106,23 @@ impl<'tcx> MonoItem<'tcx> {
105106
MonoItem::Fn(instance) => tcx.size_estimate(instance),
106107
// Conservatively estimate the size of a static declaration or
107108
// assembly item to be 1.
108-
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
109+
MonoItem::WeakAlias(_, _) | MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
109110
}
110111
}
111112

112113
pub fn is_generic_fn(&self) -> bool {
113114
match self {
114115
MonoItem::Fn(instance) => instance.args.non_erasable_generics().next().is_some(),
115-
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false,
116+
MonoItem::WeakAlias(_, _) | MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false,
116117
}
117118
}
118119

119120
pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> SymbolName<'tcx> {
120121
match *self {
121122
MonoItem::Fn(instance) => tcx.symbol_name(instance),
122-
MonoItem::Static(def_id) => tcx.symbol_name(Instance::mono(tcx, def_id)),
123+
MonoItem::Static(def_id) | MonoItem::WeakAlias(def_id, _) => {
124+
tcx.symbol_name(Instance::mono(tcx, def_id))
125+
}
123126
MonoItem::GlobalAsm(item_id) => {
124127
SymbolName::new(tcx, &format!("global_asm_{:?}", item_id.owner_id))
125128
}
@@ -137,7 +140,7 @@ impl<'tcx> MonoItem<'tcx> {
137140
// Statics and global_asm! must be instantiated exactly once.
138141
let instance = match *self {
139142
MonoItem::Fn(instance) => instance,
140-
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
143+
MonoItem::WeakAlias(_, _) | MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
141144
return InstantiationMode::GloballyShared { may_conflict: false };
142145
}
143146
};
@@ -236,7 +239,7 @@ impl<'tcx> MonoItem<'tcx> {
236239
pub fn explicit_linkage(&self, tcx: TyCtxt<'tcx>) -> Option<Linkage> {
237240
let def_id = match *self {
238241
MonoItem::Fn(ref instance) => instance.def_id(),
239-
MonoItem::Static(def_id) => def_id,
242+
MonoItem::WeakAlias(def_id, _) | MonoItem::Static(def_id) => def_id,
240243
MonoItem::GlobalAsm(..) => return None,
241244
};
242245

@@ -273,7 +276,9 @@ impl<'tcx> MonoItem<'tcx> {
273276
debug!("is_instantiable({:?})", self);
274277
let (def_id, args) = match *self {
275278
MonoItem::Fn(ref instance) => (instance.def_id(), instance.args),
276-
MonoItem::Static(def_id) => (def_id, GenericArgs::empty()),
279+
MonoItem::WeakAlias(def_id, _) | MonoItem::Static(def_id) => {
280+
(def_id, GenericArgs::empty())
281+
}
277282
// global asm never has predicates
278283
MonoItem::GlobalAsm(..) => return true,
279284
};
@@ -284,7 +289,7 @@ impl<'tcx> MonoItem<'tcx> {
284289
pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> {
285290
match *self {
286291
MonoItem::Fn(Instance { def, .. }) => def.def_id().as_local(),
287-
MonoItem::Static(def_id) => def_id.as_local(),
292+
MonoItem::WeakAlias(def_id, _) | MonoItem::Static(def_id) => def_id.as_local(),
288293
MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id),
289294
}
290295
.map(|def_id| tcx.def_span(def_id))
@@ -299,7 +304,7 @@ impl<'tcx> MonoItem<'tcx> {
299304
pub fn krate(&self) -> CrateNum {
300305
match self {
301306
MonoItem::Fn(instance) => instance.def_id().krate,
302-
MonoItem::Static(def_id) => def_id.krate,
307+
MonoItem::WeakAlias(def_id, _) | MonoItem::Static(def_id) => def_id.krate,
303308
MonoItem::GlobalAsm(..) => LOCAL_CRATE,
304309
}
305310
}
@@ -308,7 +313,7 @@ impl<'tcx> MonoItem<'tcx> {
308313
pub fn def_id(&self) -> DefId {
309314
match *self {
310315
MonoItem::Fn(Instance { def, .. }) => def.def_id(),
311-
MonoItem::Static(def_id) => def_id,
316+
MonoItem::WeakAlias(def_id, _) | MonoItem::Static(def_id) => def_id,
312317
MonoItem::GlobalAsm(item_id) => item_id.owner_id.to_def_id(),
313318
}
314319
}
@@ -321,6 +326,13 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> {
321326
MonoItem::Static(def_id) => {
322327
write!(f, "static {}", Instance::new_raw(def_id, GenericArgs::empty()))
323328
}
329+
MonoItem::WeakAlias(def_id, target) => {
330+
write!(
331+
f,
332+
"weak alias {} => {target}",
333+
Instance::new_raw(def_id, GenericArgs::empty())
334+
)
335+
}
324336
MonoItem::GlobalAsm(..) => write!(f, "global_asm"),
325337
}
326338
}
@@ -559,7 +571,9 @@ impl<'tcx> CodegenUnit<'tcx> {
559571
| InstanceKind::AsyncDropGlueCtorShim(..) => None,
560572
}
561573
}
562-
MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),
574+
MonoItem::WeakAlias(def_id, _) | MonoItem::Static(def_id) => {
575+
def_id.as_local().map(Idx::index)
576+
}
563577
MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.index()),
564578
},
565579
item.symbol_name(tcx),

0 commit comments

Comments
 (0)