什么是x86_64 va_list结构的格式?
任何人都可以参考x86_64 ABI(在Linux上使用的)中的va_list
的表示? 我试图debugging一些代码堆栈或参数看起来腐败,这将有助于理解我应该看到什么…
我把我的评论做成了一个答案。
这可能有帮助 。 这是一个参考,尽pipe轻量级。
variables参数列表参考从第50页开始,然后继续,第52-53页文档va_list
:
va_listtypes
va_listtypes是一个包含一个结构单个元素的数组,其中包含实现va_argmacros的必要信息。 va_listtypes的C定义如图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_startmacros
va_startmacros按如下方式初始化结构:
reg_save_area
元素指向寄存器保存区域的开始。
overflow_arg_area
这个指针用于获取栈上传递的参数。 它使用在堆栈上传递的第一个参数的地址进行初始化(如果有),然后始终更新为指向堆栈上下一个参数的开始。
gp_offset
元素保存从reg_save_area到保存下一个可用通用参数寄存器的位置的字节偏移量。 如果所有参数寄存器已经用尽,则将其设置为值48(6 * 8)。
fp_offset
元素保存从reg_save_area到下一个可用浮点参数寄存器保存位置的字节偏移量。 如果所有参数寄存器已经用尽,则设置为值304(6 * 8 + 16 * 16)。
事实certificate,问题是gcc使va_list
数组types。 我的function是签名:
void foo(va_list ap);
我想通过一个指针到另一个函数,所以我做了:
void foo(va_list ap) { bar(&ap); }
不幸的是,数组types衰减到函数参数列表中的指针types,所以不是将指针传递给原始结构,而是将指针传递给指针。
要解决该问题,我将代码更改为:
void foo(va_list ap) { va_list ap2; va_copy(ap2, ap); bar(&ap2); va_end(ap2); }
这是我能想到的唯一的便携式解决scheme,它解释了va_list
是一种数组types的可能性以及它不可能的可能性。