Stop emitting CET prologues for naked functions
We can apply nocf_check as a hack for now.
This commit is contained in:
parent
8824d13161
commit
92174f988b
6 changed files with 33 additions and 1 deletions
|
@ -299,6 +299,10 @@ pub fn from_fn_attrs<'ll, 'tcx>(
|
||||||
}
|
}
|
||||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
|
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
|
||||||
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
|
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
|
||||||
|
// HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions.
|
||||||
|
// And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules.
|
||||||
|
// Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768
|
||||||
|
to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
|
||||||
}
|
}
|
||||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
|
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
|
||||||
// apply to return place instead of function (unlike all other attributes applied in this function)
|
// apply to return place instead of function (unlike all other attributes applied in this function)
|
||||||
|
|
|
@ -191,6 +191,7 @@ pub enum AttributeKind {
|
||||||
StackProtect = 32,
|
StackProtect = 32,
|
||||||
NoUndef = 33,
|
NoUndef = 33,
|
||||||
SanitizeMemTag = 34,
|
SanitizeMemTag = 34,
|
||||||
|
NoCfCheck = 35,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LLVMIntPredicate
|
/// LLVMIntPredicate
|
||||||
|
|
|
@ -84,6 +84,7 @@ enum LLVMRustAttribute {
|
||||||
StackProtect = 32,
|
StackProtect = 32,
|
||||||
NoUndef = 33,
|
NoUndef = 33,
|
||||||
SanitizeMemTag = 34,
|
SanitizeMemTag = 34,
|
||||||
|
NoCfCheck = 35,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct OpaqueRustString *RustStringRef;
|
typedef struct OpaqueRustString *RustStringRef;
|
||||||
|
|
|
@ -176,6 +176,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
|
||||||
return Attribute::NoAlias;
|
return Attribute::NoAlias;
|
||||||
case NoCapture:
|
case NoCapture:
|
||||||
return Attribute::NoCapture;
|
return Attribute::NoCapture;
|
||||||
|
case NoCfCheck:
|
||||||
|
return Attribute::NoCfCheck;
|
||||||
case NoInline:
|
case NoInline:
|
||||||
return Attribute::NoInline;
|
return Attribute::NoInline;
|
||||||
case NonNull:
|
case NonNull:
|
||||||
|
|
24
src/test/assembly/x86_64-naked-fn-no-cet-prolog.rs
Normal file
24
src/test/assembly/x86_64-naked-fn-no-cet-prolog.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// compile-flags: -C no-prepopulate-passes -Zcf-protection=full
|
||||||
|
// assembly-output: emit-asm
|
||||||
|
// needs-asm-support
|
||||||
|
// only-x86_64
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(naked_functions)]
|
||||||
|
use std::arch::asm;
|
||||||
|
|
||||||
|
// The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
|
||||||
|
// meaning "no prologue whatsoever, no, really, not one instruction."
|
||||||
|
// Unfortunately, x86's control-flow enforcement, specifically indirect branch protection,
|
||||||
|
// works by using an instruction for each possible landing site,
|
||||||
|
// and LLVM implements this via making sure of that.
|
||||||
|
#[no_mangle]
|
||||||
|
#[naked]
|
||||||
|
pub unsafe extern "sysv64" fn will_halt() -> ! {
|
||||||
|
// CHECK-NOT: endbr{{32|64}}
|
||||||
|
// CHECK: hlt
|
||||||
|
asm!("hlt", options(noreturn))
|
||||||
|
}
|
||||||
|
|
||||||
|
// what about aarch64?
|
||||||
|
// "branch-protection"=false
|
|
@ -28,4 +28,4 @@ pub unsafe fn g() {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: attributes [[ATTR]] = { naked noinline{{.*}} }
|
// CHECK: attributes [[ATTR]] = { naked{{.*}}noinline{{.*}} }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue