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 <hugues.devalon@arm.com>
This commit is contained in:
parent
d60b29d1ae
commit
ce9818f2b7
@ -156,6 +156,14 @@ impl<'a> PostExpansionVisitor<'a> {
|
|||||||
"efiapi ABI is experimental and subject to change"
|
"efiapi ABI is experimental and subject to change"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"C-cmse-nonsecure-call" => {
|
||||||
|
gate_feature_post!(
|
||||||
|
&self,
|
||||||
|
abi_c_cmse_nonsecure_call,
|
||||||
|
span,
|
||||||
|
"C-cmse-nonsecure-call ABI is experimental and subject to change"
|
||||||
|
);
|
||||||
|
}
|
||||||
abi => self
|
abi => self
|
||||||
.sess
|
.sess
|
||||||
.parse_sess
|
.parse_sess
|
||||||
|
@ -28,6 +28,7 @@ fn clif_sig_from_fn_abi<'tcx>(
|
|||||||
Conv::X86_64SysV => CallConv::SystemV,
|
Conv::X86_64SysV => CallConv::SystemV,
|
||||||
Conv::X86_64Win64 => CallConv::WindowsFastcall,
|
Conv::X86_64Win64 => CallConv::WindowsFastcall,
|
||||||
Conv::ArmAapcs
|
Conv::ArmAapcs
|
||||||
|
| Conv::CCmseNonSecureCall
|
||||||
| Conv::Msp430Intr
|
| Conv::Msp430Intr
|
||||||
| Conv::PtxKernel
|
| Conv::PtxKernel
|
||||||
| Conv::X86Fastcall
|
| Conv::X86Fastcall
|
||||||
|
@ -389,7 +389,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||||||
|
|
||||||
fn llvm_cconv(&self) -> llvm::CallConv {
|
fn llvm_cconv(&self) -> llvm::CallConv {
|
||||||
match self.conv {
|
match self.conv {
|
||||||
Conv::C | Conv::Rust => llvm::CCallConv,
|
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
|
||||||
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
|
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
|
||||||
Conv::AvrInterrupt => llvm::AvrInterrupt,
|
Conv::AvrInterrupt => llvm::AvrInterrupt,
|
||||||
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
|
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
|
||||||
@ -546,6 +546,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||||||
if cconv != llvm::CCallConv {
|
if cconv != llvm::CCallConv {
|
||||||
llvm::SetInstructionCallConv(callsite, cconv);
|
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"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,6 +1100,7 @@ extern "C" {
|
|||||||
// Operations on call sites
|
// Operations on call sites
|
||||||
pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
|
pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
|
||||||
pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute);
|
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 LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32);
|
||||||
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
|
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
|
||||||
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
|
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
|
||||||
|
@ -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)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum AttributePlace {
|
pub enum AttributePlace {
|
||||||
ReturnValue,
|
ReturnValue,
|
||||||
|
@ -465,6 +465,7 @@ E0777: include_str!("./error_codes/E0777.md"),
|
|||||||
E0778: include_str!("./error_codes/E0778.md"),
|
E0778: include_str!("./error_codes/E0778.md"),
|
||||||
E0779: include_str!("./error_codes/E0779.md"),
|
E0779: include_str!("./error_codes/E0779.md"),
|
||||||
E0780: include_str!("./error_codes/E0780.md"),
|
E0780: include_str!("./error_codes/E0780.md"),
|
||||||
|
E0781: include_str!("./error_codes/E0781.md"),
|
||||||
;
|
;
|
||||||
// E0006, // merged with E0005
|
// E0006, // merged with E0005
|
||||||
// E0008, // cannot bind by-move into a pattern guard
|
// E0008, // cannot bind by-move into a pattern guard
|
||||||
|
12
compiler/rustc_error_codes/src/error_codes/E0781.md
Normal file
12
compiler/rustc_error_codes/src/error_codes/E0781.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
The `C-cmse-nonsecure-call` ABI can only be used with function pointers.
|
||||||
|
|
||||||
|
Erroneous code example:
|
||||||
|
|
||||||
|
```compile_fail,E0781
|
||||||
|
#![feature(abi_c_cmse_nonsecure_call)]
|
||||||
|
|
||||||
|
pub extern "C-cmse-nonsecure-call" fn test() {}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `C-cmse-nonsecure-call` ABI should be used by casting function pointers to
|
||||||
|
specific addresses.
|
@ -628,6 +628,9 @@ declare_features! (
|
|||||||
|
|
||||||
/// Allows using `pointer` and `reference` in intra-doc links
|
/// Allows using `pointer` and `reference` in intra-doc links
|
||||||
(active, intra_doc_pointers, "1.51.0", Some(80896), None),
|
(active, intra_doc_pointers, "1.51.0", Some(80896), None),
|
||||||
|
|
||||||
|
/// Allows `extern "C-cmse-nonsecure-call" fn()`.
|
||||||
|
(active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None),
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// feature-group-end: actual feature gates
|
// feature-group-end: actual feature gates
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -216,6 +216,14 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
|
|||||||
Call->addAttribute(Index, Attr);
|
Call->addAttribute(Index, Attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
|
||||||
|
const char *Name) {
|
||||||
|
CallBase *Call = unwrap<CallBase>(Instr);
|
||||||
|
Attribute Attr = Attribute::get(Call->getContext(), Name);
|
||||||
|
Call->addAttribute(Index, Attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
|
extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
|
||||||
unsigned Index,
|
unsigned Index,
|
||||||
uint32_t Bytes) {
|
uint32_t Bytes) {
|
||||||
|
@ -2650,6 +2650,7 @@ where
|
|||||||
Win64 => Conv::X86_64Win64,
|
Win64 => Conv::X86_64Win64,
|
||||||
SysV64 => Conv::X86_64SysV,
|
SysV64 => Conv::X86_64SysV,
|
||||||
Aapcs => Conv::ArmAapcs,
|
Aapcs => Conv::ArmAapcs,
|
||||||
|
CCmseNonSecureCall => Conv::CCmseNonSecureCall,
|
||||||
PtxKernel => Conv::PtxKernel,
|
PtxKernel => Conv::PtxKernel,
|
||||||
Msp430Interrupt => Conv::Msp430Intr,
|
Msp430Interrupt => Conv::Msp430Intr,
|
||||||
X86Interrupt => Conv::X86Intr,
|
X86Interrupt => Conv::X86Intr,
|
||||||
|
@ -218,6 +218,7 @@ symbols! {
|
|||||||
abi,
|
abi,
|
||||||
abi_amdgpu_kernel,
|
abi_amdgpu_kernel,
|
||||||
abi_avr_interrupt,
|
abi_avr_interrupt,
|
||||||
|
abi_c_cmse_nonsecure_call,
|
||||||
abi_efiapi,
|
abi_efiapi,
|
||||||
abi_msp430_interrupt,
|
abi_msp430_interrupt,
|
||||||
abi_ptx,
|
abi_ptx,
|
||||||
|
@ -551,6 +551,7 @@ pub enum Conv {
|
|||||||
|
|
||||||
// Target-specific calling conventions.
|
// Target-specific calling conventions.
|
||||||
ArmAapcs,
|
ArmAapcs,
|
||||||
|
CCmseNonSecureCall,
|
||||||
|
|
||||||
Msp430Intr,
|
Msp430Intr,
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ pub enum Abi {
|
|||||||
EfiApi,
|
EfiApi,
|
||||||
AvrInterrupt,
|
AvrInterrupt,
|
||||||
AvrNonBlockingInterrupt,
|
AvrNonBlockingInterrupt,
|
||||||
|
CCmseNonSecureCall,
|
||||||
|
|
||||||
// Multiplatform / generic ABIs
|
// Multiplatform / generic ABIs
|
||||||
System,
|
System,
|
||||||
@ -81,6 +82,7 @@ const AbiDatas: &[AbiData] = &[
|
|||||||
name: "avr-non-blocking-interrupt",
|
name: "avr-non-blocking-interrupt",
|
||||||
generic: false,
|
generic: false,
|
||||||
},
|
},
|
||||||
|
AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call", generic: false },
|
||||||
// Cross-platform ABIs
|
// Cross-platform ABIs
|
||||||
AbiData { abi: Abi::System, name: "system", generic: true },
|
AbiData { abi: Abi::System, name: "system", generic: true },
|
||||||
AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
|
AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
|
||||||
|
@ -42,6 +42,17 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
|
|||||||
)
|
)
|
||||||
.emit()
|
.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This ABI is only allowed on function pointers
|
||||||
|
if abi == Abi::CCmseNonSecureCall {
|
||||||
|
struct_span_err!(
|
||||||
|
tcx.sess,
|
||||||
|
span,
|
||||||
|
E0781,
|
||||||
|
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers."
|
||||||
|
)
|
||||||
|
.emit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper used for fns and closures. Does the grungy work of checking a function
|
/// Helper used for fns and closures. Does the grungy work of checking a function
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
# `abi_c_cmse_nonsecure_call`
|
||||||
|
|
||||||
|
The tracking issue for this feature is: [#81391]
|
||||||
|
|
||||||
|
[#81391]: https://github.com/rust-lang/rust/issues/81391
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The [TrustZone-M
|
||||||
|
feature](https://developer.arm.com/documentation/100690/latest/) is available
|
||||||
|
for targets with the Armv8-M architecture profile (`thumbv8m` in their target
|
||||||
|
name).
|
||||||
|
LLVM, the Rust compiler and the linker are providing
|
||||||
|
[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
|
||||||
|
TrustZone-M feature.
|
||||||
|
|
||||||
|
One of the things provided, with this unstable feature, is the
|
||||||
|
`C-cmse-nonsecure-call` function ABI. This ABI is used on function pointers to
|
||||||
|
non-secure code to mark a non-secure function call (see [section
|
||||||
|
5.5](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
|
||||||
|
|
||||||
|
With this ABI, the compiler will do the following to perform the call:
|
||||||
|
* save registers needed after the call to Secure memory
|
||||||
|
* clear all registers that might contain confidential information
|
||||||
|
* clear the Least Significant Bit of the function address
|
||||||
|
* branches using the BLXNS instruction
|
||||||
|
|
||||||
|
To avoid using the non-secure stack, the compiler will constrain the number and
|
||||||
|
type of parameters/return value.
|
||||||
|
|
||||||
|
The `extern "C-cmse-nonsecure-call"` ABI is otherwise equivalent to the
|
||||||
|
`extern "C"` ABI.
|
||||||
|
|
||||||
|
<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
|
||||||
|
|
||||||
|
``` rust,ignore
|
||||||
|
#![no_std]
|
||||||
|
#![feature(abi_c_cmse_nonsecure_call)]
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn call_nonsecure_function(addr: usize) -> u32 {
|
||||||
|
let non_secure_function =
|
||||||
|
unsafe { core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn() -> u32>(addr) };
|
||||||
|
non_secure_function()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
$ rustc --emit asm --crate-type lib --target thumbv8m.main-none-eabi function.rs
|
||||||
|
|
||||||
|
call_nonsecure_function:
|
||||||
|
.fnstart
|
||||||
|
.save {r7, lr}
|
||||||
|
push {r7, lr}
|
||||||
|
.setfp r7, sp
|
||||||
|
mov r7, sp
|
||||||
|
.pad #16
|
||||||
|
sub sp, #16
|
||||||
|
str r0, [sp, #12]
|
||||||
|
ldr r0, [sp, #12]
|
||||||
|
str r0, [sp, #8]
|
||||||
|
b .LBB0_1
|
||||||
|
.LBB0_1:
|
||||||
|
ldr r0, [sp, #8]
|
||||||
|
push.w {r4, r5, r6, r7, r8, r9, r10, r11}
|
||||||
|
bic r0, r0, #1
|
||||||
|
mov r1, r0
|
||||||
|
mov r2, r0
|
||||||
|
mov r3, r0
|
||||||
|
mov r4, r0
|
||||||
|
mov r5, r0
|
||||||
|
mov r6, r0
|
||||||
|
mov r7, r0
|
||||||
|
mov r8, r0
|
||||||
|
mov r9, r0
|
||||||
|
mov r10, r0
|
||||||
|
mov r11, r0
|
||||||
|
mov r12, r0
|
||||||
|
msr apsr_nzcvq, r0
|
||||||
|
blxns r0
|
||||||
|
pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
|
||||||
|
str r0, [sp, #4]
|
||||||
|
b .LBB0_2
|
||||||
|
.LBB0_2:
|
||||||
|
ldr r0, [sp, #4]
|
||||||
|
add sp, #16
|
||||||
|
pop {r7, pc}
|
||||||
|
```
|
11
src/test/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.rs
Normal file
11
src/test/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// gate-test-abi_c_cmse_nonsecure_call
|
||||||
|
fn main() {
|
||||||
|
let non_secure_function = unsafe {
|
||||||
|
core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn(i32, i32, i32, i32) -> i32>(
|
||||||
|
//~^ ERROR [E0658]
|
||||||
|
0x10000004,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let mut toto = 5;
|
||||||
|
toto += non_secure_function(toto, 2, 3, 5);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
error[E0658]: C-cmse-nonsecure-call ABI is experimental and subject to change
|
||||||
|
--> $DIR/gate_test.rs:4:46
|
||||||
|
|
|
||||||
|
LL | core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn(i32, i32, i32, i32) -> i32>(
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #81391 <https://github.com/rust-lang/rust/issues/81391> for more information
|
||||||
|
= help: add `#![feature(abi_c_cmse_nonsecure_call)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
@ -0,0 +1,15 @@
|
|||||||
|
// build-pass
|
||||||
|
// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
// only-thumbv8m.main-none-eabi
|
||||||
|
#![feature(abi_c_cmse_nonsecure_call)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn test(a: u32, b: u32, c: u32, d: u32) -> u32 {
|
||||||
|
let non_secure_function = unsafe {
|
||||||
|
core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u32>(
|
||||||
|
0x10000004,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
non_secure_function(a, b, c, d)
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
// only-thumbv8m.main-none-eabi
|
||||||
|
#![feature(abi_c_cmse_nonsecure_call)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn test(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 {
|
||||||
|
let non_secure_function = unsafe {
|
||||||
|
core::mem::transmute::<
|
||||||
|
usize,
|
||||||
|
extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32, u32) -> u32>
|
||||||
|
(
|
||||||
|
0x10000004,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
non_secure_function(a, b, c, d, e)
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
error: <unknown>:0:0: in function test i32 (i32, i32, i32, i32, i32): call to non-secure function would require passing arguments on stack
|
||||||
|
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
// only-thumbv8m.main-none-eabi
|
||||||
|
#![feature(abi_c_cmse_nonsecure_call)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
pub extern "C-cmse-nonsecure-call" fn test() {} //~ ERROR [E0781]
|
@ -0,0 +1,9 @@
|
|||||||
|
error[E0781]: the `"cmse-nonsecure-call"` ABI is only allowed on function pointers.
|
||||||
|
--> $DIR/wrong-abi-location-1.rs:6:1
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-call" fn test() {} //~ ERROR [E0781]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0781`.
|
@ -0,0 +1,8 @@
|
|||||||
|
// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
// only-thumbv8m.main-none-eabi
|
||||||
|
#![feature(abi_c_cmse_nonsecure_call)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-call" { //~ ERROR [E0781]
|
||||||
|
fn test();
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
error[E0781]: the `"C-cmse-nonsecure-call"` ABI is only allowed on function pointers.
|
||||||
|
--> $DIR/wrong-abi-location-2.rs:6:1
|
||||||
|
|
|
||||||
|
LL | / extern "C-cmse-nonsecure-call" {
|
||||||
|
LL | | fn test(); //~ ERROR [E0781]
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0781`.
|
@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
|
|||||||
LL | extern "路濫狼á́́" fn foo() {}
|
LL | extern "路濫狼á́́" fn foo() {}
|
||||||
| ^^^^^^^^^ invalid ABI
|
| ^^^^^^^^^ invalid ABI
|
||||||
|
|
|
|
||||||
= help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
= help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize`
|
|||||||
LL | "invalid-ab_isize"
|
LL | "invalid-ab_isize"
|
||||||
| ^^^^^^^^^^^^^^^^^^ invalid ABI
|
| ^^^^^^^^^^^^^^^^^^ invalid ABI
|
||||||
|
|
|
|
||||||
= help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
= help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user