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.
4 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.
8 9 package dwarf
10 11 import "strconv"
12 13 // A Type conventionally represents a pointer to any of the
14 // specific Type structures ([CharType], [StructType], etc.).
15 type Type interface {
16 Common() *CommonType
17 String() string
18 Size() int64
19 }
20 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
27 }
28 29 func (c *CommonType) Common() *CommonType { return c }
30 31 func (c *CommonType) Size() int64 { return c.ByteSize }
32 33 // Basic types
34 35 // A BasicType holds fields common to all basic types.
36 //
37 // See the documentation for [StructField] for more info on the interpretation of
38 // the BitSize/BitOffset/DataBitOffset fields.
39 type BasicType struct {
40 CommonType
41 BitSize int64
42 BitOffset int64
43 DataBitOffset int64
44 }
45 46 func (b *BasicType) Basic() *BasicType { return b }
47 48 func (t *BasicType) String() string {
49 if t.Name != "" {
50 return t.Name
51 }
52 return "?"
53 }
54 55 // A CharType represents a signed character type.
56 type CharType struct {
57 BasicType
58 }
59 60 // A UcharType represents an unsigned character type.
61 type UcharType struct {
62 BasicType
63 }
64 65 // An IntType represents a signed integer type.
66 type IntType struct {
67 BasicType
68 }
69 70 // A UintType represents an unsigned integer type.
71 type UintType struct {
72 BasicType
73 }
74 75 // A FloatType represents a floating point type.
76 type FloatType struct {
77 BasicType
78 }
79 80 // A ComplexType represents a complex floating point type.
81 type ComplexType struct {
82 BasicType
83 }
84 85 // A BoolType represents a boolean type.
86 type BoolType struct {
87 BasicType
88 }
89 90 // An AddrType represents a machine address type.
91 type AddrType struct {
92 BasicType
93 }
94 95 // An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type.
96 type UnspecifiedType struct {
97 BasicType
98 }
99 100 // qualifiers
101 102 // A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
103 type QualType struct {
104 CommonType
105 Qual string
106 Type Type
107 }
108 109 func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
110 111 func (t *QualType) Size() int64 { return t.Type.Size() }
112 113 // An ArrayType represents a fixed size array type.
114 type ArrayType struct {
115 CommonType
116 Type Type
117 StrideBitSize int64 // if > 0, number of bits to hold each element
118 Count int64 // if == -1, an incomplete array, like char x[].
119 }
120 121 func (t *ArrayType) String() string {
122 return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
123 }
124 125 func (t *ArrayType) Size() int64 {
126 if t.Count == -1 {
127 return 0
128 }
129 return t.Count * t.Type.Size()
130 }
131 132 // A VoidType represents the C void type.
133 type VoidType struct {
134 CommonType
135 }
136 137 func (t *VoidType) String() string { return "void" }
138 139 // A PtrType represents a pointer type.
140 type PtrType struct {
141 CommonType
142 Type Type
143 }
144 145 func (t *PtrType) String() string { return "*" + t.Type.String() }
146 147 // A StructType represents a struct, union, or C++ class type.
148 type StructType struct {
149 CommonType
150 StructName string
151 Kind string // "struct", "union", or "class".
152 Field []*StructField
153 Incomplete bool // if true, struct, union, class is declared but not defined
154 }
155 156 // A StructField represents a field in a struct, union, or C++ class type.
157 //
158 // # Bit Fields
159 //
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.
163 //
164 // BitSize is the number of bits in the bit field.
165 //
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.
170 //
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.
179 //
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.
184 //
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:
187 //
188 // struct S {
189 // int q;
190 // int j:5;
191 // int k:6;
192 // int m:5;
193 // int n:8;
194 // } s;
195 //
196 // For the code above, one would expect to see the following for
197 // DW_AT_bit_offset values (using GCC 8):
198 //
199 // Little | Big
200 // Endian | Endian
201 // |
202 // "j": 27 | 0
203 // "k": 21 | 5
204 // "m": 16 | 11
205 // "n": 8 | 16
206 //
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.
210 //
211 // If the compiler emits DW_AT_data_bit_offset, the expected values
212 // would be:
213 //
214 // "j": 32
215 // "k": 37
216 // "m": 43
217 // "n": 48
218 //
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
223 // many fields.
224 //
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.
229 type StructField struct {
230 Name string
231 Type Type
232 ByteOffset int64
233 ByteSize int64 // usually zero; use Type.Size() for normal fields
234 BitOffset int64
235 DataBitOffset int64
236 BitSize int64 // zero if not a bit field
237 }
238 239 func (t *StructType) String() string {
240 if t.StructName != "" {
241 return t.Kind + " " + t.StructName
242 }
243 return t.Defn()
244 }
245 246 func (f *StructField) bitOffset() int64 {
247 if f.BitOffset != 0 {
248 return f.BitOffset
249 }
250 return f.DataBitOffset
251 }
252 253 func (t *StructType) Defn() string {
254 s := t.Kind
255 if t.StructName != "" {
256 s += " " + t.StructName
257 }
258 if t.Incomplete {
259 s += " /*incomplete*/"
260 return s
261 }
262 s += " {"
263 for i, f := range t.Field {
264 if i > 0 {
265 s += "; "
266 }
267 s += f.Name + " " + f.Type.String()
268 s += "@" + strconv.FormatInt(f.ByteOffset, 10)
269 if f.BitSize > 0 {
270 s += " : " + strconv.FormatInt(f.BitSize, 10)
271 s += "@" + strconv.FormatInt(f.bitOffset(), 10)
272 }
273 }
274 s += "}"
275 return s
276 }
277 278 // An EnumType represents an enumerated type.
279 // The only indication of its native integer type is its ByteSize
280 // (inside [CommonType]).
281 type EnumType struct {
282 CommonType
283 EnumName string
284 Val []*EnumValue
285 }
286 287 // An EnumValue represents a single enumeration value.
288 type EnumValue struct {
289 Name string
290 Val int64
291 }
292 293 func (t *EnumType) String() string {
294 s := "enum"
295 if t.EnumName != "" {
296 s += " " + t.EnumName
297 }
298 s += " {"
299 for i, v := range t.Val {
300 if i > 0 {
301 s += "; "
302 }
303 s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
304 }
305 s += "}"
306 return s
307 }
308 309 // A FuncType represents a function type.
310 type FuncType struct {
311 CommonType
312 ReturnType Type
313 ParamType []Type
314 }
315 316 func (t *FuncType) String() string {
317 s := "func("
318 for i, t := range t.ParamType {
319 if i > 0 {
320 s += ", "
321 }
322 s += t.String()
323 }
324 s += ")"
325 if t.ReturnType != nil {
326 s += " " + t.ReturnType.String()
327 }
328 return s
329 }
330 331 // A DotDotDotType represents the variadic ... function parameter.
332 type DotDotDotType struct {
333 CommonType
334 }
335 336 func (t *DotDotDotType) String() string { return "..." }
337 338 // A TypedefType represents a named type.
339 type TypedefType struct {
340 CommonType
341 Type Type
342 }
343 344 func (t *TypedefType) String() string { return t.Name }
345 346 func (t *TypedefType) Size() int64 { return t.Type.Size() }
347 348 // An UnsupportedType is a placeholder returned in situations where we
349 // encounter a type that isn't supported.
350 type UnsupportedType struct {
351 CommonType
352 Tag Tag
353 }
354 355 func (t *UnsupportedType) String() string {
356 if t.Name != "" {
357 return t.Name
358 }
359 return t.Name + "(unsupported type " + t.Tag.String() + ")"
360 }
361 362 // typeReader is used to read from either the info section or the
363 // types section.
364 type typeReader interface {
365 Seek(Offset)
366 Next() (*Entry, error)
367 clone() typeReader
368 offset() Offset
369 // AddressSize returns the size in bytes of addresses in the current
370 // compilation unit.
371 AddressSize() int
372 }
373 374 // Type reads the type at off in the DWARF “info” section.
375 func (d *Data) Type(off Offset) (Type, error) {
376 return d.readType("info", d.Reader(), off, d.typeCache, nil)
377 }
378 379 type typeFixer struct {
380 typedefs []*TypedefType
381 arraytypes []*Type
382 }
383 384 func (tf *typeFixer) recordArrayType(t *Type) {
385 if t == nil {
386 return
387 }
388 _, ok := (*t).(*ArrayType)
389 if ok {
390 tf.arraytypes = append(tf.arraytypes, t)
391 }
392 }
393 394 func (tf *typeFixer) apply() {
395 for _, t := range tf.typedefs {
396 t.Common().ByteSize = t.Type.Size()
397 }
398 for _, t := range tf.arraytypes {
399 zeroArray(t)
400 }
401 }
402 403 // readType reads a type from r at off of name. It adds types to the
404 // type cache, appends new typedef types to typedefs, and computes the
405 // sizes of types. Callers should pass nil for typedefs; this is used
406 // for internal recursion.
407 func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, fixups *typeFixer) (Type, error) {
408 if t, ok := typeCache[off]; ok {
409 return t, nil
410 }
411 r.Seek(off)
412 e, err := r.Next()
413 if err != nil {
414 return nil, err
415 }
416 addressSize := r.AddressSize()
417 if e == nil || e.Offset != off {
418 return nil, DecodeError{name, off, "no type at offset"}
419 }
420 421 // If this is the root of the recursion, prepare to resolve
422 // typedef sizes and perform other fixups once the recursion is
423 // done. This must be done after the type graph is constructed
424 // because it may need to resolve cycles in a different order than
425 // readType encounters them.
426 if fixups == nil {
427 var fixer typeFixer
428 defer func() {
429 fixer.apply()
430 }()
431 fixups = &fixer
432 }
433 434 // Parse type from Entry.
435 // Must always set typeCache[off] before calling
436 // d.readType recursively, to handle circular types correctly.
437 var typ Type
438 439 nextDepth := 0
440 441 // Get next child; set err if error happens.
442 next := func() *Entry {
443 if !e.Children {
444 return nil
445 }
446 // Only return direct children.
447 // Skip over composite entries that happen to be nested
448 // inside this one. Most DWARF generators wouldn't generate
449 // such a thing, but clang does.
450 // See golang.org/issue/6472.
451 for {
452 kid, err1 := r.Next()
453 if err1 != nil {
454 err = err1
455 return nil
456 }
457 if kid == nil {
458 err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
459 return nil
460 }
461 if kid.Tag == 0 {
462 if nextDepth > 0 {
463 nextDepth--
464 continue
465 }
466 return nil
467 }
468 if kid.Children {
469 nextDepth++
470 }
471 if nextDepth > 0 {
472 continue
473 }
474 return kid
475 }
476 }
477 478 // Get Type referred to by Entry's AttrType field.
479 // Set err if error happens. Not having a type is an error.
480 typeOf := func(e *Entry) Type {
481 tval := e.Val(AttrType)
482 var t Type
483 switch toff := tval.(type) {
484 case Offset:
485 if t, err = d.readType(name, r.clone(), toff, typeCache, fixups); err != nil {
486 return nil
487 }
488 case uint64:
489 if t, err = d.sigToType(toff); err != nil {
490 return nil
491 }
492 default:
493 // It appears that no Type means "void".
494 return &VoidType{}
495 }
496 return t
497 }
498 499 switch e.Tag {
500 case TagArrayType:
501 // Multi-dimensional array. (DWARF v2 §5.4)
502 // Attributes:
503 // AttrType:subtype [required]
504 // AttrStrideSize: size in bits of each element of the array
505 // AttrByteSize: size of entire array
506 // Children:
507 // TagSubrangeType or TagEnumerationType giving one dimension.
508 // dimensions are in left to right order.
509 t := &ArrayType{}
510 typ = t
511 typeCache[off] = t
512 if t.Type = typeOf(e); err != nil {
513 goto Error
514 }
515 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
516 517 // Accumulate dimensions,
518 var dims []int64
519 for kid := next(); kid != nil; kid = next() {
520 // TODO(rsc): Can also be TagEnumerationType
521 // but haven't seen that in the wild yet.
522 switch kid.Tag {
523 case TagSubrangeType:
524 count, ok := kid.Val(AttrCount).(int64)
525 if !ok {
526 // Old binaries may have an upper bound instead.
527 count, ok = kid.Val(AttrUpperBound).(int64)
528 if ok {
529 count++ // Length is one more than upper bound.
530 } else if len(dims) == 0 {
531 count = -1 // As in x[].
532 }
533 }
534 dims = append(dims, count)
535 case TagEnumerationType:
536 err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
537 goto Error
538 }
539 }
540 if len(dims) == 0 {
541 // LLVM generates this for x[].
542 dims = []int64{-1}
543 }
544 545 t.Count = dims[0]
546 for i := len(dims) - 1; i >= 1; i-- {
547 t.Type = &ArrayType{Type: t.Type, Count: dims[i]}
548 }
549 550 case TagBaseType:
551 // Basic type. (DWARF v2 §5.1)
552 // Attributes:
553 // AttrName: name of base type in programming language of the compilation unit [required]
554 // AttrEncoding: encoding value for type (encFloat etc) [required]
555 // AttrByteSize: size of type in bytes [required]
556 // AttrBitOffset: bit offset of value within containing storage unit
557 // AttrDataBitOffset: bit offset of value within containing storage unit
558 // AttrBitSize: size in bits
559 //
560 // For most languages BitOffset/DataBitOffset/BitSize will not be present
561 // for base types.
562 name, _ := e.Val(AttrName).(string)
563 enc, ok := e.Val(AttrEncoding).(int64)
564 if !ok {
565 err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
566 goto Error
567 }
568 switch enc {
569 default:
570 err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
571 goto Error
572 573 case encAddress:
574 typ = &AddrType{}
575 case encBoolean:
576 typ = &BoolType{}
577 case encComplexFloat:
578 typ = &ComplexType{}
579 if name == "complex" {
580 // clang writes out 'complex' instead of 'complex float' or 'complex double'.
581 // clang also writes out a byte size that we can use to distinguish.
582 // See issue 8694.
583 switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
584 case 8:
585 name = "complex float"
586 case 16:
587 name = "complex double"
588 }
589 }
590 case encFloat:
591 typ = &FloatType{}
592 case encSigned:
593 typ = &IntType{}
594 case encUnsigned:
595 typ = &UintType{}
596 case encSignedChar:
597 typ = &CharType{}
598 case encUnsignedChar:
599 typ = &UcharType{}
600 }
601 typeCache[off] = typ
602 t := typ.(interface {
603 Basic() *BasicType
604 }).Basic()
605 t.Name = name
606 t.BitSize, _ = e.Val(AttrBitSize).(int64)
607 haveBitOffset := false
608 haveDataBitOffset := false
609 t.BitOffset, haveBitOffset = e.Val(AttrBitOffset).(int64)
610 t.DataBitOffset, haveDataBitOffset = e.Val(AttrDataBitOffset).(int64)
611 if haveBitOffset && haveDataBitOffset {
612 err = DecodeError{name, e.Offset, "duplicate bit offset attributes"}
613 goto Error
614 }
615 616 case TagClassType, TagStructType, TagUnionType:
617 // Structure, union, or class type. (DWARF v2 §5.5)
618 // Attributes:
619 // AttrName: name of struct, union, or class
620 // AttrByteSize: byte size [required]
621 // AttrDeclaration: if true, struct/union/class is incomplete
622 // Children:
623 // TagMember to describe one member.
624 // AttrName: name of member [required]
625 // AttrType: type of member [required]
626 // AttrByteSize: size in bytes
627 // AttrBitOffset: bit offset within bytes for bit fields
628 // AttrDataBitOffset: field bit offset relative to struct start
629 // AttrBitSize: bit size for bit fields
630 // AttrDataMemberLoc: location within struct [required for struct, class]
631 // There is much more to handle C++, all ignored for now.
632 t := &StructType{}
633 typ = t
634 typeCache[off] = t
635 switch e.Tag {
636 case TagClassType:
637 t.Kind = "class"
638 case TagStructType:
639 t.Kind = "struct"
640 case TagUnionType:
641 t.Kind = "union"
642 }
643 t.StructName, _ = e.Val(AttrName).(string)
644 t.Incomplete = e.Val(AttrDeclaration) != nil
645 t.Field = []*StructField{:0:8}
646 var lastFieldType *Type
647 var lastFieldBitSize int64
648 var lastFieldByteOffset int64
649 for kid := next(); kid != nil; kid = next() {
650 if kid.Tag != TagMember {
651 continue
652 }
653 f := &StructField{}
654 if f.Type = typeOf(kid); err != nil {
655 goto Error
656 }
657 switch loc := kid.Val(AttrDataMemberLoc).(type) {
658 case []byte:
659 // TODO: Should have original compilation
660 // unit here, not unknownFormat.
661 b := makeBuf(d, unknownFormat{}, "location", 0, loc)
662 if b.uint8() != opPlusUconst {
663 err = DecodeError{name, kid.Offset, "unexpected opcode"}
664 goto Error
665 }
666 f.ByteOffset = int64(b.uint())
667 if b.err != nil {
668 err = b.err
669 goto Error
670 }
671 case int64:
672 f.ByteOffset = loc
673 }
674 675 f.Name, _ = kid.Val(AttrName).(string)
676 f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
677 haveBitOffset := false
678 haveDataBitOffset := false
679 f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
680 f.DataBitOffset, haveDataBitOffset = kid.Val(AttrDataBitOffset).(int64)
681 if haveBitOffset && haveDataBitOffset {
682 err = DecodeError{name, e.Offset, "duplicate bit offset attributes"}
683 goto Error
684 }
685 f.BitSize, _ = kid.Val(AttrBitSize).(int64)
686 t.Field = append(t.Field, f)
687 688 if lastFieldBitSize == 0 && lastFieldByteOffset == f.ByteOffset && t.Kind != "union" {
689 // Last field was zero width. Fix array length.
690 // (DWARF writes out 0-length arrays as if they were 1-length arrays.)
691 fixups.recordArrayType(lastFieldType)
692 }
693 lastFieldType = &f.Type
694 lastFieldByteOffset = f.ByteOffset
695 lastFieldBitSize = f.BitSize
696 }
697 if t.Kind != "union" {
698 b, ok := e.Val(AttrByteSize).(int64)
699 if ok && b == lastFieldByteOffset {
700 // Final field must be zero width. Fix array length.
701 fixups.recordArrayType(lastFieldType)
702 }
703 }
704 705 case TagConstType, TagVolatileType, TagRestrictType:
706 // Type modifier (DWARF v2 §5.2)
707 // Attributes:
708 // AttrType: subtype
709 t := &QualType{}
710 typ = t
711 typeCache[off] = t
712 if t.Type = typeOf(e); err != nil {
713 goto Error
714 }
715 switch e.Tag {
716 case TagConstType:
717 t.Qual = "const"
718 case TagRestrictType:
719 t.Qual = "restrict"
720 case TagVolatileType:
721 t.Qual = "volatile"
722 }
723 724 case TagEnumerationType:
725 // Enumeration type (DWARF v2 §5.6)
726 // Attributes:
727 // AttrName: enum name if any
728 // AttrByteSize: bytes required to represent largest value
729 // Children:
730 // TagEnumerator:
731 // AttrName: name of constant
732 // AttrConstValue: value of constant
733 t := &EnumType{}
734 typ = t
735 typeCache[off] = t
736 t.EnumName, _ = e.Val(AttrName).(string)
737 t.Val = []*EnumValue{:0:8}
738 for kid := next(); kid != nil; kid = next() {
739 if kid.Tag == TagEnumerator {
740 f := &EnumValue{}
741 f.Name, _ = kid.Val(AttrName).(string)
742 f.Val, _ = kid.Val(AttrConstValue).(int64)
743 n := len(t.Val)
744 if n >= cap(t.Val) {
745 val := []*EnumValue{:n:n*2}
746 copy(val, t.Val)
747 t.Val = val
748 }
749 t.Val = t.Val[0 : n+1]
750 t.Val[n] = f
751 }
752 }
753 754 case TagPointerType:
755 // Type modifier (DWARF v2 §5.2)
756 // Attributes:
757 // AttrType: subtype [not required! void* has no AttrType]
758 // AttrAddrClass: address class [ignored]
759 t := &PtrType{}
760 typ = t
761 typeCache[off] = t
762 if e.Val(AttrType) == nil {
763 t.Type = &VoidType{}
764 break
765 }
766 t.Type = typeOf(e)
767 768 case TagSubroutineType:
769 // Subroutine type. (DWARF v2 §5.7)
770 // Attributes:
771 // AttrType: type of return value if any
772 // AttrName: possible name of type [ignored]
773 // AttrPrototyped: whether used ANSI C prototype [ignored]
774 // Children:
775 // TagFormalParameter: typed parameter
776 // AttrType: type of parameter
777 // TagUnspecifiedParameter: final ...
778 t := &FuncType{}
779 typ = t
780 typeCache[off] = t
781 if t.ReturnType = typeOf(e); err != nil {
782 goto Error
783 }
784 t.ParamType = []Type{:0:8}
785 for kid := next(); kid != nil; kid = next() {
786 var tkid Type
787 switch kid.Tag {
788 default:
789 continue
790 case TagFormalParameter:
791 if tkid = typeOf(kid); err != nil {
792 goto Error
793 }
794 case TagUnspecifiedParameters:
795 tkid = &DotDotDotType{}
796 }
797 t.ParamType = append(t.ParamType, tkid)
798 }
799 800 case TagTypedef:
801 // Typedef (DWARF v2 §5.3)
802 // Attributes:
803 // AttrName: name [required]
804 // AttrType: type definition [required]
805 t := &TypedefType{}
806 typ = t
807 typeCache[off] = t
808 t.Name, _ = e.Val(AttrName).(string)
809 t.Type = typeOf(e)
810 811 case TagUnspecifiedType:
812 // Unspecified type (DWARF v3 §5.2)
813 // Attributes:
814 // AttrName: name
815 t := &UnspecifiedType{}
816 typ = t
817 typeCache[off] = t
818 t.Name, _ = e.Val(AttrName).(string)
819 820 default:
821 // This is some other type DIE that we're currently not
822 // equipped to handle. Return an abstract "unsupported type"
823 // object in such cases.
824 t := &UnsupportedType{}
825 typ = t
826 typeCache[off] = t
827 t.Tag = e.Tag
828 t.Name, _ = e.Val(AttrName).(string)
829 }
830 831 if err != nil {
832 goto Error
833 }
834 835 {
836 b, ok := e.Val(AttrByteSize).(int64)
837 if !ok {
838 b = -1
839 switch t := typ.(type) {
840 case *TypedefType:
841 // Record that we need to resolve this
842 // type's size once the type graph is
843 // constructed.
844 fixups.typedefs = append(fixups.typedefs, t)
845 case *PtrType:
846 b = int64(addressSize)
847 }
848 }
849 typ.Common().ByteSize = b
850 }
851 return typ, nil
852 853 Error:
854 // If the parse fails, take the type out of the cache
855 // so that the next call with this offset doesn't hit
856 // the cache and return success.
857 delete(typeCache, off)
858 return nil, err
859 }
860 861 func zeroArray(t *Type) {
862 at := (*t).(*ArrayType)
863 if at.Type.Size() == 0 {
864 return
865 }
866 // Make a copy to avoid invalidating typeCache.
867 tt := *at
868 tt.Count = 0
869 *t = &tt
870 }
871