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.
This commit is contained in:
parent
a951158565
commit
abbe1ba6f2
@ -541,7 +541,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
let builtin_unreachable: RValue<'gcc> = unsafe {
|
let builtin_unreachable: RValue<'gcc> = unsafe {
|
||||||
std::mem::transmute(builtin_unreachable)
|
std::mem::transmute(builtin_unreachable)
|
||||||
};
|
};
|
||||||
self.call(self.type_void(), None, None, builtin_unreachable, &[], None);
|
self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write results to outputs.
|
// Write results to outputs.
|
||||||
|
@ -25,7 +25,7 @@ use rustc_middle::ty::layout::{
|
|||||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
|
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
|
||||||
TyAndLayout,
|
TyAndLayout,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Instance};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::{
|
use rustc_target::abi::{
|
||||||
@ -592,12 +592,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
then: Block<'gcc>,
|
then: Block<'gcc>,
|
||||||
catch: Block<'gcc>,
|
catch: Block<'gcc>,
|
||||||
_funclet: Option<&Funclet>,
|
_funclet: Option<&Funclet>,
|
||||||
|
instance: Option<Instance<'tcx>>,
|
||||||
) -> RValue<'gcc> {
|
) -> RValue<'gcc> {
|
||||||
let try_block = self.current_func().new_block("try");
|
let try_block = self.current_func().new_block("try");
|
||||||
|
|
||||||
let current_block = self.block.clone();
|
let current_block = self.block.clone();
|
||||||
self.block = try_block;
|
self.block = try_block;
|
||||||
let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here?
|
let call = self.call(typ, fn_attrs, None, func, args, None, instance); // TODO(antoyo): use funclet here?
|
||||||
self.block = current_block;
|
self.block = current_block;
|
||||||
|
|
||||||
let return_value =
|
let return_value =
|
||||||
@ -1667,6 +1668,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
func: RValue<'gcc>,
|
func: RValue<'gcc>,
|
||||||
args: &[RValue<'gcc>],
|
args: &[RValue<'gcc>],
|
||||||
funclet: Option<&Funclet>,
|
funclet: Option<&Funclet>,
|
||||||
|
_instance: Option<Instance<'tcx>>,
|
||||||
) -> RValue<'gcc> {
|
) -> RValue<'gcc> {
|
||||||
// FIXME(antoyo): remove when having a proper API.
|
// FIXME(antoyo): remove when having a proper API.
|
||||||
let gcc_func = unsafe { std::mem::transmute(func) };
|
let gcc_func = unsafe { std::mem::transmute(func) };
|
||||||
|
@ -133,6 +133,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
func,
|
func,
|
||||||
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
|
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
sym::likely => self.expect(args[0].immediate(), true),
|
sym::likely => self.expect(args[0].immediate(), true),
|
||||||
@ -401,7 +402,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
fn abort(&mut self) {
|
fn abort(&mut self) {
|
||||||
let func = self.context.get_builtin_function("abort");
|
let func = self.context.get_builtin_function("abort");
|
||||||
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
|
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
|
||||||
self.call(self.type_void(), None, None, func, &[], None);
|
self.call(self.type_void(), None, None, func, &[], None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assume(&mut self, value: Self::Value) {
|
fn assume(&mut self, value: Self::Value) {
|
||||||
@ -1103,7 +1104,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
|
|||||||
dest: RValue<'gcc>,
|
dest: RValue<'gcc>,
|
||||||
) {
|
) {
|
||||||
if bx.sess().panic_strategy() == PanicStrategy::Abort {
|
if bx.sess().panic_strategy() == PanicStrategy::Abort {
|
||||||
bx.call(bx.type_void(), None, None, try_func, &[data], None);
|
bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
|
||||||
// Return 0 unconditionally from the intrinsic call;
|
// Return 0 unconditionally from the intrinsic call;
|
||||||
// we can never unwind.
|
// we can never unwind.
|
||||||
let ret_align = bx.tcx.data_layout.i32_align.abi;
|
let ret_align = bx.tcx.data_layout.i32_align.abi;
|
||||||
@ -1177,21 +1178,21 @@ fn codegen_gnu_try<'gcc>(
|
|||||||
let zero = bx.cx.context.new_rvalue_zero(bx.int_type);
|
let zero = bx.cx.context.new_rvalue_zero(bx.int_type);
|
||||||
let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]);
|
let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]);
|
||||||
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
|
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
|
||||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None);
|
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
|
||||||
bx.ret(bx.const_i32(1));
|
bx.ret(bx.const_i32(1));
|
||||||
|
|
||||||
// NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not
|
// NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not
|
||||||
// generate a try/catch.
|
// generate a try/catch.
|
||||||
// FIXME(antoyo): add a check in the libgccjit API to prevent this.
|
// FIXME(antoyo): add a check in the libgccjit API to prevent this.
|
||||||
bx.switch_to_block(current_block);
|
bx.switch_to_block(current_block);
|
||||||
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
|
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
|
||||||
});
|
});
|
||||||
|
|
||||||
let func = unsafe { std::mem::transmute(func) };
|
let func = unsafe { std::mem::transmute(func) };
|
||||||
|
|
||||||
// Note that no invoke is used here because by definition this function
|
// Note that no invoke is used here because by definition this function
|
||||||
// can't panic (that's what it's catching).
|
// can't panic (that's what it's catching).
|
||||||
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None);
|
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None);
|
||||||
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
||||||
bx.store(ret, dest, i32_align);
|
bx.store(ret, dest, i32_align);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user