cgccvariadic-functions

variable number of arguments with -fstack-protector-strong


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


Solution

  • 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.