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 9package dwarf 10 11import "strconv" 12 13// A Type conventionally represents a pointer to any of the 14// specific Type structures ([CharType], [StructType], etc.). 15type 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. 24type 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 29func (c *CommonType) Common() *CommonType { return c } 30 31func (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. 39type BasicType struct { 40 CommonType 41 BitSize int64 42 BitOffset int64 43 DataBitOffset int64 44} 45 46func (b *BasicType) Basic() *BasicType { return b } 47 48func (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. 56type CharType struct { 57 BasicType 58} 59 60// A UcharType represents an unsigned character type. 61type UcharType struct { 62 BasicType 63} 64 65// An IntType represents a signed integer type. 66type IntType struct { 67 BasicType 68} 69 70// A UintType represents an unsigned integer type. 71type UintType struct { 72 BasicType 73} 74 75// A FloatType represents a floating point type. 76type FloatType struct { 77 BasicType 78} 79 80// A ComplexType represents a complex floating point type. 81type ComplexType struct { 82 BasicType 83} 84 85// A BoolType represents a boolean type. 86type BoolType struct { 87 BasicType 88} 89 90// An AddrType represents a machine address type. 91type AddrType struct { 92 BasicType 93} 94 95// An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type. 96type 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. 103type QualType struct { 104 CommonType 105 Qual string 106 Type Type 107} 108 109func (t *QualType) String() string { return t.Qual + " " + t.Type.String() } 110 111func (t *QualType) Size() int64 { return t.Type.Size() } 112 113// An ArrayType represents a fixed size array type. 114type 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 121func (t *ArrayType) String() string { 122 return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String() 123} 124 125func (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. 133type VoidType struct { 134 CommonType 135} 136 137func (t *VoidType) String() string { return "void" } 138 139// A PtrType represents a pointer type. 140type PtrType struct { 141 CommonType 142 Type Type 143} 144 145func (t *PtrType) String() string { return "*" + t.Type.String() } 146 147// A StructType represents a struct, union, or C++ class type. 148type 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. 229type 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 239func (t *StructType) String() string { 240 if t.StructName != "" { 241 return t.Kind + " " + t.StructName 242 } 243 return t.Defn() 244} 245 246func (f *StructField) bitOffset() int64 { 247 if f.BitOffset != 0 { 248 return f.BitOffset 249 } 250 return f.DataBitOffset 251} 252 253func (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]). 281type EnumType struct { 282 CommonType 283 EnumName string 284 Val []*EnumValue 285} 286 287// An EnumValue represents a single enumeration value. 288type EnumValue struct { 289 Name string 290 Val int64 291} 292 293func (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. 310type FuncType struct { 311 CommonType 312 ReturnType Type 313 ParamType []Type 314} 315 316func (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. 332type DotDotDotType struct { 333 CommonType 334} 335 336func (t *DotDotDotType) String() string { return "..." } 337 338// A TypedefType represents a named type. 339type TypedefType struct { 340 CommonType 341 Type Type 342} 343 344func (t *TypedefType) String() string { return t.Name } 345 346func (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. 350type UnsupportedType struct { 351 CommonType 352 Tag Tag 353} 354 355func (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. 364type 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. 375func (d *Data) Type(off Offset) (Type, error) { 376 return d.readType("info", d.Reader(), off, d.typeCache, nil) 377} 378 379type typeFixer struct { 380 typedefs []*TypedefType 381 arraytypes []*Type 382} 383 384func (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 394func (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. 407func (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 853Error: 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 861func 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