Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking issue for the "efiapi" calling convention #65815

Closed
roblabla opened this issue Oct 25, 2019 · 10 comments · Fixed by #105795
Closed

Tracking issue for the "efiapi" calling convention #65815

roblabla opened this issue Oct 25, 2019 · 10 comments · Fixed by #105795
Labels
A-ABI Area: Concerning the application binary interface (ABI) A-FFI Area: Foreign function interface (FFI) B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. O-UEFI UEFI S-tracking-ready-to-stabilize Status: This is ready to stabilize; it may need a stabilization report and a PR T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@roblabla
Copy link
Contributor

roblabla commented Oct 25, 2019

Tracking issue for the efiapi calling convention, added in PR #65809. The feature gate name is abi_efiapi.

The efiapi calling convention can be used for defining a function with an ABI compatible with the UEFI Interfaces as defined in the UEFI Specification. On the currently supported platform, this means selecting between the win64 ABI or the C ABI depending on the target architecture.

Usage

extern "efiapi" fn func() {}

Known Issues

  • The ABI is currently accessible on platforms architectures not supported by UEFI (x86, x86_64, itanium, arm, arm64 and risc-v). There is currently no way to whitelist ABI for certain architectures, see AAPCS ABI is accepted for x86 target #57182 for a similar issue.
  • EFIAPI should delegate to aapcs on ARM, and aapcs64 en ARM64, instead of delegating to C.
@jonas-schievink jonas-schievink added B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-lang Relevant to the language team, which will review and decide on the PR/issue. A-FFI Area: Foreign function interface (FFI) labels Oct 25, 2019
@joshtriplett joshtriplett added S-tracking-impl-incomplete Status: The implementation is incomplete. O-UEFI UEFI labels Jun 22, 2022
@workingjubilee workingjubilee added the A-ABI Area: Concerning the application binary interface (ABI) label Jul 1, 2022
nicholasbishop added a commit to nicholasbishop/rust that referenced this issue Nov 5, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 6, 2022
…, r=nagisa

Limit efiapi calling convention to supported arches

Supported architectures in UEFI are described here:
https://uefi.org/specs/UEFI/2.10/02_Overview.html#calling-conventions

rust-lang#65815
nicholasbishop added a commit to nicholasbishop/rust that referenced this issue Nov 6, 2022
nicholasbishop added a commit to nicholasbishop/rust that referenced this issue Nov 6, 2022
On arm, llvm treats the C calling convention as `aapcs` on soft-float
targets and `aapcs-vfp` on hard-float targets [1]. UEFI specifies in the
arm calling convention that floating point extensions aren't used [2],
so always translate `efiapi` to `aapcs` on arm.

[1]: rust-lang/compiler-builtins#116 (comment)
[2]: https://uefi.org/specs/UEFI/2.10/02_Overview.html#detailed-calling-convention

rust-lang#65815
Manishearth added a commit to Manishearth/rust that referenced this issue Nov 9, 2022
…, r=nagisa

Limit efiapi calling convention to supported arches

Supported architectures in UEFI are described here:
https://uefi.org/specs/UEFI/2.10/02_Overview.html#calling-conventions

rust-lang#65815
Manishearth added a commit to Manishearth/rust that referenced this issue Nov 10, 2022
…r=nagisa

Use aapcs for efiapi calling convention on arm

On arm, [llvm treats the C calling convention as `aapcs` on soft-float targets and `aapcs-vfp` on hard-float targets](rust-lang/compiler-builtins#116 (comment)). UEFI specifies in the arm calling convention that [floating point extensions aren't used](https://uefi.org/specs/UEFI/2.10/02_Overview.html#detailed-calling-convention), so always translate `efiapi` to `aapcs` on arm.

rust-lang#65815
Manishearth added a commit to Manishearth/rust that referenced this issue Nov 10, 2022
…r=nagisa

Use aapcs for efiapi calling convention on arm

On arm, [llvm treats the C calling convention as `aapcs` on soft-float targets and `aapcs-vfp` on hard-float targets](rust-lang/compiler-builtins#116 (comment)). UEFI specifies in the arm calling convention that [floating point extensions aren't used](https://uefi.org/specs/UEFI/2.10/02_Overview.html#detailed-calling-convention), so always translate `efiapi` to `aapcs` on arm.

rust-lang#65815
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 25, 2022
…r=JohnTitor

unstable-book: Add page for the `abi_efiapi` feature

Tracking issue for `abi_efiapi`: rust-lang#65815
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 25, 2022
…r=JohnTitor

unstable-book: Add page for the `abi_efiapi` feature

Tracking issue for `abi_efiapi`: rust-lang#65815
@nicholasbishop
Copy link
Contributor

The two known issues identified in the issue description have been resolved.

Stabilization Report

Summary

This feature adds the efiapi ABI for functions. This ABI is defined in the UEFI Specification. Example usage:

extern "efiapi" fn func() { todo!() }

When compiling for a UEFI target such as x86_64-unknown-uefi this ABI is already the default, but UEFI functions can also be called from code compiled for other targets. For example, a kernel might be compiled as an ELF executable, but to call a UEFI service it needs to use the proper UEFI ABI.

The UEFI ABI can only be used on architectures where UEFI is supported: #104020

Some examples of usage in the Rust UEFI ecosystem:

For background on why the ABI is named efiapi, see #65809 (comment)

Documentation

Tests

@lukas-code
Copy link
Member

I think this should be stabilized together with extended_varargs_abi_support, because some UEFI functions (InstallMultipleProtocolInterfaces / UninstallMultipleProtocolInterfaces) depend on that.

@nicholasbishop
Copy link
Contributor

I think this should be stabilized together with extended_varargs_abi_support, because some UEFI functions (InstallMultipleProtocolInterfaces / UninstallMultipleProtocolInterfaces) depend on that.

IMO that doesn't need to be a blocker for efiapi. There are very few functions in the UEFI spec that rely on varargs, so it doesn't matter much that it's not yet supported.

@joshtriplett joshtriplett added S-tracking-ready-to-stabilize Status: This is ready to stabilize; it may need a stabilization report and a PR and removed S-tracking-impl-incomplete Status: The implementation is incomplete. labels Nov 29, 2022
@joshtriplett
Copy link
Member

Shall we stabilieze the extern "efiapi" calling convention?

@rfcbot merge

@rfcbot
Copy link

rfcbot commented Nov 29, 2022

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Nov 29, 2022
@scottmcm
Copy link
Member

Pondering: how much value do we get from lang FCPs for calling conventions?

Could we define everything related to syntax and semantics independent of the set of values that actually are supported as CC values? Does the language spec ever really need to care if someone wants extern "fluffy"? Would a compiler ever be considered non-compliant for not supporting the "efiabi" calling convention?

My instinct is that the existence of particular calling conventions would be far better as a T-compiler decision (like for targets), and lang would only come into it for things with semantic impact, like if someone wishes to add a feature for, say, as casting between fns with different ABIs. Certainly I don't feel like I personally have any useful feedback to offer here.

@joshtriplett
Copy link
Member

@scottmcm I do think we should be reviewing new ABI proposals, yes. Among other things, some ABIs may be proposed to solve problems that may be better solved a different way or with more comprehensive interactions (e.g. defining naked functions or interrupt handlers). Some ABIs may be supported across many targets (like this one). Some ABIs may have interactions with the set of types or function attributes permitted. This ABI also raised other language issues, such as the availability of specific ABIs on targets that don't support them.

So in general, while I think most ABIs will be uncontroversial, I don't think they should pass by without review.

@nikomatsakis
Copy link
Contributor

@rfcbot reviewed

@rfcbot rfcbot added the final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. label Dec 6, 2022
@rfcbot
Copy link

rfcbot commented Dec 6, 2022

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Dec 6, 2022
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Dec 16, 2022
@rfcbot
Copy link

rfcbot commented Dec 16, 2022

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

@rfcbot rfcbot added the to-announce Announce this issue on triage meeting label Dec 16, 2022
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Jan 5, 2023
nicholasbishop added a commit to nicholasbishop/rust that referenced this issue Jan 12, 2023
@bors bors closed this as completed in fa8f77a Jan 13, 2023
ojeda added a commit to ojeda/linux that referenced this issue Nov 23, 2024
Each `bindgen` release may upgrade the list of Rust targets. For instance,
currently, in their master branch [1], the latest ones are:

    Nightly => {
        vectorcall_abi: #124485,
        ptr_metadata: #81513,
        layout_for_ptr: #69835,
    },
    Stable_1_77(77) => { offset_of: #106655 },
    Stable_1_73(73) => { thiscall_abi: #42202 },
    Stable_1_71(71) => { c_unwind_abi: #106075 },
    Stable_1_68(68) => { abi_efiapi: #105795 },

By default, the highest stable release in their list is used, and users
are expected to set one if they need to support older Rust versions
(e.g. see [2]).

Thus, over time, new Rust features are used by default, and at some
point, it is likely that `bindgen` will emit Rust code that requires a
Rust version higher than our minimum (or perhaps enabling an unstable
feature). Currently, there is no problem because the maximum they have,
as seen above, is Rust 1.77.0, and our current minimum is Rust 1.78.0.

Therefore, set a Rust target explicitly now to prevent going forward in
time too much and thus getting potential build failures at some point.

Since we also support a minimum `bindgen` version, and since `bindgen`
does not support passing unknown Rust target versions, we need to use
the list of our minimum `bindgen` version, rather than the latest. So,
since `bindgen` 0.65.1 had this list [3], we need to use Rust 1.68.0:

    /// Rust stable 1.64
    ///  * `core_ffi_c` ([Tracking issue](rust-lang/rust#94501))
    => Stable_1_64 => 1.64;
    /// Rust stable 1.68
    ///  * `abi_efiapi` calling convention ([Tracking issue](rust-lang/rust#65815))
    => Stable_1_68 => 1.68;
    /// Nightly rust
    ///  * `thiscall` calling convention ([Tracking issue](rust-lang/rust#42202))
    ///  * `vectorcall` calling convention (no tracking issue)
    ///  * `c_unwind` calling convention ([Tracking issue](rust-lang/rust#74990))
    => Nightly => nightly;

    ...

    /// Latest stable release of Rust
    pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_68;

Thus add the `--rust-target 1.68` parameter. Add a comment as well
explaining this.

An alternative would be to use the currently running (i.e. actual) `rustc`
and `bindgen` versions to pick a "better" Rust target version. However,
that would introduce more moving parts depending on the user setup and
is also more complex to implement.

Cc: Christian Poveda <[email protected]>
Cc: Emilio Cobos Álvarez <[email protected]>
Link: https://github.com/rust-lang/rust-bindgen/blob/21c60f473f4e824d4aa9b2b508056320d474b110/bindgen/features.rs#L97-L105 [1]
Link: rust-lang/rust-bindgen#2960 [2]
Link: https://github.com/rust-lang/rust-bindgen/blob/7d243056d335fdc4537f7bca73c06d01aae24ddc/bindgen/features.rs#L131-L150 [3]
Signed-off-by: Miguel Ojeda <[email protected]>
intel-lab-lkp pushed a commit to intel-lab-lkp/linux that referenced this issue Nov 25, 2024
Each `bindgen` release may upgrade the list of Rust targets. For instance,
currently, in their master branch [1], the latest ones are:

    Nightly => {
        vectorcall_abi: #124485,
        ptr_metadata: #81513,
        layout_for_ptr: #69835,
    },
    Stable_1_77(77) => { offset_of: #106655 },
    Stable_1_73(73) => { thiscall_abi: #42202 },
    Stable_1_71(71) => { c_unwind_abi: #106075 },
    Stable_1_68(68) => { abi_efiapi: #105795 },

By default, the highest stable release in their list is used, and users
are expected to set one if they need to support older Rust versions
(e.g. see [2]).

Thus, over time, new Rust features are used by default, and at some
point, it is likely that `bindgen` will emit Rust code that requires a
Rust version higher than our minimum (or perhaps enabling an unstable
feature). Currently, there is no problem because the maximum they have,
as seen above, is Rust 1.77.0, and our current minimum is Rust 1.78.0.

Therefore, set a Rust target explicitly now to prevent going forward in
time too much and thus getting potential build failures at some point.

Since we also support a minimum `bindgen` version, and since `bindgen`
does not support passing unknown Rust target versions, we need to use
the list of our minimum `bindgen` version, rather than the latest. So,
since `bindgen` 0.65.1 had this list [3], we need to use Rust 1.68.0:

    /// Rust stable 1.64
    ///  * `core_ffi_c` ([Tracking issue](rust-lang/rust#94501))
    => Stable_1_64 => 1.64;
    /// Rust stable 1.68
    ///  * `abi_efiapi` calling convention ([Tracking issue](rust-lang/rust#65815))
    => Stable_1_68 => 1.68;
    /// Nightly rust
    ///  * `thiscall` calling convention ([Tracking issue](rust-lang/rust#42202))
    ///  * `vectorcall` calling convention (no tracking issue)
    ///  * `c_unwind` calling convention ([Tracking issue](rust-lang/rust#74990))
    => Nightly => nightly;

    ...

    /// Latest stable release of Rust
    pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_68;

Thus add the `--rust-target 1.68` parameter. Add a comment as well
explaining this.

An alternative would be to use the currently running (i.e. actual) `rustc`
and `bindgen` versions to pick a "better" Rust target version. However,
that would introduce more moving parts depending on the user setup and
is also more complex to implement.

Cc: Christian Poveda <[email protected]>
Cc: Emilio Cobos Álvarez <[email protected]>
Link: https://github.com/rust-lang/rust-bindgen/blob/21c60f473f4e824d4aa9b2b508056320d474b110/bindgen/features.rs#L97-L105 [1]
Link: rust-lang/rust-bindgen#2960 [2]
Link: https://github.com/rust-lang/rust-bindgen/blob/7d243056d335fdc4537f7bca73c06d01aae24ddc/bindgen/features.rs#L131-L150 [3]
Signed-off-by: Miguel Ojeda <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ABI Area: Concerning the application binary interface (ABI) A-FFI Area: Foreign function interface (FFI) B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. O-UEFI UEFI S-tracking-ready-to-stabilize Status: This is ready to stabilize; it may need a stabilization report and a PR T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants