Skip to content
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

cmd/compiler,cmd/link: cannot distinguish between parameters and return values of DW_TAG_subroutine_type #48812

Open
u2386 opened this issue Oct 6, 2021 · 4 comments
Assignees
Milestone

Comments

@u2386
Copy link

@u2386 u2386 commented Oct 6, 2021

What version of Go are you using (go version)?

$ go version
go version go1.16.5 linux/amd64

Does this issue reproduce with the latest release?

haven't tried yet.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/hugo/.cache/go-build"
GOENV="/home/hugo/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/hugo/.gvm/pkgsets/go1.16.5/global/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/hugo/.gvm/pkgsets/go1.16.5/global"
GOPRIVATE=""
GOPROXY="https://goproxy.io,direct"
GOROOT="/home/hugo/.gvm/gos/go1.16.5"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/hugo/.gvm/gos/go1.16.5/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.5"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/hugo/Repository/go-sample/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2173517011=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Build the code below with go build -gcflags='-l -N':

package main

type Foo struct {
	FooBar func(int) int
}

func main() {
	_ = Foo{
		FooBar: func(i int) int { return i + 1 },
	}
}

The DWARF information for main.Foo.FooBar is DW_TAG_subroutine_type which has two DW_TAG_formal_parameter children and one TAG 0 (invalid).

It is difficult to distinguish the parameters of a function from the return value just from the DWARF data.

What did you expect to see?

Q: Is there an attribute or something to indicate whether or not a tag is a parameter or a return value.

What did you see instead?

DWARF data related:

 <1><3e201>: Abbrev Number: 30 (DW_TAG_subroutine_type)
    <3e202>   DW_AT_name        : func(int) int
    <3e210>   DW_AT_byte_size   : 8
    <3e211>   Unknown AT value: 2900: 19
    <3e212>   Unknown AT value: 2904: 0x0
 <2><3e21a>: Abbrev Number: 23 (DW_TAG_formal_parameter)
    <3e21b>   DW_AT_type        : <0x3e238>
 <2><3e21f>: Abbrev Number: 23 (DW_TAG_formal_parameter)
    <3e220>   DW_AT_type        : <0x3e248>
 <2><3e224>: Abbrev Number: 0

 <1><3e225>: Abbrev Number: 38 (DW_TAG_typedef)
    <3e226>   DW_AT_name        : func(int) int
    <3e234>   DW_AT_type        : <0x3e201>

...

 <1><3e1d0>: Abbrev Number: 37 (DW_TAG_structure_type)
    <3e1d1>   DW_AT_name        : main.Foo
    <3e1da>   DW_AT_byte_size   : 8
    <3e1db>   Unknown AT value: 2900: 25
    <3e1dc>   Unknown AT value: 2904: 0x0
 <2><3e1e4>: Abbrev Number: 22 (DW_TAG_member)
    <3e1e5>   DW_AT_name        : FooBar
    <3e1ec>   DW_AT_data_member_location: 0
    <3e1ed>   DW_AT_type        : <0x3e225>
    <3e1f1>   Unknown AT value: 2903: 0
 <2><3e1f2>: Abbrev Number: 0
@mknyszek mknyszek added this to the Backlog milestone Oct 6, 2021
@mknyszek mknyszek changed the title dwarf: cannot distinguish between parameters and return values of DW_TAG_subroutine_type cmd/compiler,cmd/link: cannot distinguish between parameters and return values of DW_TAG_subroutine_type Oct 6, 2021
@mknyszek
Copy link
Contributor

@mknyszek mknyszek commented Oct 6, 2021

@thanm
Copy link
Contributor

@thanm thanm commented Oct 6, 2021

DWARF type generation currently doesn't emit this info-- I don't think anyone has seen a need for it.

Can you describe your use case? Thanks.

@thanm thanm self-assigned this Oct 6, 2021
@u2386
Copy link
Author

@u2386 u2386 commented Oct 6, 2021

Thanks for replying.

I was trying to analyze DWARF data from a go program binary and reconstruct the struct types it declared, then I found the parameters and returns for DW_TAG_subroutine_type are all tagged as DW_TAG_formal_parameter.

I am not familiar with DWARF. I've searched for http://dwarfstd.org/doc/DWARF4.pdf and still didn't get it. Could you please tell me what I suppose to look for?

Thanks.

@thanm
Copy link
Contributor

@thanm thanm commented Oct 6, 2021

I am not familiar with DWARF. I've searched for http://dwarfstd.org/doc/DWARF4.pdf and still didn't get it. Could you please tell me what I suppose to look for?

The convention used by the Go compiler in other instances (specifically, for params on subprogram DIEs as opposed to params on subroutine type DIEs) is to mark returns with the DW_AT_variable_parameter attribute with value 1. So for example a return might look like

 <2><370>: Abbrev Number: xxx (DW_TAG_formal_parameter)
    <371>   DW_AT_name        : ret1
    <373>   DW_AT_variable_parameter: 1
    <374>   DW_AT_type        : <0x41360>

But as I mentioned, our compiler/linker currently doesn't emit this attribute for parameters that are part of a subroutine type DIE, only for parameters that are part of a subprogram DIE.

DWARF allows for a lot of flexibility on the part of compilers in terms of what information gets included for a given entity. For example, we could if we wanted to be emitting DW_AT_decl_column, DW_AT_decl_file, and/or DW_AT_decl_line attributes for parameter DIEs (they are allowed by the spec), but we don't, since few tools require them or make use of them.

Adding more attributes to the parameters in subroutine type DIEs would increase the size of the generated DWARF. Generally we don't want to do that (make binaries bigger) unless there is a good reason. Hence my question about your use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants