aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/debug/dwarf/type.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/debug/dwarf/type.go')
-rw-r--r--libgo/go/debug/dwarf/type.go34
1 files changed, 27 insertions, 7 deletions
diff --git a/libgo/go/debug/dwarf/type.go b/libgo/go/debug/dwarf/type.go
index a5daa1d0bb1..c76a472d78c 100644
--- a/libgo/go/debug/dwarf/type.go
+++ b/libgo/go/debug/dwarf/type.go
@@ -275,12 +275,14 @@ type typeReader interface {
// Type reads the type at off in the DWARF ``info'' section.
func (d *Data) Type(off Offset) (Type, error) {
- return d.readType("info", d.Reader(), off, d.typeCache)
+ return d.readType("info", d.Reader(), off, d.typeCache, nil)
}
-// readType reads a type from r at off of name using and updating a
-// type cache.
-func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) {
+// readType reads a type from r at off of name. It adds types to the
+// type cache, appends new typedef types to typedefs, and computes the
+// sizes of types. Callers should pass nil for typedefs; this is used
+// for internal recursion.
+func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, typedefs *[]*TypedefType) (Type, error) {
if t, ok := typeCache[off]; ok {
return t, nil
}
@@ -294,9 +296,24 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
return nil, DecodeError{name, off, "no type at offset"}
}
+ // If this is the root of the recursion, prepare to resolve
+ // typedef sizes once the recursion is done. This must be done
+ // after the type graph is constructed because it may need to
+ // resolve cycles in a different order than readType
+ // encounters them.
+ if typedefs == nil {
+ var typedefList []*TypedefType
+ defer func() {
+ for _, t := range typedefList {
+ t.Common().ByteSize = t.Type.Size()
+ }
+ }()
+ typedefs = &typedefList
+ }
+
// Parse type from Entry.
// Must always set typeCache[off] before calling
- // d.Type recursively, to handle circular types correctly.
+ // d.readType recursively, to handle circular types correctly.
var typ Type
nextDepth := 0
@@ -345,7 +362,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
var t Type
switch toff := tval.(type) {
case Offset:
- if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
+ if t, err = d.readType(name, r.clone(), toff, typeCache, typedefs); err != nil {
return nil
}
case uint64:
@@ -674,7 +691,10 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
b = -1
switch t := typ.(type) {
case *TypedefType:
- b = t.Type.Size()
+ // Record that we need to resolve this
+ // type's size once the type graph is
+ // constructed.
+ *typedefs = append(*typedefs, t)
case *PtrType:
b = int64(addressSize)
}