-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
Comments
CC @thanm |
@thanm In triage we assigned it to you so please take a look whenever you get the chance! Thanks. |
(And as usual feel free to unassign.) |
Circling back to look at this issue. I can confirm that we are indeed leaving out the variable parameter attribute in this case, however I think it would be useful to understand a bit more about why this additional bit of info is needed, e.g. what your use case is. There are many places in Go's generated DWARF where things are not as complete/exhaustive as they could be. Adding this attr would result in object file and binary bloat (admittedly a small amount). What exactly is the use case? Our main debugger (Delve) doesn't seem to need this info. |
In my case, I am using the DWARF information to model a golang binary in Ghidra. When the DWARF information is incorrect, it leads to misleading / substandard info. Happy to go into more detail if needed. |
Sure, I'm curious to learn more. Maybe a pointer to the GHIDRA code that reads the DWARF? |
Ghidra is hosted here on github The specific file that is dealing with reading DWARF data type info and translating it into ghidra-ese is DWARFDataTypeImporter.java As an example, when Ghidra translates the struct runtime._type
Length: 48 (0x30) Alignment: 8
{
uintptr size
uintptr ptrdata
uint32 hash
runtime.tflag tflag
uint8 align
uint8 fieldAlign
uint8 kind
func(unsafe.Pointer,_unsafe.Pointer)_bool * * equal
uint8 * gcdata
runtime.nameOff str
runtime.typeOff ptrToThis
} pack() Looking at the type used by the void func(unsafe.Pointer,_unsafe.Pointer)_bool(
void * ,
void * ,
bool * ) The symbol name, which we don't(can't) parse has the correct return info, but the DWARF info led us to create it with the bogus pointer-fied return value as a parameter. This specific struct & type probably won't cause many problems for users because they won't be exploring go's built-in runtime code where this field would be used, but this issue will be problematic in other places. Ghidra also has code that tries to directly parse go's rtti embedded in stripped binaries, however DWARF is still used when available (and it provides some info not available in the rtti), and also for for creating bootstrap information on how to parse go's rtti structs. |
Change https://go.dev/cl/595715 mentions this issue: |
I have created a patch https://go-review.googlesource.com/c/go/+/595715 that should address this issue. Given the nature of the change I think it would be better to not make the change for 1.23, but rather wait and check it into 1.24 early in the development cycle. I also need to spend some time benchmarking it to understand what the compile time and binary size implications are. Thanks. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat 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.
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:
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:
Additionally, the return types are converted to a pointer-to-real-return-type.
The text was updated successfully, but these errors were encountered: