aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2025-12-06 15:06:11 -0800
committerGopher Robot <gobot@golang.org>2025-12-08 09:11:14 -0800
commitb5f6816cea5b195e583c60e97a519d5d4ad5793f (patch)
treee663b5d3c6e90e4e0a9e118c5c500344261fcd2a /src/cmd/link
parent44a39c9dacdb3378197b9515add22d292dd71af9 (diff)
downloadgo-b5f6816cea5b195e583c60e97a519d5d4ad5793f.tar.xz
cmd/link: generate DWARF for moduledata
Fixes #76731 Change-Id: I5c686c91af8543b57880a89d30393912ef1958ad Reviewed-on: https://go-review.googlesource.com/c/go/+/727760 Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: Alessandro Arzilli <alessandro.arzilli@gmail.com> Reviewed-by: Florian Lehner <lehner.florian86@gmail.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/link')
-rw-r--r--src/cmd/link/dwarf_test.go92
-rw-r--r--src/cmd/link/internal/ld/dwarf.go2
2 files changed, 93 insertions, 1 deletions
diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go
index d9916ae079..3900ae0654 100644
--- a/src/cmd/link/dwarf_test.go
+++ b/src/cmd/link/dwarf_test.go
@@ -156,10 +156,102 @@ func testDWARF(t *testing.T, buildmode string, expectDWARF bool, env ...string)
if !strings.HasSuffix(line.File.Name, wantFile) || line.Line != wantLine {
t.Errorf("%#x is %s:%d, want %s:%d", addr, line.File.Name, line.Line, filepath.Join("...", wantFile), wantLine)
}
+
+ if buildmode != "c-archive" {
+ testModuledata(t, d)
+ }
})
}
}
+// testModuledata makes sure that runtime.firstmoduledata exists
+// and has a type. Issue #76731.
+func testModuledata(t *testing.T, d *dwarf.Data) {
+ const symName = "runtime.firstmoduledata"
+
+ r := d.Reader()
+ for {
+ e, err := r.Next()
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ if e == nil {
+ t.Errorf("did not find DWARF entry for %s", symName)
+ return
+ }
+
+ switch e.Tag {
+ case dwarf.TagVariable:
+ // carry on after switch
+ case dwarf.TagCompileUnit, dwarf.TagSubprogram:
+ continue
+ default:
+ r.SkipChildren()
+ continue
+ }
+
+ nameIdx, typeIdx := -1, -1
+ for i := range e.Field {
+ f := &e.Field[i]
+ switch f.Attr {
+ case dwarf.AttrName:
+ nameIdx = i
+ case dwarf.AttrType:
+ typeIdx = i
+ }
+ }
+ if nameIdx == -1 {
+ // unnamed variable?
+ r.SkipChildren()
+ continue
+ }
+ nameStr, ok := e.Field[nameIdx].Val.(string)
+ if !ok {
+ // variable name is not a string?
+ r.SkipChildren()
+ continue
+ }
+ if nameStr != symName {
+ r.SkipChildren()
+ continue
+ }
+
+ if typeIdx == -1 {
+ t.Errorf("%s has no DWARF type", symName)
+ return
+ }
+ off, ok := e.Field[typeIdx].Val.(dwarf.Offset)
+ if !ok {
+ t.Errorf("unexpected Go type %T for DWARF type for %s; expected %T", e.Field[typeIdx].Val, symName, dwarf.Offset(0))
+ return
+ }
+
+ typeInfo, err := d.Type(off)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ typeName := typeInfo.Common().Name
+ if want := "runtime.moduledata"; typeName != want {
+ t.Errorf("type of %s is %s, expected %s", symName, typeName, want)
+ }
+ for {
+ typedef, ok := typeInfo.(*dwarf.TypedefType)
+ if !ok {
+ break
+ }
+ typeInfo = typedef.Type
+ }
+ if _, ok := typeInfo.(*dwarf.StructType); !ok {
+ t.Errorf("type of %s is %T, expected %T", symName, typeInfo, dwarf.StructType{})
+ }
+
+ return
+ }
+}
+
func TestDWARF(t *testing.T) {
testDWARF(t, "", true)
if !testing.Short() {
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index ff0fa5c377..5cd39fbc53 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -2036,7 +2036,7 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
t := d.ldr.SymType(idx)
switch {
case t.IsRODATA(), t.IsDATA(), t.IsNOPTRDATA(),
- t == sym.STYPE, t == sym.SBSS, t == sym.SNOPTRBSS, t == sym.STLSBSS:
+ t == sym.STYPE, t == sym.SBSS, t == sym.SNOPTRBSS, t == sym.STLSBSS, t == sym.SMODULEDATA:
// ok
default:
continue