I am just wondering why the following code by using va_start, the addresses of the stack parameters are not in order anymore. va_start is a gcc builtin. But how can it change the addresses of the parameters?
#include <stdarg.h>
#include <stdio.h>
int my_vsnprintf(char* s, int n, char* format, ...) {
va_list args;
#if S1
va_start(args, format);
printf("with va_start\n");
#else
printf("w/o va_start\n");
#endif
printf(" ps=0x%p\n", &s);
printf(" pn=0x%p\n", &n);
printf("pformat=0x%p\n", &format);
}
int main() {
char buf[100];
my_vsnprintf(buf, 100, "%d\n", 0x1234);
return 0;
}
in order with: -m32 -fstack-protector-strong
w/o va_start
ps=0x0xffdd23b0
pn=0x0xffdd23b4
pformat=0x0xffdd23b8
not in order with: -m32 -fstack-protector-strong -DS1
with va_start
ps=0x0xffa2edec
pn=0x0xffa2ee14
pformat=0x0xffa2ede8
Test with gcc 15.1, see https://godbolt.org/z/TYhGqGrK4
I am just wondering why the following code by using va_start, the addresses of the stack parameters are not in order anymore.
And this information will be useful to you how?
va_start is a gcc builtin. But how can it change the addresses of the parameters?
va_start
is a macro provided by the C standard library, according to the language spec. But even (more) if GCC implements it as a built-in, the answer is that to whatever extent use of va_start
causes objects to have different absolute or relative addresses, that's a result of GCC building the program differently when va_start
is used than it does when va_start
is not used. It is a compile-time effect, not a runtime effect. And that should not seem mysterious.
Note also that the C language has no sense of "stack parameters" or even of "stack". In practice, function arguments are not necessarily passed on a stack. Many ABIs call for most arguments to be passed in registers, instead, in which case they might not even have addresses if you never apply the &
operator to them.