Skip to content

trans/codegen_c: Honor "fastcall"/"stdcall"/"sysv64"/"win64" ABI on GCC - #433

Open
rautyrauty wants to merge 1 commit into
thepowersgang:masterfrom
rautyrauty:upstream-gcc-callconv
Open

rautyrauty wants to merge 1 commit into
thepowersgang:masterfrom
rautyrauty:upstream-gcc-callconv

Conversation

@rautyrauty

Copy link
Copy Markdown
Contributor

This is necessary because mrustc previously ignored every non-default calling convention on GCC: emit_type_fn and emit_function_header only handled MSVC's "system" -> __stdcall. For any other ABI string the C output came out as plain cdecl on x86 (and the default SysV on x86_64), silently disagreeing with the declared Rust ABI.

On i586 this breaks psm (used by rustc via stacker for deep typecheck recursion). Its extern_item! macro picks the ABI per architecture, and under target_arch = "x86" that is extern "fastcall", matching the hand-written assembly stubs in vendor/psm/src/arch/x86.s which read arguments from %ecx and %edx. With mrustc's cdecl emission those registers held whatever happened to be there at the call site, and rust_psm_on_stack then jumped through a garbage callback pointer onto an unrelated mmap page - producing the SIGSEGV during the i586 stage-2 libcore compile, with PC at a no-symbol address inside a high-mmap region and corrupt return frames in the backtrace.

The other architectures did not notice because the ABI the same macro picks for them is already what mrustc emits: plain C on aarch64, "sysv64" on x86_64 (the default C ABI on Linux) and "aapcs" on arm (likewise the default). "aapcs" is therefore left unhandled here rather than mapped to an attribute.

Link: https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html

This is necessary because mrustc previously ignored every non-default
calling convention on GCC: emit_type_fn and emit_function_header only
handled MSVC's "system" -> __stdcall. For any other ABI string the C
output came out as plain cdecl on x86 (and the default SysV on
x86_64), silently disagreeing with the declared Rust ABI.

On i586 this breaks `psm` (used by rustc via `stacker` for deep
typecheck recursion). Its `extern_item!` macro picks the ABI per
architecture, and under `target_arch = "x86"` that is
`extern "fastcall"`, matching the hand-written assembly stubs in
`vendor/psm/src/arch/x86.s` which read arguments from %ecx and %edx.
With mrustc's cdecl emission those registers held whatever happened
to be there at the call site, and `rust_psm_on_stack` then jumped
through a garbage callback pointer onto an unrelated mmap page -
producing the SIGSEGV during the i586 stage-2 libcore compile, with
PC at a no-symbol address inside a high-mmap region and corrupt
return frames in the backtrace.

The other architectures did not notice because the ABI the same macro
picks for them is already what mrustc emits: plain C on aarch64,
"sysv64" on x86_64 (the default C ABI on Linux) and "aapcs" on arm
(likewise the default). "aapcs" is therefore left unhandled here
rather than mapped to an attribute.

Link: https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant