Skip to content

Commit 1548de1

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 55d4364 + d4526ac commit 1548de1

File tree

10 files changed

+122
-75
lines changed

10 files changed

+122
-75
lines changed

compiler/rustc_codegen_gcc/src/mono_item.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,6 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
7676
self.functions.borrow_mut().insert(symbol_name.to_string(), decl);
7777
self.function_instances.borrow_mut().insert(instance, decl);
7878
}
79+
80+
fn weak_alias(&self, _aliasee: Self::Function, _aliasee_name: &str, _name: &str) {}
7981
}

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/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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,4 +2670,12 @@ unsafe extern "C" {
26702670

26712671
pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value);
26722672
pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
2673+
2674+
pub(crate) fn LLVMAddAlias2<'ll>(
2675+
M: &'ll Module,
2676+
ValueTy: &Type,
2677+
AddressSpace: c_uint,
2678+
Aliasee: &Value,
2679+
Name: *const c_char,
2680+
) -> &'ll Value;
26732681
}

compiler/rustc_codegen_llvm/src/llvm/mod.rs

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

99
use libc::c_uint;
10-
use rustc_abi::{Align, Size, WrappingRange};
10+
use rustc_abi::{AddressSpace, Align, Size, WrappingRange};
1111
use rustc_llvm::RustString;
1212

1313
pub(crate) use self::CallConv::*;
@@ -350,6 +350,17 @@ impl Intrinsic {
350350
}
351351
}
352352

353+
/// Safe wrapper for `LLVMAddAlias2`
354+
pub(crate) fn add_alias<'ll>(
355+
module: &'ll Module,
356+
ty: &Type,
357+
address_space: AddressSpace,
358+
aliasee: &Value,
359+
name: &CStr,
360+
) -> &'ll Value {
361+
unsafe { LLVMAddAlias2(module, ty, address_space.0, aliasee, name.as_ptr()) }
362+
}
363+
353364
/// Safe wrapper for `LLVMSetValueName2` from a byte slice
354365
pub(crate) fn set_value_name(value: &Value, name: &[u8]) {
355366
unsafe {

compiler/rustc_codegen_llvm/src/mono_item.rs

Lines changed: 47 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,51 @@ 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+
let ty = self.get_type_of_global(aliasee);
119+
let alias = llvm::add_alias(
120+
self.llmod,
121+
ty,
122+
AddressSpace::DATA,
123+
aliasee,
124+
&CString::new(name).unwrap(),
125+
);
126+
127+
llvm::set_linkage(alias, llvm::Linkage::WeakAnyLinkage);
128+
}
82129
}
83130

84131
impl CodegenCx<'_, '_> {

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,9 +1976,11 @@ fn add_linked_symbol_object(
19761976
cmd: &mut dyn Linker,
19771977
sess: &Session,
19781978
tmpdir: &Path,
1979-
symbols: &[(String, SymbolExportKind)],
1979+
crate_type: CrateType,
1980+
linked_symbols: &[(String, SymbolExportKind)],
1981+
exported_symbols: &[String],
19801982
) {
1981-
if symbols.is_empty() {
1983+
if linked_symbols.is_empty() && exported_symbols.is_empty() {
19821984
return;
19831985
}
19841986

@@ -2015,7 +2017,7 @@ fn add_linked_symbol_object(
20152017
None
20162018
};
20172019

2018-
for (sym, kind) in symbols.iter() {
2020+
for (sym, kind) in linked_symbols.iter() {
20192021
let symbol = file.add_symbol(object::write::Symbol {
20202022
name: sym.clone().into(),
20212023
value: 0,
@@ -2073,6 +2075,38 @@ fn add_linked_symbol_object(
20732075
}
20742076
}
20752077

2078+
if sess.target.is_like_msvc {
2079+
// Symbol visibility takes care of this for executables typically
2080+
let should_filter_symbols = if crate_type == CrateType::Executable {
2081+
sess.opts.unstable_opts.export_executable_symbols
2082+
} else {
2083+
true
2084+
};
2085+
if should_filter_symbols {
2086+
// Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
2087+
// export symbols from a dynamic library. When building a dynamic library,
2088+
// however, we're going to want some symbols exported, so this adds a
2089+
// `.drectve` section which lists all the symbols using /EXPORT arguments.
2090+
//
2091+
// The linker will read these arguments from the `.drectve` section and
2092+
// export all the symbols from the dynamic library. Note that this is not
2093+
// as simple as just exporting all the symbols in the current crate (as
2094+
// specified by `codegen.reachable`) but rather we also need to possibly
2095+
// export the symbols of upstream crates. Upstream rlibs may be linked
2096+
// statically to this dynamic library, in which case they may continue to
2097+
// transitively be used and hence need their symbols exported.
2098+
let drectve = exported_symbols
2099+
.into_iter()
2100+
.map(|sym| format!(" /EXPORT:\"{sym}\""))
2101+
.collect::<Vec<_>>()
2102+
.join("");
2103+
2104+
let section =
2105+
file.add_section(vec![], b".drectve".to_vec(), object::SectionKind::Linker);
2106+
file.append_section_data(section, drectve.as_bytes(), 1);
2107+
}
2108+
}
2109+
20762110
let path = tmpdir.join("symbols.o");
20772111
let result = std::fs::write(&path, file.write().unwrap());
20782112
if let Err(error) = result {
@@ -2247,7 +2281,9 @@ fn linker_with_args(
22472281
cmd,
22482282
sess,
22492283
tmpdir,
2284+
crate_type,
22502285
&codegen_results.crate_info.linked_symbols[&crate_type],
2286+
&codegen_results.crate_info.exported_symbols[&crate_type],
22512287
);
22522288

22532289
// Sanitizer libraries.

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,19 +1086,10 @@ impl<'a> Linker for MsvcLinker<'a> {
10861086
}
10871087
}
10881088

1089-
// Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
1090-
// export symbols from a dynamic library. When building a dynamic library,
1091-
// however, we're going to want some symbols exported, so this function
1092-
// generates a DEF file which lists all the symbols.
1093-
//
1094-
// The linker will read this `*.def` file and export all the symbols from
1095-
// the dynamic library. Note that this is not as simple as just exporting
1096-
// all the symbols in the current crate (as specified by `codegen.reachable`)
1097-
// but rather we also need to possibly export the symbols of upstream
1098-
// crates. Upstream rlibs may be linked statically to this dynamic library,
1099-
// in which case they may continue to transitively be used and hence need
1100-
// their symbols exported.
1101-
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
1089+
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, _symbols: &[String]) {
1090+
// We already add /EXPORT arguments to the .drectve section of symbols.o. We generate
1091+
// a .DEF file here anyway as it might prevent auto-export of some symbols.
1092+
11021093
// Symbol visibility takes care of this typically
11031094
if crate_type == CrateType::Executable {
11041095
let should_export_executable_symbols =
@@ -1116,10 +1107,6 @@ impl<'a> Linker for MsvcLinker<'a> {
11161107
// straight to exports.
11171108
writeln!(f, "LIBRARY")?;
11181109
writeln!(f, "EXPORTS")?;
1119-
for symbol in symbols {
1120-
debug!(" _{symbol}");
1121-
writeln!(f, " {symbol}")?;
1122-
}
11231110
};
11241111
if let Err(error) = res {
11251112
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });

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, aliasee_name: &str, name: &str);
2024
}

library/alloc/src/alloc.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ unsafe extern "Rust" {
3131
#[rustc_std_internal_symbol]
3232
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
3333

34-
#[rustc_std_internal_symbol]
35-
static __rust_no_alloc_shim_is_unstable: u8;
3634
}
3735

3836
/// The global memory allocator.
@@ -85,13 +83,7 @@ pub struct Global;
8583
#[inline]
8684
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
8785
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
88-
unsafe {
89-
// Make sure we don't accidentally allow omitting the allocator shim in
90-
// stable code until it is actually stabilized.
91-
core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable);
92-
93-
__rust_alloc(layout.size(), layout.align())
94-
}
86+
unsafe { __rust_alloc(layout.size(), layout.align()) }
9587
}
9688

9789
/// Deallocates memory with the global allocator.
@@ -168,13 +160,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
168160
#[inline]
169161
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
170162
pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
171-
unsafe {
172-
// Make sure we don't accidentally allow omitting the allocator shim in
173-
// stable code until it is actually stabilized.
174-
core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable);
175-
176-
__rust_alloc_zeroed(layout.size(), layout.align())
177-
}
163+
unsafe { __rust_alloc_zeroed(layout.size(), layout.align()) }
178164
}
179165

180166
impl Global {

0 commit comments

Comments
 (0)