2014-03-19 22 views
5

我還沒有找到關於這個問題的答案。如何從一個精靈文件中提取函數原型?

使用GDB,我可以使用命令「call」來獲取函數的原型。 例子:

(gdb) call fn 
$1 = {void (int, int)} 0x8048414 <fn> 

所以,GDB是隻能從精靈文件弄清楚的是,FN()返回void,並採取兩個整數作爲參數。

但是,我需要使用其他工具從elf文件中提取函數原型。最好,我想使用objdump/readelf。

有誰知道這是可能的嗎? 如果不可能,GDB如何做? elf文件的哪個部分是函數原型存儲的?

回答

4

GDB通過DWARF debuginfo知道函數的簽名。 readelf -w ELF會轉儲。您可能想要閱讀Michael J. Eager的Introduction to the DWARF Debugging Format。使用pyelftools,您可以在交互式Python會話中探索並實驗DWARF。

要提取函數原型,您需要subprogram調試信息條目。 dwarf格式的教程的一個例子是:

strndup.c

1: #include "ansidecl.h" 
2: #include <stddef.h> 
3: 
4: extern size_t strlen (const char*); 
5: extern PTR malloc (size_t); 
6: extern PTR memcpy (PTR, const PTR, size_t); 
7: 
8: char * 
9: strndup (const char *s, size_t n) 
10: { 
11: char *result; 
12: size_t len = strlen (s); 
13: 
14: if (n < len) 
15: len = n; 
16: 
17: result = (char *) malloc (len + 1); 
18: if (!result) 
19: return 0; 
20: 
21: result[len] = '\0'; 
22: return (char *) memcpy (result, s, len); 
23: } 

爲strndup.c

<1>: DW_TAG_base_type 
    DW_AT_name = int 
    DW_AT_byte_size = 4 
    DW_AT_encoding = signed 
<2>: DW_TAG_typedef 
    DW_AT_name = size_t 
    DW_AT_type = <3> 
<3>: DW_TAG_base_type 
    DW_AT_name = unsigned int 
    DW_AT_byte_size = 4 
    DW_AT_encoding = unsigned 
<4>: DW_TAG_base_type 
    DW_AT_name = long int 
    DW_AT_byte_size = 4 
    DW_AT_encoding = signed 
<5>: DW_TAG_subprogram 
    DW_AT_sibling = <10> 
    DW_AT_external = 1 
    DW_AT_name = strndup 
    DW_AT_prototyped = 1 
    DW_AT_type = <10> 
    DW_AT_low_pc = 0 
    DW_AT_high_pc = 0x7b 
<6>: DW_TAG_formal_parameter 
    DW_AT_name = s 
    DW_AT_type = <12> 
    DW_AT_location = 
    (DW_OP_fbreg: 0) 
<7>: DW_TAG_formal_parameter 
    DW_AT_name = n 
    DW_AT_type = <2> 
    DW_AT_location = 
    (DW_OP_fbreg: 4) 
<8>: DW_TAG_variable 
    DW_AT_name = result 
    DW_AT_type = <10> 
    DW_AT_location = 
    (DW_OP_fbreg: -28) 
<9>: DW_TAG_variable 
    DW_AT_name = len 
    DW_AT_type = <2> 
    DW_AT_location = 
    (DW_OP_fbreg: -24) 
<10>: DW_TAG_pointer_type 
    DW_AT_byte_size = 4 
    DW_AT_type = <11> 
<11>: DW_TAG_base_type 
    DW_AT_name = char 
    DW_AT_byte_size = 1 
    DW_AT_encoding = 
    signed char 
<12>: DW_TAG_pointer_type 
    DW_AT_byte_size = 4 
    DW_AT_type = <13> 
<13>: DW_TAG_const_type 
    DW_AT_type = <11> 

更完整的示例實現矮的描述,看看在Petr Machata的this C reflection library。它的代碼做你想要什麼用下面的警告:

  • 反思過程中運行出來的進程,而不是像GDB
  • 這取決於libdwelfutilslibdwfl。不知道你會如何看待增長這些外部庫依賴關係。
相關問題