Skip to content

Commit

Permalink
Rollup merge of rust-lang#65809 - roblabla:eficall-abi, r=nagisa
Browse files Browse the repository at this point in the history
Add new EFIAPI ABI

Fixes rust-lang#54527

Adds a new ABI, "efiapi", which reflects the calling convention as specified by [the current spec UEFI spec](https://uefi.org/sites/default/files/resources/UEFI%20Spec%202_7_A%20Sept%206.pdf#G6.999903). When compiling for x86_64, we should select the `win64` ABI, while on all other architectures (Itanium, x86, ARM and ARM64 and RISC-V), we should select the `C` ABI.

Currently, this is done by just turning it into the C ABI everywhere except on x86_64, where it's turned into the win64 ABI. Should we prevent this ABI from being used on unsupported architectures, and if so, how would this be done?
  • Loading branch information
Centril committed Oct 29, 2019
2 parents fb73c0b + 1099826 commit c5d8681
Show file tree
Hide file tree
Showing 15 changed files with 203 additions and 82 deletions.
1 change: 1 addition & 0 deletions src/librustc/ich/impls_syntax.rs
Expand Up @@ -80,6 +80,7 @@ impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi {
Msp430Interrupt,
X86Interrupt,
AmdGpuKernel,
EfiApi,
Rust,
C,
System,
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/layout.rs
Expand Up @@ -2596,6 +2596,7 @@ where

// It's the ABI's job to select this, not ours.
System => bug!("system abi should be selected elsewhere"),
EfiApi => bug!("eficall abi should be selected elsewhere"),

Stdcall => Conv::X86Stdcall,
Fastcall => Conv::X86Fastcall,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_target/spec/abi.rs
Expand Up @@ -21,6 +21,7 @@ pub enum Abi {
Msp430Interrupt,
X86Interrupt,
AmdGpuKernel,
EfiApi,

// Multiplatform / generic ABIs
Rust,
Expand Down Expand Up @@ -58,6 +59,7 @@ const AbiDatas: &[AbiData] = &[
AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false },
AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
AbiData {abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
AbiData {abi: Abi::EfiApi, name: "efiapi", generic: false },

// Cross-platform ABIs
AbiData {abi: Abi::Rust, name: "Rust", generic: true },
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_target/spec/mod.rs
Expand Up @@ -905,6 +905,13 @@ impl Target {
abi
}
},
Abi::EfiApi => {
if self.arch == "x86_64" {
Abi::Win64
} else {
Abi::C
}
},
abi => abi
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/feature_gate/active.rs
Expand Up @@ -533,6 +533,9 @@ declare_features! (
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
(active, object_safe_for_dispatch, "1.40.0", Some(43561), None),

/// Allows using the `efiapi` ABI.
(active, abi_efiapi, "1.40.0", Some(65815), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/feature_gate/check.rs
Expand Up @@ -227,6 +227,10 @@ impl<'a> PostExpansionVisitor<'a> {
gate_feature_post!(&self, abi_amdgpu_kernel, span,
"amdgpu-kernel ABI is experimental and subject to change");
},
Abi::EfiApi => {
gate_feature_post!(&self, abi_efiapi, span,
"efiapi ABI is experimental and subject to change");
},
// Stable
Abi::Cdecl |
Abi::Stdcall |
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax_pos/symbol.rs
Expand Up @@ -110,6 +110,7 @@ symbols! {
aarch64_target_feature,
abi,
abi_amdgpu_kernel,
abi_efiapi,
abi_msp430_interrupt,
abi_ptx,
abi_sysv64,
Expand Down
31 changes: 31 additions & 0 deletions src/test/codegen/abi-efiapi.rs
@@ -0,0 +1,31 @@
// Checks if the correct annotation for the efiapi ABI is passed to llvm.

// revisions:x86_64 i686 aarch64 arm riscv

// min-llvm-version 9.0

//[x86_64] compile-flags: --target x86_64-unknown-uefi
//[i686] compile-flags: --target i686-unknown-linux-musl
//[aarch64] compile-flags: --target aarch64-unknown-none
//[arm] compile-flags: --target armv7r-none-eabi
//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
#![feature(no_core, lang_items, abi_efiapi)]
#![no_core]

#[lang="sized"]
trait Sized { }
#[lang="freeze"]
trait Freeze { }
#[lang="copy"]
trait Copy { }

//x86_64: define win64cc void @has_efiapi
//i686: define void @has_efiapi
//aarch64: define void @has_efiapi
//arm: define void @has_efiapi
//riscv: define void @has_efiapi
#[no_mangle]
pub extern "efiapi" fn has_efiapi() {}
2 changes: 1 addition & 1 deletion src/test/ui/codemap_tests/unicode.stderr
Expand Up @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
LL | extern "路濫狼á́́" fn foo() {}
| ^^^^^^^^^ invalid ABI
|
= help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
= help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted

error: aborting due to previous error

8 changes: 8 additions & 0 deletions src/test/ui/feature-gates/feature-gate-abi.rs
Expand Up @@ -7,6 +7,7 @@
// gate-test-abi_ptx
// gate-test-abi_x86_interrupt
// gate-test-abi_amdgpu_kernel
// gate-test-abi_efiapi

// Functions
extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
Expand All @@ -20,6 +21,7 @@ extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject t
extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental
extern "thiscall" fn f8() {} //~ ERROR thiscall is experimental and subject to change
extern "amdgpu-kernel" fn f9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
extern "efiapi" fn f10() {} //~ ERROR efiapi ABI is experimental and subject to change

// Methods in trait definition
trait Tr {
Expand All @@ -34,6 +36,7 @@ trait Tr {
extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental
extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change
extern "amdgpu-kernel" fn m9(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change
extern "efiapi" fn m10(); //~ ERROR efiapi ABI is experimental and subject to change

extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change
extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change
Expand All @@ -42,6 +45,7 @@ trait Tr {
extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental
extern "thiscall" fn dm8() {} //~ ERROR thiscall is experimental and subject to change
extern "amdgpu-kernel" fn dm9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
extern "efiapi" fn dm10() {} //~ ERROR efiapi ABI is experimental and subject to change
}

struct S;
Expand All @@ -59,6 +63,7 @@ impl Tr for S {
extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental
extern "thiscall" fn m8() {} //~ ERROR thiscall is experimental and subject to change
extern "amdgpu-kernel" fn m9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
extern "efiapi" fn m10() {} //~ ERROR efiapi ABI is experimental and subject to change
}

// Methods in inherent impl
Expand All @@ -74,6 +79,7 @@ impl S {
extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
extern "thiscall" fn im8() {} //~ ERROR thiscall is experimental and subject to change
extern "amdgpu-kernel" fn im9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
extern "efiapi" fn im10() {} //~ ERROR efiapi ABI is experimental and subject to change
}

// Function pointer types
Expand All @@ -86,6 +92,7 @@ type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and sub
type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental
type A8 = extern "thiscall" fn(); //~ ERROR thiscall is experimental and subject to change
type A9 = extern "amdgpu-kernel" fn(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change
type A10 = extern "efiapi" fn(); //~ ERROR efiapi ABI is experimental and subject to change

// Foreign modules
extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
Expand All @@ -97,5 +104,6 @@ extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change
extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental
extern "thiscall" {} //~ ERROR thiscall is experimental and subject to change
extern "amdgpu-kernel" {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
extern "efiapi" {} //~ ERROR efiapi ABI is experimental and subject to change

fn main() {}

0 comments on commit c5d8681

Please sign in to comment.