У кого-нибудь есть ссылка на представление va_list в ABI x86_64 (тот, который используется в Linux)? Я пытаюсь отладить некоторый код, где стек или аргументы кажутся коррумпированными, и это действительно поможет понять, что я должен видеть...
Каков формат структуры va_list x86_64?
Ответ 1
Я сделал свой комментарий в ответ.
Это может помочь. Это ссылка, пусть и легкая.
Ссылка на список аргументов Variable начинается на стр. 50, затем она продолжается, стр. 52-53 документы va_list:
Тип va_list
Тип va_list - это массив содержащий один элемент из одного структура, содержащая необходимые информация для внедрения va_arg макро. Определение C va_list тип приведен на рисунке 3.34
// Figure 3.34
typedef struct {
   unsigned int gp_offset;
   unsigned int fp_offset;
   void *overflow_arg_area;
   void *reg_save_area;
} va_list[1];
Макрос va_start
Макрос va_start инициализирует структуры следующим образом:
reg_save_areaЭлемент указывает на начало области сохранения регистров.
overflow_arg_areaЭтот указатель используется для извлечения аргументов, переданных на стек. Он инициализируется адрес первого аргумента, переданного стек, если он есть, а затем всегда обновить, чтобы указать на начало следующий аргумент в стеке.
gp_offsetЭлемент содержит смещение в байтах от reg_save_area до место, где следующий доступный общий регистр аргументов назначения сохраняется. В все регистры аргументов были исчерпан, он установлен в значение 48 (6 * 8).
fp_offsetЭлемент содержит смещение в байтах от reg_save_area до место, где следующий доступный регистр точечного аргумента сохраняется. В все регистры аргументов были исчерпан, он установлен в значение 304 (6 * 8 + 16 * 16).
Ответ 2
Оказывается, проблема заключалась в том, что gcc создал va_list тип массива. Моя функция была подписи:
void foo(va_list ap);
 и я хотел передать указатель на ap на другую функцию, поэтому я сделал:
void foo(va_list ap)
{
    bar(&ap);
}
К сожалению, типы массивов распадаются на типы указателей в списках аргументов функций, поэтому вместо передачи указателя на исходную структуру я передавал указатель на указатель.
Чтобы обойти проблему, я изменил код на:
void foo(va_list ap)
{
    va_list ap2;
    va_copy(ap2, ap);
    bar(&ap2);
    va_end(ap2);
}
Это единственное портативное решение, которое я мог бы придумать, что объясняет как возможность, что va_list - тип массива, так и возможность того, что это не так.