找出模式以便在编译的程序中找到变量

时间:2012-07-03 13:56:39

标签: windows dwarf readelf debug-information

我需要从已编译的c程序中提取全局变量。我现在正在做的是使用Linux readelf命令来获取该信息。换句话说,当我这样做时:

  readelf.exe -w[i]  myFile.out      

我使用readelf.exe这个可以从here下载的程序。因为我使用的是Windows,这是我需要的唯一命令。在linux上,我将打开控制台并执行readelf -w[i] myFile.out

无论如何,当我执行该命令时,我会得到类似的东西:

 <1><86923>: Abbrev Number: 2 (DW_TAG_base_type)
    <86924>   DW_AT_name        : unsigned int  
    <86925>   DW_AT_encoding    : 7 (unsigned)
    <86927>   DW_AT_byte_size   : 4 
<1>..
...
... bla bla bla
... 
<1><870a1>: Abbrev Number: 12 (DW_TAG_variable)
    <870a2>   DW_AT_decl_file   : 25    
    <870a3>   DW_AT_decl_line   : 543   
    <870a5>   DW_AT_external    : 1 
    <870a6>   DW_AT_name        : NetBuf_ID_Ctr     // <------------------- First variable
    <870b4>   DW_AT_type        : <0x86923> 
    <870b8>   DW_AT_location    : 5 byte block: 3 ff f9 b 20    (DW_OP_addr: fff90b20)
 <1><870be>: Abbrev Number: 3 (DW_TAG_typedef)
    <870bf>   DW_AT_decl_file   : 26    
    <870c0>   DW_AT_decl_line   : 192   
    <870c2>   DW_AT_name        : NET_CONN_FAMILY   
    <870d2>   DW_AT_type        : <0x862f1> 
 <1><870d6>: Abbrev Number: 3 (DW_TAG_typedef)
    <870d7>   DW_AT_decl_file   : 26    
 ....

使用那个“树”我能够获得所有全局变量和类型。例如,如果您查看第一个变量NetBuf_ID_Ctr,我们可以看到我们可以获取有关节点<0x86923>上的类型的信息。那个节点在树的某个地方!如果你看一下实际上是第一个节点。启动<1><86923>....的那个,如果你看到那个节点内部,我们就知道变量是一个4字节大小的无符号整数。


现在我的问题是当我使用readelf命令时,我得到了 enter image description here 我需要解析192883行文本!这棵树给了我更多关于我需要的信息。如果我用十六进制编辑器查看文件,这就是我所看到的:

enter image description here

请注意,我能够找到相同的变量NetBuf_ID_Ctr,旁边(突出显示)是地址<0x86923>

互联网上是否有一些地方可以指导我如何构建树?命令readelf.exe需要.1秒来创建树!它将它的输出放在StreamReader上,这就是为什么它如此之快。如果我希望将StreamReader放在内存上,将其转换为需要这么长时间的字符串。


修改

总之,我想知道如何从myFile.out构造树(readelf的输出)。我无法弄清楚这种模式既不是互联网上解释如何的地方。

1 个答案:

答案 0 :(得分:1)

基本上,ELF对象文件中的矮调试信息位于

部分
  • .debug_aranges
  • .debug_frame
  • .debug_info
  • .debug_line
  • .debug_pubnames
  • .debug_pubtypes

通过解析.debug_info中的信息来构造die树,该信息描述了调试信息条目(DIE)之间的关系。如何存储此信息在DWARF标准中有所描述,可以找到here

从您的问题来看,您似乎希望尽可能快地转储所有全局符号。 如果要从自己的程序中执行此操作,可以使用libdwarf来解析.debug_pubnames的内容。此部分包含标题集,后跟许多名称,偏移对。名称是全局名称,偏移量是DIE从其编译单元开始的偏移量。 libdwarf可以再次使用它来获取有关它的更详细信息。

libdwarf可以很容易地在Windows上编译,但你也需要libelf。 有关DWARF调试信息格式

的简单说明,另请参阅this