1 // Copyright 2009 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.
5 // DWARF type information structures.
6 // The format is heavily biased toward C, but for simplicity
7 // the String methods use a pseudo-Go syntax.
13 // A Type conventionally represents a pointer to any of the
14 // specific Type structures (CharType, StructType, etc.).
21 // A CommonType holds fields common to multiple types.
22 // If a field is not known or not applicable for a given type,
23 // the zero value is used.
24 type CommonType
struct {
25 ByteSize
int64 // size of value of this type, in bytes
26 Name
string // name that can be used to refer to type
29 func (c
*CommonType
) Common() *CommonType
{ return c
}
31 func (c
*CommonType
) Size() int64 { return c
.ByteSize
}
35 // A BasicType holds fields common to all basic types.
37 // See the documentation for StructField for more info on the interpretation of
38 // the BitSize/BitOffset/DataBitOffset fields.
39 type BasicType
struct {
46 func (b
*BasicType
) Basic() *BasicType
{ return b
}
48 func (t
*BasicType
) String() string {
55 // A CharType represents a signed character type.
56 type CharType
struct {
60 // A UcharType represents an unsigned character type.
61 type UcharType
struct {
65 // An IntType represents a signed integer type.
70 // A UintType represents an unsigned integer type.
71 type UintType
struct {
75 // A FloatType represents a floating point type.
76 type FloatType
struct {
80 // A ComplexType represents a complex floating point type.
81 type ComplexType
struct {
85 // A BoolType represents a boolean type.
86 type BoolType
struct {
90 // An AddrType represents a machine address type.
91 type AddrType
struct {
95 // An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type.
96 type UnspecifiedType
struct {
102 // A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
103 type QualType
struct {
109 func (t
*QualType
) String() string { return t
.Qual
+ " " + t
.Type
.String() }
111 func (t
*QualType
) Size() int64 { return t
.Type
.Size() }
113 // An ArrayType represents a fixed size array type.
114 type ArrayType
struct {
117 StrideBitSize
int64 // if > 0, number of bits to hold each element
118 Count
int64 // if == -1, an incomplete array, like char x[].
121 func (t
*ArrayType
) String() string {
122 return "[" + strconv
.FormatInt(t
.Count
, 10) + "]" + t
.Type
.String()
125 func (t
*ArrayType
) Size() int64 {
129 return t
.Count
* t
.Type
.Size()
132 // A VoidType represents the C void type.
133 type VoidType
struct {
137 func (t
*VoidType
) String() string { return "void" }
139 // A PtrType represents a pointer type.
140 type PtrType
struct {
145 func (t
*PtrType
) String() string { return "*" + t
.Type
.String() }
147 // A StructType represents a struct, union, or C++ class type.
148 type StructType
struct {
151 Kind
string // "struct", "union", or "class".
153 Incomplete
bool // if true, struct, union, class is declared but not defined
156 // A StructField represents a field in a struct, union, or C++ class type.
160 // The BitSize, BitOffset, and DataBitOffset fields describe the bit
161 // size and offset of data members declared as bit fields in C/C++
162 // struct/union/class types.
164 // BitSize is the number of bits in the bit field.
166 // DataBitOffset, if non-zero, is the number of bits from the start of
167 // the enclosing entity (e.g. containing struct/class/union) to the
168 // start of the bit field. This corresponds to the DW_AT_data_bit_offset
169 // DWARF attribute that was introduced in DWARF 4.
171 // BitOffset, if non-zero, is the number of bits between the most
172 // significant bit of the storage unit holding the bit field to the
173 // most significant bit of the bit field. Here "storage unit" is the
174 // type name before the bit field (for a field "unsigned x:17", the
175 // storage unit is "unsigned"). BitOffset values can vary depending on
176 // the endianness of the system. BitOffset corresponds to the
177 // DW_AT_bit_offset DWARF attribute that was deprecated in DWARF 4 and
178 // removed in DWARF 5.
180 // At most one of DataBitOffset and BitOffset will be non-zero;
181 // DataBitOffset/BitOffset will only be non-zero if BitSize is
182 // non-zero. Whether a C compiler uses one or the other
183 // will depend on compiler vintage and command line options.
185 // Here is an example of C/C++ bit field use, along with what to
186 // expect in terms of DWARF bit offset info. Consider this code:
196 // For the code above, one would expect to see the following for
197 // DW_AT_bit_offset values (using GCC 8):
207 // Note that in the above the offsets are purely with respect to the
208 // containing storage unit for j/k/m/n -- these values won't vary based
209 // on the size of prior data members in the containing struct.
211 // If the compiler emits DW_AT_data_bit_offset, the expected values
219 // Here the value 32 for "j" reflects the fact that the bit field is
220 // preceded by other data members (recall that DW_AT_data_bit_offset
221 // values are relative to the start of the containing struct). Hence
222 // DW_AT_data_bit_offset values can be quite large for structs with
225 // DWARF also allow for the possibility of base types that have
226 // non-zero bit size and bit offset, so this information is also
227 // captured for base types, but it is worth noting that it is not
228 // possible to trigger this behavior using mainstream languages.
230 type StructField
struct {
234 ByteSize
int64 // usually zero; use Type.Size() for normal fields
237 BitSize
int64 // zero if not a bit field
240 func (t
*StructType
) String() string {
241 if t
.StructName
!= "" {
242 return t
.Kind
+ " " + t
.StructName
247 func (f
*StructField
) bitOffset() int64 {
248 if f
.BitOffset
!= 0 {
251 return f
.DataBitOffset
254 func (t
*StructType
) Defn() string {
256 if t
.StructName
!= "" {
257 s
+= " " + t
.StructName
260 s
+= " /*incomplete*/"
264 for i
, f
:= range t
.Field
{
268 s
+= f
.Name
+ " " + f
.Type
.String()
269 s
+= "@" + strconv
.FormatInt(f
.ByteOffset
, 10)
271 s
+= " : " + strconv
.FormatInt(f
.BitSize
, 10)
272 s
+= "@" + strconv
.FormatInt(f
.bitOffset(), 10)
279 // An EnumType represents an enumerated type.
280 // The only indication of its native integer type is its ByteSize
281 // (inside CommonType).
282 type EnumType
struct {
288 // An EnumValue represents a single enumeration value.
289 type EnumValue
struct {
294 func (t
*EnumType
) String() string {
296 if t
.EnumName
!= "" {
297 s
+= " " + t
.EnumName
300 for i
, v
:= range t
.Val
{
304 s
+= v
.Name
+ "=" + strconv
.FormatInt(v
.Val
, 10)
310 // A FuncType represents a function type.
311 type FuncType
struct {
317 func (t
*FuncType
) String() string {
319 for i
, t
:= range t
.ParamType
{
326 if t
.ReturnType
!= nil {
327 s
+= " " + t
.ReturnType
.String()
332 // A DotDotDotType represents the variadic ... function parameter.
333 type DotDotDotType
struct {
337 func (t
*DotDotDotType
) String() string { return "..." }
339 // A TypedefType represents a named type.
340 type TypedefType
struct {
345 func (t
*TypedefType
) String() string { return t
.Name
}
347 func (t
*TypedefType
) Size() int64 { return t
.Type
.Size() }
349 // An UnsupportedType is a placeholder returned in situations where we
350 // encounter a type that isn't supported.
351 type UnsupportedType
struct {
356 func (t
*UnsupportedType
) String() string {
360 return t
.Name
+ "(unsupported type " + t
.Tag
.String() + ")"
363 // typeReader is used to read from either the info section or the
365 type typeReader
interface {
367 Next() (*Entry
, error
)
370 // AddressSize returns the size in bytes of addresses in the current
375 // Type reads the type at off in the DWARF ``info'' section.
376 func (d
*Data
) Type(off Offset
) (Type
, error
) {
377 return d
.readType("info", d
.Reader(), off
, d
.typeCache
, nil)
380 type typeFixer
struct {
381 typedefs
[]*TypedefType
385 func (tf
*typeFixer
) recordArrayType(t
*Type
) {
389 _
, ok
:= (*t
).(*ArrayType
)
391 tf
.arraytypes
= append(tf
.arraytypes
, t
)
395 func (tf
*typeFixer
) apply() {
396 for _
, t
:= range tf
.typedefs
{
397 t
.Common().ByteSize
= t
.Type
.Size()
399 for _
, t
:= range tf
.arraytypes
{
404 // readType reads a type from r at off of name. It adds types to the
405 // type cache, appends new typedef types to typedefs, and computes the
406 // sizes of types. Callers should pass nil for typedefs; this is used
407 // for internal recursion.
408 func (d
*Data
) readType(name
string, r typeReader
, off Offset
, typeCache
map[Offset
]Type
, fixups
*typeFixer
) (Type
, error
) {
409 if t
, ok
:= typeCache
[off
]; ok
{
417 addressSize
:= r
.AddressSize()
418 if e
== nil || e
.Offset
!= off
{
419 return nil, DecodeError
{name
, off
, "no type at offset"}
422 // If this is the root of the recursion, prepare to resolve
423 // typedef sizes and perform other fixups once the recursion is
424 // done. This must be done after the type graph is constructed
425 // because it may need to resolve cycles in a different order than
426 // readType encounters them.
435 // Parse type from Entry.
436 // Must always set typeCache[off] before calling
437 // d.readType recursively, to handle circular types correctly.
442 // Get next child; set err if error happens.
443 next
:= func() *Entry
{
447 // Only return direct children.
448 // Skip over composite entries that happen to be nested
449 // inside this one. Most DWARF generators wouldn't generate
450 // such a thing, but clang does.
451 // See golang.org/issue/6472.
453 kid
, err1
:= r
.Next()
459 err
= DecodeError
{name
, r
.offset(), "unexpected end of DWARF entries"}
479 // Get Type referred to by Entry's AttrType field.
480 // Set err if error happens. Not having a type is an error.
481 typeOf
:= func(e
*Entry
) Type
{
482 tval
:= e
.Val(AttrType
)
484 switch toff
:= tval
.(type) {
486 if t
, err
= d
.readType(name
, r
.clone(), toff
, typeCache
, fixups
); err
!= nil {
490 if t
, err
= d
.sigToType(toff
); err
!= nil {
494 // It appears that no Type means "void".
502 // Multi-dimensional array. (DWARF v2 §5.4)
504 // AttrType:subtype [required]
505 // AttrStrideSize: size in bits of each element of the array
506 // AttrByteSize: size of entire array
508 // TagSubrangeType or TagEnumerationType giving one dimension.
509 // dimensions are in left to right order.
513 if t
.Type
= typeOf(e
); err
!= nil {
516 t
.StrideBitSize
, _
= e
.Val(AttrStrideSize
).(int64)
518 // Accumulate dimensions,
520 for kid
:= next(); kid
!= nil; kid
= next() {
521 // TODO(rsc): Can also be TagEnumerationType
522 // but haven't seen that in the wild yet.
524 case TagSubrangeType
:
525 count
, ok
:= kid
.Val(AttrCount
).(int64)
527 // Old binaries may have an upper bound instead.
528 count
, ok
= kid
.Val(AttrUpperBound
).(int64)
530 count
++ // Length is one more than upper bound.
531 } else if len(dims
) == 0 {
532 count
= -1 // As in x[].
535 dims
= append(dims
, count
)
536 case TagEnumerationType
:
537 err
= DecodeError
{name
, kid
.Offset
, "cannot handle enumeration type as array bound"}
542 // LLVM generates this for x[].
547 for i
:= len(dims
) - 1; i
>= 1; i
-- {
548 t
.Type
= &ArrayType
{Type
: t
.Type
, Count
: dims
[i
]}
552 // Basic type. (DWARF v2 §5.1)
554 // AttrName: name of base type in programming language of the compilation unit [required]
555 // AttrEncoding: encoding value for type (encFloat etc) [required]
556 // AttrByteSize: size of type in bytes [required]
557 // AttrBitOffset: bit offset of value within containing storage unit
558 // AttrDataBitOffset: bit offset of value within containing storage unit
559 // AttrBitSize: size in bits
561 // For most languages BitOffset/DataBitOffset/BitSize will not be present
563 name
, _
:= e
.Val(AttrName
).(string)
564 enc
, ok
:= e
.Val(AttrEncoding
).(int64)
566 err
= DecodeError
{name
, e
.Offset
, "missing encoding attribute for " + name
}
571 err
= DecodeError
{name
, e
.Offset
, "unrecognized encoding attribute value"}
578 case encComplexFloat
:
579 typ
= new(ComplexType
)
580 if name
== "complex" {
581 // clang writes out 'complex' instead of 'complex float' or 'complex double'.
582 // clang also writes out a byte size that we can use to distinguish.
584 switch byteSize
, _
:= e
.Val(AttrByteSize
).(int64); byteSize
{
586 name
= "complex float"
588 name
= "complex double"
599 case encUnsignedChar
:
603 t
:= typ
.(interface {
607 t
.BitSize
, _
= e
.Val(AttrBitSize
).(int64)
608 haveBitOffset
:= false
609 haveDataBitOffset
:= false
610 t
.BitOffset
, haveBitOffset
= e
.Val(AttrBitOffset
).(int64)
611 t
.DataBitOffset
, haveDataBitOffset
= e
.Val(AttrDataBitOffset
).(int64)
612 if haveBitOffset
&& haveDataBitOffset
{
613 err
= DecodeError
{name
, e
.Offset
, "duplicate bit offset attributes"}
617 case TagClassType
, TagStructType
, TagUnionType
:
618 // Structure, union, or class type. (DWARF v2 §5.5)
620 // AttrName: name of struct, union, or class
621 // AttrByteSize: byte size [required]
622 // AttrDeclaration: if true, struct/union/class is incomplete
624 // TagMember to describe one member.
625 // AttrName: name of member [required]
626 // AttrType: type of member [required]
627 // AttrByteSize: size in bytes
628 // AttrBitOffset: bit offset within bytes for bit fields
629 // AttrDataBitOffset: field bit offset relative to struct start
630 // AttrBitSize: bit size for bit fields
631 // AttrDataMemberLoc: location within struct [required for struct, class]
632 // There is much more to handle C++, all ignored for now.
644 t
.StructName
, _
= e
.Val(AttrName
).(string)
645 t
.Incomplete
= e
.Val(AttrDeclaration
) != nil
646 t
.Field
= make([]*StructField
, 0, 8)
647 var lastFieldType
*Type
648 var lastFieldBitSize
int64
649 var lastFieldByteOffset
int64
650 for kid
:= next(); kid
!= nil; kid
= next() {
651 if kid
.Tag
!= TagMember
{
654 f
:= new(StructField
)
655 if f
.Type
= typeOf(kid
); err
!= nil {
658 switch loc
:= kid
.Val(AttrDataMemberLoc
).(type) {
660 // TODO: Should have original compilation
661 // unit here, not unknownFormat.
662 b
:= makeBuf(d
, unknownFormat
{}, "location", 0, loc
)
663 if b
.uint8() != opPlusUconst
{
664 err
= DecodeError
{name
, kid
.Offset
, "unexpected opcode"}
667 f
.ByteOffset
= int64(b
.uint())
676 f
.Name
, _
= kid
.Val(AttrName
).(string)
677 f
.ByteSize
, _
= kid
.Val(AttrByteSize
).(int64)
678 haveBitOffset
:= false
679 haveDataBitOffset
:= false
680 f
.BitOffset
, haveBitOffset
= kid
.Val(AttrBitOffset
).(int64)
681 f
.DataBitOffset
, haveDataBitOffset
= kid
.Val(AttrDataBitOffset
).(int64)
682 if haveBitOffset
&& haveDataBitOffset
{
683 err
= DecodeError
{name
, e
.Offset
, "duplicate bit offset attributes"}
686 f
.BitSize
, _
= kid
.Val(AttrBitSize
).(int64)
687 t
.Field
= append(t
.Field
, f
)
689 if lastFieldBitSize
== 0 && lastFieldByteOffset
== f
.ByteOffset
&& t
.Kind
!= "union" {
690 // Last field was zero width. Fix array length.
691 // (DWARF writes out 0-length arrays as if they were 1-length arrays.)
692 fixups
.recordArrayType(lastFieldType
)
694 lastFieldType
= &f
.Type
695 lastFieldByteOffset
= f
.ByteOffset
696 lastFieldBitSize
= f
.BitSize
698 if t
.Kind
!= "union" {
699 b
, ok
:= e
.Val(AttrByteSize
).(int64)
700 if ok
&& b
== lastFieldByteOffset
{
701 // Final field must be zero width. Fix array length.
702 fixups
.recordArrayType(lastFieldType
)
706 case TagConstType
, TagVolatileType
, TagRestrictType
:
707 // Type modifier (DWARF v2 §5.2)
713 if t
.Type
= typeOf(e
); err
!= nil {
719 case TagRestrictType
:
721 case TagVolatileType
:
725 case TagEnumerationType
:
726 // Enumeration type (DWARF v2 §5.6)
728 // AttrName: enum name if any
729 // AttrByteSize: bytes required to represent largest value
732 // AttrName: name of constant
733 // AttrConstValue: value of constant
737 t
.EnumName
, _
= e
.Val(AttrName
).(string)
738 t
.Val
= make([]*EnumValue
, 0, 8)
739 for kid
:= next(); kid
!= nil; kid
= next() {
740 if kid
.Tag
== TagEnumerator
{
742 f
.Name
, _
= kid
.Val(AttrName
).(string)
743 f
.Val
, _
= kid
.Val(AttrConstValue
).(int64)
746 val
:= make([]*EnumValue
, n
, n
*2)
750 t
.Val
= t
.Val
[0 : n
+1]
756 // Type modifier (DWARF v2 §5.2)
758 // AttrType: subtype [not required! void* has no AttrType]
759 // AttrAddrClass: address class [ignored]
763 if e
.Val(AttrType
) == nil {
769 case TagSubroutineType
:
770 // Subroutine type. (DWARF v2 §5.7)
772 // AttrType: type of return value if any
773 // AttrName: possible name of type [ignored]
774 // AttrPrototyped: whether used ANSI C prototype [ignored]
776 // TagFormalParameter: typed parameter
777 // AttrType: type of parameter
778 // TagUnspecifiedParameter: final ...
782 if t
.ReturnType
= typeOf(e
); err
!= nil {
785 t
.ParamType
= make([]Type
, 0, 8)
786 for kid
:= next(); kid
!= nil; kid
= next() {
791 case TagFormalParameter
:
792 if tkid
= typeOf(kid
); err
!= nil {
795 case TagUnspecifiedParameters
:
796 tkid
= &DotDotDotType
{}
798 t
.ParamType
= append(t
.ParamType
, tkid
)
802 // Typedef (DWARF v2 §5.3)
804 // AttrName: name [required]
805 // AttrType: type definition [required]
806 t
:= new(TypedefType
)
809 t
.Name
, _
= e
.Val(AttrName
).(string)
812 case TagUnspecifiedType
:
813 // Unspecified type (DWARF v3 §5.2)
816 t
:= new(UnspecifiedType
)
819 t
.Name
, _
= e
.Val(AttrName
).(string)
822 // This is some other type DIE that we're currently not
823 // equipped to handle. Return an abstract "unsupported type"
824 // object in such cases.
825 t
:= new(UnsupportedType
)
829 t
.Name
, _
= e
.Val(AttrName
).(string)
837 b
, ok
:= e
.Val(AttrByteSize
).(int64)
840 switch t
:= typ
.(type) {
842 // Record that we need to resolve this
843 // type's size once the type graph is
845 fixups
.typedefs
= append(fixups
.typedefs
, t
)
847 b
= int64(addressSize
)
850 typ
.Common().ByteSize
= b
855 // If the parse fails, take the type out of the cache
856 // so that the next call with this offset doesn't hit
857 // the cache and return success.
858 delete(typeCache
, off
)
862 func zeroArray(t
*Type
) {
863 at
:= (*t
).(*ArrayType
)
864 if at
.Type
.Size() == 0 {
867 // Make a copy to avoid invalidating typeCache.