2014-09-18 111 views
2

我有一个ARM二进制文件,我需要准确地找到它的函数的序言结尾和结尾开始的地址。换句话说,我需要职能机构的界限。举例来说,如果我有,其装配的功能是一样的东西:DWARF - 如何在给定的二进制文件中查找函数的序言结束/尾声开始地址?

0x00000320 <+0>: push {r7, lr} 
0x00000322 <+2>: sub sp, #16 
0x00000324 <+4>: add r7, sp, #0 
0x00000326 <+6>: str r0, [r7, #4] 
0x00000328 <+8>: (Function body starts here) 
... 
0x0000034c <+44>: (Function body ends here) 
0x0000034e <+46>: mov sp, r7 
0x00000350 <+48>: pop {r7, pc} 

我需要一种方法来快速找到任何0x00000326和​​(开场白结束/尾声开始)或0x000003280x0000034c(函数体开始/结束)使用诸如readelf或objdump之类的东西。简单地拆解它并检查代码将无法做到(理想情况下,我会使用脚本来分析readelf的输出或用于获取DWARF信息的任何程序)。

根据DWARF 4标准,.debug_line部分应该包含行号信息,其中包括“prologue_end”和“epilogue_begin”,这正是我所需要的。但是,arm-linux-readelf --debug-dump=rawline,decodedline的输出不会给我这些信息。

我正在编译使用gcc 4.8.2-ggdb3标志。

编辑:一些更多的信息:objdump的都和readelf告诉我这样的事情:

Line Number Statements: 
[0x00000074] Extended opcode 2: set Address to 0x100 
[0x0000007b] Advance Line by 302 to 303 
[0x0000007e] Copy 
[0x0000007f] Special opcode 34: advance Address by 4 to 0x104 and Line by 1 to 304 
[0x00000080] Special opcode 34: advance Address by 4 to 0x108 and Line by 1 to 305 
[0x00000081] Special opcode 37: advance Address by 4 to 0x10c and Line by 4 to 309 
[0x00000082] Special opcode 34: advance Address by 4 to 0x110 and Line by 1 to 310 
[0x00000083] Special opcode 20: advance Address by 2 to 0x112 and Line by 1 to 311 
[0x00000084] Special opcode 37: advance Address by 4 to 0x116 and Line by 4 to 315 
[0x00000085] Special opcode 34: advance Address by 4 to 0x11a and Line by 1 to 316 
[0x00000086] Advance Line by -13 to 303 
[0x00000088] Special opcode 19: advance Address by 2 to 0x11c and Line by 0 to 303 
[0x00000089] Special opcode 34: advance Address by 4 to 0x120 and Line by 1 to 304 
[0x0000008a] Advance PC by 4 to 0x124 
[0x0000008c] Extended opcode 1: End of Sequence 

看的binutils' dwarf.c的来源,似乎应该打印类似“设置prologue_end在行信息转储中将其设置为true“和”将epilogue_begin设置为true“。但是,所有的操作码似乎都是特殊的,而不是标准的。

+0

对于值得用“clang-3.6 -gdwarf-4 -g3”编译的代码,我得到了“Set prologue_end to true”DWARF info:GCC似乎无法生成这个(还没有?)。 – ysdx 2014-12-08 00:52:44

回答

0

尝试

readelf -wi 

,寻找DW_AT_low_pc和DW_AT_high_pc您正在查找的子程序。

的DWARF规范说:

子程序条目可以具有一个DW_AT_low_pc和DW_AT_high_pc对属性或DW_AT_ranges属性,其值编码连续的或不连续的地址范围,分别的机器指令为子程序生成(参见2.17节)。

如果我没有记错的话,DW_AT_low_pc是序言之后的地址,DW_AT_high_pc是结尾之前的最后一个地址。

不要担心操作码是“特殊的”,这只是意味着它们不会在参数中保存编码行号程序中的空间参数。

+0

不幸的是,DW_AT_low_pc似乎对应于子程序第一条指令的地址(也就是第一条序言指令),而DW_AT_high_pc似乎是跟在最后一条结尾指令之后的指令的偏移量。 – Martin 2014-09-29 13:33:34

相关问题