如何从 DWARF 导出字符串或数组的长度?

How to derive the length of a string or an array from DWARF?

下面的代码,经过GCC编译后,是否可以从DWARF中导出"teststr"和"testarray"变量的长度?

void func(char *str1, char *str2){
     ...
     ...
     return;
}

int main(void){
     char *teststr = "123456";
     char testarray[6] = "123456";

     func(teststr, testarray);     
     ....
     ....

     return 0;
}

DWARF 几乎代表了编译器对源程序的了解。所以这个问题的一般答案是:如果你能在源代码中找到大小"locally",那么是的;否则没有。

但在这种情况下,如果我们从您的程序中删除 ...s 并编译它,我们可以直接使用 readelf.

读取 DWARF

这是 main 中的 testarray 的样子:

 <2><5c>: Abbrev Number: 3 (DW_TAG_variable)
    <5d>   DW_AT_name        : (indirect string, offset: 0x5): testarray
    <61>   DW_AT_decl_file   : 1
    <62>   DW_AT_decl_line   : 7
    <63>   DW_AT_type        : <0x7f>
    <67>   DW_AT_location    : 2 byte block: 91 60  (DW_OP_fbreg: -32)
...
 <1><7f>: Abbrev Number: 7 (DW_TAG_array_type)
    <80>   DW_AT_type        : <0x78>
    <84>   DW_AT_sibling     : <0x8f>
 <2><88>: Abbrev Number: 8 (DW_TAG_subrange_type)
    <89>   DW_AT_type        : <0x8f>
    <8d>   DW_AT_upper_bound : 5
 <2><8e>: Abbrev Number: 0
 <1><8f>: Abbrev Number: 6 (DW_TAG_base_type)
    <90>   DW_AT_byte_size   : 8
    <91>   DW_AT_encoding    : 7    (unsigned)
    <92>   DW_AT_name        : (indirect string, offset: 0x60): sizetype

也就是6个字符的数组。所以在这种情况下,您可以找到长度——正是您阅读源代码所期望的长度。

然而 teststrfunc 中的变量看起来更像:

 <2><4e>: Abbrev Number: 3 (DW_TAG_variable)
    <4f>   DW_AT_name        : (indirect string, offset: 0xf): teststr
    <53>   DW_AT_decl_file   : 1
    <54>   DW_AT_decl_line   : 6
    <55>   DW_AT_type        : <0x72>
    <59>   DW_AT_location    : 2 byte block: 91 68  (DW_OP_fbreg: -24)
...
 <1><72>: Abbrev Number: 5 (DW_TAG_pointer_type)
    <73>   DW_AT_byte_size   : 8
    <74>   DW_AT_type        : <0x78>
 <1><78>: Abbrev Number: 6 (DW_TAG_base_type)
    <79>   DW_AT_byte_size   : 1
    <7a>   DW_AT_encoding    : 6    (signed char)
    <7b>   DW_AT_name        : (indirect string, offset: 0x7d): char

这表示它只是一个指向字符的指针——换句话说,长度不是静态已知的。像 gdb 这样的调试器可以在运行时通过从底层读取内存来找到长度,就像您的程序必须做的那样。