diff options
| author | Keith Randall <keithr@alum.mit.edu> | 2017-07-19 19:52:29 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2017-08-16 16:22:20 +0000 |
| commit | e70fae8a649ebc35867cc4ba937d4ffd4488fe05 (patch) | |
| tree | d1019fc0d318c3c43102c8de16fcec0ce25a0514 | |
| parent | df709828255ba5a0e66c668b22bf555b35475d13 (diff) | |
| download | go-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.go | 10 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/dwarf_test.go | 55 |
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) + } + } + } +} |
