Skip to content

Conversation

ehuss
Copy link
Contributor

@ehuss ehuss commented Sep 17, 2025

This updates the definitions of the extern ABIs to try to make them a little clearer as to what they mean.

This also adds new statements about the equivalence of some ABIs to the "C" ABI.

Fixes #1946.

@ehuss
Copy link
Contributor Author

ehuss commented Sep 17, 2025

@ChrisDenton We rephrased the description of the "system" ABI, and were wondering if you could take a look to see if the new text was accurate and conveyed the right meaning.

@Amanieu or @ChrisDenton We made a few new claims in this edit about the "C" ABI. We were sure who to ask, but were wondering if you knew the answer. In particular it is specifying that:

  • "win64" is the same as the "C" ABI on Windows x86_64 targets
  • "sysv64" is the same as the "C" ABI on non-Windows x86_64 targets

@Amanieu
Copy link
Member

Amanieu commented Sep 17, 2025

Yes, that seems correct to me.

@ChrisDenton
Copy link
Member

ChrisDenton commented Sep 17, 2025

Should probably @workingjubilee and @RalfJung who are knowledgable in this area.

This looks good to me though rust-lang/rust#136946 will need to adjust the the Windows 32-bit documentation to note the varargs peculiarity.

Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds right but I don't actually know that much about all these target-specific ABIs.

Not sure how I feel about linking to the Microsoft docs for some of these (even when they are not Microsoft-defined ABIs, or are they?), but I don't know a better place to link to either.


r[items.extern.abi.c]
* `unsafe extern "C"` --- This is the same as `extern fn foo()`; whatever the default your C compiler supports.
* `unsafe extern "C"` --- The "C" ABI attempts to match the default ABI chosen by the dominant C compiler for the target.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"attempts to match" is a bit... weak?^^

* `unsafe extern "system"` --- This is equivalent to `extern "C"` except on Windows x86_32 where it is equivalent to `"stdcall"`.

> [!NOTE]
> As the correct underlying ABI on Windows is target-specific, it's best to use `extern "system"` when attemping to link to the Windows API.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't true for all of the Windows API though, some of it uses "C"...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, though I think you meant cdecl here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I meant "C". "cdecl" is x86-32-only.

r[items.extern.abi.stdcall]
* `unsafe extern "stdcall"` --- The default for the Win32 API on x86_32.
* `unsafe extern "stdcall"` --- The calling convention typically used by the [Win32 API] on x86_32.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this correspond to __stdcall or __attribute__((stdcall)) or anything like that on any other compiler?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the answer is "yes". Are you suggesting this should explicitly say that like the entry for fastcall does?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems worthwhile, doesn't it?


r[items.extern.abi.cdecl]
* `unsafe extern "cdecl"` --- The default for x86_32 C code.
* `unsafe extern "cdecl"` --- The calling convention typically used with x86_32 C code.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this correspond to __scdecl or __attribute__((cdecl)) or anything like that on any other compiler?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the answer here is also "yes" (assuming the s is a typo).

Comment on lines 146 to 155
* `unsafe extern "win64"` --- The Windows x64 ABI.
* Only available on x86_64 targets.
* "win64" is the same as the "C" ABI on Windows x86_64 targets.

> [!NOTE]
> See <https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions> and <https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention> for more information.
r[items.extern.abi.sysv64]
* `unsafe extern "sysv64"` --- The default for C code on non-Windows x86_64.
* `unsafe extern "sysv64"` --- The System V ABI.
* Only available on x86_64 targets.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do clang/gcc/MSVC have attributes that correspond to our win64/sysv64?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the answer is "kinda".

AFAIK, Microsoft's __cdecl is the same as our "win64" or "C" (and I believe clang/gcc also do the same).

I believe for "sysv64", the answer is "no" for MSVC, you cannot explicitly specify that on MSVC. It looks like clang and gcc use the attribute sysv_abi.

Are you suggesting that we should be more explicit about these equivalences?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, Microsoft's __cdecl is the same as our "win64" or "C"

That's just a consequence of "C" being "win64" for them, right?

Do clang/gcc support explicitly using the win64 ABI somehow? That would be the most direct equivalent.

Are you suggesting that we should be more explicit about these equivalences?

We're very explicit about it in some cases but not others. That seemed odd.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's truer to say that __cdecl, __fastcall, etc is ignored outside of x86_32. I don't believe MSVC has an explicit calling convention for arm64 or x86_64. It just ignores any calling convention other than __vector_call and thus uses the default. I guess you could claim that one of these ignored calling conventions is the "real" name for the calling convention on x64 or arm64 but I don't think it's particularly useful to do so.

This updates the definitions of the extern ABIs to try to make them a
little clearer as to what they mean.

This also adds new statements about the equivalence of some ABIs
to the "C" ABI.
@ehuss
Copy link
Contributor Author

ehuss commented Sep 29, 2025

OK, I pushed up a change that tries to be more consistent with showing the equivalent attributes.

My homework for investigating this:

Primary sources are:

For the translation in rustc to LLVM, there are multiple places to look:

  • AbiMapping -- This is a first canonicalization of ABIs. Most ABIs have a clear translation ("Rust" is "Rust"). Some are erased at this stage (efiapi gets translated to various other ABIs based on the target).
  • llvm::CallConv -- Converts rustc's call convention to LLVM's.
  • LLVM CallingConv.h -- LLVM's definition of the different calling conventions.
  • Clang CallingConv -- How attributes to mapped to a calling convention.
  • Clang ClangCallConvToLLVMCallConv -- Converts clang's calling convention to LLVM.

Generally I tried to make sure that clang translation to LLVM is the same as rustc's.

@ehuss ehuss marked this pull request as ready for review September 29, 2025 20:52
@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Sep 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: The marked PR is awaiting review from a maintainer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Description of "aapcs" ABI seems wrong
5 participants