Gdb 如何从elf文件中提取函数原型?

Gdb 如何从elf文件中提取函数原型?,gdb,elf,objdump,function-prototypes,readelf,Gdb,Elf,Objdump,Function Prototypes,Readelf,我没有成功地找到这个问题的答案 使用GDB,我可以使用命令“call”来获得函数的原型。 例如: (gdb)呼叫fn $1={void(int,int)}0x8048414 因此,GDB只能从elf文件中找出fn()返回void并将两个整数作为参数 但是,我需要使用其他工具从elf文件中提取函数原型。最好使用objdump/readelf 有人知道这是否可能吗? 如果不可能,GDB是如何做到的? elf文件的哪个部分存储了函数原型?GDB通过debuginfo知道函数的签名readelf-w

我没有成功地找到这个问题的答案

使用GDB,我可以使用命令“call”来获得函数的原型。 例如:

(gdb)呼叫fn
$1={void(int,int)}0x8048414
因此,GDB只能从elf文件中找出fn()返回void并将两个整数作为参数

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

有人知道这是否可能吗? 如果不可能,GDB是如何做到的?
elf文件的哪个部分存储了函数原型?

GDB通过debuginfo知道函数的签名
readelf-w ELF
会将其转储。你可能会想读迈克尔·J·埃格的作品。通过使用,您可以从交互式Python会话中探索和试验DWARF

要提取函数原型,需要
子程序
调试信息条目。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: }
<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>
1:#包括“ansidecl.h”
2:#包括
三:
4:外部尺寸(常量字符*);
5:外部PTR malloc(尺寸);
6:外部PTR memcpy(PTR、常数PTR、尺寸);
7:
8:char*
9:strndup(常量字符*s,大小\u t n)
10: {
11:字符*结果;
12:尺寸长度=标准长度;
13:
14:如果(n
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: }
<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>
:DW\u标签\u基本类型
DW_AT_name=int
字节大小为4时的DW_
DW_AT_编码=有符号
:DW_TAG_typedef
DW_AT_name=尺寸
DW_在_类型=
:DW\u标记\u基础\u类型
DW_AT_name=无符号整数
字节大小为4时的DW_
DW_AT_编码=无符号
:DW\u标记\u基础\u类型
DW_AT_name=long int
字节大小为4时的DW_
DW_AT_编码=有符号
:DW_TAG_子程序
DW_在_同级=
DW_在_外部=1
DW_AT_name=strndup
DW_AT_原型=1
DW_在_类型=
低功率时的功率因数=0
DW_在_高_pc=0x7b
:DW\u标记\u形式\u参数
DW_AT_name=s
DW_在_类型=
DW_在_位置=
(DW_OP_fbreg:0)
:DW\u标记\u形式\u参数
DW_AT_name=n
DW_在_类型=
DW_在_位置=
(DW_OP_fbreg:4)
:DW_标记_变量
DW_AT_name=结果
DW_在_类型=
DW_在_位置=
(DW_OP_fbreg:-28)
:DW_标记_变量
DW_AT_name=len
DW_在_类型=
DW_在_位置=
(DW_OP_fbreg:-24)
:DW\u标记\u指针\u类型
字节大小为4时的DW_
DW_在_类型=
:DW\u标记\u基础\u类型
DW_AT_name=char
字节大小为1时的DW_
DW_AT_编码=
签名字符
:DW\u标记\u指针\u类型
字节大小为4时的DW_
DW_在_类型=
:DW\u标记\u常量\u类型
DW_在_类型=
要获得更完整的示例实现,请查看Petr Machata的文章。它有代码可以根据您的需要执行以下警告:

  • 反射在进程内运行,而不是像GDB那样在进程外运行
  • 它取决于来自的
    libdw
    libdwfl
    。不确定您对增加这些外部库依赖项的感觉如何

指向c反射库的链接不再有效@约翰卡尼,用更新的链接编辑我的答案。谢谢