Skip to content

Commit

Permalink
CFI: Append debug location to CFI blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
1c3t3a committed Nov 6, 2024
1 parent 4d215e2 commit 5033dd3
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 37 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable");
let builtin_unreachable: RValue<'gcc> =
unsafe { std::mem::transmute(builtin_unreachable) };
self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None);
self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None, None);
}

// Write results to outputs.
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,12 +598,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
catch: Block<'gcc>,
_funclet: Option<&Funclet>,
instance: Option<Instance<'tcx>>,
_dbg_loc: Option<Self::DILocation>,
) -> RValue<'gcc> {
let try_block = self.current_func().new_block("try");

let current_block = self.block;
self.block = try_block;
let call = self.call(typ, fn_attrs, None, func, args, None, instance); // TODO(antoyo): use funclet here?
let call = self.call(typ, fn_attrs, None, func, args, None, instance, None); // TODO(antoyo): use funclet here?
self.block = current_block;

let return_value =
Expand Down Expand Up @@ -1673,6 +1674,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
args: &[RValue<'gcc>],
funclet: Option<&Funclet>,
_instance: Option<Instance<'tcx>>,
_dbg_loc: Option<Self::DILocation>,
) -> RValue<'gcc> {
// FIXME(antoyo): remove when having a proper API.
let gcc_func = unsafe { std::mem::transmute::<RValue<'gcc>, Function<'gcc>>(func) };
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
fn abort(&mut self) {
let func = self.context.get_builtin_function("abort");
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
self.call(self.type_void(), None, None, func, &[], None, None);
self.call(self.type_void(), None, None, func, &[], None, None, None);
}

fn assume(&mut self, value: Self::Value) {
Expand Down Expand Up @@ -1108,7 +1108,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
dest: RValue<'gcc>,
) {
if bx.sess().panic_strategy() == PanicStrategy::Abort {
bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
bx.call(bx.type_void(), None, None, try_func, &[data], None, None, None);
// Return 0 unconditionally from the intrinsic call;
// we can never unwind.
let ret_align = bx.tcx.data_layout.i32_align.abi;
Expand Down Expand Up @@ -1182,21 +1182,21 @@ fn codegen_gnu_try<'gcc>(
let zero = bx.cx.context.new_rvalue_zero(bx.int_type);
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());
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None, None);
bx.ret(bx.const_i32(1));

// NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not
// generate a try/catch.
// FIXME(antoyo): add a check in the libgccjit API to prevent this.
bx.switch_to_block(current_block);
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None, None);
});

let func = unsafe { std::mem::transmute::<Function<'gcc>, RValue<'gcc>>(func) };

// Note that no invoke is used here because by definition this function
// can't panic (that's what it's catching).
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None);
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None, None);
let i32_align = bx.tcx().data_layout.i32_align.abi;
bx.store(ret, dest, i32_align);
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,11 +475,11 @@ pub(crate) fn inline_asm_call<'ll>(

let call = if !labels.is_empty() {
assert!(catch_funclet.is_none());
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None, None)
} else if let Some((catch, funclet)) = catch_funclet {
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None, None)
} else {
bx.call(fty, None, None, v, inputs, None, None)
bx.call(fty, None, None, v, inputs, None, None, None)
};

// Store mark in a metadata node so we can map LLVM errors
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::abi::FnAbiLlvmExt;
use crate::attributes;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm::debuginfo::DILocation;
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
Expand Down Expand Up @@ -234,6 +235,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
catch: &'ll BasicBlock,
funclet: Option<&Funclet<'ll>>,
instance: Option<Instance<'tcx>>,
dbg_loc: Option<&'ll DILocation>,
) -> &'ll Value {
debug!("invoke {:?} with args ({:?})", llfn, args);

Expand All @@ -245,7 +247,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}

// Emit CFI pointer type membership test
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
self.cfi_type_test(fn_attrs, fn_abi, instance, dbg_loc, llfn);

// Emit KCFI operand bundle
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
Expand Down Expand Up @@ -1172,6 +1174,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
args: &[&'ll Value],
funclet: Option<&Funclet<'ll>>,
instance: Option<Instance<'tcx>>,
dbg_loc: Option<&'ll DILocation>,
) -> &'ll Value {
debug!("call {:?} with args ({:?})", llfn, args);

Expand All @@ -1183,7 +1186,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}

// Emit CFI pointer type membership test
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
self.cfi_type_test(fn_attrs, fn_abi, instance, dbg_loc, llfn);

// Emit KCFI operand bundle
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
Expand Down Expand Up @@ -1414,7 +1417,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {

pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
let (ty, f) = self.cx.get_intrinsic(intrinsic);
self.call(ty, None, None, f, args, None, None)
self.call(ty, None, None, f, args, None, None, None)
}

fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
Expand Down Expand Up @@ -1472,7 +1475,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
format!("llvm.{instr}.sat.i{int_width}.f{float_width}")
};
let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None, None)
self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None, None, None)
}

pub(crate) fn landing_pad(
Expand Down Expand Up @@ -1501,6 +1504,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
indirect_dest: &[&'ll BasicBlock],
funclet: Option<&Funclet<'ll>>,
instance: Option<Instance<'tcx>>,
dbg_loc: Option<&'ll DILocation>,
) -> &'ll Value {
debug!("invoke {:?} with args ({:?})", llfn, args);

Expand All @@ -1512,7 +1516,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
}

// Emit CFI pointer type membership test
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
self.cfi_type_test(fn_attrs, fn_abi, instance, dbg_loc, llfn);

// Emit KCFI operand bundle
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
Expand Down Expand Up @@ -1547,6 +1551,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
instance: Option<Instance<'tcx>>,
dbg_loc: Option<&'ll DILocation>,
llfn: &'ll Value,
) {
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
Expand Down Expand Up @@ -1582,10 +1587,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
self.cond_br(cond, bb_pass, bb_fail);

self.switch_to_block(bb_fail);
if let Some(dbg_loc) = dbg_loc {
self.set_dbg_loc(dbg_loc);
}
self.abort();
self.unreachable();

self.switch_to_block(bb_pass);
if let Some(dbg_loc) = dbg_loc {
self.set_dbg_loc(dbg_loc);
}
}
}

Expand Down
Loading

0 comments on commit 5033dd3

Please sign in to comment.