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/compile: DWARF DW_TAG_subroutine_type doesn't mark return value's formal parameters as DW_AT_variable_parameter #59977

Open
dev747368 opened this issue May 4, 2023 · 3 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@dev747368
Copy link

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

$ go version
go version go1.20.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

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

go env Output
$ go env
GOARCH="amd64"
GOOS="linux"

What did you do?

When trying to decode the type info for a pointer to a function (DW_TAG_subroutine_type), the return values of the function type DIE aren't encoded in a way that lets you determine that they are return values instead of normal parameters.

package main

type myfunctype func(int) bool

//go:noinline
func getfoo() myfunctype {
	return func(p1 int) bool {
		return false
	}
}

func main() {

	foo := getfoo();

	println("foo: ", foo(1))
}

What did you expect to see?

I expected that a function type DIE's parameters & return values to be encoded in a similar way as a function DIE.

For example, the function that is returned from getfoo() is defined this way, with the return value being the correct type and being marked with a DW_AT_variable_parameter flag:

$ readelf -wi funcdef | grep -B1 -A18 main.getfoo.func1
 <1><4959b>: Abbrev Number: 3 (DW_TAG_subprogram)
    <4959c>   DW_AT_name        : main.getfoo.func1
    <495ae>   DW_AT_low_pc      : 0x458180
    <495b6>   DW_AT_high_pc     : 0x458183
    <495be>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
    <495c0>   DW_AT_decl_file   : 0x2
    <495c4>   DW_AT_external    : 1
 <2><495c5>: Abbrev Number: 18 (DW_TAG_formal_parameter)
    <495c6>   DW_AT_name        : p1
    <495c9>   DW_AT_variable_parameter: 0
    <495ca>   DW_AT_decl_line   : 7
    <495cb>   DW_AT_type        : <0x4a079>
    <495cf>   DW_AT_location    : 0x6ec83 (location list)
 <2><495d3>: Abbrev Number: 17 (DW_TAG_formal_parameter)
    <495d4>   DW_AT_name        : ~r0
    <495d8>   DW_AT_variable_parameter: 1      <----- flag to indicate that this is a return value
    <495d9>   DW_AT_decl_line   : 7
    <495da>   DW_AT_type        : <0x499c9>   <---- normal bool type
    <495de>   DW_AT_location    : 0 byte block: 	()
 <2><495df>: Abbrev Number: 0

What did you see instead?

Looking at the DWARF for the function type definition, I get a DIE that defines 2 parameters with no way to tell that the last parameter is a return value:

$ readelf -wi funcdef | grep -A10 myfunctype
    <4a03f>   DW_AT_name        : main.myfunctype
    <4a04f>   DW_AT_byte_size   : 8
    <4a050>   Unknown AT value: 2900: 19
    <4a051>   Unknown AT value: 2904: 0x0
 <2><4a059>: Abbrev Number: 25 (DW_TAG_formal_parameter)
    <4a05a>   DW_AT_type        : <0x4a079>
 <2><4a05e>: Abbrev Number: 25 (DW_TAG_formal_parameter)
    <4a05f>   DW_AT_type        : <0x499da>   <--- bool* type instead of bool
<2><4a063>: Abbrev Number: 0                   <--------- this is where I would expect a DW_AT_variable_parameter flag
...

$ readelf -wi funcdef | grep -A10 "<499da"
 <1><499da>: Abbrev Number: 35 (DW_TAG_pointer_type)
    <499db>   DW_AT_name        : *bool
    <499e1>   DW_AT_type        : <0x499c9>
    <499e5>   Unknown AT value: 2900: 0
    <499e6>   Unknown AT value: 2904: 0x2760
...

Additionally, the return types are converted to a pointer-to-real-return-type.

@ianlancetaylor ianlancetaylor changed the title DWARF DW_TAG_subroutine_type doesn't mark return value's formal parameters as DW_AT_variable_parameter cmd/compile: DWARF DW_TAG_subroutine_type doesn't mark return value's formal parameters as DW_AT_variable_parameter May 4, 2023
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label May 4, 2023
@ianlancetaylor
Copy link
Contributor

CC @thanm

@cagedmantis cagedmantis added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 5, 2023
@cagedmantis cagedmantis added this to the Backlog milestone May 5, 2023
@mknyszek
Copy link
Contributor

@thanm In triage we assigned it to you so please take a look whenever you get the chance! Thanks.

@mknyszek
Copy link
Contributor

(And as usual feel free to unassign.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
Development

No branches or pull requests

6 participants