From ce9818f2b7beaed0039f42605e2f547e9e461430 Mon Sep 17 00:00:00 2001 From: Hugues de Valon Date: Sun, 24 Jan 2021 17:15:05 +0000 Subject: Add a new ABI to support cmse_nonsecure_call This commit adds a new ABI to be selected via `extern "C-cmse-nonsecure-call"` on function pointers in order for the compiler to apply the corresponding cmse_nonsecure_call callsite attribute. For Armv8-M targets supporting TrustZone-M, this will perform a non-secure function call by saving, clearing and calling a non-secure function pointer using the BLXNS instruction. See the page on the unstable book for details. Signed-off-by: Hugues de Valon --- compiler/rustc_codegen_llvm/src/abi.rs | 14 +++++++++++++- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_llvm/src/llvm/mod.rs | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_codegen_llvm') diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 915dd3d9eda..a69241e456f 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -389,7 +389,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { fn llvm_cconv(&self) -> llvm::CallConv { match self.conv { - Conv::C | Conv::Rust => llvm::CCallConv, + Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv, Conv::AmdGpuKernel => llvm::AmdGpuKernel, Conv::AvrInterrupt => llvm::AvrInterrupt, Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt, @@ -546,6 +546,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { if cconv != llvm::CCallConv { llvm::SetInstructionCallConv(callsite, cconv); } + + if self.conv == Conv::CCmseNonSecureCall { + // This will probably get ignored on all targets but those supporting the TrustZone-M + // extension (thumbv8m targets). + unsafe { + llvm::AddCallSiteAttrString( + callsite, + llvm::AttributePlace::Function, + rustc_data_structures::const_cstr!("cmse_nonsecure_call"), + ); + } + } } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index d9f42efebab..e82198f8f0c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1100,6 +1100,7 @@ extern "C" { // Operations on call sites pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint); pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute); + pub fn LLVMRustAddCallSiteAttrString(Instr: &Value, index: c_uint, Name: *const c_char); pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32); pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index fc40065a966..bb9c6d47373 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -43,6 +43,10 @@ pub fn AddFunctionAttrString(llfn: &'a Value, idx: AttributePlace, attr: &CStr) } } +pub fn AddCallSiteAttrString(callsite: &Value, idx: AttributePlace, attr: &CStr) { + unsafe { LLVMRustAddCallSiteAttrString(callsite, idx.as_uint(), attr.as_ptr()) } +} + #[derive(Copy, Clone)] pub enum AttributePlace { ReturnValue, -- cgit 1.4.1-3-g733a5