Reputation: 8754
Compiler Explorer seems to be able to reliably find the assembly code corresponding to a function. How can I do that myself, assuming a x86_64-unknown-linux-gnu
toolchain, a regular (no attributes) function, and without extra tools like cargo-asm
?
I know that to produce the assembly, I can use rustc's --emit asm
flag. One might think that finding the function is easy as searching for its name in the .s file, but I found that it's not.
For instance, the .s file often doesn't even mention the function name, in which case adding #[inline(never)]
to the function helps. Second, having found the label with the function name, how do you determine where the function ends? In my test crate, I found a second mention of the function name in a .size
directive farther down – does that maybe mark the end of the function? Or is it maybe the first retq
after the function start?
Assuming this goal is achievable, I hope to learn:
Upvotes: 2
Views: 2699
Reputation: 8754
Since there was no answer, I did a little bit of research and this should do the trick:
main()
in case of a binary crate, or by a pub
function in case of a library crate (or is pub
itself).#[inline(never)]
.type <mangled_name>,@function
<mangled_name>:
.cfi_startproc
.Lfunc_end<number>:
.size <mangled_name>, .Lfunc_end<number>-<mangled_name>
.cfi_endproc
This can sometimes be preceded by a retq
, but not reliably.
Those lines that start with a dot and do not end with a colon, like .type
, are directives. The directives that the GNU assembler understands are documented here, and the output of --emit asm
should be valid input to the GNU assembler.
cargo-asm
It seems that Compiler Explorer actually keeps the entire file and does not search for functions, it just filters out certain lines. At least that is what the source code seems to be doing.
cargo-asm
specifically appears to look for .cfi_endproc
on Linux and Mac, and .seh_endproc
on Windows.
Upvotes: 2