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

@ -447,10 +447,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)
@ -460,27 +464,35 @@ func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
r.Type = objabi.R_DWARFREF
}
// dwarfSym returns the DWARF symbol for TEXT symbol.
func (ctxt *Link) dwarfSym(s *LSym) *LSym {
// dwarfSym returns the DWARF symbols for TEXT symbol.
func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfRangesSym *LSym) {
if s.Type != objabi.STEXT {
ctxt.Diag("dwarfSym of non-TEXT %v", s)
}
if s.Func.dwarfSym == nil {
s.Func.dwarfSym = ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name)
s.Func.dwarfRangesSym = ctxt.LookupDerived(s, dwarf.RangePrefix+s.Name)
}
return s.Func.dwarfSym
return s.Func.dwarfSym, s.Func.dwarfRangesSym
}
// populateDWARF fills in the DWARF Debugging Information Entry for TEXT symbol s.
// The DWARF symbol must already have been initialized in InitTextSym.
func (s *LSym) Len() int64 {
return s.Size
}
// populateDWARF fills in the DWARF Debugging Information Entries for TEXT symbol s.
// The DWARFs symbol must already have been initialized in InitTextSym.
func (ctxt *Link) populateDWARF(curfn interface{}, s *LSym) {
dsym := ctxt.dwarfSym(s)
dsym, drsym := ctxt.dwarfSym(s)
if dsym.Size != 0 {
ctxt.Diag("makeFuncDebugEntry double process %v", s)
}
var vars []*dwarf.Var
var scopes []dwarf.Scope
if ctxt.DebugInfo != nil {
vars = ctxt.DebugInfo(s, curfn)
scopes = ctxt.DebugInfo(s, curfn)
}
err := dwarf.PutFunc(dwCtxt{ctxt}, dsym, drsym, s.Name, !s.Static(), s, s.Size, scopes)
if err != nil {
ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
}
dwarf.PutFunc(dwCtxt{ctxt}, dsym, s.Name, !s.Static(), s, s.Size, vars)
}