1

我需要知道从哪个变量编译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 和链接器的调试选项。找到了一些有用的信息,但他们仍然没有解决我的问题。
我找到的信息是:

  • 选项-fdump-rtl-vartrack可以跟踪所有变量,似乎很有用。但是在使用此选项进行编译时,我没有找到预期的 *.vartrack 转储文件。
  • 选项*fdump-rtl-vartrack-uid显示每个变量的唯一 ID (DECL_UID)。但是我在使用时收到了这个错误:cc1: error: unrecognized command line option "-fdump-tree-uid"
  • 选项fdump-rtl-lreg转储本地寄存器分配,但我看不出它如何告诉我从 reg 到变量的映射。

有没有人有一些经验或想法?

谢谢你们!

破解...

4

3 回答 3

0

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

解码显然不是一件容易的事。如果您想尝试一下,请查看http://dwarfstd.org/上的 DWARF 标准。

于 2011-02-23T13:56:24.197 回答
0

编译器生成混合的汇编器/源代码列表是很常见的。它将显示它编译的源代码,并在其下方显示生成的汇编代码。一个快速的谷歌给出

http://www.delorie.com/djgpp/v2faq/faq8_20.html

于 2011-02-02T23:54:13.123 回答
0

为此,您可以使用标志:

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

还有其他几个用于不同目的。

于 2019-07-04T07:28:52.257 回答