使用binutils / readelf确定符号地址

时间:2015-06-18 20:49:11

标签: elf debug-symbols dwarf readelf

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

我最初尝试readelf -s file.elf并且似​​乎访问了一些符号,特别是那些用汇编语言编写的符号。但是,我想要的许多符号都不存在 - 特别是那些源自我们的Ada代码的符号。

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

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

1 个答案:

答案 0 :(得分:1)

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之间的符号符号不匹配。