Issue |
144164
|
Summary |
Clang on macOS does not emit stack-passed arguments when calling __attribute__((ms_abi)) functions from System V callers
|
Labels |
clang
|
Assignees |
|
Reporter |
Inakito
|
Description:
When compiling with Apple Clang 17.0.0 on macOS, calls from System V ABI functions (e.g., main) to functions marked with __attribute__((ms_abi)) do not correctly follow the Microsoft x64 ABI. Specifically, arguments that exceed the first four (passed in RCX, RDX, R8, R9) are not passed at all — they are not placed on the stack as required.
This causes serious runtime issues in ms_abi variadic functions which expect those parameters.
Environment:
- macOS 14.x (Apple Silicon or Intel, both reproducible)
- Apple Clang 17.0.0 (Xcode 15.3)
- Target: x86_64 (System V by default)
- Tested with -O0 and -O1
Reproduction Case:
```c
#include <stdio.h>
__attribute__((ms_abi)) void systemv_printf(const char *fmt, ...);
int main() {
double f1 = 1.1, f2 = 2.2, f3 = 3.3, f4 = 4.4, f5 = 5.5;
// Only the first 4 arguments are passed
systemv_printf("%g %g %g %g %g\n", f1, f2, f3, f4, f5);
return 0;
}
```
Implementation of systemv_printf attempts to read the 5th argument from the stack using frame pointer offset — but it's missing.
Expected behavior:
According to the Microsoft x64 ABI specification:
- First four arguments → in RCX, RDX, R8, R9
- Floating-point args duplicated into XMM0–XMM3
- Additional arguments → placed on the stack, 8-byte aligned
- Callee uses va_start or manual stack access to retrieve extra args
Actual behavior:
Clang emits code for the ms_abi call with only the first 4 arguments passed in registers. The 5th and beyond are not passed at all — no stack space is used, and the values are never pushed or stored.
Disassembly confirms this — even with volatile variables and -O0:
```asm
; systemv_printf("%g %g %g %g %g\n", f1, f2, f3, f4, f5);
leaq ... -> %rcx ; format string
movq ... -> %rdx ; f1
movq ... -> %r8 ; f2
movq ... -> %r9 ; f3
; NO instruction for f4 or f5 (e.g. mov to [rsp + N])
callq systemv_printf
```
Control Test (ms_abi → ms_abi):
When both caller and callee are marked __attribute__((ms_abi)), all arguments including the 5th float are properly passed — the last argument is correctly copied to [rsp+0x20] and accessible.
This suggests that Clang fails to emit proper Microsoft ABI code only when the caller is System V.
Impact:
This breaks interoperability between System V code (the default on macOS) and ms_abi functions — especially for printf-like variadic trampolines or ABI bridging layers, which depend on full argument delivery.
Suggested Fix:
Ensure that when a System V function calls an __attribute__((ms_abi)) function:
- The Microsoft ABI rules are fully applied
- Additional arguments beyond the 4th are pushed on the stack
Thank you!
Let me know if you'd like a full reproducer or test case archive.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs