This is a tracking issue/bug for a modest compiler/linker enhancement involving DWARF type generation.
Background / motivation
Consider the following Go program:
package main
type astruct struct {
a, b int
}
type bstruct struct {
c, d byte
}
func dead() {
var iface = []bstruct{}
println(iface)
}
func main() {
var iface interface{} = map[string]astruct{}
println(iface)
}
We have two functions, "dead" and "main". The main function is obviously useful, but the function 'dead' is uncalled, and will be eliminated by the linker's dead code elimination phase.
When generating DWARF for 'main', we would like to insure that the types used by main are included, that is, that we emit DWARF DIEs for each interesting type. The tricky part here is that there are no variables (autos or parameters) in main that refer to types like astruct or map[string]astruct, which means that these types are also vulnerable to linker deadcode.
The compiler and linker currently handle this via a construct known as an "Autom"; the compiler emits an Autom record for each auto-tmp variable used by the function; these autom's get placed into the object file entry for the function. In the case of 'main' above, the compiler-generated temp var used to construct the value map[string]astruct{} triggers generation of an Autom.
The linker then reads in autom's when it reads the object file, and later on during linker processing it walks the Autom's for each live (non-dead-coded) function and generates a DWARF type DIE for its type if needed.
Note that for the example program above, we'll get type information for astruct (via the autom mechanism) but not for bstruct, since that type is not referenced by any live function.
Proposed change
What the section above leaves out is that the autom mechanism is cumbersome and heavyweight -- Autom's in the object file have a lot more information than strictly needed (this has happened gradually over time due to more DWARF generation moving from the compiler to the linker). This results in object file bloat and extra processing time in the linker.
What would work equally well is to attach dummy relocations to each function symbol that record the Go types used by its associated autotmps, then use these relocations to drive the DWARF type generation. This would speed up the compiler and linker and reduce object file size.
Issues/caveats/problem
There is a small chunk of code in the linker specific to the Plan9 target that does processing of Autom's to create directives or symbols for Autom's in the Plan9 object file. It's hard to tell from the code whether this is at all useful, since we haven't been able to find someone who knows how to run the Plan9 debugger. Given the current usage of autom's (e.g. for non-user-visible variables) it seems unlikely that removing the Plan9 autom handling will cause any debugging issues, so the proposal is to just drop this code.
This is a tracking issue/bug for a modest compiler/linker enhancement involving DWARF type generation.
Background / motivation
Consider the following Go program:
package main type astruct struct { a, b int } type bstruct struct { c, d byte } func dead() { var iface = []bstruct{} println(iface) } func main() { var iface interface{} = map[string]astruct{} println(iface) }We have two functions, "dead" and "main". The main function is obviously useful, but the function 'dead' is uncalled, and will be eliminated by the linker's dead code elimination phase.
When generating DWARF for 'main', we would like to insure that the types used by main are included, that is, that we emit DWARF DIEs for each interesting type. The tricky part here is that there are no variables (autos or parameters) in main that refer to types like
astructormap[string]astruct, which means that these types are also vulnerable to linker deadcode.The compiler and linker currently handle this via a construct known as an "Autom"; the compiler emits an Autom record for each auto-tmp variable used by the function; these autom's get placed into the object file entry for the function. In the case of 'main' above, the compiler-generated temp var used to construct the value
map[string]astruct{}triggers generation of an Autom.The linker then reads in autom's when it reads the object file, and later on during linker processing it walks the Autom's for each live (non-dead-coded) function and generates a DWARF type DIE for its type if needed.
Note that for the example program above, we'll get type information for
astruct(via the autom mechanism) but not forbstruct, since that type is not referenced by any live function.Proposed change
What the section above leaves out is that the autom mechanism is cumbersome and heavyweight -- Autom's in the object file have a lot more information than strictly needed (this has happened gradually over time due to more DWARF generation moving from the compiler to the linker). This results in object file bloat and extra processing time in the linker.
What would work equally well is to attach dummy relocations to each function symbol that record the Go types used by its associated autotmps, then use these relocations to drive the DWARF type generation. This would speed up the compiler and linker and reduce object file size.
Issues/caveats/problem
There is a small chunk of code in the linker specific to the Plan9 target that does processing of Autom's to create directives or symbols for Autom's in the Plan9 object file. It's hard to tell from the code whether this is at all useful, since we haven't been able to find someone who knows how to run the Plan9 debugger. Given the current usage of autom's (e.g. for non-user-visible variables) it seems unlikely that removing the Plan9 autom handling will cause any debugging issues, so the proposal is to just drop this code.