Commit e29f74ef authored by Alessandro Arzilli's avatar Alessandro Arzilli Committed by Heschi Kreinick

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: default avatarHeschi Kreinick <heschi@google.com>
parent abefcac1
...@@ -497,6 +497,8 @@ func Main(archInit func(*Arch)) { ...@@ -497,6 +497,8 @@ func Main(archInit func(*Arch)) {
finishUniverse() finishUniverse()
recordPackageName()
typecheckok = true typecheckok = true
// Process top-level declarations in phases. // Process top-level declarations in phases.
...@@ -1406,6 +1408,18 @@ func recordFlags(flags ...string) { ...@@ -1406,6 +1408,18 @@ func recordFlags(flags ...string) {
s.P = cmd.Bytes()[1:] 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. // flag_lang is the language version we are compiling for, set by the -lang flag.
var flag_lang string var flag_lang string
......
...@@ -298,6 +298,8 @@ const ( ...@@ -298,6 +298,8 @@ const (
DW_AT_go_embedded_field = 0x2903 DW_AT_go_embedded_field = 0x2903
DW_AT_go_runtime_type = 0x2904 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 DW_AT_internal_location = 253 // params and locals; not emitted
) )
...@@ -369,6 +371,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{ ...@@ -369,6 +371,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
{DW_AT_ranges, DW_FORM_sec_offset}, {DW_AT_ranges, DW_FORM_sec_offset},
{DW_AT_comp_dir, DW_FORM_string}, {DW_AT_comp_dir, DW_FORM_string},
{DW_AT_producer, 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{ ...@@ -381,6 +384,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
{DW_AT_language, DW_FORM_data1}, {DW_AT_language, DW_FORM_data1},
{DW_AT_comp_dir, DW_FORM_string}, {DW_AT_comp_dir, DW_FORM_string},
{DW_AT_producer, DW_FORM_string}, {DW_AT_producer, DW_FORM_string},
{DW_AT_go_package_name, DW_FORM_string},
}, },
}, },
......
...@@ -1833,6 +1833,12 @@ func dwarfGenerateDebugInfo(ctxt *Link) { ...@@ -1833,6 +1833,12 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
newattr(unit.dwinfo, dwarf.DW_AT_producer, dwarf.DW_CLS_STRING, int64(len(producer)), producer) 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 { if len(lib.Textp) == 0 {
unit.dwinfo.Abbrev = dwarf.DW_ABRV_COMPUNIT_TEXTLESS unit.dwinfo.Abbrev = dwarf.DW_ABRV_COMPUNIT_TEXTLESS
} }
......
...@@ -1142,3 +1142,56 @@ func main() { ...@@ -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)
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment