summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <keithr@alum.mit.edu>2017-07-19 19:52:29 -0700
committerKeith Randall <khr@golang.org>2017-08-16 16:22:20 +0000
commite70fae8a649ebc35867cc4ba937d4ffd4488fe05 (patch)
treed1019fc0d318c3c43102c8de16fcec0ce25a0514
parentdf709828255ba5a0e66c668b22bf555b35475d13 (diff)
downloadgo-git-e70fae8a649ebc35867cc4ba937d4ffd4488fe05.tar.gz
cmd/link: fix bad dwarf for sudog<T>
The DWARF entries for type-specific sudog entries used the channel value type instead of a pointer-to-value type for the elem field. Fixes #21094 R=go1.10 Change-Id: I3f63a5664f42b571f729931309f2c9f6f38ab031 Reviewed-on: https://go-review.googlesource.com/50170 Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r--src/cmd/link/internal/ld/dwarf.go10
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go55
2 files changed, 57 insertions, 8 deletions
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index 9692dd6b4e..c36069e5de 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -767,20 +767,14 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
continue
}
elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
- elemsize := decodetypeSize(ctxt.Arch, elemgotype)
elemname := elemgotype.Name[5:]
elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
// sudog<T>
dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
copychildren(ctxt, dws, sudog)
- substitutetype(dws, "elem", elemtype)
- if elemsize > 8 {
- elemsize -= 8
- } else {
- elemsize = 0
- }
- newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize)+elemsize, nil)
+ substitutetype(dws, "elem", defptrto(ctxt, elemtype))
+ newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize), nil)
})
// waitq<T>
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index fd789e2d4b..2776bbf595 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -239,3 +239,58 @@ func main() {
}
}
}
+
+func TestFieldOverlap(t *testing.T) {
+ // This test grew out of issue 21094, where specific sudog<T> DWARF types
+ // had elem fields set to values instead of pointers.
+ const prog = `
+package main
+
+var c chan string
+
+func main() {
+ c <- "foo"
+}
+`
+ dir, err := ioutil.TempDir("", "TestFieldOverlap")
+ if err != nil {
+ t.Fatalf("could not create directory: %v", err)
+ }
+ defer os.RemoveAll(dir)
+
+ f := gobuild(t, dir, prog)
+ defer f.Close()
+
+ d, err := f.DWARF()
+ if err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+
+ rdr := d.Reader()
+ for entry, err := rdr.Next(); entry != nil; entry, err = rdr.Next() {
+ if err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+ if entry.Tag != dwarf.TagStructType {
+ continue
+ }
+ typ, err := d.Type(entry.Offset)
+ if err != nil {
+ t.Fatalf("can't read type: %v", err)
+ }
+ s := typ.(*dwarf.StructType)
+ for i := 0; i < len(s.Field); i++ {
+ end := s.Field[i].ByteOffset + s.Field[i].Type.Size()
+ var limit int64
+ if i == len(s.Field)-1 {
+ limit = s.Size()
+ } else {
+ limit = s.Field[i+1].ByteOffset
+ }
+ if end > limit {
+ name := entry.Val(dwarf.AttrName).(string)
+ t.Fatalf("field %s.%s overlaps next field", name, s.Field[i].Name)
+ }
+ }
+ }
+}