2014-09-18 31 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

相關問題