0

Compiler Explorer似乎能够可靠地找到与函数对应的汇编代码。x86_64-unknown-linux-gnu假设一个工具链、一个常规(无属性)函数,并且没有额外的工具,我怎么能自己做到这一点cargo-asm

我知道要生成程序集,我可以使用rustc's --emit asmflag。有人可能认为找到函数就像在 .s 文件中搜索其名称一样容易,但我发现并非如此。

例如,.s 文件通常甚至没有提及函数名称,在这种情况下,添加#[inline(never)]到函数中会有所帮助。其次,找到带有函数名称的标签后,如何确定函数的结束位置?在我的测试箱中,我发现在更下方的指令中再次提到了函数名称.size——这可能标志着函数的结束吗?或者它可能是retq函数启动后的第一个?

假设这个目标是可以实现的,我希望学习:

  • 找到函数的开始和结束的最可靠方法是什么?
  • 获得合适的汇编文件的先决条件是什么?
4

1 回答 1

1

由于没有答案,我做了一些研究,这应该可以解决问题:

  1. 确保在main()二进制 crate 的情况下由函数使用该函数,或者pub在库 crate 的情况下由函数使用(或pub本身)。
  2. 为了避免编译器内联你的基准,标记它#[inline(never)]
  3. 搜索函数名称,它应该找到开始,如下所示:
    .type   <mangled_name>,@function
<mangled_name>:
    .cfi_startproc
  1. 搜索函数的结尾,标记为:
.Lfunc_end<number>:
    .size   <mangled_name>, .Lfunc_end<number>-<mangled_name>
    .cfi_endproc

有时可以在前面加上 a retq,但不可靠。

那些以点开头且不以冒号结尾的行,例如.type,是指令。GNU 汇编器理解的指令在此处记录,并且 的输出--emit asm应该是 GNU 汇编器的有效输入。

编译器资源管理器和cargo-asm

似乎编译器资源管理器实际上保留了整个文件并且不搜索函数,它只是过滤掉某些行。至少那是源代码似乎正在做的事情。

cargo-asm特别似乎.cfi_endproc在 Linux 和 Mac 以及.seh_endprocWindows上寻找。

于 2020-06-03T18:39:40.937 回答