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

@ -542,10 +542,14 @@ func (c dwCtxt) SymValue(s dwarf.Sym) int64 {
return 0
}
func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
rsym := data.(*LSym)
ls := s.(*LSym)
size := c.PtrSize()
ls.WriteAddr(c.Link, ls.Size, size, rsym, value)
if data != nil {
rsym := data.(*LSym)
ls.WriteAddr(c.Link, ls.Size, size, rsym, value)
} else {
ls.WriteInt(c.Link, ls.Size, size, value)
}
}
func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
ls := s.(*LSym)
@ -555,6 +559,10 @@ func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
r.Type = R_DWARFREF
}
func (s *LSym) Len() int64 {
return s.Size
}
// makeFuncDebugEntry makes a DWARF Debugging Information Entry
// for TEXT symbol s.
func makeFuncDebugEntry(ctxt *Link, curfn interface{}, s *LSym) {
@ -564,10 +572,21 @@ func makeFuncDebugEntry(ctxt *Link, curfn interface{}, s *LSym) {
}
dsym.Type = SDWARFINFO
dsym.Set(AttrDuplicateOK, s.DuplicateOK())
var vars []*dwarf.Var
if ctxt.DebugInfo != nil {
vars = ctxt.DebugInfo(s, curfn)
drsym := ctxt.Lookup(dwarf.RangePrefix+s.Name, int(s.Version))
if drsym.Size != 0 {
return
}
dwarf.PutFunc(dwCtxt{ctxt}, dsym, s.Name, s.Version == 0, s, s.Size, vars)
ctxt.Data = append(ctxt.Data, dsym)
drsym.Type = SDWARFRANGE
drsym.Set(AttrDuplicateOK, s.DuplicateOK())
var scopes []dwarf.Scope
if ctxt.DebugInfo != nil {
scopes = ctxt.DebugInfo(s, curfn)
}
err := dwarf.PutFunc(dwCtxt{ctxt}, dsym, drsym, s.Name, s.Version == 0, s, s.Size, scopes)
if err != nil {
ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
}
ctxt.Data = append(ctxt.Data, dsym, drsym)
}