1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 // Parse the type units stored in a DWARF4 .debug_types section. Each
13 // type unit defines a single primary type and an 8-byte signature.
14 // Other sections may then use formRefSig8 to refer to the type.
16 // The typeUnit format is a single type with a signature. It holds
17 // the same data as a compilation unit.
18 type typeUnit
struct {
20 toff Offset
// Offset to signature type within data.
21 name
string // Name of .debug_type section.
22 cache Type
// Cache the type, nil to start.
25 // Parse a .debug_types section.
26 func (d
*Data
) parseTypes(name
string, types
[]byte) error
{
27 b
:= makeBuf(d
, unknownFormat
{}, name
, 0, types
)
30 n
, dwarf64
:= b
.unitLength()
31 if n
!= Offset(uint32(n
)) {
32 b
.error("type unit length overflow")
36 vers
:= int(b
.uint16())
38 b
.error("unsupported DWARF version " + strconv
.Itoa(vers
))
43 ao
= uint64(b
.uint32())
47 atable
, err
:= d
.parseAbbrev(ao
, vers
)
59 if to64
!= uint64(uint32(to64
)) {
60 b
.error("type unit type offset overflow")
67 d
.typeSigs
[sig
] = &typeUnit
{
71 data
: b
.bytes(int(n
- (b
.off
- hdroff
))),
87 // Return the type for a type signature.
88 func (d
*Data
) sigToType(sig
uint64) (Type
, error
) {
91 return nil, fmt
.Errorf("no type unit with signature %v", sig
)
97 b
:= makeBuf(d
, tu
, tu
.name
, tu
.off
, tu
.data
)
98 r
:= &typeUnitReader
{d
: d
, tu
: tu
, b
: b
}
99 t
, err
:= d
.readType(tu
.name
, r
, tu
.toff
, make(map[Offset
]Type
), nil)
108 // typeUnitReader is a typeReader for a tagTypeUnit.
109 type typeUnitReader
struct {
116 // Seek to a new position in the type unit.
117 func (tur
*typeUnitReader
) Seek(off Offset
) {
119 doff
:= off
- tur
.tu
.off
120 if doff
< 0 || doff
>= Offset(len(tur
.tu
.data
)) {
121 tur
.err
= fmt
.Errorf("%s: offset %d out of range; max %d", tur
.tu
.name
, doff
, len(tur
.tu
.data
))
124 tur
.b
= makeBuf(tur
.d
, tur
.tu
, tur
.tu
.name
, off
, tur
.tu
.data
[doff
:])
127 // AddressSize returns the size in bytes of addresses in the current type unit.
128 func (tur
*typeUnitReader
) AddressSize() int {
129 return tur
.tu
.unit
.asize
132 // Next reads the next Entry from the type unit.
133 func (tur
*typeUnitReader
) Next() (*Entry
, error
) {
137 if len(tur
.tu
.data
) == 0 {
140 e
:= tur
.b
.entry(tur
.tu
.atable
, tur
.tu
.base
)
141 if tur
.b
.err
!= nil {
148 // clone returns a new reader for the type unit.
149 func (tur
*typeUnitReader
) clone() typeReader
{
150 return &typeUnitReader
{
153 b
: makeBuf(tur
.d
, tur
.tu
, tur
.tu
.name
, tur
.tu
.off
, tur
.tu
.data
),
157 // offset returns the current offset.
158 func (tur
*typeUnitReader
) offset() Offset
{