mirror of
https://github.com/golang/go
synced 2024-11-22 22:50:03 -07:00
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>
This commit is contained in:
parent
df70982825
commit
e70fae8a64
@ -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() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user