我需要知道obj文件中的二进制指令的寄存器是从哪个变量编译而来的。
简而言之:每条指令从寄存器到变量的映射
示例:假设 objdump 给出 obj 文件的片段如下:
MOV R1 5 # move 5 to register R1
SW R2 SP[-20] # store the value of R2 to address SP-20
我们如何从源代码中知道 R1 存储变量,例如 var1? R2 存储 var2?
我在readelf的文档中进行了搜索,不幸的是没有结果。
(虽然它可以给我源代码和二进制文件之间的行映射,但它对我没有任何帮助)
然后我搜索了gcc和链接器的一些调试选项。找到了一些有用的信息,但仍然没有解决我的问题。
我找到的信息是:
有人有经验或想法吗?
谢谢大家!
破解...
编译器生成混合汇编器/源代码列表是很常见的。它将显示它编译的源代码,并且在其下面将显示生成的汇编代码。快速谷歌给出了
GCC 的“-fverbose-asm”选项可能会有所帮助。 它用变量名称注释编译器的输出。 不幸的是,这些名称通常是编译器发明的临时名称,例如“D.1234”。 它仍然可以帮助您了解正在发生的事情。
尝试编译一些简单的东西并看看:
gcc -g -O0 -S -fverbose-asm foo.c -o foo.s
像 GDB 这样的调试器(对于大多数系统)使用由编译器生成并存储在目标文件中的 DWARF 调试信息来确定变量在程序中给定点的存储位置。 如果您的系统使用 DWARF,那么 readelf 将为您对此信息做一些非常基本的解释。 试试这个:
readelf --debug-dump=info foo.o
解码显然并不简单。 如果您想尝试一下,请查看 DWARF 标准:http://dwarfstd.org/。
为此目的,您可以使用标志:
gcc foo.c -da -dp -fdump-tree-all-raw-lineno
地点:
-da
生成所有 RTL 转储
-dp
用注释来注释汇编器输出,指示哪个
使用模式和替代方案。
-fdump-tree-all-raw-lineno
启用显示语句的行号。
这将创建大约 167 个文件,每个文件都意味着 GIMPLE 和 RTL 传递、优化等不同阶段。 这是发生的事情的简单解释:
https://www.cse.iitb.ac.in/~uday/courses/cs715-09/gcc-rtl.pdf
最有用的转储是:
foo.c.227t.optimized
foo.c.229r.expand
foo.c.259r.combine
foo.c.307r.finish
以及其他几个用于不同目的的。