github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/debug/dwarf/type.go (about) 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 new(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 := new(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 = new(AddrType) 575 case encBoolean: 576 typ = new(BoolType) 577 case encComplexFloat: 578 typ = new(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 = new(FloatType) 592 case encSigned: 593 typ = new(IntType) 594 case encUnsigned: 595 typ = new(UintType) 596 case encSignedChar: 597 typ = new(CharType) 598 case encUnsignedChar: 599 typ = new(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 := new(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 = make([]*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 := new(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 := new(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 := new(EnumType) 734 typ = t 735 typeCache[off] = t 736 t.EnumName, _ = e.Val(AttrName).(string) 737 t.Val = make([]*EnumValue, 0, 8) 738 for kid := next(); kid != nil; kid = next() { 739 if kid.Tag == TagEnumerator { 740 f := new(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 := make([]*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 := new(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 := new(FuncType) 779 typ = t 780 typeCache[off] = t 781 if t.ReturnType = typeOf(e); err != nil { 782 goto Error 783 } 784 t.ParamType = make([]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 := new(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 := new(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 := new(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 }