cmd/compile: output DWARF lexical blocks for local variables

Change compiler and linker to emit DWARF lexical blocks in .debug_info
section when compiling with -N -l.

Version of debug_info is updated from DWARF v2 to DWARF v3 since
version 2 does not allow lexical blocks with discontinuous PC ranges.

Remaining open problems:
- scope information is removed from inlined functions
- variables records do not have DW_AT_start_scope attributes so a
variable will shadow other variables with the same name as soon as its
containing scope begins, even before its declaration.

Updates #6913.
Updates #12899.

Change-Id: Idc6808788512ea20e7e45bcf782453acb416fb49
Reviewed-on: https://go-review.googlesource.com/40095
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
Alessandro Arzilli 2017-05-02 16:46:01 +02:00 committed by Matthew Dempsky
parent 0f0a51f1d1
commit 2ad41a3090
22 changed files with 1021 additions and 111 deletions

View file

@ -299,13 +299,15 @@ func compileFunctions() {
}
}
func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var {
func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope {
fn := curfn.(*Node)
if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
}
var vars []*dwarf.Var
var dwarfVars []*dwarf.Var
var varScopes []ScopeID
for _, n := range fn.Func.Dcl {
if n.Op != ONAME { // might be OTYPE or OLITERAL
continue
@ -353,18 +355,26 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var {
}
typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
vars = append(vars, &dwarf.Var{
dwarfVars = append(dwarfVars, &dwarf.Var{
Name: n.Sym.Name,
Abbrev: abbrev,
Offset: int32(offs),
Type: Ctxt.Lookup(typename),
})
var scope ScopeID
if !n.Name.Captured() && !n.Name.Byval() {
// n.Pos of captured variables is their first
// use in the closure but they should always
// be assigned to scope 0 instead.
// TODO(mdempsky): Verify this.
scope = findScope(fn.Func.Marks, n.Pos)
}
varScopes = append(varScopes, scope)
}
// Stable sort so that ties are broken with declaration order.
sort.Stable(dwarf.VarsByOffset(vars))
return vars
return assembleScopes(fnsym, fn, dwarfVars, varScopes)
}
// fieldtrack adds R_USEFIELD relocations to fnsym to record any