Skip to content

Commit 850f0cb

Browse files
Auto merge of #142366 - bjorn3:aliases, r=<try>
[WIP] Use weak aliases for the allocator shim try-job: x86_64-msvc-1 try-job: x86_64-msvc-2
2 parents fe5c95d + 8290684 commit 850f0cb

File tree

23 files changed

+262
-121
lines changed

23 files changed

+262
-121
lines changed

compiler/rustc_codegen_cranelift/src/driver/aot.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ fn codegen_cgu_content(
563563
);
564564
codegened_functions.push(codegened_function);
565565
}
566+
MonoItem::WeakAlias(_, _) => todo!(),
566567
MonoItem::Static(def_id) => {
567568
let data_id = crate::constant::codegen_static(tcx, module, def_id);
568569
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: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use libc::c_uint;
22
use rustc_ast::expand::allocator::{
3-
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
4-
alloc_error_handler_name, default_fn_name, global_fn_name,
3+
AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name,
54
};
65
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
76
use rustc_middle::bug;
@@ -18,7 +17,6 @@ pub(crate) unsafe fn codegen(
1817
tcx: TyCtxt<'_>,
1918
cx: SimpleCx<'_>,
2019
module_name: &str,
21-
kind: AllocatorKind,
2220
alloc_error_handler_kind: AllocatorKind,
2321
) {
2422
let usize = match tcx.sess.target.pointer_width {
@@ -28,38 +26,6 @@ pub(crate) unsafe fn codegen(
2826
tws => bug!("Unsupported target word size for int: {}", tws),
2927
};
3028
let i8 = cx.type_i8();
31-
let i8p = cx.type_ptr();
32-
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-
}
6329

6430
// rust alloc error handler
6531
create_wrapper_function(

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: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use std::{iter, ptr};
55
pub(crate) mod autodiff;
66

77
use libc::{c_char, c_uint, size_t};
8-
use rustc_abi as abi;
9-
use rustc_abi::{Align, Size, WrappingRange};
8+
use rustc_abi::{self as abi, Align, Size, WrappingRange};
109
use rustc_codegen_ssa::MemFlags;
1110
use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind};
1211
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>>,
@@ -614,7 +614,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
614614
const_globals: Default::default(),
615615
statics_to_rauw: RefCell::new(Vec::new()),
616616
used_statics: Vec::new(),
617-
compiler_used_statics: Vec::new(),
617+
compiler_used_statics: RefCell::new(Vec::new()),
618618
type_lowering: Default::default(),
619619
scalar_lltypes: Default::default(),
620620
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/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,14 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
108108
&self,
109109
tcx: TyCtxt<'tcx>,
110110
module_name: &str,
111-
kind: AllocatorKind,
111+
_kind: AllocatorKind,
112112
alloc_error_handler_kind: AllocatorKind,
113113
) -> ModuleLlvm {
114114
let module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
115115
let cx =
116116
SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size);
117117
unsafe {
118-
allocator::codegen(tcx, cx, module_name, kind, alloc_error_handler_kind);
118+
allocator::codegen(tcx, cx, module_name, alloc_error_handler_kind);
119119
}
120120
module_llvm
121121
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,8 @@ unsafe extern "C" {
20832083
ValueLen: size_t,
20842084
);
20852085

2086+
pub(crate) fn LLVMRustAddLinkerOptions(M: &Module, Value: *const c_char, ValueLen: size_t);
2087+
20862088
pub(crate) fn LLVMRustDIBuilderCreateCompileUnit<'a>(
20872089
Builder: &DIBuilder<'a>,
20882090
Lang: c_uint,
@@ -2662,4 +2664,12 @@ unsafe extern "C" {
26622664

26632665
pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value);
26642666
pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
2667+
2668+
pub(crate) fn LLVMAddAlias2<'ll>(
2669+
M: &'ll Module,
2670+
ValueTy: &Type,
2671+
AddressSpace: c_uint,
2672+
Aliasee: &Value,
2673+
Name: *const c_char,
2674+
) -> &'ll Value;
26652675
}

compiler/rustc_codegen_llvm/src/llvm/mod.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::str::FromStr;
66
use std::string::FromUtf8Error;
77

88
use libc::c_uint;
9-
use rustc_abi::{Align, Size, WrappingRange};
9+
use rustc_abi::{AddressSpace, Align, Size, WrappingRange};
1010
use rustc_llvm::RustString;
1111

1212
pub(crate) use self::CallConv::*;
@@ -327,6 +327,17 @@ pub(crate) fn get_value_name(value: &Value) -> &[u8] {
327327
}
328328
}
329329

330+
/// Safe wrapper for `LLVMAddAlias2`
331+
pub(crate) fn add_alias<'ll>(
332+
module: &'ll Module,
333+
ty: &Type,
334+
address_space: AddressSpace,
335+
aliasee: &Value,
336+
name: &CStr,
337+
) -> &'ll Value {
338+
unsafe { LLVMAddAlias2(module, ty, address_space.0, aliasee, name.as_ptr()) }
339+
}
340+
330341
/// Safe wrapper for `LLVMSetValueName2` from a byte slice
331342
pub(crate) fn set_value_name(value: &Value, name: &[u8]) {
332343
unsafe {
@@ -430,6 +441,12 @@ pub(crate) fn add_module_flag_str(
430441
}
431442
}
432443

444+
pub(crate) fn add_module_linker_option(module: &Module, value: &str) {
445+
unsafe {
446+
LLVMRustAddLinkerOptions(module, value.as_c_char_ptr(), value.len());
447+
}
448+
}
449+
433450
pub(crate) fn set_dllimport_storage_class<'ll>(v: &'ll Value) {
434451
unsafe {
435452
LLVMSetDLLStorageClass(v, DLLStorageClass::DllImport);

compiler/rustc_codegen_llvm/src/mono_item.rs

Lines changed: 55 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,59 @@ 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(
87+
lldecl,
88+
symbol_name.name,
89+
&mangle_internal_symbol(self.tcx, "__rust_alloc"),
90+
);
91+
}
92+
if symbol_name.name.contains("__rdl_dealloc") {
93+
self.weak_alias(
94+
lldecl,
95+
symbol_name.name,
96+
&mangle_internal_symbol(self.tcx, "__rust_dealloc"),
97+
);
98+
}
99+
if symbol_name.name.contains("__rdl_realloc") {
100+
self.weak_alias(
101+
lldecl,
102+
symbol_name.name,
103+
&mangle_internal_symbol(self.tcx, "__rust_realloc"),
104+
);
105+
}
106+
if symbol_name.name.contains("__rdl_alloc_zeroed") {
107+
self.weak_alias(
108+
lldecl,
109+
symbol_name.name,
110+
&mangle_internal_symbol(self.tcx, "__rust_alloc_zeroed"),
111+
);
112+
}
113+
80114
self.instances.borrow_mut().insert(instance, lldecl);
81115
}
116+
117+
fn weak_alias(&self, aliasee: Self::Function, aliasee_name: &str, name: &str) {
118+
if self.tcx.sess.target.is_like_msvc {
119+
llvm::add_module_linker_option(
120+
self.llmod,
121+
&format!("/alternatename:{name}={aliasee_name}"),
122+
);
123+
} else {
124+
let ty = self.get_type_of_global(aliasee);
125+
let alias = llvm::add_alias(
126+
self.llmod,
127+
ty,
128+
AddressSpace::DATA,
129+
aliasee,
130+
&CString::new(name).unwrap(),
131+
);
132+
133+
llvm::set_linkage(alias, llvm::Linkage::WeakAnyLinkage);
134+
self.add_compiler_used_global(alias);
135+
}
136+
}
82137
}
83138

84139
impl CodegenCx<'_, '_> {

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,9 +1973,10 @@ fn add_linked_symbol_object(
19731973
cmd: &mut dyn Linker,
19741974
sess: &Session,
19751975
tmpdir: &Path,
1976-
symbols: &[(String, SymbolExportKind)],
1976+
linked_symbols: &[(String, SymbolExportKind)],
1977+
exported_symbols: &[(String, SymbolExportKind)],
19771978
) {
1978-
if symbols.is_empty() {
1979+
if linked_symbols.is_empty() {
19791980
return;
19801981
}
19811982

@@ -2012,7 +2013,7 @@ fn add_linked_symbol_object(
20122013
None
20132014
};
20142015

2015-
for (sym, kind) in symbols.iter() {
2016+
for (sym, kind) in linked_symbols.iter() {
20162017
let symbol = file.add_symbol(object::write::Symbol {
20172018
name: sym.clone().into(),
20182019
value: 0,
@@ -2070,6 +2071,23 @@ fn add_linked_symbol_object(
20702071
}
20712072
}
20722073

2074+
if sess.target.is_like_msvc {
2075+
let drectve = exported_symbols
2076+
.into_iter()
2077+
.map(|(sym, kind)| {
2078+
if *kind == SymbolExportKind::Text {
2079+
format!(" /EXPORT:\"{sym}\"")
2080+
} else {
2081+
format!(" /EXPORT:\"{sym}\",DATA")
2082+
}
2083+
})
2084+
.collect::<Vec<_>>()
2085+
.join("");
2086+
2087+
let section = file.add_section(vec![], b".drectve".to_vec(), object::SectionKind::Linker);
2088+
file.append_section_data(section, drectve.as_bytes(), 1);
2089+
}
2090+
20732091
let path = tmpdir.join("symbols.o");
20742092
let result = std::fs::write(&path, file.write().unwrap());
20752093
if let Err(error) = result {
@@ -2236,6 +2254,7 @@ fn linker_with_args(
22362254
sess,
22372255
tmpdir,
22382256
&codegen_results.crate_info.linked_symbols[&crate_type],
2257+
&codegen_results.crate_info.exported_symbols[&crate_type],
22392258
);
22402259

22412260
// Sanitizer libraries.

0 commit comments

Comments
 (0)