From c44af2d4a23a30cb0930adfca9e56b3d1e04a35c Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Wed, 11 Mar 2020 11:18:00 -0400 Subject: [PATCH] [dev.link] cmd/internal/obj: add dump of aux symbols for -S=2 For compiler developers interested in seeing DWARF generation details, this patch provides symbol "debug asm" dumps for DWARF aux symbols when -S=2 is in effect. Change-Id: I5a0b6b65ce7b708948cbbf23c6b0d279bd4f8d9f Reviewed-on: https://go-review.googlesource.com/c/go/+/223017 Reviewed-by: Jeremy Faller Reviewed-by: Cherry Zhang Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- src/cmd/internal/obj/objfile.go | 6 ++- src/cmd/internal/obj/objfile2.go | 30 ++++++++++++-- src/cmd/internal/obj/sym.go | 68 +++++++++++++++++++++++--------- 3 files changed, 81 insertions(+), 23 deletions(-) diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index 4669e415cc..0f73e48b05 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -21,7 +21,11 @@ func WriteObjFile(ctxt *Link, bout *bio.Writer, pkgpath string) { } func (ctxt *Link) writeSymDebug(s *LSym) { - fmt.Fprintf(ctxt.Bso, "%s ", s.Name) + ctxt.writeSymDebugNamed(s, s.Name) +} + +func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) { + fmt.Fprintf(ctxt.Bso, "%s ", name) if s.Type != 0 { fmt.Fprintf(ctxt.Bso, "%v ", s.Type) } diff --git a/src/cmd/internal/obj/objfile2.go b/src/cmd/internal/obj/objfile2.go index dc492733ac..9ccbcd5352 100644 --- a/src/cmd/internal/obj/objfile2.go +++ b/src/cmd/internal/obj/objfile2.go @@ -18,9 +18,8 @@ import ( // Entry point of writing new object file. func WriteObjFile2(ctxt *Link, b *bio.Writer, pkgpath string) { - if ctxt.Debugasm > 0 { - ctxt.traverseSyms(traverseDefs, ctxt.writeSymDebug) - } + + debugAsmEmit(ctxt) genFuncInfoSyms(ctxt) @@ -434,3 +433,28 @@ func genFuncInfoSyms(ctxt *Link) { } ctxt.defs = append(ctxt.defs, infosyms...) } + +// debugDumpAux is a dumper for selected aux symbols. +func writeAuxSymDebug(ctxt *Link, par *LSym, aux *LSym) { + // Most aux symbols (ex: funcdata) are not interesting-- + // pick out just the DWARF ones for now. + if aux.Type != objabi.SDWARFLOC && + aux.Type != objabi.SDWARFINFO && + aux.Type != objabi.SDWARFLINES && + aux.Type != objabi.SDWARFRANGE { + return + } + ctxt.writeSymDebugNamed(aux, "aux for "+par.Name) +} + +func debugAsmEmit(ctxt *Link) { + if ctxt.Debugasm > 0 { + ctxt.traverseSyms(traverseDefs, ctxt.writeSymDebug) + if ctxt.Debugasm > 1 { + fn := func(par *LSym, aux *LSym) { + writeAuxSymDebug(ctxt, par, aux) + } + ctxt.traverseAuxSyms(fn) + } + } +} diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go index e1e749db92..818d464c91 100644 --- a/src/cmd/internal/obj/sym.go +++ b/src/cmd/internal/obj/sym.go @@ -294,28 +294,58 @@ func (ctxt *Link) traverseSyms(flag traverseFlag, fn func(*LSym)) { fn(s.Gotype) } if s.Type == objabi.STEXT { - pc := &s.Func.Pcln - for _, d := range pc.Funcdata { - if d != nil { - fn(d) - } - } - for _, f := range pc.File { - if fsym := ctxt.Lookup(f); fsym != nil { - fn(fsym) - } - } - for _, call := range pc.InlTree.nodes { - if call.Func != nil { - fn(call.Func) - } - f, _ := linkgetlineFromPos(ctxt, call.Pos) - if fsym := ctxt.Lookup(f); fsym != nil { - fn(fsym) - } + f := func(parent *LSym, aux *LSym) { + fn(aux) } + ctxt.traverseFuncAux(s, f) } } } } } + +func (ctxt *Link) traverseFuncAux(fsym *LSym, fn func(parent *LSym, aux *LSym)) { + pc := &fsym.Func.Pcln + for _, d := range pc.Funcdata { + if d != nil { + fn(fsym, d) + } + } + for _, f := range pc.File { + if filesym := ctxt.Lookup(f); filesym != nil { + fn(fsym, filesym) + } + } + for _, call := range pc.InlTree.nodes { + if call.Func != nil { + fn(fsym, call.Func) + } + f, _ := linkgetlineFromPos(ctxt, call.Pos) + if filesym := ctxt.Lookup(f); filesym != nil { + fn(fsym, filesym) + } + } + dwsyms := []*LSym{fsym.Func.dwarfRangesSym, fsym.Func.dwarfLocSym} + for _, dws := range dwsyms { + if dws == nil || dws.Size == 0 { + continue + } + fn(fsym, dws) + } +} + +// Traverse aux symbols, calling fn for each sym/aux pair. +func (ctxt *Link) traverseAuxSyms(fn func(parent *LSym, aux *LSym)) { + lists := [][]*LSym{ctxt.Text, ctxt.Data, ctxt.ABIAliases} + for _, list := range lists { + for _, s := range list { + if s.Gotype != nil { + fn(s, s.Gotype) + } + if s.Type != objabi.STEXT { + continue + } + ctxt.traverseFuncAux(s, fn) + } + } +}