On 5/13/2026 3:42 AM, Ard Biesheuvel via groups.io wrote:
On Tue, 12 May 2026, at 22:02, Oliver Smith-Denny via groups.io wrote:
...
I or someone on my team will put up a PR to address this (which again,
__builtin_va_list on CLANGPDB is still the MS ABI, so there might be
some perf benefit, but no interop benefit) and we'll fix up the in-tree
usage of VA_LIST across ABI boundaries (which may be limited to the
crypto case).
Sean had an idea I liked here: why not handroll the AAPCS64 ABI for
the VA* implementation in Base.h so that CLANGPDB can align to the spec
correctly and not have interop issues with GCC/CLANGDWARF? We would do
the same for MSVC ARM64, but again, I consider that to be a dead
toolchain.
The MS ABI code in Base.h is already handrolled because no compiler
builtin for MSVC exists.
I think this might be feasible, although it is not pretty :-)
I think little we do is pretty :)
There are two cases to consider here:
1) MSVC compiled vararg function calling a AAPCS64 function taking a VA_LIST
The callee requires a full AAPCS64 struct va_list, or it will read
garbage off the stack. However, I think this is rather straight-forward,
since we can pretend that all arguments were already on the stack (as
this is what MSVC's __va_start() guarantees by spilling register arguments
into the shadow region. So we can ignore gr_offs/gr_top in this case.
2) AAPCS64 compiled vararg function calling a MSVC function taking a VA_LIST
Here, the struct va_list is populated by the compiler, and gr_top/gr_offs
may be set to non-zero values. Our implementation of VA_ARG() should take
these into account. Fortunately, the AAPCS64 document has pseudo-code that
describes how to deal with this, so this also seems feasible.
We can ignore FP arguments and therefore the vr_top/vr_offs fields.
One thing we must take into account, though, is that passing the VA_LIST
type itself by value violates the UEFI spec (paragraph 2.3), given that
its size exceeds the size of UINTN. So it might be better to pass
VA_LISTs by reference instead when used in PPIs / protocols.
Good point. Gives further fuel to change the crypto API, regardless of
this.
(Untested attempt below)
--- a/MdePkg/Include/Base.h
+++ b/MdePkg/Include/Base.h
@@ -578,15 +578,23 @@ struct _LIST_ENTRY {
#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN)
- 1))
#if defined (_M_ARM64)
-//
-// MSFT ARM variable argument list support.
-//
-typedef char *VA_LIST;
+typedef struct {
+ char *stack; // next stack param
+ char *gr_top; // end of GP arg reg save area
+ char *vr_top; // end of FP/SIMD arg reg save area
+ int gr_offs; // offset from gr_top to next GP register arg
+ int vr_offs; // offset from vr_top to next FP/SIMD register arg
+} VA_LIST;
-#define VA_START(Marker, Parameter) __va_start (&Marker, &Parameter, _INT_SIZE_OF (Parameter), __alignof(Parameter), &Parameter)
-#define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE) +
((-(INTN)Marker) & (sizeof(TYPE) - 1))) - _INT_SIZE_OF (TYPE)))
-#define VA_END(Marker) (Marker = (VA_LIST) 0)
+#define VA_START(Marker, Parameter) Marker.gr_top = Marker.vr_top = NULL, \
+ Marker.gr_offs = Marker.vr_offs = 0, \
+ __va_start (&Marker.stack, &Parameter,
_INT_SIZE_OF (Parameter), __alignof (Parameter), &Parameter)
+#define VA_STACK_ARG(Marker, TYPE) ((Marker.stack += _INT_SIZE_OF (TYPE) +
((-(INTN)Marker.stack) & (sizeof(TYPE) - 1))) - _INT_SIZE_OF (TYPE))
+#define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker.gr_offs += _INT_SIZE_OF
(TYPE)) <= 0 \
+ ? &Marker.gr_top[Marker.gr_offs -
_INT_SIZE_OF (TYPE)] \
+ : VA_STACK_ARG(Marker, TYPE)))
+#define VA_END(Marker) (Marker.stack = NULL)
#define VA_COPY(Dest, Start) ((void)((Dest) = (Start)))
#elif defined (__GNUC__) || defined (__clang__)
Doug and I started down this path yesterday as well, I'll do some
testing of this today (and compare our version to yours, make sure we
didn't miss something).
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#121950): https://edk2.groups.io/g/devel/message/121950
Mute This Topic: https://groups.io/mt/119278849/21656
Group Owner: [email protected]
Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-