parameter passing in go ELF binaries

79 views
Skip to first unread message

Oren Ish-Shalom

unread,
Nov 29, 2021, 1:16:56 PM11/29/21
to golang-nuts
Hi all,
I have a question in SO regarding parameter passing in ELF binaries:


One of the comments referenced me to this mailing list, so I'm re-posting here:

I’m trying to understand parameter passing in go ELF binaries

mov    %rdi,0x8(%rsp)   <----- first parameter (?)
mov    %r8,0x10(%rsp)   <----- second
mov    %r9,0x18(%rsp)   <----- third
mov    %r10,0x20(%rsp)  <----- fourth
mov    %rcx,0x28(%rsp)  <----- fifth
sub    %edx,%ebx
movslq %ebx,%rcx
mov    %rcx,0x30(%rsp)  <----- sixth
callq  5aaba0 <math/big.nat.shl> <----- call to native golang func

It seems that parameters are passed on stack, but when I look at the function here (line 681):

// z = x << s
func (z nat) shl(x nat, s uint) nat { ... }

The number of parameter is just 2, and in the ELF it looks like 6 (?)

Ian Lance Taylor

unread,
Nov 29, 2021, 2:11:26 PM11/29/21
to Oren Ish-Shalom, golang-nuts
First, let me say that you asked about ELF binaries but the parameter
passing used by the gc compiler doesn't have anything to do with
whether the output is ELF. It only depends on the GOARCH and GOOS
values.

Second, in 1.17 for amd64/linux, amd64/windows, and amd64/darwin, the
compiler changed the way that parameter passing works. Before that
release it passed all arguments on the stack for those platforms. In
1.17 it started passing the first several parameters in registers.
For an introduction to that see
https://go.googlesource.com/proposal/+/refs/heads/master/design/40724-register-calling.md.

Third, I think you are assuming that every parameter is passed in a
single register or stack location. That is not the case. Slices are
a struct of three values, where each value requires a register/stack
location.

Fourth, when calling a method, the receiver value is passed as an
ordinary argument.

So the method

func (z nat) shl(x nat, s uint) nat { ... }

has a receiver and two arguments. The nat values are slices (nat is
defined as []Word), which are three values each. So calling this
method requires passing seven values in registers or the stack.

Hope this helps.

Ian
Reply all
Reply to author
Forward
0 new messages