4

我正在开发一个项目,我们的验证测试脚本需要在被测软件的构建中定位符号地址。这可能用于设置断点或从内存中读取静态数据。我所追求的是创建一个包含符号名称、内存中的基地址和大小的映射文件。我们的构建输出一个 ELF 文件,其中包含我想要的信息。我一直在尝试使用readelf、nm 和 objdump工具来尝试并获得我需要的符号地址。

我最初尝试过readelf -s file.elf,这似乎可以访问一些符号,尤其是那些用汇编程序编写的符号。然而,我想要的许多符号都不在那里——特别是那些源自我们的 Ada 代码的符号。

我曾经readelf --debug-dump file.elf转储所有调试信息。从中我确实看到了所有符号,包括 Ada 代码中的符号。但是,格式似乎是 DWARF 格式。当我要求它列出符号信息时,有谁知道为什么 readelf 不会输出这些符号?也许我只是缺少一个选项。

现在我可以编写一个自定义 DWARF 解析器来获取信息,但如果我可以使用 Binutils(nm、readelf、objdump)之一来获取它,那么我真的更喜欢标准解决方案。

4

1 回答 1

5

DWARF 是调试信息,并试图反映原始源代码的关系。以以下代码为例

static int one() {
  // something
  return 1;
}
int main(int ac, char **av) {
  return one();
}

使用 编译后gcc -O3 -g,静态函数one将内联到main. 所以当你使用时readelf -s,你永远不会看到这个符号one。但是,当您使用 时readelf --debug-dump,您可以看到one是一个内联函数。

所以,在这个例子中,编译器不禁止你使用优化-g,所以你仍然可以调试可执行文件。在那个例子中,即使函数被优化和内联,gdb 仍然可以使用 DWARF 信息从内联函数内部的当前代码块中了解函数和源/行。

以上只是编译器优化的一个案例。可能有很多原因可能导致readelf -s与 DWARF 之间的符号地址不匹配。

于 2015-06-19T01:10:26.987 回答