Make __rust_alloc_error_handler_should_panic a function
diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs
index ffb932a..04f1129 100644
--- a/compiler/rustc_codegen_cranelift/src/allocator.rs
+++ b/compiler/rustc_codegen_cranelift/src/allocator.rs
@@ -84,19 +84,34 @@ fn codegen_inner(
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
);
- let data_id = module
- .declare_data(
- &mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
- Linkage::Export,
- false,
- false,
- )
- .unwrap();
- let mut data = DataDescription::new();
- data.set_align(1);
- let val = oom_strategy.should_panic();
- data.define(Box::new([val]));
- module.define_data(data_id, &data).unwrap();
+ {
+ let sig = Signature {
+ call_conv: module.target_config().default_call_conv,
+ params: vec![],
+ returns: vec![AbiParam::new(types::I8)],
+ };
+ let func_id = module
+ .declare_function(
+ &mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
+ Linkage::Export,
+ &sig,
+ )
+ .unwrap();
+ let mut ctx = Context::new();
+ ctx.func.signature = sig;
+ {
+ let mut func_ctx = FunctionBuilderContext::new();
+ let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
+
+ let block = bcx.create_block();
+ bcx.switch_to_block(block);
+ let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64);
+ bcx.ins().return_(&[value]);
+ bcx.seal_all_blocks();
+ bcx.finalize();
+ }
+ module.define_function(func_id, &mut ctx).unwrap();
+ }
{
let sig = Signature {
diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs
index cf8aa50..0d8dc93 100644
--- a/compiler/rustc_codegen_gcc/src/allocator.rs
+++ b/compiler/rustc_codegen_gcc/src/allocator.rs
@@ -1,6 +1,6 @@
-use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
#[cfg(feature = "master")]
-use gccjit::{FnAttribute, VarAttribute};
+use gccjit::FnAttribute;
+use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
use rustc_ast::expand::allocator::{
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
alloc_error_handler_name, default_fn_name, global_fn_name,
@@ -71,15 +71,13 @@ pub(crate) unsafe fn codegen(
None,
);
- let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
- let global = context.new_global(None, GlobalKind::Exported, i8, name);
- #[cfg(feature = "master")]
- global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
- tcx.sess.default_visibility(),
- )));
- let value = tcx.sess.opts.unstable_opts.oom.should_panic();
- let value = context.new_rvalue_from_int(i8, value as i32);
- global.global_set_initializer_rvalue(value);
+ create_const_value_function(
+ tcx,
+ context,
+ &mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
+ i8,
+ context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32),
+ );
create_wrapper_function(
tcx,
@@ -91,6 +89,30 @@ pub(crate) unsafe fn codegen(
);
}
+fn create_const_value_function(
+ tcx: TyCtxt<'_>,
+ context: &Context<'_>,
+ name: &str,
+ output: Type<'_>,
+ value: RValue<'_>,
+) {
+ let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);
+
+ #[cfg(feature = "master")]
+ func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
+ tcx.sess.default_visibility(),
+ )));
+
+ func.add_attribute(FnAttribute::AlwaysInline);
+
+ if tcx.sess.must_emit_unwind_tables() {
+ // TODO(antoyo): emit unwind tables.
+ }
+
+ let block = func.new_block("entry");
+ block.end_with_return(None, value);
+}
+
fn create_wrapper_function(
tcx: TyCtxt<'_>,
context: &Context<'_>,
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index 9dca63c..2b5090e 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -11,7 +11,7 @@
use crate::builder::SBuilder;
use crate::declare::declare_simple_fn;
-use crate::llvm::{self, False, True, Type};
+use crate::llvm::{self, False, True, Type, Value};
use crate::{SimpleCx, attributes, debuginfo};
pub(crate) unsafe fn codegen(
@@ -73,13 +73,14 @@ pub(crate) unsafe fn codegen(
);
unsafe {
- // __rust_alloc_error_handler_should_panic
- let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
- let ll_g = cx.declare_global(&name, i8);
- llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
- let val = tcx.sess.opts.unstable_opts.oom.should_panic();
- let llval = llvm::LLVMConstInt(i8, val as u64, False);
- llvm::set_initializer(ll_g, llval);
+ // __rust_alloc_error_handler_should_panic_v2
+ create_const_value_function(
+ tcx,
+ &cx,
+ &mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
+ &i8,
+ &llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, False),
+ );
// __rust_no_alloc_shim_is_unstable_v2
create_wrapper_function(
@@ -100,6 +101,34 @@ pub(crate) unsafe fn codegen(
}
}
+fn create_const_value_function(
+ tcx: TyCtxt<'_>,
+ cx: &SimpleCx<'_>,
+ name: &str,
+ output: &Type,
+ value: &Value,
+) {
+ let ty = cx.type_func(&[], output);
+ let llfn = declare_simple_fn(
+ &cx,
+ name,
+ llvm::CallConv::CCallConv,
+ llvm::UnnamedAddr::Global,
+ llvm::Visibility::from_generic(tcx.sess.default_visibility()),
+ ty,
+ );
+
+ attributes::apply_to_llfn(
+ llfn,
+ llvm::AttributePlace::Function,
+ &[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)],
+ );
+
+ let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) };
+ let mut bx = SBuilder::build(&cx, llbb);
+ bx.ret(value);
+}
+
fn create_wrapper_function(
tcx: TyCtxt<'_>,
cx: &SimpleCx<'_>,
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 73bb047..0639363 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -3340,7 +3340,7 @@ pub enum OomStrategy {
}
impl OomStrategy {
- pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic";
+ pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic_v2";
pub fn should_panic(self) -> u8 {
match self {
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index b4176e9..c9b98fa 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -429,10 +429,10 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! {
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
// Its value depends on the -Zoom={panic,abort} compiler option.
#[rustc_std_internal_symbol]
- static __rust_alloc_error_handler_should_panic: u8;
+ fn __rust_alloc_error_handler_should_panic_v2() -> u8;
}
- if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
+ if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } {
panic!("memory allocation of {size} bytes failed")
} else {
core::panicking::panic_nounwind_fmt(
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index b574e9f..1d61630 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -349,10 +349,10 @@ fn default_alloc_error_hook(layout: Layout) {
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
// Its value depends on the -Zoom={panic,abort} compiler option.
#[rustc_std_internal_symbol]
- static __rust_alloc_error_handler_should_panic: u8;
+ fn __rust_alloc_error_handler_should_panic_v2() -> u8;
}
- if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
+ if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } {
panic!("memory allocation of {} bytes failed", layout.size());
} else {
// This is the default path taken on OOM, and the only path taken on stable with std.
diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs
index a2ea3db..f02a3f4 100644
--- a/src/tools/miri/src/shims/extern_static.rs
+++ b/src/tools/miri/src/shims/extern_static.rs
@@ -1,7 +1,5 @@
//! Provides the `extern static` that this platform expects.
-use rustc_symbol_mangling::mangle_internal_symbol;
-
use crate::*;
impl<'tcx> MiriMachine<'tcx> {
@@ -45,15 +43,6 @@ fn weak_symbol_extern_statics(
/// Sets up the "extern statics" for this machine.
pub fn init_extern_statics(ecx: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> {
- // "__rust_alloc_error_handler_should_panic"
- let val = ecx.tcx.sess.opts.unstable_opts.oom.should_panic();
- let val = ImmTy::from_int(val, ecx.machine.layouts.u8);
- Self::alloc_extern_static(
- ecx,
- &mangle_internal_symbol(*ecx.tcx, "__rust_alloc_error_handler_should_panic"),
- val,
- )?;
-
if ecx.target_os_is_unix() {
// "environ" is mandated by POSIX.
let environ = ecx.machine.env_vars.unix().environ();
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 97070eb..1b66735 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -615,6 +615,12 @@ fn emulate_foreign_item_inner(
// This is a no-op shim that only exists to prevent making the allocator shims instantly stable.
let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
}
+ name if name == this.mangle_internal_symbol("__rust_alloc_error_handler_should_panic_v2") => {
+ // Gets the value of the `oom` option.
+ let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
+ let val = this.tcx.sess.opts.unstable_opts.oom.should_panic();
+ this.write_int(val, dest)?;
+ }
// C memory handling functions
"memcmp" => {
diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.rs b/src/tools/miri/tests/pass/alloc-access-tracking.rs
index 9eba0ca..b285250 100644
--- a/src/tools/miri/tests/pass/alloc-access-tracking.rs
+++ b/src/tools/miri/tests/pass/alloc-access-tracking.rs
@@ -1,7 +1,7 @@
#![no_std]
#![no_main]
-//@compile-flags: -Zmiri-track-alloc-id=19 -Zmiri-track-alloc-accesses -Cpanic=abort
-//@normalize-stderr-test: "id 19" -> "id $$ALLOC"
+//@compile-flags: -Zmiri-track-alloc-id=18 -Zmiri-track-alloc-accesses -Cpanic=abort
+//@normalize-stderr-test: "id 18" -> "id $$ALLOC"
//@only-target: linux # alloc IDs differ between OSes (due to extern static allocations)
extern "Rust" {