Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit b593389

Browse files
committed
Auto merge of rust-lang#81346 - hug-dev:nonsecure-call-abi, r=jonas-schievink
Add a new ABI to support cmse_nonsecure_call This adds support for the `cmse_nonsecure_call` feature to be able to perform non-secure function call. See the discussion on Zulip [here](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes/near/223054928). This is a followup to rust-lang#75810 which added `cmse_nonsecure_entry`. As for that PR, I assume that the changes are small enough to not have to go through a RFC but I don't mind doing one if needed 😃 I did not yet create a tracking issue, but if most of it is fine, I can create one and update the various files accordingly (they refer to the other tracking issue now). On the Zulip chat, I believe `@jonas-schievink` volunteered to be a reviewer 💯
2 parents e6a0f3c + ce9818f commit b593389

File tree

35 files changed

+251
-3
lines changed

35 files changed

+251
-3
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@ impl<'a> PostExpansionVisitor<'a> {
156156
"efiapi ABI is experimental and subject to change"
157157
);
158158
}
159+
"C-cmse-nonsecure-call" => {
160+
gate_feature_post!(
161+
&self,
162+
abi_c_cmse_nonsecure_call,
163+
span,
164+
"C-cmse-nonsecure-call ABI is experimental and subject to change"
165+
);
166+
}
159167
abi => self
160168
.sess
161169
.parse_sess

compiler/rustc_codegen_cranelift/src/abi/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ fn clif_sig_from_fn_abi<'tcx>(
2828
Conv::X86_64SysV => CallConv::SystemV,
2929
Conv::X86_64Win64 => CallConv::WindowsFastcall,
3030
Conv::ArmAapcs
31+
| Conv::CCmseNonSecureCall
3132
| Conv::Msp430Intr
3233
| Conv::PtxKernel
3334
| Conv::X86Fastcall

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
389389

390390
fn llvm_cconv(&self) -> llvm::CallConv {
391391
match self.conv {
392-
Conv::C | Conv::Rust => llvm::CCallConv,
392+
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
393393
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
394394
Conv::AvrInterrupt => llvm::AvrInterrupt,
395395
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
@@ -546,6 +546,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
546546
if cconv != llvm::CCallConv {
547547
llvm::SetInstructionCallConv(callsite, cconv);
548548
}
549+
550+
if self.conv == Conv::CCmseNonSecureCall {
551+
// This will probably get ignored on all targets but those supporting the TrustZone-M
552+
// extension (thumbv8m targets).
553+
unsafe {
554+
llvm::AddCallSiteAttrString(
555+
callsite,
556+
llvm::AttributePlace::Function,
557+
rustc_data_structures::const_cstr!("cmse_nonsecure_call"),
558+
);
559+
}
560+
}
549561
}
550562
}
551563

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,7 @@ extern "C" {
11001100
// Operations on call sites
11011101
pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
11021102
pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute);
1103+
pub fn LLVMRustAddCallSiteAttrString(Instr: &Value, index: c_uint, Name: *const c_char);
11031104
pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32);
11041105
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
11051106
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);

compiler/rustc_codegen_llvm/src/llvm/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ pub fn AddFunctionAttrString(llfn: &'a Value, idx: AttributePlace, attr: &CStr)
4343
}
4444
}
4545

46+
pub fn AddCallSiteAttrString(callsite: &Value, idx: AttributePlace, attr: &CStr) {
47+
unsafe { LLVMRustAddCallSiteAttrString(callsite, idx.as_uint(), attr.as_ptr()) }
48+
}
49+
4650
#[derive(Copy, Clone)]
4751
pub enum AttributePlace {
4852
ReturnValue,

compiler/rustc_error_codes/src/error_codes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ E0777: include_str!("./error_codes/E0777.md"),
466466
E0778: include_str!("./error_codes/E0778.md"),
467467
E0779: include_str!("./error_codes/E0779.md"),
468468
E0780: include_str!("./error_codes/E0780.md"),
469+
E0781: include_str!("./error_codes/E0781.md"),
469470
;
470471
// E0006, // merged with E0005
471472
// E0008, // cannot bind by-move into a pattern guard
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
The `C-cmse-nonsecure-call` ABI can only be used with function pointers.
2+
3+
Erroneous code example:
4+
5+
```compile_fail,E0781
6+
#![feature(abi_c_cmse_nonsecure_call)]
7+
8+
pub extern "C-cmse-nonsecure-call" fn test() {}
9+
```
10+
11+
The `C-cmse-nonsecure-call` ABI should be used by casting function pointers to
12+
specific addresses.

compiler/rustc_feature/src/active.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,9 @@ declare_features! (
628628

629629
/// Allows using `pointer` and `reference` in intra-doc links
630630
(active, intra_doc_pointers, "1.51.0", Some(80896), None),
631+
632+
/// Allows `extern "C-cmse-nonsecure-call" fn()`.
633+
(active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None),
631634
// -------------------------------------------------------------------------
632635
// feature-group-end: actual feature gates
633636
// -------------------------------------------------------------------------

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,14 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
216216
Call->addAttribute(Index, Attr);
217217
}
218218

219+
extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
220+
const char *Name) {
221+
CallBase *Call = unwrap<CallBase>(Instr);
222+
Attribute Attr = Attribute::get(Call->getContext(), Name);
223+
Call->addAttribute(Index, Attr);
224+
}
225+
226+
219227
extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
220228
unsigned Index,
221229
uint32_t Bytes) {

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2650,6 +2650,7 @@ where
26502650
Win64 => Conv::X86_64Win64,
26512651
SysV64 => Conv::X86_64SysV,
26522652
Aapcs => Conv::ArmAapcs,
2653+
CCmseNonSecureCall => Conv::CCmseNonSecureCall,
26532654
PtxKernel => Conv::PtxKernel,
26542655
Msp430Interrupt => Conv::Msp430Intr,
26552656
X86Interrupt => Conv::X86Intr,

0 commit comments

Comments
 (0)