Biohazrd
Biohazrd copied to clipboard
Add support for variable arguments (non-va_list)
No attempt at supporting variable arguments was made in the original prototype. Supporting these will be non-trivial because if I remember right, the runtime doesn't officially support P/Invoke with variable arguments outside of Windows.
If I remember how va_list
works internally, supporting it should be relatively simple. So a good starting point should be to support that, which should cover any C++ libraries that provide both a variable arguments function and a va_list
function. (And if I am correctly remembering how variable arguments works under the hood, supporting it first is likely needed to support them anyway.)
Some notes from quick-and-dirty messing with implementing vargs manually to test ImGui:
CRT puts most of the implementation of vargs in macros in vadefs.h
for x86:
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
#define __crt_va_start_a(ap, v) ((void)(ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v)))
#define __crt_va_arg(ap, t) (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define __crt_va_end(ap) ((void)(ap = (va_list)0))
For x64:
void __cdecl __va_start(va_list* , ...);
#define __crt_va_start_a(ap, x) ((void)(__va_start(&ap, x)))
#define __crt_va_arg(ap, t) \
((sizeof(t) > sizeof(__int64) || (sizeof(t) & (sizeof(t) - 1)) != 0) \
? **(t**)((ap += sizeof(__int64)) - sizeof(__int64)) \
: *(t* )((ap += sizeof(__int64)) - sizeof(__int64)))
#define __crt_va_end(ap) ((void)(ap = (va_list)0))
I couldn't dig up __va_start
in the reference source for x64, but quick tests seem to suggest it works the same way as x86.
In general, things are always/usually word-aligned. Floating point numbers are always promoted to doubles. (Including on x86?)
Here's what manually using va_list
looks like in the InfectedImGui sample:
https://github.com/InfectedLibraries/InfectedImGui/blob/aaabb2ba2b3bc74d20cdd9ff8ccb02ad1ac6d796/InfectedImGui.Sample/Program.cs#L166-L167
Recommending people just pass in tuples might actually be a pretty solid strategy here. However we do need to explore whether this is viable for all ABIs or not. It might be a good idea to provide an analyzer to do printf-like parameter validation for these scenarios.
I broke out va_list
support to https://github.com/InfectedLibraries/Biohazrd/issues/164 as it's much simpler than "proper" variable arguments.