我正在开发一个项目,我们的验证测试脚本需要在被测软件的构建中找到符号地址。这可能用于设置断点或从内存中读取静态数据。我要做的是创建一个包含符号名称,内存中的基地址和大小的映射文件。我们的构建输出一个ELF文件,其中包含我想要的信息。我一直在尝试使用 readelf,nm和objdump 工具来尝试获取我需要的符号地址。
我最初尝试readelf -s file.elf
并且似乎访问了一些符号,特别是那些用汇编语言编写的符号。但是,我想要的许多符号都不存在 - 特别是那些源自我们的Ada代码的符号。
我使用readelf --debug-dump file.elf
转储所有调试信息。从那里我确实看到所有符号,包括Ada代码中的符号。但是,格式似乎是DWARF格式。当我要求它列出符号信息时,有谁知道为什么readelf不会输出这些符号?也许只有一个我缺少的选项。
现在我可以解决编写自定义DWARF解析器以获取信息的问题,但如果我可以使用其中一个Binutils(nm,readelf,objdump)来获取它,那么我真的更喜欢标准解决方案。
答案 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之间的符号符号不匹配。