From: Keith Randall Date: Thu, 20 Jul 2017 02:52:29 +0000 (-0700) Subject: cmd/link: fix bad dwarf for sudog X-Git-Tag: go1.10beta1~1515 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e70fae8a649ebc35867cc4ba937d4ffd4488fe05;p=gostls13.git cmd/link: fix bad dwarf for sudog 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 --- 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 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 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 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) + } + } + } +}