]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fix bad dwarf for sudog<T>
authorKeith Randall <keithr@alum.mit.edu>
Thu, 20 Jul 2017 02:52:29 +0000 (19:52 -0700)
committerKeith Randall <khr@golang.org>
Wed, 16 Aug 2017 16:22:20 +0000 (16:22 +0000)
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>
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/dwarf_test.go

index 9692dd6b4eea0869145b4bed8bd44ffc3a0b5e55..c36069e5de8213b0a1b43321f9eeb20e705885f1 100644 (file)
@@ -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>
index fd789e2d4b985078ae2a54c50c519ce78c3abec3..2776bbf5950d5dde76ae15f3fa6464a7379faeed 100644 (file)
@@ -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)
+                       }
+               }
+       }
+}