On 5/13/2026 8:50 AM, Oliver Smith-Denny wrote:
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:
(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).
This worked in our testing, both in the original crypto API failure
case and a pair of test drivers I wrote that communicate via protocol,
calling variadic functions (which should always work, but I wanted to
make sure) and passing VA_LIST as a parameter. Each side validated the
expected input/output. I tried all four combinations of GCC vs CLANGPDB
built consumer/producer and all worked (without this change all
four combinations were broken).
Do you want to put up a PR for this? I can, but I didn't make any
changes to your suggestion, it "just worked." Feel free to add a
tested-by for me, not that carries too much weight :)
Thanks,
Oliver
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#121952): https://edk2.groups.io/g/devel/message/121952
Mute This Topic: https://groups.io/mt/119278849/21656
Group Owner: [email protected]
Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-