From 7967915c7b456d59fd963260822d3cf583969948 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Fri, 15 Mar 2024 19:45:46 +0000 Subject: CFI: Use Instance at callsites We already use `Instance` at declaration sites when available to glean additional information about possible abstractions of the type in use. This does the same when possible at callsites as well. The primary purpose of this change is to allow CFI to alter how it generates type information for indirect calls through `Virtual` instances. --- compiler/rustc_codegen_ssa/src/base.rs | 19 +++++++++++++------ compiler/rustc_codegen_ssa/src/mir/block.rs | 19 +++++++++++++------ compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- compiler/rustc_codegen_ssa/src/size_of_val.rs | 10 +++++++++- compiler/rustc_codegen_ssa/src/traits/builder.rs | 4 +++- 5 files changed, 39 insertions(+), 15 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 13809ef72ec..f7f2bfca838 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -462,27 +462,34 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let ptr_ty = cx.type_ptr(); let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx); - let (start_fn, start_ty, args) = if let EntryFnType::Main { sigpipe } = entry_type { + let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type + { let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None); - let start_fn = cx.get_fn_addr(ty::Instance::expect_resolve( + let start_instance = ty::Instance::expect_resolve( cx.tcx(), ty::ParamEnv::reveal_all(), start_def_id, cx.tcx().mk_args(&[main_ret_ty.into()]), - )); + ); + let start_fn = cx.get_fn_addr(start_instance); let i8_ty = cx.type_i8(); let arg_sigpipe = bx.const_u8(sigpipe); let start_ty = cx.type_func(&[cx.val_ty(rust_main), isize_ty, ptr_ty, i8_ty], isize_ty); - (start_fn, start_ty, vec![rust_main, arg_argc, arg_argv, arg_sigpipe]) + ( + start_fn, + start_ty, + vec![rust_main, arg_argc, arg_argv, arg_sigpipe], + Some(start_instance), + ) } else { debug!("using user-defined start fn"); let start_ty = cx.type_func(&[isize_ty, ptr_ty], isize_ty); - (rust_main, start_ty, vec![arg_argc, arg_argv]) + (rust_main, start_ty, vec![arg_argc, arg_argv], None) }; - let result = bx.call(start_ty, None, None, start_fn, &args, None); + let result = bx.call(start_ty, None, None, start_fn, &args, None, instance); if cx.sess().target.os.contains("uefi") { bx.ret(result); } else { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index dcc27a4f0e5..8c668597a43 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -232,6 +232,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { ret_llbb, unwind_block, self.funclet(fx), + instance, ); if fx.mir[self.bb].is_cleanup { bx.apply_attrs_to_cleanup_callsite(invokeret); @@ -247,7 +248,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } MergingSucc::False } else { - let llret = bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx)); + let llret = + bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance); if fx.mir[self.bb].is_cleanup { bx.apply_attrs_to_cleanup_callsite(llret); } @@ -502,7 +504,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = location.ty(self.mir, bx.tcx()).ty; let ty = self.monomorphize(ty); let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty); - let instance = drop_fn.clone(); if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def { // we don't actually need to drop anything. @@ -518,7 +519,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args1 = [place.llval]; &args1[..] }; - let (drop_fn, fn_abi) = + let (drop_fn, fn_abi, drop_instance) = match ty.kind() { // FIXME(eddyb) perhaps move some of this logic into // `Instance::resolve_drop_in_place`? @@ -550,6 +551,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE) .get_fn(bx, vtable, ty, fn_abi), fn_abi, + virtual_drop, ) } ty::Dynamic(_, _, ty::DynStar) => { @@ -592,9 +594,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE) .get_fn(bx, meta.immediate(), ty, fn_abi), fn_abi, + virtual_drop, ) } - _ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())), + _ => ( + bx.get_fn_addr(drop_fn), + bx.fn_abi_of_instance(drop_fn, ty::List::empty()), + drop_fn, + ), }; helper.do_call( self, @@ -605,7 +612,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some((ReturnDest::Nothing, target)), unwind, &[], - Some(instance), + Some(drop_instance), mergeable_succ, ) } @@ -1699,7 +1706,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { let fn_ty = bx.fn_decl_backend_type(fn_abi); - let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref()); + let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref(), None); bx.apply_attrs_to_cleanup_callsite(llret); } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 15f2e0e56d8..8abbbe2bfb9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { None }; - bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None) + bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None, Some(instance)) } else { bx.get_static(def_id) }; diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index e2e95cede60..c250cc26823 100644 --- a/compiler/rustc_codegen_ssa/src/size_of_val.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -70,7 +70,15 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // (But we are in good company, this code is duplicated plenty of times.) let fn_ty = bx.fn_decl_backend_type(fn_abi); - bx.call(fn_ty, /* fn_attrs */ None, Some(fn_abi), llfn, &[msg.0, msg.1], None); + bx.call( + fn_ty, + /* fn_attrs */ None, + Some(fn_abi), + llfn, + &[msg.0, msg.1], + None, + None, + ); // This function does not return so we can now return whatever we want. let size = bx.const_usize(layout.size.bytes()); diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 7bc9dee3a89..6c8dcc5b690 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -17,7 +17,7 @@ use crate::MemFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout}; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{Instance, Ty}; use rustc_session::config::OptLevel; use rustc_span::Span; use rustc_target::abi::call::FnAbi; @@ -82,6 +82,7 @@ pub trait BuilderMethods<'a, 'tcx>: then: Self::BasicBlock, catch: Self::BasicBlock, funclet: Option<&Self::Funclet>, + instance: Option>, ) -> Self::Value; fn unreachable(&mut self); @@ -389,6 +390,7 @@ pub trait BuilderMethods<'a, 'tcx>: llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, + instance: Option>, ) -> Self::Value; fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; -- cgit 1.4.1-3-g733a5