【问题标题】:how to get from line in disassembled .text section in ELF file to the corresponding line in source code如何从ELF文件中反汇编的.text部分中的行到源代码中的相应行
【发布时间】: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 中的信息,但我不太明白。

我已经设法遇到了这个:

https://wiki.osdev.org/DWARF

他们说: 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


【解决方案1】:

但现在我被困在尝试将各个装配线映射到它们在 C 源代码中的位置。

你想要两件事:

  1. 使用调试信息构建您的固件。通常,您只需将-g 添加到所有现有的编译和链接行。

    注意:不要删除任何优化标志,否则编译后的代码将不再匹配您为其收集覆盖范围的二进制文件。

    注意:如果您的构建过程运行strip,您需要在剥离它之前保存二进制文件

  2. 使用dwarf_decode_address.py 中的decode_file_line 将您收集的每个地址(PC)映射到文件、行对。

【讨论】:

  • 这只能让我进入函数(在“子程序”DIE 条目中明确设置。我需要进入代码中的特定行。关于构建固件,我会检查,谢谢。
  • nvm,我想我明白了。 lineprog.get_entries() 是我可能需要的
猜你喜欢
  • 2020-07-09
  • 2010-12-11
  • 2012-12-26
  • 2020-07-09
  • 2022-12-10
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多