assembly - 如何在(发布的)Rust版本中找到函数的汇编代码?

标签 assembly rust x86-64 compiler-explorer

Compiler Explorer似乎能够可靠地找到与功能相对应的汇编代码。假设使用x86_64-unknown-linux-gnu工具链,常规(无属性)功能并且没有像cargo-asm这样的额外工具,我该如何自己做呢?

我知道要生成程序集,可以使用rustc's --emit asm flag。有人可能会认为,在.s文件中搜索函数的名称很容易,但是我发现并非如此。

例如,.s文件通常甚至没有提到函数名称,在这种情况下,向函数添加#[inline(never)]会有所帮助。其次,找到带有函数名称的标签后,如何确定函数的结束位置?在我的测试箱中,我在更深处的.size指令中第二次提到了函数名称-这是否标志着函数的结束?还是函数启动后的第一个retq

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

  • 查找函数开始和结束的最可靠方法是什么?
  • 获得合适的程序集文件以执行此操作的先决条件是什么?
  • 最佳答案

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

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

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

    那些以点开头但不以冒号结尾的行(例如.type)是指令。 GNU汇编器可理解的指令已记录在here中,并且--emit asm的输出应为GNU汇编器的有效输入。

    编译器资源管理器和cargo-asm
    似乎Compiler Explorer实际上保留了整个文件,并且不搜索功能,它只是过滤掉某些行。至少那是source code似乎正在做的事情。
    cargo-asm似乎专门用于寻找 .cfi_endproc on Linux and Mac, and .seh_endproc on Windows

    关于assembly - 如何在(发布的)Rust版本中找到函数的汇编代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62008744/

    相关文章:

    导入时出现 Rust "expected identifier, found keyword"

    rust - 在模块中派生可编码特征不起作用

    assembly - 不同 CPU 上未对齐的 MOVSD 会发生什么情况?

    c - 为什么在ubuntu64中反转堆栈中元素的地址?

    linux - 截断的核心转储有什么用?

    assembly - ARM cortex m4 DSP 代码上的快速 1 位透明 blit

    assembly - 为什么(或不是?)SFENCE + LFENCE 等价于 MFENCE?

    c++ - 内联函数是如何编译成汇编的?

    assembly - 如何将此 ATT 程序集转换为英特尔语法?不使用寄存器跳转到非相对地址

    linux - 如何获取从 Rust 程序内部运行的 Bash 脚本的退出代码?