Commit e70fae8a authored by Keith Randall's avatar Keith Randall Committed by Keith Randall

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/50170Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent df709828
...@@ -767,20 +767,14 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) { ...@@ -767,20 +767,14 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
continue continue
} }
elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol) elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
elemsize := decodetypeSize(ctxt.Arch, elemgotype)
elemname := elemgotype.Name[5:] elemname := elemgotype.Name[5:]
elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype)) elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
// sudog<T> // sudog<T>
dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) { dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
copychildren(ctxt, dws, sudog) copychildren(ctxt, dws, sudog)
substitutetype(dws, "elem", elemtype) substitutetype(dws, "elem", defptrto(ctxt, elemtype))
if elemsize > 8 { newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize), nil)
elemsize -= 8
} else {
elemsize = 0
}
newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize)+elemsize, nil)
}) })
// waitq<T> // waitq<T>
......
...@@ -239,3 +239,58 @@ func main() { ...@@ -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)
}
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment