-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: simplify converting a Go function to buildable Go assembly #29538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Someone on Slack mentioned https://github.com/rsc/tmp/tree/master/go2asm, which seems to be a very similar tool. Looks a bit outdated and seems like it only supports amd64. I wonder if optimistically supporting all architectures would be a good idea. /cc @rsc |
This is something I want frequently. |
I forgot to address one point - why this should be part of |
Does anyone know how to handle for example |
Change the |
Thanks! Got 3 new questions now if that's ok to ask since it might be relevant:
|
I'm slowly learning x86 assembly and how Go uses it, so it's very useful to see how existing functions in Go are translated to it.
The next logical step is to be able to make small changes to that assembly, to see if my understanding of it is correct, and to play with trying to make the code better manually. However, as I've found out, there's no easy way to move a function from a
.go
file to a.s
file.After reading some blog posts online and some trial and error, I've found out that most functions can be translated by hand. For example, take a single file with this very simple Go function:
With
go tool compile -S f.go
, we can scroll through the output to find its assembly:However, we can't just add the assembly to the source code and make the Go func a stub, as that just fails:
We can apply multiple changes to get it to work:
FUNCDATA
andPCDATA
lines"".Func
with·Func
NOSPLIT|ABIInternal
, to get rid of errors likeillegal or missing addressing mode for symbol NOSPLIT
"".var
withvar
"".~r2
withr2
(I still don't understand that tilde)End result, which works just as fine as the Go code:
In this case, we're done. But if the function had jumps like
JMP 90
, we'd have to add a label likeL90
after finding the right line, and then modifying the jump to beJMP L90
.go vet
also tends to complain about the result of the process above, even when the assembly works - for example, in our case:I've succsesfully done this with multiple funcs on the small side, but it's tedious. Worse even, I still haven't been able to correctly translate a function calling another function to assembly - I keep getting panics like
runtime: unexpected return pc for ...
, which are very confusing.I think the compiler should support translating Go functions to assembly which can just be dumped onto a
.s
file after replacing their Go implementation with a stub. It doesn't matter if it couldn't directly work on some weird edge cases; if at least it could give a starting point after doing grunt work as mentioned above, that would already be a huge improvement.Ideas that come to mind to improve
go tool compile -S
(thanks for @josharian for his input):GOSSAFUNC
..s
file as-is.For example, borrowing from flags like
compile -d
, one might imaginego tool compile -S=func=Add,clean
to do what I had done manually above.If this makes sense, I'm happy to do some of the work during the upcoming cycle. I'll just need a bit of help from the compiler folks, as my assembly (and especially Go assembly syntax) knowledge is limited.
/cc @randall77 @griesemer @josharian @mdempsky @martisch, as per https://dev.golang.org/owners/.
The text was updated successfully, but these errors were encountered: