Skip to content

Commit b48a193

Browse files
committed
Use weak linkage for the alloc error handler too
1 parent 928767a commit b48a193

File tree

15 files changed

+29
-175
lines changed

15 files changed

+29
-175
lines changed

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// Adapted from rustc
33

44
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
5-
use rustc_ast::expand::allocator::{
6-
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE,
7-
};
5+
use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE;
86
use rustc_codegen_ssa::base::needs_allocator_shim;
97
use rustc_session::config::OomStrategy;
108
use rustc_symbol_mangling::mangle_internal_symbol;
@@ -14,48 +12,15 @@ use crate::prelude::*;
1412
/// Returns whether an allocator shim was created
1513
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
1614
if needs_allocator_shim(tcx) {
17-
codegen_inner(
18-
tcx,
19-
module,
20-
tcx.alloc_error_handler_kind(()).unwrap(),
21-
tcx.sess.opts.unstable_opts.oom,
22-
);
15+
codegen_inner(tcx, module, tcx.sess.opts.unstable_opts.oom);
2316
true
2417
} else {
2518
false
2619
}
2720
}
2821

29-
fn codegen_inner(
30-
tcx: TyCtxt<'_>,
31-
module: &mut dyn Module,
32-
alloc_error_handler_kind: AllocatorKind,
33-
oom_strategy: OomStrategy,
34-
) {
35-
let usize_ty = module.target_config().pointer_type();
36-
37-
if alloc_error_handler_kind == AllocatorKind::Default {
38-
let sig = Signature {
39-
call_conv: module.target_config().default_call_conv,
40-
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
41-
returns: vec![],
42-
};
43-
crate::common::create_wrapper_function(
44-
module,
45-
sig,
46-
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
47-
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT),
48-
);
49-
}
50-
51-
let data_id = module
52-
.declare_data(
53-
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
54-
Linkage::Export,
55-
false,
56-
false,
57-
)
58-
.unwrap();
22+
fn codegen_inner(tcx: TyCtxt<'_>, module: &mut dyn Module, oom_strategy: OomStrategy) {
23+
let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap();
5924
let mut data = DataDescription::new();
6025
data.set_align(1);
6126
let val = oom_strategy.should_panic();

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
22
#[cfg(feature = "master")]
33
use gccjit::{FnAttribute, VarAttribute};
4-
use rustc_ast::expand::allocator::{
5-
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE,
6-
};
7-
use rustc_middle::bug;
4+
use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE;
85
use rustc_middle::ty::TyCtxt;
96
use rustc_session::config::OomStrategy;
107
use rustc_symbol_mangling::mangle_internal_symbol;
@@ -13,33 +10,10 @@ use crate::GccContext;
1310
#[cfg(feature = "master")]
1411
use crate::base::symbol_visibility_to_gcc;
1512

16-
pub(crate) unsafe fn codegen(
17-
tcx: TyCtxt<'_>,
18-
mods: &mut GccContext,
19-
_module_name: &str,
20-
alloc_error_handler_kind: AllocatorKind,
21-
) {
13+
pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str) {
2214
let context = &mods.context;
23-
let usize = match tcx.sess.target.pointer_width {
24-
16 => context.new_type::<u16>(),
25-
32 => context.new_type::<u32>(),
26-
64 => context.new_type::<u64>(),
27-
tws => bug!("Unsupported target word size for int: {}", tws),
28-
};
2915
let i8 = context.new_type::<i8>();
3016

31-
if alloc_error_handler_kind == AllocatorKind::Default {
32-
// FIXME(bjorn3): Add noreturn attribute
33-
create_wrapper_function(
34-
tcx,
35-
context,
36-
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
37-
Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)),
38-
&[usize, usize],
39-
None,
40-
);
41-
}
42-
4317
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
4418
let global = context.new_global(None, GlobalKind::Exported, i8, name);
4519
#[cfg(feature = "master")]

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ use back::lto::{ThinBuffer, ThinData};
9595
use gccjit::{CType, Context, OptimizationLevel};
9696
#[cfg(feature = "master")]
9797
use gccjit::{TargetInfo, Version};
98-
use rustc_ast::expand::allocator::AllocatorKind;
9998
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
10099
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
101100
use rustc_codegen_ssa::back::write::{
@@ -277,12 +276,7 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> {
277276
}
278277

279278
impl ExtraBackendMethods for GccCodegenBackend {
280-
fn codegen_allocator(
281-
&self,
282-
tcx: TyCtxt<'_>,
283-
module_name: &str,
284-
alloc_error_handler_kind: AllocatorKind,
285-
) -> Self::Module {
279+
fn codegen_allocator(&self, tcx: TyCtxt<'_>, module_name: &str) -> Self::Module {
286280
let mut mods = GccContext {
287281
context: Arc::new(SyncContext::new(new_context(tcx))),
288282
relocation_model: tcx.sess.relocation_model(),
@@ -291,7 +285,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
291285
};
292286

293287
unsafe {
294-
allocator::codegen(tcx, &mut mods, module_name, alloc_error_handler_kind);
288+
allocator::codegen(tcx, &mut mods, module_name);
295289
}
296290
mods
297291
}

compiler/rustc_codegen_llvm/src/allocator.rs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use libc::c_uint;
2-
use rustc_ast::expand::allocator::{
3-
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE,
4-
};
2+
use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE;
53
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
6-
use rustc_middle::bug;
74
use rustc_middle::ty::TyCtxt;
85
use rustc_session::config::{DebugInfo, OomStrategy};
96
use rustc_symbol_mangling::mangle_internal_symbol;
@@ -13,33 +10,9 @@ use crate::declare::declare_simple_fn;
1310
use crate::llvm::{self, False, True, Type};
1411
use crate::{SimpleCx, attributes, debuginfo};
1512

16-
pub(crate) unsafe fn codegen(
17-
tcx: TyCtxt<'_>,
18-
cx: SimpleCx<'_>,
19-
module_name: &str,
20-
alloc_error_handler_kind: AllocatorKind,
21-
) {
22-
let usize = match tcx.sess.target.pointer_width {
23-
16 => cx.type_i16(),
24-
32 => cx.type_i32(),
25-
64 => cx.type_i64(),
26-
tws => bug!("Unsupported target word size for int: {}", tws),
27-
};
13+
pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, cx: SimpleCx<'_>, module_name: &str) {
2814
let i8 = cx.type_i8();
2915

30-
if alloc_error_handler_kind == AllocatorKind::Default {
31-
// rust alloc error handler
32-
create_wrapper_function(
33-
tcx,
34-
&cx,
35-
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
36-
Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)),
37-
&[usize, usize], // size, align
38-
None,
39-
true,
40-
);
41-
}
42-
4316
unsafe {
4417
// __rust_alloc_error_handler_should_panic
4518
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use back::write::{create_informational_target_machine, create_target_machine};
2828
use context::SimpleCx;
2929
use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig};
3030
use llvm_util::target_config;
31-
use rustc_ast::expand::allocator::AllocatorKind;
3231
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
3332
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
3433
use rustc_codegen_ssa::back::write::{
@@ -104,17 +103,12 @@ impl Drop for TimeTraceProfiler {
104103
}
105104

106105
impl ExtraBackendMethods for LlvmCodegenBackend {
107-
fn codegen_allocator<'tcx>(
108-
&self,
109-
tcx: TyCtxt<'tcx>,
110-
module_name: &str,
111-
alloc_error_handler_kind: AllocatorKind,
112-
) -> ModuleLlvm {
106+
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str) -> ModuleLlvm {
113107
let module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
114108
let cx =
115109
SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size);
116110
unsafe {
117-
allocator::codegen(tcx, cx, module_name, alloc_error_handler_kind);
111+
allocator::codegen(tcx, cx, module_name);
118112
}
119113
module_llvm
120114
}

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::hash_map::Entry::*;
22

33
use rustc_abi::{CanonAbi, X86Call};
4-
use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, NO_ALLOC_SHIM_IS_UNSTABLE};
4+
use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE;
55
use rustc_data_structures::unord::UnordMap;
66
use rustc_hir::def::DefKind;
77
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId};
@@ -214,7 +214,6 @@ fn exported_symbols_provider_local<'tcx>(
214214
// Mark allocator shim symbols as exported only if they were generated.
215215
if needs_allocator_shim(tcx) {
216216
for symbol_name in [
217-
mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
218217
mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
219218
mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
220219
] {

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -708,15 +708,8 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
708708
if needs_allocator_shim(tcx) {
709709
let llmod_id =
710710
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
711-
let module_llvm = tcx.sess.time("write_allocator_module", || {
712-
backend.codegen_allocator(
713-
tcx,
714-
&llmod_id,
715-
// If allocator_kind is Some then alloc_error_handler_kind must
716-
// also be Some.
717-
tcx.alloc_error_handler_kind(()).unwrap(),
718-
)
719-
});
711+
let module_llvm =
712+
tcx.sess.time("write_allocator_module", || backend.codegen_allocator(tcx, &llmod_id));
720713

721714
ongoing_codegen.wait_for_signal_to_codegen_item();
722715
ongoing_codegen.check_for_errors(tcx.sess);

compiler/rustc_codegen_ssa/src/traits/backend.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::any::Any;
22
use std::hash::Hash;
33

4-
use rustc_ast::expand::allocator::AllocatorKind;
54
use rustc_data_structures::fx::FxIndexMap;
65
use rustc_data_structures::sync::{DynSend, DynSync};
76
use rustc_metadata::EncodedMetadata;
@@ -103,12 +102,7 @@ pub trait CodegenBackend {
103102
pub trait ExtraBackendMethods:
104103
CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
105104
{
106-
fn codegen_allocator<'tcx>(
107-
&self,
108-
tcx: TyCtxt<'tcx>,
109-
module_name: &str,
110-
alloc_error_handler_kind: AllocatorKind,
111-
) -> Self::Module;
105+
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str) -> Self::Module;
112106

113107
/// This generates the codegen unit and returns it along with
114108
/// a `u64` giving an estimate of the unit's processing cost.

compiler/rustc_metadata/src/creader.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::str::FromStr;
77
use std::time::Duration;
88
use std::{cmp, env, iter};
99

10-
use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, AllocatorKind, global_fn_name};
10+
use rustc_ast::expand::allocator::{AllocatorKind, global_fn_name};
1111
use rustc_ast::{self as ast, *};
1212
use rustc_data_structures::fx::FxHashSet;
1313
use rustc_data_structures::owned_slice::OwnedSlice;
@@ -25,8 +25,8 @@ use rustc_middle::ty::data_structures::IndexSet;
2525
use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
2626
use rustc_proc_macro::bridge::client::ProcMacro;
2727
use rustc_session::config::{
28-
self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers,
29-
TargetModifier,
28+
self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OomStrategy,
29+
OptionsTargetModifiers, TargetModifier,
3030
};
3131
use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
3232
use rustc_session::lint::{self, BuiltinLintDiag};
@@ -322,10 +322,6 @@ impl CStore {
322322
self.allocator_kind
323323
}
324324

325-
pub(crate) fn alloc_error_handler_kind(&self) -> Option<AllocatorKind> {
326-
self.alloc_error_handler_kind
327-
}
328-
329325
pub(crate) fn has_global_allocator(&self) -> bool {
330326
self.has_global_allocator
331327
}
@@ -1068,7 +1064,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10681064
spans => !spans.is_empty(),
10691065
};
10701066
self.cstore.has_alloc_error_handler =
1071-
match &*fn_spans(krate, Symbol::intern(ALLOC_ERROR_HANDLER)) {
1067+
match &*fn_spans(krate, Symbol::intern(OomStrategy::SYMBOL)) {
10721068
[span1, span2, ..] => {
10731069
self.dcx().emit_err(errors::NoMultipleAllocErrorHandler {
10741070
span2: *span2,

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
432432
provide_cstore_hooks(providers);
433433
providers.queries = rustc_middle::query::Providers {
434434
allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(),
435-
alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(),
436435
is_private_dep: |_tcx, LocalCrate| false,
437436
native_library: |tcx, id| {
438437
tcx.native_libraries(id.krate)

compiler/rustc_middle/src/query/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2257,10 +2257,6 @@ rustc_queries! {
22572257
eval_always
22582258
desc { "getting the allocator kind for the current crate" }
22592259
}
2260-
query alloc_error_handler_kind(_: ()) -> Option<AllocatorKind> {
2261-
eval_always
2262-
desc { "alloc error handler kind for the current crate" }
2263-
}
22642260

22652261
query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
22662262
desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) }

library/alloc/src/alloc.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,8 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
359359
#[cfg(not(no_global_oom_handling))]
360360
unsafe extern "Rust" {
361361
// This is the magic symbol to call the global alloc error handler. rustc generates
362-
// it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the
363-
// default implementations below (`__rdl_oom`) otherwise.
362+
// it if there is a `#[alloc_error_handler]`, or to the weak implementations below
363+
// is called otherwise.
364364
#[rustc_std_internal_symbol]
365365
fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
366366
}
@@ -421,10 +421,9 @@ pub const fn handle_alloc_error(layout: Layout) -> ! {
421421
#[allow(unused_attributes)]
422422
#[unstable(feature = "alloc_internals", issue = "none")]
423423
pub mod __alloc_error_handler {
424-
// called via generated `__rust_alloc_error_handler` if there is no
425-
// `#[alloc_error_handler]`.
426424
#[rustc_std_internal_symbol]
427-
pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! {
425+
#[linkage = "weak"]
426+
pub unsafe extern "Rust" fn __rust_alloc_error_handler(size: usize, _align: usize) -> ! {
428427
unsafe extern "Rust" {
429428
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
430429
// Its value depends on the -Zoom={panic,abort} compiler option.

library/alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
#![feature(iter_next_chunk)]
129129
#![feature(layout_for_ptr)]
130130
#![feature(legacy_receiver_trait)]
131+
#![feature(linkage)]
131132
#![feature(local_waker)]
132133
#![feature(maybe_uninit_slice)]
133134
#![feature(maybe_uninit_uninit_array_transpose)]

library/std/src/alloc.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,10 @@ fn default_alloc_error_hook(layout: Layout) {
358358
// This is the default path taken on OOM, and the only path taken on stable with std.
359359
// Crucially, it does *not* call any user-defined code, and therefore users do not have to
360360
// worry about allocation failure causing reentrancy issues. That makes it different from
361-
// the default `__rdl_oom` defined in alloc (i.e., the default alloc error handler that is
362-
// called when there is no `#[alloc_error_handler]`), which triggers a regular panic and
363-
// thus can invoke a user-defined panic hook, executing arbitrary user-defined code.
361+
// the default `__rust_alloc_error_handler` defined in alloc (i.e., the default alloc error
362+
// handler that is called when there is no `#[alloc_error_handler]`), which triggers a
363+
// regular panic and thus can invoke a user-defined panic hook, executing arbitrary
364+
// user-defined code.
364365
rtprintpanic!("memory allocation of {} bytes failed\n", layout.size());
365366
}
366367
}

0 commit comments

Comments
 (0)