1
0
mirror of https://github.com/golang/go synced 2024-09-23 17:10:13 -06:00

compile,link: export package name in debug_info

Add a new custom attribute to compile units containing the package name
of the package (i.e. the name after the 'package' keyword), so that
debuggers can know it when it's different from the last segment
of the package path.

Change-Id: Ieadaab6f47091aabf2f4dc42c8524452eaa6715b
Reviewed-on: https://go-review.googlesource.com/c/go/+/163677
Run-TryBot: Alessandro Arzilli <alessandro.arzilli@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Alessandro Arzilli 2019-02-25 13:56:18 +01:00 committed by Heschi Kreinick
parent abefcac10a
commit e29f74efb9
4 changed files with 77 additions and 0 deletions

View File

@ -497,6 +497,8 @@ func Main(archInit func(*Arch)) {
finishUniverse()
recordPackageName()
typecheckok = true
// Process top-level declarations in phases.
@ -1406,6 +1408,18 @@ func recordFlags(flags ...string) {
s.P = cmd.Bytes()[1:]
}
// recordPackageName records the name of the package being
// compiled, so that the linker can save it in the compile unit's DIE.
func recordPackageName() {
s := Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + myimportpath)
s.Type = objabi.SDWARFINFO
// Sometimes (for example when building tests) we can link
// together two package main archives. So allow dups.
s.Set(obj.AttrDuplicateOK, true)
Ctxt.Data = append(Ctxt.Data, s)
s.P = []byte(localpkg.Name)
}
// flag_lang is the language version we are compiling for, set by the -lang flag.
var flag_lang string

View File

@ -298,6 +298,8 @@ const (
DW_AT_go_embedded_field = 0x2903
DW_AT_go_runtime_type = 0x2904
DW_AT_go_package_name = 0x2905 // Attribute for DW_TAG_compile_unit
DW_AT_internal_location = 253 // params and locals; not emitted
)
@ -369,6 +371,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
{DW_AT_ranges, DW_FORM_sec_offset},
{DW_AT_comp_dir, DW_FORM_string},
{DW_AT_producer, DW_FORM_string},
{DW_AT_go_package_name, DW_FORM_string},
},
},
@ -381,6 +384,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
{DW_AT_language, DW_FORM_data1},
{DW_AT_comp_dir, DW_FORM_string},
{DW_AT_producer, DW_FORM_string},
{DW_AT_go_package_name, DW_FORM_string},
},
},

View File

@ -1833,6 +1833,12 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
newattr(unit.dwinfo, dwarf.DW_AT_producer, dwarf.DW_CLS_STRING, int64(len(producer)), producer)
var pkgname string
if s := ctxt.Syms.ROLookup(dwarf.CUInfoPrefix+"packagename."+unit.lib.Pkg, 0); s != nil {
pkgname = string(s.P)
}
newattr(unit.dwinfo, dwarf.DW_AT_go_package_name, dwarf.DW_CLS_STRING, int64(len(pkgname)), pkgname)
if len(lib.Textp) == 0 {
unit.dwinfo.Abbrev = dwarf.DW_ABRV_COMPUNIT_TEXTLESS
}

View File

@ -1142,3 +1142,56 @@ func main() {
}
}
}
func TestPackageNameAttr(t *testing.T) {
const dwarfAttrGoPackageName = dwarf.Attr(0x2905)
const dwarfGoLanguage = 22
testenv.MustHaveGoBuild(t)
if runtime.GOOS == "plan9" {
t.Skip("skipping on plan9; no DWARF symbol table in executables")
}
t.Parallel()
dir, err := ioutil.TempDir("", "go-build")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
const prog = "package main\nfunc main() {\nprintln(\"hello world\")\n}\n"
f := gobuild(t, dir, prog, NoOpt)
defer f.Close()
d, err := f.DWARF()
if err != nil {
t.Fatalf("error reading DWARF: %v", err)
}
rdr := d.Reader()
for {
e, err := rdr.Next()
if err != nil {
t.Fatal(err)
}
if e == nil {
break
}
if e.Tag != dwarf.TagCompileUnit {
continue
}
if lang, _ := e.Val(dwarf.AttrLanguage).(int64); lang != dwarfGoLanguage {
continue
}
_, ok := e.Val(dwarfAttrGoPackageName).(string)
if !ok {
name, _ := e.Val(dwarf.AttrName).(string)
t.Errorf("found compile unit without package name: %s", name)
}
}
}