diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index dd8d5ae624a3c..97cef7d08ac4e 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -11,17 +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 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 NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable"; 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 d2b4e1ca824fd..acde6323b061d 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -56,7 +56,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 { @@ -90,6 +90,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; - let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind); + let item = + cx.item(span, Ident::from_str_and_span("__rust_alloc_error_handler", span), attrs, kind); cx.stmt_item(sig_span, item) } diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 5e33b9d606fa5..5805f738d0a1a 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -1,85 +1,23 @@ //! Allocator shim // Adapted from rustc -use rustc_ast::expand::allocator::{ - 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; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; +use rustc_codegen_ssa::base::needs_allocator_shim; use rustc_session::config::OomStrategy; 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( - module, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); - true -} - -fn codegen_inner( - 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, - &global_fn_name(method.name), - &default_fn_name(method.name), - ); - } + if needs_allocator_shim(tcx) { + codegen_inner(module, tcx.sess.opts.unstable_opts.oom); + true + } else { + false } +} - 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, - "__rust_alloc_error_handler", - &alloc_error_handler_name(alloc_error_handler_kind), - ); - +fn codegen_inner(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); diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index f13a75648aea8..4a2eb21c95b15 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -1,72 +1,13 @@ -#[cfg(feature = "master")] -use gccjit::FnAttribute; -use gccjit::{Context, FunctionType, GlobalKind, 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, -}; -use rustc_middle::bug; +use gccjit::GlobalKind; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; use crate::GccContext; -pub(crate) unsafe fn codegen( - tcx: TyCtxt<'_>, - mods: &mut GccContext, - _module_name: &str, - kind: AllocatorKind, - 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::(); - 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 = global_fn_name(method.name); - let to_name = default_fn_name(method.name); - - create_wrapper_function(tcx, context, &from_name, &to_name, &types, output); - } - } - - // FIXME(bjorn3): Add noreturn attribute - create_wrapper_function( - tcx, - context, - "__rust_alloc_error_handler", - alloc_error_handler_name(alloc_error_handler_kind), - &[usize, usize], - None, - ); let name = OomStrategy::SYMBOL.to_string(); let global = context.new_global(None, GlobalKind::Exported, i8, name); @@ -79,77 +20,3 @@ pub(crate) unsafe fn codegen( let value = context.new_rvalue_from_int(i8, 0); global.global_set_initializer_rvalue(value); } - -fn create_wrapper_function( - tcx: TyCtxt<'_>, - context: &Context<'_>, - from_name: &str, - to_name: &str, - types: &[Type<'_>], - output: Option>, -) { - let void = context.new_type::<()>(); - - let args: Vec<_> = types - .iter() - .enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, format!("param{}", index))) - .collect(); - let func = context.new_function( - None, - FunctionType::Exported, - output.unwrap_or(void), - &args, - from_name, - false, - ); - - #[cfg(feature = "master")] - match tcx.sess.default_visibility() { - rustc_target::spec::SymbolVisibility::Hidden => { - func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)) - } - rustc_target::spec::SymbolVisibility::Protected => { - func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Protected)) - } - rustc_target::spec::SymbolVisibility::Interposable => {} - } - - if tcx.sess.must_emit_unwind_tables() { - // TODO(antoyo): emit unwind tables. - } - - let args: Vec<_> = types - .iter() - .enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, format!("param{}", index))) - .collect(); - let callee = context.new_function( - None, - FunctionType::Extern, - output.unwrap_or(void), - &args, - to_name, - false, - ); - #[cfg(feature = "master")] - callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - - let block = func.new_block("entry"); - - let args = args - .iter() - .enumerate() - .map(|(i, _)| func.get_param(i as i32).to_rvalue()) - .collect::>(); - let ret = context.new_call(None, callee, &args); - //llvm::LLVMSetTailCall(ret, True); - if output.is_some() { - block.end_with_return(None, ret); - } else { - block.end_with_void_return(None); - } - - // TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances - // as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643 -} diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index f2efa981f976f..9885eebec488f 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -92,7 +92,6 @@ use errors::LTONotSupported; use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, @@ -287,13 +286,7 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { } impl ExtraBackendMethods for GccCodegenBackend { - fn codegen_allocator( - &self, - tcx: TyCtxt<'_>, - module_name: &str, - kind: AllocatorKind, - 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))), should_combine_object_files: false, @@ -301,7 +294,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); } mods } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 149ded28356b8..5d7f7444ec208 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,78 +1,15 @@ -use libc::c_uint; -use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, -}; -use rustc_middle::bug; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; use crate::common::AsCCharPtr; -use crate::llvm::{self, Context, False, Module, True, Type}; -use crate::{ModuleLlvm, attributes, debuginfo}; +use crate::llvm::{self, False}; +use crate::{ModuleLlvm, debuginfo}; -pub(crate) unsafe fn codegen( - tcx: TyCtxt<'_>, - module_llvm: &mut ModuleLlvm, - module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, -) { +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, module_llvm: &mut ModuleLlvm, module_name: &str) { let llcx = &*module_llvm.llcx; let llmod = module_llvm.llmod(); - let usize = unsafe { - match tcx.sess.target.pointer_width { - 16 => llvm::LLVMInt16TypeInContext(llcx), - 32 => llvm::LLVMInt32TypeInContext(llcx), - 64 => llvm::LLVMInt64TypeInContext(llcx), - tws => bug!("Unsupported target word size for int: {}", tws), - } - }; let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) }; - let i8p = unsafe { llvm::LLVMPointerTypeInContext(llcx, 0) }; - - 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 = global_fn_name(method.name); - let to_name = default_fn_name(method.name); - - create_wrapper_function(tcx, llcx, llmod, &from_name, &to_name, &args, output, false); - } - } - - // rust alloc error handler - create_wrapper_function( - tcx, - llcx, - llmod, - "__rust_alloc_error_handler", - alloc_error_handler_name(alloc_error_handler_kind), - &[usize, usize], // size, align - None, - true, - ); unsafe { // __rust_alloc_error_handler_should_panic @@ -96,80 +33,3 @@ pub(crate) unsafe fn codegen( dbg_cx.finalize(tcx.sess); } } - -fn create_wrapper_function( - tcx: TyCtxt<'_>, - llcx: &Context, - llmod: &Module, - from_name: &str, - to_name: &str, - args: &[&Type], - output: Option<&Type>, - no_return: bool, -) { - unsafe { - let ty = llvm::LLVMFunctionType( - output.unwrap_or_else(|| llvm::LLVMVoidTypeInContext(llcx)), - args.as_ptr(), - args.len() as c_uint, - False, - ); - let llfn = llvm::LLVMRustGetOrInsertFunction( - llmod, - from_name.as_c_char_ptr(), - from_name.len(), - ty, - ); - let no_return = if no_return { - // -> ! DIFlagNoReturn - let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]); - Some(no_return) - } else { - None - }; - - llvm::set_visibility(llfn, llvm::Visibility::from_generic(tcx.sess.default_visibility())); - - if tcx.sess.must_emit_unwind_tables() { - let uwtable = - attributes::uwtable_attr(llcx, tcx.sess.opts.unstable_opts.use_sync_unwind); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); - } - - let callee = - llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_c_char_ptr(), to_name.len(), ty); - if let Some(no_return) = no_return { - // -> ! DIFlagNoReturn - attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]); - } - llvm::set_visibility(callee, llvm::Visibility::Hidden); - - let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr()); - - let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); - llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); - let args = args - .iter() - .enumerate() - .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) - .collect::>(); - let ret = llvm::LLVMBuildCallWithOperandBundles( - llbuilder, - ty, - callee, - args.as_ptr(), - args.len() as c_uint, - [].as_ptr(), - 0 as c_uint, - c"".as_ptr(), - ); - llvm::LLVMSetTailCall(ret, True); - if output.is_some() { - llvm::LLVMBuildRet(llbuilder, ret); - } else { - llvm::LLVMBuildRetVoid(llbuilder); - } - llvm::LLVMDisposeBuilder(llbuilder); - } -} diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0de0c6a7a89ec..4d0322e362c4f 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -29,7 +29,6 @@ use back::owned_target_machine::OwnedTargetMachine; use back::write::{create_informational_target_machine, create_target_machine}; use errors::ParseTargetMachineConfig; pub use llvm_util::target_features_cfg; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, @@ -111,16 +110,10 @@ impl Drop for TimeTraceProfiler { } impl ExtraBackendMethods for LlvmCodegenBackend { - fn codegen_allocator<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, - ) -> ModuleLlvm { + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str) -> ModuleLlvm { let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name); unsafe { - allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut module_llvm, 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 60ab291935256..17bdbef5c9883 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,6 +1,6 @@ use std::collections::hash_map::Entry::*; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, 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}; @@ -16,7 +16,7 @@ use rustc_session::config::{CrateType, OomStrategy}; 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()) @@ -206,20 +206,13 @@ fn exported_symbols_provider_local( } // Mark allocator shim symbols as exported only if they were generated. - if allocator_kind_for_codegen(tcx).is_some() { - for symbol_name in ALLOCATOR_METHODS - .iter() - .map(|method| format!("__rust_{}", method.name)) - .chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()]) - { - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); - - symbols.push((exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Text, - used: false, - })); - } + if needs_allocator_shim(tcx) { + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &OomStrategy::SYMBOL)); + symbols.push((exported_symbol, SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Text, + used: false, + })); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(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 77e1fed720dfb..65c3b76df53e8 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -4,7 +4,7 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name}; +use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, global_fn_name}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::{Lrc, par_map}; @@ -584,7 +584,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` @@ -595,7 +595,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( @@ -664,19 +664,11 @@ pub fn codegen_crate( start_async_codegen(backend.clone(), tcx, target_cpu, metadata, metadata_module); // 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(), - ) - }); + 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 ebcf118b90380..ff5a001fb82e5 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; @@ -100,13 +99,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, - kind: AllocatorKind, - 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 c8715f94d5dd3..e0abfa4247a18 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -8,7 +8,7 @@ use std::time::Duration; use std::{cmp, env, iter}; use proc_macro::bridge::client::ProcMacro; -use rustc_ast::expand::allocator::{AllocatorKind, alloc_error_handler_name, 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; @@ -23,7 +23,7 @@ use rustc_hir::definitions::Definitions; use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; -use rustc_session::config::{self, CrateType, ExternLocation}; +use rustc_session::config::{self, CrateType, ExternLocation, OomStrategy}; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; use rustc_session::lint::{self, BuiltinLintDiag}; use rustc_session::output::validate_crate_name; @@ -264,10 +264,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 } @@ -1127,6 +1123,8 @@ fn global_allocator_spans(krate: &ast::Crate) -> Vec { fn visit_item(&mut self, item: &'ast ast::Item) { if item.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); } @@ -1149,6 +1147,8 @@ fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec { fn visit_item(&mut self, item: &'ast ast::Item) { if item.ident.name == self.name && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) + // Ignore the default alloc error handler in libstd with weak linkage + && attr::find_by_name(&item.attrs, sym::linkage).is_none() { self.spans.push(item.span); } @@ -1156,7 +1156,7 @@ fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec { } } - let name = Symbol::intern(alloc_error_handler_name(AllocatorKind::Global)); + let name = Symbol::intern(OomStrategy::SYMBOL); let mut f = Finder { name, spans: Vec::new() }; visit::walk_crate(&mut f, krate); f.spans diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 527f2f10205a6..5211e650acbe8 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -435,7 +435,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 2c2dffe8b88f0..e826922c7a358 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1983,10 +1983,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/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 7b17966343084..cb3f83984578f 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -887,19 +887,11 @@ 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 - // 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/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index ae34fc653260e..235ad9ff836d3 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -12,12 +12,12 @@ use core::ptr::{self, NonNull}; extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates - // them to call `__rg_alloc` etc. 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`) - // 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. + // 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`) + // 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] fn __rust_alloc(size: usize, align: usize) -> *mut u8; @@ -357,8 +357,8 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg(not(no_global_oom_handling))] 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 an `#[alloc_error_handler]`, or to the weak implementations below + // is called otherwise. fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } @@ -421,14 +421,40 @@ pub use std::alloc::handle_alloc_error; #[doc(hidden)] #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(not(bootstrap))] +pub mod __alloc_error_handler { + #[rustc_std_internal_symbol] + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_alloc_error_handler(size: usize, _align: usize) -> ! { + // 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( + format_args!("memory allocation of {size} bytes failed"), + /* force_no_backtrace */ false, + ) + } + } +} + +#[cfg(all(not(no_global_oom_handling), not(test)))] +#[doc(hidden)] +#[allow(unused_attributes)] +#[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(bootstrap)] 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) -> ! { extern "Rust" { - // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. static __rust_alloc_error_handler_should_panic: u8; } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 40759cb0ba83c..a8ba95e91b258 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -124,6 +124,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 5d51d6a0c78a8..2c64da8f5640e 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -357,9 +357,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()); } } @@ -380,18 +381,72 @@ pub fn rust_oom(layout: Layout) -> ! { #[doc(hidden)] #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(not(bootstrap))] 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 + // 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 + #[rustc_std_internal_symbol] + #[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 { + let layout = Layout::from_size_align_unchecked(size, align); + System.alloc(layout) + } + } + + #[rustc_std_internal_symbol] + #[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] + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_realloc( + ptr: *mut u8, + old_size: usize, + align: usize, + new_size: usize, + ) -> *mut u8 { + // SAFETY: see the guarantees expected by `Layout::from_size_align` and + // `GlobalAlloc::realloc`. + unsafe { + let old_layout = Layout::from_size_align_unchecked(old_size, align); + System.realloc(ptr, old_layout, new_size) + } + } + + #[rustc_std_internal_symbol] + #[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 { + let layout = Layout::from_size_align_unchecked(size, align); + System.alloc_zeroed(layout) + } + } +} + +#[cfg(not(test))] +#[doc(hidden)] +#[allow(unused_attributes)] +#[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(bootstrap)] +pub mod __default_lib_allocator { + use super::{GlobalAlloc, Layout, System}; + #[rustc_std_internal_symbol] pub unsafe extern "C" fn __rdl_alloc(size: usize, align: usize) -> *mut u8 { // SAFETY: see the guarantees expected by `Layout::from_size_align` and diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 2b27400e9e362..308455feaf619 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -919,7 +919,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if fn_abi.conv != exp_abi { throw_ub_format!( "calling a function with ABI {:?} using caller ABI {:?}", - exp_abi, fn_abi.conv); + exp_abi, + fn_abi.conv + ); } interp_ok(()) } @@ -964,6 +966,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/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 7b2a0d6f4d641..09c77267717e4 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -5,16 +5,15 @@ use std::path::Path; use rustc_abi::{Align, AlignFromBytesError, 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; -use rustc_middle::{mir, ty}; +use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::Ty; +use rustc_middle::{mir, ty}; use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; - use self::helpers::{ToHost, ToSoft}; use super::alloc::EvalContextExt as _; use super::backtrace::EvalContextExt as _; @@ -50,25 +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() { - "__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 = alloc_error_handler_name(handler_kind); - let handler = this - .lookup_exported_symbol(Symbol::intern(name))? - .expect("missing alloc error handler symbol"); - return interp_ok(Some(handler)); - } - _ => {} - } - // 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 => { @@ -135,7 +115,7 @@ 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); let symbol_name = if let Some(export_name) = attrs.export_name { @@ -146,39 +126,71 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Skip over items without an explicitly defined symbol name. return interp_ok(()); }; + let is_weak = + attrs.linkage.map_or(false, |linkage| linkage == Linkage::WeakAny); if symbol_name == link_name { - 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), - }); + 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)) } }; @@ -279,7 +291,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Miri-specific extern functions "miri_start_unwind" => { - let [payload] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::Rust, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } @@ -288,7 +300,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.run_provenance_gc(); } "miri_get_alloc_id" => { - let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { err_machine_stop!(TerminationInfo::Abort(format!( @@ -298,7 +310,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?; } "miri_print_borrow_state" => { - let [id, show_unnamed] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let [id, show_unnamed] = this.check_shim(abi, Conv::Rust, link_name, args)?; let id = this.read_scalar(id)?.to_u64()?; let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?; if let Some(id) = std::num::NonZero::new(id).map(AllocId) @@ -312,8 +324,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_pointer_name" => { // This associates a name to a tag. Very useful for debugging, and also makes // tests more strict. - let [ptr, nth_parent, name] = - this.check_shim(abi, Conv::Rust, link_name, args)?; + let [ptr, nth_parent, name] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let nth_parent = this.read_scalar(nth_parent)?.to_u8()?; let name = this.read_immediate(name)?; @@ -337,8 +348,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.machine.static_roots.push(alloc_id); } "miri_host_to_target_path" => { - let [ptr, out, out_size] = - this.check_shim(abi, Conv::Rust, link_name, args)?; + let [ptr, out, out_size] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; let out_size = this.read_scalar(out_size)?.to_target_usize(this)?; @@ -429,13 +439,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Aborting the process. "exit" => { - let [code] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [code] = this.check_shim(abi, Conv::C, link_name, args)?; let code = this.read_scalar(code)?.to_i32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } "abort" => { - let [] = this.check_shim(abi, Conv::C , link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; throw_machine_stop!(TerminationInfo::Abort( "the program aborted execution".to_owned() )) @@ -443,8 +452,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Standard C allocation "malloc" => { - let [size] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [size] = this.check_shim(abi, Conv::C, link_name, args)?; let size = this.read_target_usize(size)?; if size <= this.max_size_of_val().bytes() { let res = this.malloc(size, /*zero_init:*/ false)?; @@ -458,8 +466,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "calloc" => { - let [items, elem_size] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [items, elem_size] = this.check_shim(abi, Conv::C, link_name, args)?; let items = this.read_target_usize(items)?; let elem_size = this.read_target_usize(elem_size)?; if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) { @@ -474,14 +481,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "free" => { - let [ptr] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; this.free(ptr)?; } "realloc" => { - let [old_ptr, new_size] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [old_ptr, new_size] = this.check_shim(abi, Conv::C, link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; let new_size = this.read_target_usize(new_size)?; if new_size <= this.max_size_of_val().bytes() { @@ -619,8 +624,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // C memory handling functions "memcmp" => { - let [left, right, n] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [left, right, n] = this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; let n = Size::from_bytes(this.read_target_usize(n)?); @@ -644,8 +648,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_i32(result), dest)?; } "memrchr" => { - let [ptr, val, num] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -671,8 +674,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "memchr" => { - let [ptr, val, num] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -695,8 +697,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "strlen" => { - let [ptr] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_c_str(ptr)?.len(); @@ -706,8 +707,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "wcslen" => { - let [ptr] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_wchar_t_str(ptr)?.len(); @@ -717,8 +717,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "memcpy" => { - let [ptr_dest, ptr_src, n] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr_dest, ptr_src, n] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; let n = this.read_target_usize(n)?; @@ -732,8 +731,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr_dest, dest)?; } "strcpy" => { - let [ptr_dest, ptr_src] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr_dest, ptr_src] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; @@ -878,8 +876,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgammaf_r" => { - let [x, signp] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?; let x = this.read_scalar(x)?.to_f32()?; let signp = this.deref_pointer(signp)?; @@ -890,8 +887,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgamma_r" => { - let [x, signp] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?; let x = this.read_scalar(x)?.to_f64()?; let signp = this.deref_pointer(signp)?; @@ -904,8 +900,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // LLVM intrinsics "llvm.prefetch" => { - let [p, rw, loc, ty] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [p, rw, loc, ty] = this.check_shim(abi, Conv::C, link_name, args)?; let _ = this.read_pointer(p)?; let rw = this.read_scalar(rw)?.to_i32()?; @@ -932,7 +927,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm // `{i,u}8x16_popcnt` functions. name if name.starts_with("llvm.ctpop.v") => { - let [op] = this.check_shim(abi, Conv::C , link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; 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 3642f3f28ca2a..79a357cd541d1 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 d12e119bce3dd..2d8927d47ad90 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 f495d65a8b017..e592a83c47567 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 `start`