From 81807c713408a73b4223cc08f61f73f6eb9559c0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 26 Jun 2025 13:44:01 +0000 Subject: [PATCH 1/8] Use a const for all __rust_alloc_error_handler name references --- compiler/rustc_ast/src/expand/allocator.rs | 1 + compiler/rustc_codegen_cranelift/src/allocator.rs | 4 ++-- compiler/rustc_codegen_gcc/src/allocator.rs | 4 ++-- compiler/rustc_codegen_llvm/src/allocator.rs | 4 ++-- compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 6 ++++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index 7dee2ed17b4be..b265a10230099 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -22,6 +22,7 @@ pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'st } } +pub const ALLOC_ERROR_HANDLER: &str = "__rust_alloc_error_handler"; pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2"; pub enum AllocatorTy { diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index ffb932a3c38e6..1a3149f84eb66 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -3,7 +3,7 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, default_fn_name, global_fn_name, }; use rustc_codegen_ssa::base::allocator_kind_for_codegen; @@ -80,7 +80,7 @@ fn codegen_inner( crate::common::create_wrapper_function( module, sig, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), ); diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index cf8aa500c778f..9ab5c628c12c8 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -2,7 +2,7 @@ use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute}; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, default_fn_name, global_fn_name, }; use rustc_middle::bug; @@ -65,7 +65,7 @@ pub(crate) unsafe fn codegen( create_wrapper_function( tcx, context, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), &[usize, usize], None, diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 9dca63cfc8d4f..8cc5ec0450ce9 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,6 +1,6 @@ use libc::c_uint; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, default_fn_name, global_fn_name, }; use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; @@ -65,7 +65,7 @@ pub(crate) unsafe fn codegen( create_wrapper_function( tcx, &cx, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), &[usize, usize], // size, align None, diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 19c005d418e89..8bdccfc2b686f 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,7 +1,9 @@ use std::collections::hash_map::Entry::*; use rustc_abi::{CanonAbi, X86Call}; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name}; +use rustc_ast::expand::allocator::{ + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name, +}; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; @@ -217,7 +219,7 @@ fn exported_symbols_provider_local<'tcx>( .iter() .map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str())) .chain([ - mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), mangle_internal_symbol(tcx, OomStrategy::SYMBOL), mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), ]) From e8adaa6db822a744f6774f97b06c8cb26f3cf1eb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 26 Jun 2025 14:28:45 +0000 Subject: [PATCH 2/8] Support #[alloc_error_handler] without the allocator shim Currently it is possible to avoid linking the allocator shim when __rust_no_alloc_shim_is_unstable_v2 is defined when linking rlibs directly as some build systems need. However this currently requires liballoc to be compiled with --cfg no_global_oom_handling, which places huge restrictions on what functions you can call and makes it impossible to use libstd. Or alternatively you have to define __rust_alloc_error_handler and (when using libstd) __rust_alloc_error_handler_should_panic using #[rustc_std_internal_symbol]. With this commit the former can be replaced with #[alloc_error_handler]. Eventually the alloc_error_handler may either be removed entirely (though the PR for that has been stale for years now) or we may start using weak symbols for it instead. For the latter case this commit is a prerequisite anyway. --- compiler/rustc_ast/src/expand/allocator.rs | 8 +----- .../src/alloc_error_handler.rs | 5 ++-- .../rustc_codegen_cranelift/src/allocator.rs | 28 ++++++++++--------- compiler/rustc_codegen_gcc/src/allocator.rs | 24 ++++++++-------- compiler/rustc_codegen_llvm/src/allocator.rs | 26 +++++++++-------- compiler/rustc_metadata/src/creader.rs | 24 ++++++++-------- tests/run-make/bin-emit-no-symbols/rmake.rs | 2 +- tests/ui/sanitizer/dataflow-abilist.txt | 1 - 8 files changed, 59 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index b265a10230099..b80f1025ae18c 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -15,14 +15,8 @@ pub fn default_fn_name(base: Symbol) -> String { format!("__rdl_{base}") } -pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str { - match alloc_error_handler_kind { - AllocatorKind::Global => "__rg_oom", - AllocatorKind::Default => "__rdl_oom", - } -} - pub const ALLOC_ERROR_HANDLER: &str = "__rust_alloc_error_handler"; +pub const ALLOC_ERROR_HANDLER_DEFAULT: &str = "__rdl_oom"; pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2"; pub enum AllocatorTy { diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index e75bc944d7ec8..c05cb81f2fde4 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -1,3 +1,4 @@ +use rustc_ast::expand::allocator::ALLOC_ERROR_HANDLER; use rustc_ast::ptr::P; use rustc_ast::{ self as ast, Fn, FnHeader, FnSig, Generics, ItemKind, Safety, Stmt, StmtKind, TyKind, @@ -56,7 +57,7 @@ pub(crate) fn expand( } // #[rustc_std_internal_symbol] -// unsafe fn __rg_oom(size: usize, align: usize) -> ! { +// unsafe fn __rust_alloc_error_handler(size: usize, align: usize) -> ! { // handler(core::alloc::Layout::from_size_align_unchecked(size, align)) // } fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { @@ -85,7 +86,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span let kind = ItemKind::Fn(Box::new(Fn { defaultness: ast::Defaultness::Final, sig, - ident: Ident::from_str_and_span("__rg_oom", span), + ident: Ident::from_str_and_span(ALLOC_ERROR_HANDLER, span), generics: Generics::default(), contract: None, body, diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 1a3149f84eb66..80d58aa821d97 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -3,8 +3,8 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind, + AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; @@ -72,17 +72,19 @@ fn codegen_inner( } } - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], - }; - crate::common::create_wrapper_function( - module, - sig, - &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), - &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), - ); + if alloc_error_handler_kind == AllocatorKind::Default { + let sig = Signature { + call_conv: module.target_config().default_call_conv, + params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], + returns: vec![], + }; + crate::common::create_wrapper_function( + module, + sig, + &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), + &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT), + ); + } let data_id = module .declare_data( diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 9ab5c628c12c8..2185e6a2f13eb 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -2,8 +2,8 @@ use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute}; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind, + AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; @@ -61,15 +61,17 @@ pub(crate) unsafe fn codegen( } } - // FIXME(bjorn3): Add noreturn attribute - create_wrapper_function( - tcx, - context, - &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), - Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), - &[usize, usize], - None, - ); + if alloc_error_handler_kind == AllocatorKind::Default { + // FIXME(bjorn3): Add noreturn attribute + create_wrapper_function( + tcx, + context, + &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), + Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)), + &[usize, usize], + None, + ); + } let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); let global = context.new_global(None, GlobalKind::Exported, i8, name); diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 8cc5ec0450ce9..6a95bb9a17eaa 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,7 +1,7 @@ use libc::c_uint; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind, + AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_middle::bug; @@ -61,16 +61,18 @@ pub(crate) unsafe fn codegen( } } - // rust alloc error handler - create_wrapper_function( - tcx, - &cx, - &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), - Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), - &[usize, usize], // size, align - None, - true, - ); + if alloc_error_handler_kind == AllocatorKind::Default { + // rust alloc error handler + create_wrapper_function( + tcx, + &cx, + &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), + Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)), + &[usize, usize], // size, align + None, + true, + ); + } unsafe { // __rust_alloc_error_handler_should_panic diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index de19c10bc57c8..84ed3d1c3c20e 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -7,7 +7,7 @@ use std::str::FromStr; use std::time::Duration; use std::{cmp, env, iter}; -use rustc_ast::expand::allocator::{AllocatorKind, alloc_error_handler_name, global_fn_name}; +use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, AllocatorKind, global_fn_name}; use rustc_ast::{self as ast, *}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::owned_slice::OwnedSlice; @@ -1067,17 +1067,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } spans => !spans.is_empty(), }; - self.cstore.has_alloc_error_handler = match &*fn_spans( - krate, - Symbol::intern(alloc_error_handler_name(AllocatorKind::Global)), - ) { - [span1, span2, ..] => { - self.dcx() - .emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 }); - true - } - spans => !spans.is_empty(), - }; + self.cstore.has_alloc_error_handler = + match &*fn_spans(krate, Symbol::intern(ALLOC_ERROR_HANDLER)) { + [span1, span2, ..] => { + self.dcx().emit_err(errors::NoMultipleAllocErrorHandler { + span2: *span2, + span1: *span1, + }); + true + } + spans => !spans.is_empty(), + }; // Check to see if we actually need an allocator. This desire comes // about through the `#![needs_allocator]` attribute and is typically diff --git a/tests/run-make/bin-emit-no-symbols/rmake.rs b/tests/run-make/bin-emit-no-symbols/rmake.rs index 2faeb20025bb7..0822bd6dfd6a8 100644 --- a/tests/run-make/bin-emit-no-symbols/rmake.rs +++ b/tests/run-make/bin-emit-no-symbols/rmake.rs @@ -14,5 +14,5 @@ fn main() { let out = llvm_readobj().input("app.o").arg("--symbols").run(); out.assert_stdout_contains("rust_begin_unwind"); out.assert_stdout_contains("rust_eh_personality"); - out.assert_stdout_contains("__rg_oom"); + out.assert_stdout_contains("__rust_alloc_error_handler"); } diff --git a/tests/ui/sanitizer/dataflow-abilist.txt b/tests/ui/sanitizer/dataflow-abilist.txt index 3d32397a175d4..8ad8cd71e6568 100644 --- a/tests/ui/sanitizer/dataflow-abilist.txt +++ b/tests/ui/sanitizer/dataflow-abilist.txt @@ -494,7 +494,6 @@ fun:__rdl_alloc=uninstrumented fun:__rdl_alloc_zeroed=uninstrumented fun:__rdl_dealloc=uninstrumented fun:__rdl_realloc=uninstrumented -fun:__rg_oom=uninstrumented fun:__rust_alloc=uninstrumented fun:__rust_alloc_error_handler=uninstrumented fun:__rust_alloc_zeroed=uninstrumented From 784aa4dde6e760e9bdda4ccff3c64f9faef62047 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:09:50 +0000 Subject: [PATCH 3/8] [WIP] Use weak linkage instead of compiler generated shims This is still keeping the allocator shim for the oom handler and the __rust_no_alloc_shim_is_unstable symbol for now. TODO: Update comments everywhere and test on macOS and Windows --- compiler/rustc_ast/src/expand/allocator.rs | 4 - .../rustc_codegen_cranelift/src/allocator.rs | 64 ++------ compiler/rustc_codegen_gcc/src/allocator.rs | 35 +---- compiler/rustc_codegen_gcc/src/lib.rs | 3 +- compiler/rustc_codegen_llvm/src/allocator.rs | 36 +---- compiler/rustc_codegen_llvm/src/lib.rs | 3 +- .../src/back/symbol_export.rs | 4 +- compiler/rustc_codegen_ssa/src/base.rs | 9 +- .../rustc_codegen_ssa/src/traits/backend.rs | 1 - compiler/rustc_metadata/src/creader.rs | 2 + .../rustc_monomorphize/src/partitioning.rs | 1 + library/alloc/src/alloc.rs | 2 +- library/std/src/alloc.rs | 17 ++- src/tools/miri/src/shims/alloc.rs | 33 +--- src/tools/miri/src/shims/foreign_items.rs | 144 ++++++++---------- 15 files changed, 109 insertions(+), 249 deletions(-) diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index b80f1025ae18c..7ad0f565181c2 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -11,10 +11,6 @@ pub fn global_fn_name(base: Symbol) -> String { format!("__rust_{base}") } -pub fn default_fn_name(base: Symbol) -> String { - format!("__rdl_{base}") -} - pub const ALLOC_ERROR_HANDLER: &str = "__rust_alloc_error_handler"; pub const ALLOC_ERROR_HANDLER_DEFAULT: &str = "__rdl_oom"; pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2"; diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 80d58aa821d97..b57bef7ee31cb 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -3,10 +3,9 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind, - AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, + ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, }; -use rustc_codegen_ssa::base::allocator_kind_for_codegen; +use rustc_codegen_ssa::base::needs_allocator_shim; use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; @@ -14,64 +13,27 @@ use crate::prelude::*; /// Returns whether an allocator shim was created pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { - let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; - codegen_inner( - tcx, - module, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); - true + if needs_allocator_shim(tcx) { + codegen_inner( + tcx, + module, + tcx.alloc_error_handler_kind(()).unwrap(), + tcx.sess.opts.unstable_opts.oom, + ); + true + } else { + false + } } fn codegen_inner( tcx: TyCtxt<'_>, module: &mut dyn Module, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, ) { let usize_ty = module.target_config().pointer_type(); - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut arg_tys = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - arg_tys.push(usize_ty); // size - arg_tys.push(usize_ty); // align - } - AllocatorTy::Ptr => arg_tys.push(usize_ty), - AllocatorTy::Usize => arg_tys.push(usize_ty), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), - } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(usize_ty), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: arg_tys.iter().cloned().map(AbiParam::new).collect(), - returns: output.into_iter().map(AbiParam::new).collect(), - }; - crate::common::create_wrapper_function( - module, - sig, - &mangle_internal_symbol(tcx, &global_fn_name(method.name)), - &mangle_internal_symbol(tcx, &default_fn_name(method.name)), - ); - } - } - if alloc_error_handler_kind == AllocatorKind::Default { let sig = Signature { call_conv: module.target_config().default_call_conv, diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 2185e6a2f13eb..ce748b8ae555b 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -2,8 +2,7 @@ use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute}; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind, - AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, + ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; @@ -18,7 +17,6 @@ pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) { let context = &mods.context; @@ -29,37 +27,6 @@ pub(crate) unsafe fn codegen( tws => bug!("Unsupported target word size for int: {}", tws), }; let i8 = context.new_type::(); - let i8p = i8.make_pointer(); - - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut types = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - types.push(usize); - types.push(usize); - } - AllocatorTy::Ptr => types.push(i8p), - AllocatorTy::Usize => types.push(usize), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), - } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(i8p), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); - let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); - - create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); - } - } if alloc_error_handler_kind == AllocatorKind::Default { // FIXME(bjorn3): Add noreturn attribute diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index a912678ef2a10..d606a1636df04 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -281,7 +281,6 @@ impl ExtraBackendMethods for GccCodegenBackend { &self, tcx: TyCtxt<'_>, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> Self::Module { let mut mods = GccContext { @@ -292,7 +291,7 @@ impl ExtraBackendMethods for GccCodegenBackend { }; unsafe { - allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut mods, module_name, alloc_error_handler_kind); } mods } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 6a95bb9a17eaa..3eb3388c6af5d 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,7 +1,6 @@ use libc::c_uint; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind, - AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, + ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, }; use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_middle::bug; @@ -18,7 +17,6 @@ pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, cx: SimpleCx<'_>, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) { let usize = match tcx.sess.target.pointer_width { @@ -28,38 +26,6 @@ pub(crate) unsafe fn codegen( tws => bug!("Unsupported target word size for int: {}", tws), }; let i8 = cx.type_i8(); - let i8p = cx.type_ptr(); - - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut args = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - args.push(usize); // size - args.push(usize); // align - } - AllocatorTy::Ptr => args.push(i8p), - AllocatorTy::Usize => args.push(usize), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), - } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(i8p), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - - let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); - let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); - - create_wrapper_function(tcx, &cx, &from_name, Some(&to_name), &args, output, false); - } - } if alloc_error_handler_kind == AllocatorKind::Default { // rust alloc error handler diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index cdfffbe47bfa5..44432009a6a95 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -108,14 +108,13 @@ impl ExtraBackendMethods for LlvmCodegenBackend { &self, tcx: TyCtxt<'tcx>, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> ModuleLlvm { let module_llvm = ModuleLlvm::new_metadata(tcx, module_name); let cx = SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size); unsafe { - allocator::codegen(tcx, cx, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, cx, module_name, alloc_error_handler_kind); } module_llvm } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 8bdccfc2b686f..567d7a0e1a92d 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -20,7 +20,7 @@ use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{SanitizerSet, TlsModel}; use tracing::debug; -use crate::base::allocator_kind_for_codegen; +use crate::base::needs_allocator_shim; fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(tcx.crate_types()) @@ -214,7 +214,7 @@ fn exported_symbols_provider_local<'tcx>( } // Mark allocator shim symbols as exported only if they were generated. - if allocator_kind_for_codegen(tcx).is_some() { + if needs_allocator_shim(tcx) { for symbol_name in ALLOCATOR_METHODS .iter() .map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str())) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index cc90271cd0c6f..f65b19f12fe31 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -6,7 +6,7 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; use rustc_ast as ast; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name}; +use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, global_fn_name}; use rustc_attr_data_structures::OptimizeAttr; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; @@ -648,7 +648,7 @@ pub fn collect_debugger_visualizers_transitive( /// Decide allocator kind to codegen. If `Some(_)` this will be the same as /// `tcx.allocator_kind`, but it may be `None` in more cases (e.g. if using /// allocator definitions from a dylib dependency). -pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option { +pub fn needs_allocator_shim(tcx: TyCtxt<'_>) -> bool { // If the crate doesn't have an `allocator_kind` set then there's definitely // no shim to generate. Otherwise we also check our dependency graph for all // our output crate types. If anything there looks like its a `Dynamic` @@ -659,7 +659,7 @@ pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option { use rustc_middle::middle::dependency_format::Linkage; list.iter().any(|&linkage| linkage == Linkage::Dynamic) }); - if any_dynamic_crate { None } else { tcx.allocator_kind(()) } + if any_dynamic_crate { false } else { tcx.allocator_kind(()).is_some() } } pub fn codegen_crate( @@ -705,14 +705,13 @@ pub fn codegen_crate( let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu); // Codegen an allocator shim, if necessary. - if let Some(kind) = allocator_kind_for_codegen(tcx) { + if needs_allocator_shim(tcx) { let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); let module_llvm = tcx.sess.time("write_allocator_module", || { backend.codegen_allocator( tcx, &llmod_id, - kind, // If allocator_kind is Some then alloc_error_handler_kind must // also be Some. tcx.alloc_error_handler_kind(()).unwrap(), diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 29ec7eb1da3b3..ff320754e6844 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -107,7 +107,6 @@ pub trait ExtraBackendMethods: &self, tcx: TyCtxt<'tcx>, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> Self::Module; diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 84ed3d1c3c20e..cca14b8e652f4 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -1406,6 +1406,8 @@ fn fn_spans(krate: &ast::Crate, name: Symbol) -> Vec { if let Some(ident) = item.kind.ident() && ident.name == self.name && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) + // Ignore the default allocator in libstd with weak linkage + && attr::find_by_name(&item.attrs, sym::linkage).is_none() { self.spans.push(item.span); } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 49025673bbd2f..289934bccbb9e 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -898,6 +898,7 @@ fn mono_item_visibility<'tcx>( // Removal of these functions can't be done by LLVM but rather must be // done by the linker as it's a non-local decision. // + // FIXME update comment // * Second is "std internal symbols". Currently this is primarily used // for allocator symbols. Allocators are a little weird in their // implementation, but the idea is that the compiler, at the last diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index b4176e9c1f4d0..819395077d68b 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -12,7 +12,7 @@ unsafe extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates // them to call the global allocator if there is a `#[global_allocator]` attribute // (the code expanding that attribute macro generates those functions), or to call - // the default implementations in std (`__rdl_alloc` etc. in `library/std/src/alloc.rs`) + // the default implementations in std (weak symbols in `library/std/src/alloc.rs`) // otherwise. #[rustc_allocator] #[rustc_nounwind] diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index b574e9f3a25e3..5bae91e5dbe30 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -383,9 +383,8 @@ pub fn rust_oom(layout: Layout) -> ! { #[unstable(feature = "alloc_internals", issue = "none")] pub mod __default_lib_allocator { use super::{GlobalAlloc, Layout, System}; - // These magic symbol names are used as a fallback for implementing the - // `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs`) when there is - // no `#[global_allocator]` attribute. + // These are used as a fallback for implementing the `__rust_alloc`, etc symbols + // (see `src/liballoc/alloc.rs`) when there is no `#[global_allocator]` attribute. // for symbol names src/librustc_ast/expand/allocator.rs // for signatures src/librustc_allocator/lib.rs @@ -394,7 +393,8 @@ pub mod __default_lib_allocator { // ABI #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_alloc(size: usize, align: usize) -> *mut u8 { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_alloc(size: usize, align: usize) -> *mut u8 { // SAFETY: see the guarantees expected by `Layout::from_size_align` and // `GlobalAlloc::alloc`. unsafe { @@ -404,14 +404,16 @@ pub mod __default_lib_allocator { } #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize) { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize) { // SAFETY: see the guarantees expected by `Layout::from_size_align` and // `GlobalAlloc::dealloc`. unsafe { System.dealloc(ptr, Layout::from_size_align_unchecked(size, align)) } } #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_realloc( + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_realloc( ptr: *mut u8, old_size: usize, align: usize, @@ -426,7 +428,8 @@ pub mod __default_lib_allocator { } #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 { // SAFETY: see the guarantees expected by `Layout::from_size_align` and // `GlobalAlloc::alloc_zeroed`. unsafe { diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index f05c5fbbe1d4f..acfc671b2c389 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -1,5 +1,4 @@ use rustc_abi::{Align, Size}; -use rustc_ast::expand::allocator::AllocatorKind; use crate::*; @@ -55,31 +54,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Emulates calling the internal __rust_* allocator functions - fn emulate_allocator( - &mut self, - default: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { - let this = self.eval_context_mut(); - - let Some(allocator_kind) = this.tcx.allocator_kind(()) else { - // in real code, this symbol does not exist without an allocator - return interp_ok(EmulateItemResult::NotSupported); - }; - - match allocator_kind { - AllocatorKind::Global => { - // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion - // of this attribute. As such we have to call an exported Rust function, - // and not execute any Miri shim. Somewhat unintuitively doing so is done - // by returning `NotSupported`, which triggers the `lookup_exported_symbol` - // fallback case in `emulate_foreign_item`. - interp_ok(EmulateItemResult::NotSupported) - } - AllocatorKind::Default => { - default(this)?; - interp_ok(EmulateItemResult::NeedsReturn) - } - } + fn emulate_allocator(&mut self) -> InterpResult<'tcx, EmulateItemResult> { + // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion + // of this attribute. As such we have to call an exported Rust function, + // and not execute any Miri shim. Somewhat unintuitively doing so is done + // by returning `NotSupported`, which triggers the `lookup_exported_symbol` + // fallback case in `emulate_foreign_item`. + interp_ok(EmulateItemResult::NotSupported) } fn malloc(&mut self, size: u64, init: AllocInit) -> InterpResult<'tcx, Pointer> { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 416cb1ab55e6a..9f994b4036275 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -9,6 +9,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::AllocInit; +use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::{Instance, Ty}; use rustc_middle::{mir, ty}; use rustc_span::Symbol; @@ -138,56 +139,80 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Entry::Occupied(e) => e.into_mut(), Entry::Vacant(e) => { // Find it if it was not cached. - let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None; + let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum, bool)> = None; helpers::iter_exported_symbols(tcx, |cnum, def_id| { let attrs = tcx.codegen_fn_attrs(def_id); // Skip over imports of items. if tcx.is_foreign_item(def_id) { return interp_ok(()); } - // Skip over items without an explicitly defined symbol name. - if !(attrs.export_name.is_some() - || attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) - || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)) - { - return interp_ok(()); - } - let instance = Instance::mono(tcx, def_id); let symbol_name = tcx.symbol_name(instance).name; - if symbol_name == link_name.as_str() { - if let Some((original_instance, original_cnum)) = instance_and_crate { - // Make sure we are consistent wrt what is 'first' and 'second'. - let original_span = tcx.def_span(original_instance.def_id()).data(); - let span = tcx.def_span(def_id).data(); - if original_span < span { - throw_machine_stop!(TerminationInfo::MultipleSymbolDefinitions { - link_name, - first: original_span, - first_crate: tcx.crate_name(original_cnum), - second: span, - second_crate: tcx.crate_name(cnum), - }); - } else { - throw_machine_stop!(TerminationInfo::MultipleSymbolDefinitions { - link_name, - first: span, - first_crate: tcx.crate_name(cnum), - second: original_span, - second_crate: tcx.crate_name(original_cnum), - }); + let is_weak = + attrs.linkage.map_or(false, |linkage| linkage == Linkage::WeakAny); + if symbol_name == link_name { + if let Some((original_instance, original_cnum, original_is_weak)) = + instance_and_crate + { + match (is_weak, original_is_weak) { + (false, true) => { + // Original definition is a weak definition. Override it. + + instance_and_crate = + Some((ty::Instance::mono(tcx, def_id), cnum, is_weak)); + } + (true, false) => { + // Current definition is a weak definition. Keep the original one. + } + (true, true) | (false, false) => { + // Either both definitions are non-weak or both are weak. In + // either case return an error. For weak definitions we error + // because it is undefined which definition would have been + // picked by the linker. + + // Make sure we are consistent wrt what is 'first' and 'second'. + let original_span = + tcx.def_span(original_instance.def_id()).data(); + let span = tcx.def_span(def_id).data(); + if original_span < span { + throw_machine_stop!( + TerminationInfo::MultipleSymbolDefinitions { + link_name, + first: original_span, + first_crate: tcx.crate_name(original_cnum), + second: span, + second_crate: tcx.crate_name(cnum), + } + ); + } else { + throw_machine_stop!( + TerminationInfo::MultipleSymbolDefinitions { + link_name, + first: span, + first_crate: tcx.crate_name(cnum), + second: original_span, + second_crate: tcx.crate_name(original_cnum), + } + ); + } + } } + } else { + instance_and_crate = + Some((ty::Instance::mono(tcx, def_id), cnum, is_weak)); } - if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) { - throw_ub_format!( - "attempt to call an exported symbol that is not defined as a function" - ); - } - instance_and_crate = Some((ty::Instance::mono(tcx, def_id), cnum)); } interp_ok(()) })?; + if let Some((instance, _, _)) = instance_and_crate { + if !matches!(tcx.def_kind(instance.def_id()), DefKind::Fn | DefKind::AssocFn) { + throw_ub_format!( + "attempt to call an exported symbol that is not defined as a function" + ); + } + } + e.insert(instance_and_crate.map(|ic| ic.0)) } }; @@ -530,27 +555,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { default(this)?; return interp_ok(EmulateItemResult::NeedsReturn); } - _ => return this.emulate_allocator(default), + _ => return this.emulate_allocator(), } } name if name == this.mangle_internal_symbol("__rust_alloc_zeroed") => { - return this.emulate_allocator(|this| { - // See the comment for `__rust_alloc` why `check_shim` is only called in the - // default case. - let [size, align] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?; - let size = this.read_target_usize(size)?; - let align = this.read_target_usize(align)?; - - this.check_rustc_alloc_request(size, align)?; - - let ptr = this.allocate_ptr( - Size::from_bytes(size), - Align::from_bytes(align).unwrap(), - MiriMemoryKind::Rust.into(), - AllocInit::Zero, - )?; - this.write_pointer(ptr, dest) - }); + return this.emulate_allocator(); } name if name == this.mangle_internal_symbol("__rust_dealloc") || name == "miri_dealloc" => @@ -582,34 +591,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { default(this)?; return interp_ok(EmulateItemResult::NeedsReturn); } - _ => return this.emulate_allocator(default), + _ => return this.emulate_allocator(), } } name if name == this.mangle_internal_symbol("__rust_realloc") => { - return this.emulate_allocator(|this| { - // See the comment for `__rust_alloc` why `check_shim` is only called in the - // default case. - let [ptr, old_size, align, new_size] = - this.check_shim(abi, CanonAbi::Rust, link_name, args)?; - let ptr = this.read_pointer(ptr)?; - let old_size = this.read_target_usize(old_size)?; - let align = this.read_target_usize(align)?; - let new_size = this.read_target_usize(new_size)?; - // No need to check old_size; we anyway check that they match the allocation. - - this.check_rustc_alloc_request(new_size, align)?; - - let align = Align::from_bytes(align).unwrap(); - let new_ptr = this.reallocate_ptr( - ptr, - Some((Size::from_bytes(old_size), align)), - Size::from_bytes(new_size), - align, - MiriMemoryKind::Rust.into(), - AllocInit::Uninit, - )?; - this.write_pointer(new_ptr, dest) - }); + return this.emulate_allocator(); } name if name == this.mangle_internal_symbol("__rust_no_alloc_shim_is_unstable_v2") => { // This is a no-op shim that only exists to prevent making the allocator shims instantly stable. From 8c10d420d3603fa9aacaad2facefc26940491a11 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 09:15:04 +0000 Subject: [PATCH 4/8] Update comments and simplify miri allocator handling a bit --- .../src/back/symbol_export.rs | 18 +++----- .../rustc_monomorphize/src/partitioning.rs | 15 ++---- library/std/src/alloc.rs | 3 +- src/tools/miri/src/shims/alloc.rs | 10 ---- src/tools/miri/src/shims/foreign_items.rs | 46 ++++--------------- 5 files changed, 19 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 567d7a0e1a92d..c96f7cf662b3a 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,9 +1,7 @@ use std::collections::hash_map::Entry::*; use rustc_abi::{CanonAbi, X86Call}; -use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name, -}; +use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, NO_ALLOC_SHIM_IS_UNSTABLE}; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; @@ -215,15 +213,11 @@ fn exported_symbols_provider_local<'tcx>( // Mark allocator shim symbols as exported only if they were generated. if needs_allocator_shim(tcx) { - for symbol_name in ALLOCATOR_METHODS - .iter() - .map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str())) - .chain([ - mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), - mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), - ]) - { + for symbol_name in [ + mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), + mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), + ] { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); symbols.push(( diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 289934bccbb9e..1c6f2fc1a4186 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -900,18 +900,9 @@ fn mono_item_visibility<'tcx>( // // FIXME update comment // * Second is "std internal symbols". Currently this is primarily used - // for allocator symbols. Allocators are a little weird in their - // implementation, but the idea is that the compiler, at the last - // minute, defines an allocator with an injected object file. The - // `alloc` crate references these symbols (`__rust_alloc`) and the - // definition doesn't get hooked up until a linked crate artifact is - // generated. - // - // The symbols synthesized by the compiler (`__rust_alloc`) are thin - // veneers around the actual implementation, some other symbol which - // implements the same ABI. These symbols (things like `__rg_alloc`, - // `__rdl_alloc`, `__rde_alloc`, etc), are all tagged with "std - // internal symbols". + // for allocator symbols and the unwinder runtime to allow cyclic + // dependencies between the defining and using crate and to allow + // replacing them. // // The std-internal symbols here **should not show up in a dll as an // exported interface**, so they return `false` from diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 5bae91e5dbe30..14996370d6e67 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -386,8 +386,7 @@ pub mod __default_lib_allocator { // These are used as a fallback for implementing the `__rust_alloc`, etc symbols // (see `src/liballoc/alloc.rs`) when there is no `#[global_allocator]` attribute. - // for symbol names src/librustc_ast/expand/allocator.rs - // for signatures src/librustc_allocator/lib.rs + // for symbol names and signatures see compiler/rustc_ast/src/expand/allocator.rs // linkage directives are provided as part of the current compiler allocator // ABI diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index acfc671b2c389..5e0d93bd4c031 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -53,16 +53,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Align::from_bytes(prev_power_of_two(size)).unwrap() } - /// Emulates calling the internal __rust_* allocator functions - fn emulate_allocator(&mut self) -> InterpResult<'tcx, EmulateItemResult> { - // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion - // of this attribute. As such we have to call an exported Rust function, - // and not execute any Miri shim. Somewhat unintuitively doing so is done - // by returning `NotSupported`, which triggers the `lookup_exported_symbol` - // fallback case in `emulate_foreign_item`. - interp_ok(EmulateItemResult::NotSupported) - } - fn malloc(&mut self, size: u64, init: AllocInit) -> InterpResult<'tcx, Pointer> { let this = self.eval_context_mut(); let align = this.malloc_align(size); diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 9f994b4036275..a8f7540a2010f 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -525,7 +525,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Rust allocation - name if name == this.mangle_internal_symbol("__rust_alloc") || name == "miri_alloc" => { + "miri_alloc" => { let default = |ecx: &mut MiriInterpCx<'tcx>| { // Only call `check_shim` when `#[global_allocator]` isn't used. When that // macro is used, we act like no shim exists, so that the exported function can run. @@ -533,37 +533,22 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let size = ecx.read_target_usize(size)?; let align = ecx.read_target_usize(align)?; - ecx.check_rustc_alloc_request(size, align)?; - - let memory_kind = match link_name.as_str() { - "miri_alloc" => MiriMemoryKind::Miri, - _ => MiriMemoryKind::Rust, - }; + this.check_rustc_alloc_request(size, align)?; let ptr = ecx.allocate_ptr( Size::from_bytes(size), Align::from_bytes(align).unwrap(), - memory_kind.into(), + MiriMemoryKind::Miri.into(), AllocInit::Uninit, )?; ecx.write_pointer(ptr, dest) }; - match link_name.as_str() { - "miri_alloc" => { - default(this)?; - return interp_ok(EmulateItemResult::NeedsReturn); - } - _ => return this.emulate_allocator(), - } - } - name if name == this.mangle_internal_symbol("__rust_alloc_zeroed") => { - return this.emulate_allocator(); + default(this)?; + return interp_ok(EmulateItemResult::NeedsReturn); } - name if name == this.mangle_internal_symbol("__rust_dealloc") - || name == "miri_dealloc" => - { + "miri_dealloc" => { let default = |ecx: &mut MiriInterpCx<'tcx>| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. @@ -573,29 +558,16 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let old_size = ecx.read_target_usize(old_size)?; let align = ecx.read_target_usize(align)?; - let memory_kind = match link_name.as_str() { - "miri_dealloc" => MiriMemoryKind::Miri, - _ => MiriMemoryKind::Rust, - }; - // No need to check old_size/align; we anyway check that they match the allocation. ecx.deallocate_ptr( ptr, Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())), - memory_kind.into(), + MiriMemoryKind::Miri.into(), ) }; - match link_name.as_str() { - "miri_dealloc" => { - default(this)?; - return interp_ok(EmulateItemResult::NeedsReturn); - } - _ => return this.emulate_allocator(), - } - } - name if name == this.mangle_internal_symbol("__rust_realloc") => { - return this.emulate_allocator(); + default(this)?; + return interp_ok(EmulateItemResult::NeedsReturn); } name if name == this.mangle_internal_symbol("__rust_no_alloc_shim_is_unstable_v2") => { // This is a no-op shim that only exists to prevent making the allocator shims instantly stable. From d2499e92f5b0297cd82ec829fcb34bd5fc703ea0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:14:18 +0000 Subject: [PATCH 5/8] Use weak linkage for the alloc error handler too --- .../rustc_codegen_cranelift/src/allocator.rs | 43 ++----------------- compiler/rustc_codegen_gcc/src/allocator.rs | 30 +------------ compiler/rustc_codegen_gcc/src/lib.rs | 10 +---- compiler/rustc_codegen_llvm/src/allocator.rs | 31 +------------ compiler/rustc_codegen_llvm/src/lib.rs | 10 +---- .../src/back/symbol_export.rs | 3 +- compiler/rustc_codegen_ssa/src/base.rs | 11 +---- .../rustc_codegen_ssa/src/traits/backend.rs | 8 +--- compiler/rustc_metadata/src/creader.rs | 12 ++---- .../src/rmeta/decoder/cstore_impl.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 4 -- library/alloc/src/alloc.rs | 9 ++-- library/alloc/src/lib.rs | 1 + library/std/src/alloc.rs | 7 +-- src/tools/miri/src/shims/foreign_items.rs | 24 ----------- 15 files changed, 29 insertions(+), 175 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index b57bef7ee31cb..0cddea5a7227f 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -2,9 +2,7 @@ // Adapted from rustc use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; -use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, -}; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_codegen_ssa::base::needs_allocator_shim; use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; @@ -14,48 +12,15 @@ use crate::prelude::*; /// Returns whether an allocator shim was created pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { if needs_allocator_shim(tcx) { - codegen_inner( - tcx, - module, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); + codegen_inner(tcx, module, tcx.sess.opts.unstable_opts.oom); true } else { false } } -fn codegen_inner( - tcx: TyCtxt<'_>, - module: &mut dyn Module, - alloc_error_handler_kind: AllocatorKind, - oom_strategy: OomStrategy, -) { - let usize_ty = module.target_config().pointer_type(); - - if alloc_error_handler_kind == AllocatorKind::Default { - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], - }; - crate::common::create_wrapper_function( - module, - sig, - &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), - &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT), - ); - } - - let data_id = module - .declare_data( - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - Linkage::Export, - false, - false, - ) - .unwrap(); +fn codegen_inner(tcx: TyCtxt<'_>, module: &mut dyn Module, oom_strategy: OomStrategy) { + let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); let mut data = DataDescription::new(); data.set_align(1); let val = oom_strategy.should_panic(); diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index ce748b8ae555b..44d26b0175049 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -1,10 +1,7 @@ use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute}; -use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, -}; -use rustc_middle::bug; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; @@ -13,33 +10,10 @@ use crate::GccContext; #[cfg(feature = "master")] use crate::base::symbol_visibility_to_gcc; -pub(crate) unsafe fn codegen( - tcx: TyCtxt<'_>, - mods: &mut GccContext, - _module_name: &str, - alloc_error_handler_kind: AllocatorKind, -) { +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str) { let context = &mods.context; - let usize = match tcx.sess.target.pointer_width { - 16 => context.new_type::(), - 32 => context.new_type::(), - 64 => context.new_type::(), - tws => bug!("Unsupported target word size for int: {}", tws), - }; let i8 = context.new_type::(); - if alloc_error_handler_kind == AllocatorKind::Default { - // FIXME(bjorn3): Add noreturn attribute - create_wrapper_function( - tcx, - context, - &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), - Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)), - &[usize, usize], - None, - ); - } - let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); let global = context.new_global(None, GlobalKind::Exported, i8, name); #[cfg(feature = "master")] diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index d606a1636df04..f2baac5be6fe3 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -95,7 +95,6 @@ use back::lto::{ThinBuffer, ThinData}; use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ @@ -277,12 +276,7 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { } impl ExtraBackendMethods for GccCodegenBackend { - fn codegen_allocator( - &self, - tcx: TyCtxt<'_>, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, - ) -> Self::Module { + fn codegen_allocator(&self, tcx: TyCtxt<'_>, module_name: &str) -> Self::Module { let mut mods = GccContext { context: Arc::new(SyncContext::new(new_context(tcx))), relocation_model: tcx.sess.relocation_model(), @@ -291,7 +285,7 @@ impl ExtraBackendMethods for GccCodegenBackend { }; unsafe { - allocator::codegen(tcx, &mut mods, module_name, alloc_error_handler_kind); + allocator::codegen(tcx, &mut mods, module_name); } mods } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 3eb3388c6af5d..b1607a870a92f 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,9 +1,6 @@ use libc::c_uint; -use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, -}; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; -use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; use rustc_symbol_mangling::mangle_internal_symbol; @@ -13,33 +10,9 @@ use crate::declare::declare_simple_fn; use crate::llvm::{self, False, True, Type}; use crate::{SimpleCx, attributes, debuginfo}; -pub(crate) unsafe fn codegen( - tcx: TyCtxt<'_>, - cx: SimpleCx<'_>, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, -) { - let usize = match tcx.sess.target.pointer_width { - 16 => cx.type_i16(), - 32 => cx.type_i32(), - 64 => cx.type_i64(), - tws => bug!("Unsupported target word size for int: {}", tws), - }; +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, cx: SimpleCx<'_>, module_name: &str) { let i8 = cx.type_i8(); - if alloc_error_handler_kind == AllocatorKind::Default { - // rust alloc error handler - create_wrapper_function( - tcx, - &cx, - &mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), - Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)), - &[usize, usize], // size, align - None, - true, - ); - } - unsafe { // __rust_alloc_error_handler_should_panic let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 44432009a6a95..eaead726595ef 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -28,7 +28,6 @@ use back::write::{create_informational_target_machine, create_target_machine}; use context::SimpleCx; use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig}; use llvm_util::target_config; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ @@ -104,17 +103,12 @@ impl Drop for TimeTraceProfiler { } impl ExtraBackendMethods for LlvmCodegenBackend { - fn codegen_allocator<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, - ) -> ModuleLlvm { + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str) -> ModuleLlvm { let module_llvm = ModuleLlvm::new_metadata(tcx, module_name); let cx = SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size); unsafe { - allocator::codegen(tcx, cx, module_name, alloc_error_handler_kind); + allocator::codegen(tcx, cx, module_name); } module_llvm } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index c96f7cf662b3a..c2b7140d7a445 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,7 +1,7 @@ use std::collections::hash_map::Entry::*; use rustc_abi::{CanonAbi, X86Call}; -use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, NO_ALLOC_SHIM_IS_UNSTABLE}; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; @@ -214,7 +214,6 @@ fn exported_symbols_provider_local<'tcx>( // Mark allocator shim symbols as exported only if they were generated. if needs_allocator_shim(tcx) { for symbol_name in [ - mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER), mangle_internal_symbol(tcx, OomStrategy::SYMBOL), mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), ] { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f65b19f12fe31..4b8e4cba29a9f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -708,15 +708,8 @@ pub fn codegen_crate( if needs_allocator_shim(tcx) { let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); - let module_llvm = tcx.sess.time("write_allocator_module", || { - backend.codegen_allocator( - tcx, - &llmod_id, - // If allocator_kind is Some then alloc_error_handler_kind must - // also be Some. - tcx.alloc_error_handler_kind(()).unwrap(), - ) - }); + let module_llvm = + tcx.sess.time("write_allocator_module", || backend.codegen_allocator(tcx, &llmod_id)); ongoing_codegen.wait_for_signal_to_codegen_item(); ongoing_codegen.check_for_errors(tcx.sess); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index ff320754e6844..f34f0f733778a 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -1,7 +1,6 @@ use std::any::Any; use std::hash::Hash; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_metadata::EncodedMetadata; @@ -103,12 +102,7 @@ pub trait CodegenBackend { pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync { - fn codegen_allocator<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, - ) -> Self::Module; + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str) -> Self::Module; /// This generates the codegen unit and returns it along with /// a `u64` giving an estimate of the unit's processing cost. diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index cca14b8e652f4..f9369c0c98a86 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -7,7 +7,7 @@ use std::str::FromStr; use std::time::Duration; use std::{cmp, env, iter}; -use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, AllocatorKind, global_fn_name}; +use rustc_ast::expand::allocator::{AllocatorKind, global_fn_name}; use rustc_ast::{self as ast, *}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::owned_slice::OwnedSlice; @@ -25,8 +25,8 @@ use rustc_middle::ty::data_structures::IndexSet; use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; use rustc_proc_macro::bridge::client::ProcMacro; use rustc_session::config::{ - self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers, - TargetModifier, + self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OomStrategy, + OptionsTargetModifiers, TargetModifier, }; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; use rustc_session::lint::{self, BuiltinLintDiag}; @@ -322,10 +322,6 @@ impl CStore { self.allocator_kind } - pub(crate) fn alloc_error_handler_kind(&self) -> Option { - self.alloc_error_handler_kind - } - pub(crate) fn has_global_allocator(&self) -> bool { self.has_global_allocator } @@ -1068,7 +1064,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { spans => !spans.is_empty(), }; self.cstore.has_alloc_error_handler = - match &*fn_spans(krate, Symbol::intern(ALLOC_ERROR_HANDLER)) { + match &*fn_spans(krate, Symbol::intern(OomStrategy::SYMBOL)) { [span1, span2, ..] => { self.dcx().emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 375928c22459f..3bdfe15890578 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -432,7 +432,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { provide_cstore_hooks(providers); providers.queries = rustc_middle::query::Providers { allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), - alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), is_private_dep: |_tcx, LocalCrate| false, native_library: |tcx, id| { tcx.native_libraries(id.krate) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3668f4e12f5d9..b4d025a9ad0d7 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2257,10 +2257,6 @@ rustc_queries! { eval_always desc { "getting the allocator kind for the current crate" } } - query alloc_error_handler_kind(_: ()) -> Option { - eval_always - desc { "alloc error handler kind for the current crate" } - } query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap> { desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 819395077d68b..e8bb9ea88a0c5 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -359,8 +359,8 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg(not(no_global_oom_handling))] unsafe extern "Rust" { // This is the magic symbol to call the global alloc error handler. rustc generates - // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the - // default implementations below (`__rdl_oom`) otherwise. + // it if there is a `#[alloc_error_handler]`, or to the weak implementations below + // is called otherwise. #[rustc_std_internal_symbol] fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } @@ -421,10 +421,9 @@ pub const fn handle_alloc_error(layout: Layout) -> ! { #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] pub mod __alloc_error_handler { - // called via generated `__rust_alloc_error_handler` if there is no - // `#[alloc_error_handler]`. #[rustc_std_internal_symbol] - pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_alloc_error_handler(size: usize, _align: usize) -> ! { unsafe extern "Rust" { // This symbol is emitted by rustc next to __rust_alloc_error_handler. // Its value depends on the -Zoom={panic,abort} compiler option. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index f416732a8d63b..8c136978d6048 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -128,6 +128,7 @@ #![feature(iter_next_chunk)] #![feature(layout_for_ptr)] #![feature(legacy_receiver_trait)] +#![feature(linkage)] #![feature(local_waker)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array_transpose)] diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 14996370d6e67..17c3a1fd70d67 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -358,9 +358,10 @@ fn default_alloc_error_hook(layout: Layout) { // This is the default path taken on OOM, and the only path taken on stable with std. // Crucially, it does *not* call any user-defined code, and therefore users do not have to // worry about allocation failure causing reentrancy issues. That makes it different from - // the default `__rdl_oom` defined in alloc (i.e., the default alloc error handler that is - // called when there is no `#[alloc_error_handler]`), which triggers a regular panic and - // thus can invoke a user-defined panic hook, executing arbitrary user-defined code. + // the default `__rust_alloc_error_handler` defined in alloc (i.e., the default alloc error + // handler that is called when there is no `#[alloc_error_handler]`), which triggers a + // regular panic and thus can invoke a user-defined panic hook, executing arbitrary + // user-defined code. rtprintpanic!("memory allocation of {} bytes failed\n", layout.size()); } } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index a8f7540a2010f..830066cc75192 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -4,7 +4,6 @@ use std::path::Path; use rustc_abi::{Align, AlignFromBytesError, CanonAbi, Size}; use rustc_apfloat::Float; -use rustc_ast::expand::allocator::alloc_error_handler_name; use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; @@ -50,29 +49,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { let this = self.eval_context_mut(); - // Some shims forward to other MIR bodies. - match link_name.as_str() { - name if name == this.mangle_internal_symbol("__rust_alloc_error_handler") => { - // Forward to the right symbol that implements this function. - let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else { - // in real code, this symbol does not exist without an allocator - throw_unsup_format!( - "`__rust_alloc_error_handler` cannot be called when no alloc error handler is set" - ); - }; - let name = Symbol::intern( - this.mangle_internal_symbol(alloc_error_handler_name(handler_kind)), - ); - let handler = - this.lookup_exported_symbol(name)?.expect("missing alloc error handler symbol"); - return interp_ok(Some(handler)); - } - _ => {} - } - - // FIXME: avoid allocating memory - let dest = this.force_allocation(dest)?; - // The rest either implements the logic, or falls back to `lookup_exported_symbol`. match this.emulate_foreign_item_inner(link_name, abi, args, &dest)? { EmulateItemResult::NeedsReturn => { From 98c33c08f398afb7f44635db7d5c67db313a0242 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:02:11 +0000 Subject: [PATCH 6/8] Provide a default for __rust_alloc_error_handler_should_panic --- library/alloc/src/alloc.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index e8bb9ea88a0c5..4ce8ceed6f4af 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -359,7 +359,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg(not(no_global_oom_handling))] unsafe extern "Rust" { // This is the magic symbol to call the global alloc error handler. rustc generates - // it if there is a `#[alloc_error_handler]`, or to the weak implementations below + // it if there is an `#[alloc_error_handler]`, or to the weak implementations below // is called otherwise. #[rustc_std_internal_symbol] fn __rust_alloc_error_handler(size: usize, align: usize) -> !; @@ -424,14 +424,16 @@ pub mod __alloc_error_handler { #[rustc_std_internal_symbol] #[linkage = "weak"] pub unsafe extern "Rust" fn __rust_alloc_error_handler(size: usize, _align: usize) -> ! { - unsafe extern "Rust" { - // 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; - } - - if unsafe { __rust_alloc_error_handler_should_panic != 0 } { + // This symbol is normally overwritten by rustc next to __rust_alloc_error_handler. + // However when skipping the allocator handler shim the value here is used which + // corresponds to -Zoom=abort. + // Its value depends on the -Zoom={panic,abort} compiler option. + #[rustc_std_internal_symbol] + #[linkage = "weak"] + #[allow(non_upper_case_globals)] + static __rust_alloc_error_handler_should_panic: u8 = 0; + + if __rust_alloc_error_handler_should_panic != 0 { panic!("memory allocation of {size} bytes failed") } else { core::panicking::panic_nounwind_fmt( From fcf0323ffe3bfac546e56b0a1a40ddef7124622e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:42:40 +0000 Subject: [PATCH 7/8] Revert some miri changes --- library/alloc/src/alloc.rs | 8 +- src/tools/miri/src/helpers.rs | 15 +++ src/tools/miri/src/shims/alloc.rs | 29 +++++ src/tools/miri/src/shims/foreign_items.rs | 101 ++++++++++++++++-- .../fail/alloc/alloc_error_handler.stderr | 2 +- .../alloc/alloc_error_handler_custom.stderr | 2 +- .../alloc/alloc_error_handler_no_std.stderr | 2 +- 7 files changed, 142 insertions(+), 17 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 4ce8ceed6f4af..22d2a6be187f3 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -10,10 +10,12 @@ use core::ptr::{self, NonNull}; unsafe extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates - // them to call the global allocator if there is a `#[global_allocator]` attribute - // (the code expanding that attribute macro generates those functions), or to call + // them to call `GLOBAL.alloc` etc. if there is a `#[global_allocator]` attribute + // (the code expanding that attribute macro generates those functions), or if not // the default implementations in std (weak symbols in `library/std/src/alloc.rs`) - // otherwise. + // is used otherwise. + // The rustc fork of LLVM 14 and earlier also special-cases these function names to + // be able to optimize them like `malloc`, `realloc`, and `free`, respectively. #[rustc_allocator] #[rustc_nounwind] #[rustc_std_internal_symbol] diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 4edecc864dd42..3d48c7f71f144 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -988,6 +988,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(()); } + if ["__rust_alloc", "__rust_alloc_zeroed", "__rust_realloc", "__rust_dealloc"] + .contains(&link_name.as_str()) + { + let attrs = self.eval_context_ref().tcx.codegen_fn_attrs(instance.def_id()); + if attrs + .linkage + .map_or(false, |linkage| linkage == rustc_middle::mir::mono::Linkage::WeakAny) + && attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + { + // We intentionally intercept the allocator methods even though libstd provides + // default implementations. + return interp_ok(()); + } + } + throw_machine_stop!(TerminationInfo::SymbolShimClashing { link_name, span: body.span.data(), diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 5e0d93bd4c031..f05c5fbbe1d4f 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -1,4 +1,5 @@ use rustc_abi::{Align, Size}; +use rustc_ast::expand::allocator::AllocatorKind; use crate::*; @@ -53,6 +54,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Align::from_bytes(prev_power_of_two(size)).unwrap() } + /// Emulates calling the internal __rust_* allocator functions + fn emulate_allocator( + &mut self, + default: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx>, + ) -> InterpResult<'tcx, EmulateItemResult> { + let this = self.eval_context_mut(); + + let Some(allocator_kind) = this.tcx.allocator_kind(()) else { + // in real code, this symbol does not exist without an allocator + return interp_ok(EmulateItemResult::NotSupported); + }; + + match allocator_kind { + AllocatorKind::Global => { + // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion + // of this attribute. As such we have to call an exported Rust function, + // and not execute any Miri shim. Somewhat unintuitively doing so is done + // by returning `NotSupported`, which triggers the `lookup_exported_symbol` + // fallback case in `emulate_foreign_item`. + interp_ok(EmulateItemResult::NotSupported) + } + AllocatorKind::Default => { + default(this)?; + interp_ok(EmulateItemResult::NeedsReturn) + } + } + } + fn malloc(&mut self, size: u64, init: AllocInit) -> InterpResult<'tcx, Pointer> { let this = self.eval_context_mut(); let align = this.malloc_align(size); diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 830066cc75192..836911bf76c59 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -1,5 +1,6 @@ use std::collections::hash_map::Entry; use std::io::Write; +use std::iter; use std::path::Path; use rustc_abi::{Align, AlignFromBytesError, CanonAbi, Size}; @@ -501,49 +502,127 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Rust allocation - "miri_alloc" => { + "__rust_alloc" | "miri_alloc" => { let default = |ecx: &mut MiriInterpCx<'tcx>| { // Only call `check_shim` when `#[global_allocator]` isn't used. When that // macro is used, we act like no shim exists, so that the exported function can run. - let [size, align] = ecx.check_shim(abi, CanonAbi::Rust, link_name, args)?; + let [size, align] = ecx.check_shim(abi, Conv::Rust, link_name, args)?; let size = ecx.read_target_usize(size)?; let align = ecx.read_target_usize(align)?; - this.check_rustc_alloc_request(size, align)?; + ecx.check_rustc_alloc_request(size, align)?; + + let memory_kind = match link_name.as_str() { + "__rust_alloc" => MiriMemoryKind::Rust, + "miri_alloc" => MiriMemoryKind::Miri, + _ => unreachable!(), + }; let ptr = ecx.allocate_ptr( Size::from_bytes(size), Align::from_bytes(align).unwrap(), - MiriMemoryKind::Miri.into(), + memory_kind.into(), AllocInit::Uninit, )?; ecx.write_pointer(ptr, dest) }; - default(this)?; - return interp_ok(EmulateItemResult::NeedsReturn); + match link_name.as_str() { + "__rust_alloc" => return this.emulate_allocator(default), + "miri_alloc" => { + default(this)?; + return interp_ok(EmulateItemResult::NeedsReturn); + } + _ => unreachable!(), + } } - "miri_dealloc" => { + "__rust_alloc_zeroed" => { + return this.emulate_allocator(|this| { + // See the comment for `__rust_alloc` why `check_shim` is only called in the + // default case. + let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let size = this.read_target_usize(size)?; + let align = this.read_target_usize(align)?; + + this.check_rustc_alloc_request(size, align)?; + + let ptr = this.allocate_ptr( + Size::from_bytes(size), + Align::from_bytes(align).unwrap(), + MiriMemoryKind::Rust.into(), + AllocInit::Zero, + )?; + + // We just allocated this, the access is definitely in-bounds. + this.write_bytes_ptr( + ptr.into(), + iter::repeat(0u8).take(usize::try_from(size).unwrap()), + ) + .unwrap(); + this.write_pointer(ptr, dest) + }); + } + "__rust_dealloc" | "miri_dealloc" => { let default = |ecx: &mut MiriInterpCx<'tcx>| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align] = - ecx.check_shim(abi, CanonAbi::Rust, link_name, args)?; + ecx.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = ecx.read_pointer(ptr)?; let old_size = ecx.read_target_usize(old_size)?; let align = ecx.read_target_usize(align)?; + let memory_kind = match link_name.as_str() { + "__rust_dealloc" => MiriMemoryKind::Rust, + "miri_dealloc" => MiriMemoryKind::Miri, + _ => unreachable!(), + }; + // No need to check old_size/align; we anyway check that they match the allocation. ecx.deallocate_ptr( ptr, Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())), - MiriMemoryKind::Miri.into(), + memory_kind.into(), ) }; - default(this)?; - return interp_ok(EmulateItemResult::NeedsReturn); + match link_name.as_str() { + "__rust_dealloc" => { + return this.emulate_allocator(default); + } + "miri_dealloc" => { + default(this)?; + return interp_ok(EmulateItemResult::NeedsReturn); + } + _ => unreachable!(), + } + } + "__rust_realloc" => { + return this.emulate_allocator(|this| { + // See the comment for `__rust_alloc` why `check_shim` is only called in the + // default case. + let [ptr, old_size, align, new_size] = + this.check_shim(abi, Conv::Rust, link_name, args)?; + let ptr = this.read_pointer(ptr)?; + let old_size = this.read_target_usize(old_size)?; + let align = this.read_target_usize(align)?; + let new_size = this.read_target_usize(new_size)?; + // No need to check old_size; we anyway check that they match the allocation. + + this.check_rustc_alloc_request(new_size, align)?; + + let align = Align::from_bytes(align).unwrap(); + let new_ptr = this.reallocate_ptr( + ptr, + Some((Size::from_bytes(old_size), align)), + Size::from_bytes(new_size), + align, + MiriMemoryKind::Rust.into(), + AllocInit::Uninit, + )?; + this.write_pointer(new_ptr, dest) + }); } name if name == this.mangle_internal_symbol("__rust_no_alloc_shim_is_unstable_v2") => { // This is a no-op shim that only exists to prevent making the allocator shims instantly stable. diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr index d67dabd693543..9bc1382d3a966 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr @@ -9,7 +9,7 @@ LL | ABORT() = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC = note: inside `std::process::abort` at RUSTLIB/std/src/process.rs:LL:CC = note: inside `std::alloc::rust_oom` at RUSTLIB/std/src/alloc.rs:LL:CC - = note: inside `std::alloc::_::__rg_oom` at RUSTLIB/std/src/alloc.rs:LL:CC + = note: inside `std::alloc::_::__rust_alloc_error_handler` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside `std::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `std::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC note: inside `main` diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr index 29c56ca81f752..999ad282e0be2 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr @@ -7,7 +7,7 @@ LL | core::intrinsics::abort(); | = note: BACKTRACE: = note: inside `alloc_error_handler` at tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC -note: inside `_::__rg_oom` +note: inside `_::__rust_alloc_error_handler` --> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC | LL | #[alloc_error_handler] diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr index 45ba366acae32..539a1d4c41b92 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr @@ -9,7 +9,7 @@ LL | core::intrinsics::abort(); | = note: BACKTRACE: = note: inside `panic_handler` at tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC - = note: inside `alloc::alloc::__alloc_error_handler::__rdl_oom` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::__alloc_error_handler::__rust_alloc_error_handler` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC note: inside `miri_start` From 1fe27c582e916b21a7a60772d367658d2b27d863 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:55:06 +0000 Subject: [PATCH 8/8] Update tests --- tests/ui/sanitizer/dataflow-abilist.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/ui/sanitizer/dataflow-abilist.txt b/tests/ui/sanitizer/dataflow-abilist.txt index 8ad8cd71e6568..2a39ca7568e3b 100644 --- a/tests/ui/sanitizer/dataflow-abilist.txt +++ b/tests/ui/sanitizer/dataflow-abilist.txt @@ -490,10 +490,6 @@ fun:__dfso_*=uninstrumented fun:__dfso_*=discard # Rust functions. -fun:__rdl_alloc=uninstrumented -fun:__rdl_alloc_zeroed=uninstrumented -fun:__rdl_dealloc=uninstrumented -fun:__rdl_realloc=uninstrumented fun:__rust_alloc=uninstrumented fun:__rust_alloc_error_handler=uninstrumented fun:__rust_alloc_zeroed=uninstrumented