【发布时间】:2020-08-05 04:00:51
【问题描述】:
我正在尝试用 Python 创建一个行覆盖程序。
目标是从设备上运行的测试中接收 PC 列表,并获取该设备的 FW 的哪些功能、条件和线路被测试覆盖的信息。
如果有帮助的话,上述设备有一个 ARC 处理器。
我有 ELF 二进制文件和源代码(用 C 编写),但不能在这里分享(公司机密信息)。
我已经获取了 ELF 文件并设法获得了 .text 部分的反汇编(本质上是程序的汇编代码)。
我已经对设备的FW进行了拆解,所以我的拆解FW是这样的:
PC: hex_opcode assembly_command 操作数
像这样:
0x100: 7eff mov a,b
另外,使用 Eli Bendersky 的 pyelftools :https://github.com/eliben/pyelftools
我已经设法获得了函数开头的源文件和行号,所以我设法将每个函数的汇编代码映射到源代码。
并使用函数中的 High PC 和 Low PC,我设法将 PC 从测试日志链接到函数。
但现在我被困在尝试将各个装配线映射到它们在 C 源代码中的位置。
我知道为此我需要阅读 DWARF 中 .debug_line 中的信息,但我不太明白。
我已经设法遇到了这个:
他们说: Line += Line base + (Opcode - Opcode base) % Line range
我拥有除 Line 和 Opcode 之外的所有信息。
“线”是指功能的起点吗? (例如,如果“void func()”位于文件 source.c 第 5 行)上一行?
“操作码”是汇编命令的主要操作码吗?或者完整的汇编命令操作码(如二进制表示中的 0x7eff)还有别的吗?来自 DWARF 信息的其他一些操作码?
根据我的理解,计算是十进制的,所以操作码必须转换为十进制。
提前感谢您的帮助。
瓦迪姆
【问题讨论】:
-
操作码是矮小的操作码而不是汇编/机器码。显然,您使用什么基数并不重要,没有什么可以转换的。您链接的 wiki 页面中有示例,它甚至指向您的详细规范。您可以制作一个小型非机密程序进行测试。
-
这些是 DWARF 操作码吗:DW_LNE_set_address DW_LNS_advance_line DW_LNS_copy 等。我从 .debug_line 得到这些
-
好的,知道了。我从 DWARF 中看到了标准和扩展操作码编号,但找不到我从哪里获得特殊操作码编号。另外,“行”表示函数的开头,或上一行代码
-
f.e.如果函数像 1. void main() 2. { 3. printf("hello world"); 4. } 我每次计算都从第 1 行开始吗?还是加到上一行?
标签: c assembly code-coverage elf dwarf