cmd/compile: output DWARF lexical blocks for local variables

Change compiler and linker to emit DWARF lexical blocks in debug_info.
Version of debug_info is updated from DWARF v.2 to DWARF v.3 since version 2
does not allow lexical blocks with discontinuous ranges.

Second attempt at https://go-review.googlesource.com/#/c/29591/

Remaining open problems:
- scope information is removed from inlined functions
- variables in debug_info 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, before its declaration.

Updates golang/go#12899, golang/go#6913

Change-Id: I0e260a45b564d14a87b88974eb16c5387cb410a5
Reviewed-on: https://go-review.googlesource.com/36879
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Alessandro Arzilli 2017-03-07 18:59:14 +01:00 committed by Matthew Dempsky
parent 7165bcc6ba
commit c8b889cc48
21 changed files with 890 additions and 110 deletions

View file

@ -310,13 +310,18 @@ func compile(fn *Node) {
pp.Free()
}
func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var {
func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope {
fn := curfn.(*Node)
if expect := Linksym(fn.Func.Nname.Sym); fnsym != expect {
Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
}
var vars []*dwarf.Var
scopes := make([]dwarf.Scope, len(fn.Func.scopes.Scopes))
for i := range scopes {
scopes[i] = dwarf.Scope{Scope: fn.Func.scopes.Scopes[i]}
}
for _, n := range fn.Func.Dcl {
if n.Op != ONAME { // might be OTYPE or OLITERAL
continue
@ -363,8 +368,14 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var {
continue
}
var scope int32 = 0
// Only record scope information when inlining is disabled.
if Debug['l'] == 0 {
scope = findScope(n.Pos, scopes)
}
typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
vars = append(vars, &dwarf.Var{
scopes[scope].Vars = append(scopes[scope].Vars, &dwarf.Var{
Name: n.Sym.Name,
Abbrev: abbrev,
Offset: int32(offs),
@ -373,9 +384,13 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var {
}
// Stable sort so that ties are broken with declaration order.
sort.Stable(dwarf.VarsByOffset(vars))
for i := range scopes {
sort.Stable(dwarf.VarsByOffset(scopes[i].Vars))
}
return vars
scopeRanges(fnsym, scopes)
return scopes
}
// fieldtrack adds R_USEFIELD relocations to fnsym to record any