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