]> Cypherpunks repositories - gostls13.git/commitdiff
compile,link: export package name in debug_info
authorAlessandro Arzilli <alessandro.arzilli@gmail.com>
Mon, 25 Feb 2019 12:56:18 +0000 (13:56 +0100)
committerHeschi Kreinick <heschi@google.com>
Tue, 2 Apr 2019 17:40:36 +0000 (17:40 +0000)
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>
src/cmd/compile/internal/gc/main.go
src/cmd/internal/dwarf/dwarf.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/dwarf_test.go

index 98ff2a3d27a1c3c81f710f8bec0c80f03459b098..20bc4acc6abb8b354d9464e2b59bf0188eb9b6f0 100644 (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
 
index 7f37cf059d4a946c737dba389c9c28f1345f576d..df80039063c3759c72dc20e64858cc0f0ed57448 100644 (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},
                },
        },
 
index e86247dd04e11eaa6052989922a16618c5a76274..feee63d065d4685d0ad197a98c5b715c80cdf3a7 100644 (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
                }
index 287ad5c99df39fc5de9743078f5f212e739a5ac9..333680511ab851d8f6ddcec2bf64e3619b32dec9 100644 (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)
+               }
+       }
+}