什么是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的可能性以及它不可能的可能性。