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

Proposal: extern "uefi" ABI #54527

Closed
HadrienG2 opened this issue Sep 24, 2018 · 10 comments · Fixed by #65809
Closed

Proposal: extern "uefi" ABI #54527

HadrienG2 opened this issue Sep 24, 2018 · 10 comments · Fixed by #65809
Labels
A-ffi Area: Foreign Function Interface (FFI) C-feature-request Category: A feature request, i.e: not implemented / a PR. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@HadrienG2
Copy link

HadrienG2 commented Sep 24, 2018

The UEFI firmware interface has some calling conventions which are documented in chapter 2.3 of the current spec.

For the most part, these are pretty close to the Windows ABI conventions ("cdecl" on IA-32, "win64" on AMD64...), which should come as no surprise given the strong influence that Microsoft has on the UEFI forum. However, the UEFI spec also defines calling conventions for hardware architectures like RISC-V where Windows has not been ported.

UEFI applications (such as OS loaders) must be extra careful to use the right ABI when calling into UEFI, since unless you are Windows, extern "C" will not necessarily map into what the firmware expects.

In rust-osdev/uefi-rs#41 , @GabrielMajeri proposed to make the life of UEFI application developers easier by adding language-level support for the UEFI FFI in the form of an extern "uefi" ABI. How open would you be to this idea?

@nagisa nagisa added A-ffi Area: Foreign Function Interface (FFI) C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Sep 24, 2018
@eddyb
Copy link
Member

eddyb commented Sep 24, 2018

cc @rust-lang/compiler @alexcrichton

@steveklabnik
Copy link
Member

Is this discussion better had here or on internals?

@HadrienG2
Copy link
Author

Whichever way you like best 😉

@parched
Copy link
Contributor

parched commented Sep 24, 2018

How do the C compilers handle this?

@petrochenkov
Copy link
Contributor

I wonder if it's possible to support custom ABIs through some plugin-based interface.
You write some Rust code describing how the ABI works, then link it proc macro style, then use the new ABI.

(Disclaimer: I have no idea how the current ABI definitions work, and what interface the ABI plugin should have, especially for calling conventions.)

@eddyb
Copy link
Member

eddyb commented Sep 24, 2018

@petrochenkov It's very close to being pure data, so I would prefer to have it mostly be described in JSON, or something like that, if possible. (I've considered it before, albeit not in a purely declarative manner, it's mostly a matter of "resource categorization and allocation")

Everything other than calling conventions is already described through the "datalayout" string, and I'd prefer to avoid adding plugin systems to rustc, as they impose significant technical burden.


OTOH, us gathering call ABIs ("calling conventions") for various targets comes at almost 0 cost and since it's all isolated in a rustc_target library with no dependencies on the compiler, we can even merge efforts with Cranelift, to make it easy to build upon those ABI definitions (cc @sunfishcode).

The "mainstream" approach of rewriting all the rules for all the targets, by hand, in every compiler, is a waste of effort, and unshares knowledge, and rustc can do a public service here.

@Centril Centril added T-lang Relevant to the language team, which will review and decide on the PR/issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 24, 2018
@Centril
Copy link
Contributor

Centril commented Sep 25, 2018

I say let's do it :)

@GabrielMajeri
Copy link
Contributor

GabrielMajeri commented Sep 25, 2018

How do the C compilers handle this?

The C compilers make a distinction between "different calling conventions" and "same calling convention name, different ABIs".

GCC and Clang support custom function attributes which allow one to write __cdecl __attribute__((ms_abi)) vs __cdecl __attribute__((sysv_abi)).

Also, this attribute has no effect on non-x86_64, so everything fits perfectly. In our use case, extern "win64" is allowed on 32-bit (weird) and it generates code different from extern "C".

As for usage of this feature: it is used in gnuefi (for UEFI calling convention) and wine (for building ELF files with Windows calling conventions).

I would prefer to have it mostly be described in JSON, or something like that

Interesting, but my question is, how can we make this composable and allow this to work with libraries?
If we have a library providing UEFI bindings, it should be its responsability to define extern "uefi", instead of relying on downstream binaries to include JSON in their build script.

@estebank
Copy link
Contributor

I would prefer to have it mostly be described in JSON, or something like that

Interesting, but my question is, how can we make this composable and allow this to work with libraries?
If we have a library providing UEFI bindings, it should be its responsability to define extern "uefi", instead of relying on downstream binaries to include JSON in their build script.

I believe the point is to make it configurable on our end, so that adding new extern targets can be done purely with metadata, instead of changing rustc code. That doesn't mean that developers would be required to come up with their own files for any of the supported calling conventions ("C"/"uefi"), but it would enable them to come up with their own if needed (regardless on wether a rustc would be needed ^_^).

@Rua
Copy link
Contributor

Rua commented Feb 23, 2019

This seems like a good idea to me. Like extern "C", this would simply be an alias for different things on different platforms, and new mappings could be added if UEFI ever gets extended to new platforms in the future.

Centril added a commit to Centril/rust that referenced this issue Oct 29, 2019
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?
Centril added a commit to Centril/rust that referenced this issue Oct 29, 2019
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?
@bors bors closed this as completed in 46063ed Oct 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ffi Area: Foreign Function Interface (FFI) C-feature-request Category: A feature request, i.e: not implemented / a PR. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. 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