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