diff options
Diffstat (limited to 'libgo/go/debug/dwarf/type.go')
-rw-r--r-- | libgo/go/debug/dwarf/type.go | 34 |
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) } |