Edw*_*hen 9 libraries dynamic-linking
我目前正在摆弄一些没有文档的 c 库。我想知道是否有可能在调用nm -Dor提供的内容之外检索更多元数据,例如参数和返回值objdump -T filename | grep text。我不确定这是否可行,但如果可行,我就不用去追捕负责图书馆的人了!
编辑:如果可能的话,我希望能够在不阅读机器代码的情况下做到这一点。如果我是机器代码方面的专家,似乎有一些解决方案可以让我轻松地做到这一点,但是由于我不是并且目前没有跳下那个兔子洞的愿望,我真的希望还有另一个解决方案道路。
Mat*_*Mat 10
Stack Overflow 上提出了一个非常相似的问题:如何从 ELF 文件中提取函数原型?
简而言之:通常你不能。如果可执行文件(或共享库)没有调试信息,则有关参数数量和类型的信息不会存储在可执行文件中。
如果共享对象文件确实有调试信息,那么您应该能够readelf -wi使用 或使用调试器提取信息。
例如,我有一个 ELF 可执行文件,其中包含一个int foo(char a, long b)使用调试信息编译的函数。GDB 告诉我:
(gdb) p foo
$1 = {int (char, long int)} 0x40051c <foo>
Run Code Online (Sandbox Code Playgroud)
并且readelf -wi(有点神秘,你必须自己匹配条目)有:
<1><2d>: Abbrev Number: 2 (DW_TAG_subprogram) <= function
<2e> DW_AT_external : 1
<2f> DW_AT_name : foo <= func name
<33> DW_AT_decl_file : 1
<34> DW_AT_decl_line : 1
<35> DW_AT_prototyped : 1
<36> DW_AT_type : <0x6c> <= return type
<3a> DW_AT_low_pc : 0x40051c
<42> DW_AT_high_pc : 0x400532
<4a> DW_AT_frame_base : 0x0 (location list)
<4e> DW_AT_GNU_all_call_sites: 1
<4f> DW_AT_sibling : <0x6c>
<2><53>: Abbrev Number: 3 (DW_TAG_formal_parameter) <= parameter
<54> DW_AT_name : a
<56> DW_AT_decl_file : 1
<57> DW_AT_decl_line : 1
<58> DW_AT_type : <0x73>
<5c> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)
<2><5f>: Abbrev Number: 3 (DW_TAG_formal_parameter) <= other param
<60> DW_AT_name : b
<62> DW_AT_decl_file : 1
<63> DW_AT_decl_line : 1
<64> DW_AT_type : <0x7a>
<68> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<1><6c>: Abbrev Number: 4 (DW_TAG_base_type)
<6d> DW_AT_byte_size : 4
<6e> DW_AT_encoding : 5 (signed)
<6f> DW_AT_name : int
<1><73>: Abbrev Number: 5 (DW_TAG_base_type)
<74> DW_AT_byte_size : 1
<75> DW_AT_encoding : 6 (signed char)
<76> DW_AT_name : (indirect string, offset: 0x2e): char
<1><7a>: Abbrev Number: 5 (DW_TAG_base_type)
<7b> DW_AT_byte_size : 8
<7c> DW_AT_encoding : 5 (signed)
<7d> DW_AT_name : (indirect string, offset: 0x0): long int
Run Code Online (Sandbox Code Playgroud)
请注意,对于 C++,您看到的符号nm带有更多信息(除非它们已被声明extern "C"- 参数的数量和类型必须可供链接器使用以处理重载。但返回类型信息也不存在。(但是符号被破坏 -c++filt可用于破坏。)
编译与 C++ 相同的源文件为 提供以下输出nm a.out | c++filt:
...
0000000000400554 T foo(char, long)
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10791 次 |
| 最近记录: |