gitlab.com/Raven-IO/raven-delve@v1.22.4/pkg/dwarf/godwarf/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 // Borrowed from golang.org/x/debug/dwarf/type.go 10 11 package godwarf 12 13 import ( 14 "debug/dwarf" 15 "fmt" 16 "reflect" 17 "strconv" 18 19 "gitlab.com/Raven-IO/raven-delve/pkg/dwarf/op" 20 ) 21 22 const ( 23 AttrGoKind dwarf.Attr = 0x2900 24 AttrGoKey dwarf.Attr = 0x2901 25 AttrGoElem dwarf.Attr = 0x2902 26 AttrGoEmbeddedField dwarf.Attr = 0x2903 27 AttrGoRuntimeType dwarf.Attr = 0x2904 28 AttrGoPackageName dwarf.Attr = 0x2905 29 AttrGoDictIndex dwarf.Attr = 0x2906 30 AttrGoClosureOffset dwarf.Attr = 0x2907 31 ) 32 33 // Basic type encodings -- the value for AttrEncoding in a TagBaseType Entry. 34 const ( 35 encAddress = 0x01 36 encBoolean = 0x02 37 encComplexFloat = 0x03 38 encFloat = 0x04 39 encSigned = 0x05 40 encSignedChar = 0x06 41 encUnsigned = 0x07 42 encUnsignedChar = 0x08 43 encImaginaryFloat = 0x09 44 ) 45 46 const cyclicalTypeStop = "<cyclical>" // guard value printed for types with a cyclical definition, to avoid infinite recursion in Type.String 47 48 type recCheck map[dwarf.Offset]struct{} 49 50 func (recCheck recCheck) acquire(off dwarf.Offset) (release func()) { 51 if _, rec := recCheck[off]; rec { 52 return nil 53 } 54 recCheck[off] = struct{}{} 55 return func() { 56 delete(recCheck, off) 57 } 58 } 59 60 func sizeAlignToSize(sz, align int64) int64 { 61 return sz 62 } 63 64 func sizeAlignToAlign(sz, align int64) int64 { 65 return align 66 } 67 68 // A Type conventionally represents a pointer to any of the 69 // specific Type structures (CharType, StructType, etc.). 70 type Type interface { 71 Common() *CommonType 72 String() string 73 Size() int64 74 Align() int64 75 76 stringIntl(recCheck) string 77 sizeAlignIntl(recCheck) (int64, int64) 78 } 79 80 // A CommonType holds fields common to multiple types. 81 // If a field is not known or not applicable for a given type, 82 // the zero value is used. 83 type CommonType struct { 84 Index int // index supplied by caller of ReadType 85 ByteSize int64 // size of value of this type, in bytes 86 Name string // name that can be used to refer to type 87 ReflectKind reflect.Kind // the reflect kind of the type. 88 Offset dwarf.Offset // the offset at which this type was read 89 } 90 91 func (c *CommonType) Common() *CommonType { return c } 92 93 func (c *CommonType) Size() int64 { return c.ByteSize } 94 func (c *CommonType) Align() int64 { return c.ByteSize } 95 func (c *CommonType) sizeAlignIntl(recCheck) (int64, int64) { return c.ByteSize, c.ByteSize } 96 97 // Basic types 98 99 // A BasicType holds fields common to all basic types. 100 type BasicType struct { 101 CommonType 102 BitSize int64 103 BitOffset int64 104 } 105 106 func (t *BasicType) Basic() *BasicType { return t } 107 108 func (t *BasicType) String() string { return t.stringIntl(nil) } 109 110 func (t *BasicType) stringIntl(recCheck) string { 111 if t.Name != "" { 112 return t.Name 113 } 114 return "?" 115 } 116 117 func (t *BasicType) Align() int64 { return t.CommonType.ByteSize } 118 119 // A CharType represents a signed character type. 120 type CharType struct { 121 BasicType 122 } 123 124 // A UcharType represents an unsigned character type. 125 type UcharType struct { 126 BasicType 127 } 128 129 // An IntType represents a signed integer type. 130 type IntType struct { 131 BasicType 132 } 133 134 // A UintType represents an unsigned integer type. 135 type UintType struct { 136 BasicType 137 } 138 139 // A FloatType represents a floating point type. 140 type FloatType struct { 141 BasicType 142 } 143 144 // A ComplexType represents a complex floating point type. 145 type ComplexType struct { 146 BasicType 147 } 148 149 // A BoolType represents a boolean type. 150 type BoolType struct { 151 BasicType 152 } 153 154 // An AddrType represents a machine address type. 155 type AddrType struct { 156 BasicType 157 } 158 159 // An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type. 160 type UnspecifiedType struct { 161 BasicType 162 } 163 164 // qualifiers 165 166 // A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier. 167 type QualType struct { 168 CommonType 169 Qual string 170 Type Type 171 } 172 173 func (t *QualType) String() string { return t.stringIntl(make(recCheck)) } 174 175 func (t *QualType) stringIntl(recCheck recCheck) string { 176 release := recCheck.acquire(t.CommonType.Offset) 177 if release == nil { 178 return cyclicalTypeStop 179 } 180 defer release() 181 return t.Qual + " " + t.Type.stringIntl(recCheck) 182 } 183 184 func (t *QualType) Size() int64 { return sizeAlignToSize(t.sizeAlignIntl(make(recCheck))) } 185 func (t *QualType) Align() int64 { return sizeAlignToAlign(t.sizeAlignIntl(make(recCheck))) } 186 187 func (t *QualType) sizeAlignIntl(recCheck recCheck) (int64, int64) { 188 release := recCheck.acquire(t.CommonType.Offset) 189 if release == nil { 190 return t.CommonType.ByteSize, t.CommonType.ByteSize 191 } 192 defer release() 193 return t.Type.sizeAlignIntl(recCheck) 194 } 195 196 // An ArrayType represents a fixed size array type. 197 type ArrayType struct { 198 CommonType 199 Type Type 200 StrideBitSize int64 // if > 0, number of bits to hold each element 201 Count int64 // if == -1, an incomplete array, like char x[]. 202 } 203 204 func (t *ArrayType) String() string { return t.stringIntl(make(recCheck)) } 205 206 func (t *ArrayType) stringIntl(recCheck recCheck) string { 207 release := recCheck.acquire(t.CommonType.Offset) 208 if release == nil { 209 return cyclicalTypeStop 210 } 211 defer release() 212 return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.stringIntl(recCheck) 213 } 214 215 func (t *ArrayType) Size() int64 { return sizeAlignToSize(t.sizeAlignIntl(make(recCheck))) } 216 func (t *ArrayType) Align() int64 { return sizeAlignToAlign(t.sizeAlignIntl(make(recCheck))) } 217 218 func (t *ArrayType) sizeAlignIntl(recCheck recCheck) (int64, int64) { 219 release := recCheck.acquire(t.CommonType.Offset) 220 if release == nil { 221 return t.CommonType.ByteSize, 1 222 } 223 defer release() 224 sz, align := t.Type.sizeAlignIntl(recCheck) 225 if t.CommonType.ByteSize != 0 { 226 return t.CommonType.ByteSize, align 227 } 228 return sz * t.Count, align 229 } 230 231 // A VoidType represents the C void type. 232 type VoidType struct { 233 CommonType 234 } 235 236 func (t *VoidType) String() string { return t.stringIntl(nil) } 237 238 func (t *VoidType) stringIntl(recCheck) string { return "void" } 239 240 // A PtrType represents a pointer type. 241 type PtrType struct { 242 CommonType 243 Type Type 244 } 245 246 func (t *PtrType) String() string { return t.stringIntl(make(recCheck)) } 247 248 func (t *PtrType) stringIntl(recCheck recCheck) string { 249 release := recCheck.acquire(t.CommonType.Offset) 250 if release == nil { 251 return cyclicalTypeStop 252 } 253 defer release() 254 return "*" + t.Type.stringIntl(recCheck) 255 } 256 257 // A StructType represents a struct, union, or C++ class type. 258 type StructType struct { 259 CommonType 260 StructName string 261 Kind string // "struct", "union", or "class". 262 Field []*StructField 263 Incomplete bool // if true, struct, union, class is declared but not defined 264 } 265 266 // A StructField represents a field in a struct, union, or C++ class type. 267 type StructField struct { 268 Name string 269 Type Type 270 ByteOffset int64 271 ByteSize int64 272 BitOffset int64 // within the ByteSize bytes at ByteOffset 273 BitSize int64 // zero if not a bit field 274 Embedded bool 275 } 276 277 func (t *StructType) String() string { return t.stringIntl(make(recCheck)) } 278 279 func (t *StructType) stringIntl(recCheck recCheck) string { 280 if t.StructName != "" { 281 return t.Kind + " " + t.StructName 282 } 283 return t.Defn(recCheck) 284 } 285 286 func (t *StructType) Defn(recCheck recCheck) string { 287 release := recCheck.acquire(t.CommonType.Offset) 288 if release == nil { 289 return cyclicalTypeStop 290 } 291 defer release() 292 s := t.Kind 293 if t.StructName != "" { 294 s += " " + t.StructName 295 } 296 if t.Incomplete { 297 s += " /*incomplete*/" 298 return s 299 } 300 s += " {" 301 for i, f := range t.Field { 302 if i > 0 { 303 s += "; " 304 } 305 s += f.Name + " " + f.Type.stringIntl(recCheck) 306 s += "@" + strconv.FormatInt(f.ByteOffset, 10) 307 if f.BitSize > 0 { 308 s += " : " + strconv.FormatInt(f.BitSize, 10) 309 s += "@" + strconv.FormatInt(f.BitOffset, 10) 310 } 311 } 312 s += "}" 313 return s 314 } 315 316 func (t *StructType) Size() int64 { return sizeAlignToSize(t.sizeAlignIntl(make(recCheck))) } 317 func (t *StructType) Align() int64 { return sizeAlignToAlign(t.sizeAlignIntl(make(recCheck))) } 318 319 func (t *StructType) sizeAlignIntl(recCheck recCheck) (int64, int64) { 320 release := recCheck.acquire(t.CommonType.Offset) 321 if release == nil { 322 return t.CommonType.ByteSize, 1 323 } 324 defer release() 325 if len(t.Field) == 0 { 326 return t.CommonType.ByteSize, 1 327 } 328 return t.CommonType.ByteSize, sizeAlignToAlign(t.Field[0].Type.sizeAlignIntl(recCheck)) 329 } 330 331 // A SliceType represents a Go slice type. It looks like a StructType, describing 332 // the runtime-internal structure, with extra fields. 333 type SliceType struct { 334 StructType 335 ElemType Type 336 } 337 338 func (t *SliceType) String() string { return t.stringIntl(make(recCheck)) } 339 340 func (t *SliceType) stringIntl(recCheck recCheck) string { 341 release := recCheck.acquire(t.CommonType.Offset) 342 if release == nil { 343 return cyclicalTypeStop 344 } 345 defer release() 346 if t.Name != "" { 347 return t.Name 348 } 349 return "[]" + t.ElemType.stringIntl(recCheck) 350 } 351 352 // A StringType represents a Go string type. It looks like a StructType, describing 353 // the runtime-internal structure, but we wrap it for neatness. 354 type StringType struct { 355 StructType 356 } 357 358 func (t *StringType) String() string { return t.stringIntl(nil) } 359 360 func (t *StringType) stringIntl(recCheck recCheck) string { 361 if t.Name != "" { 362 return t.Name 363 } 364 return "string" 365 } 366 367 // An InterfaceType represents a Go interface. 368 type InterfaceType struct { 369 TypedefType 370 } 371 372 func (t *InterfaceType) String() string { return t.stringIntl(nil) } 373 374 func (t *InterfaceType) stringIntl(recCheck recCheck) string { 375 if t.Name != "" { 376 return t.Name 377 } 378 return "Interface" 379 } 380 381 // An EnumType represents an enumerated type. 382 // The only indication of its native integer type is its ByteSize 383 // (inside CommonType). 384 type EnumType struct { 385 CommonType 386 EnumName string 387 Val []*EnumValue 388 } 389 390 // An EnumValue represents a single enumeration value. 391 type EnumValue struct { 392 Name string 393 Val int64 394 } 395 396 func (t *EnumType) String() string { return t.stringIntl(nil) } 397 398 func (t *EnumType) stringIntl(recCheck recCheck) string { 399 s := "enum" 400 if t.EnumName != "" { 401 s += " " + t.EnumName 402 } 403 s += " {" 404 for i, v := range t.Val { 405 if i > 0 { 406 s += "; " 407 } 408 s += v.Name + "=" + strconv.FormatInt(v.Val, 10) 409 } 410 s += "}" 411 return s 412 } 413 414 // A FuncType represents a function type. 415 type FuncType struct { 416 CommonType 417 ReturnType Type 418 ParamType []Type 419 } 420 421 func (t *FuncType) String() string { return t.stringIntl(make(recCheck)) } 422 423 func (t *FuncType) stringIntl(recCheck recCheck) string { 424 release := recCheck.acquire(t.CommonType.Offset) 425 if release == nil { 426 return cyclicalTypeStop 427 } 428 defer release() 429 s := "func(" 430 for i, t := range t.ParamType { 431 if i > 0 { 432 s += ", " 433 } 434 s += t.stringIntl(recCheck) 435 } 436 s += ")" 437 if t.ReturnType != nil { 438 s += " " + t.ReturnType.stringIntl(recCheck) 439 } 440 return s 441 } 442 443 // A DotDotDotType represents the variadic ... function parameter. 444 type DotDotDotType struct { 445 CommonType 446 } 447 448 func (t *DotDotDotType) String() string { return t.stringIntl(nil) } 449 450 func (t *DotDotDotType) stringIntl(recCheck recCheck) string { return "..." } 451 452 // A TypedefType represents a named type. 453 type TypedefType struct { 454 CommonType 455 Type Type 456 } 457 458 func (t *TypedefType) String() string { return t.stringIntl(nil) } 459 460 func (t *TypedefType) stringIntl(recCheck recCheck) string { return t.Name } 461 462 func (t *TypedefType) Size() int64 { return sizeAlignToSize(t.sizeAlignIntl(make(recCheck))) } 463 func (t *TypedefType) Align() int64 { return sizeAlignToAlign(t.sizeAlignIntl(make(recCheck))) } 464 465 func (t *TypedefType) sizeAlignIntl(recCheck recCheck) (int64, int64) { 466 release := recCheck.acquire(t.CommonType.Offset) 467 if release == nil { 468 return t.CommonType.ByteSize, t.CommonType.ByteSize 469 } 470 defer release() 471 if t.Type == nil { 472 return 0, 1 473 } 474 return t.Type.sizeAlignIntl(recCheck) 475 } 476 477 // A MapType represents a Go map type. It looks like a TypedefType, describing 478 // the runtime-internal structure, with extra fields. 479 type MapType struct { 480 TypedefType 481 KeyType Type 482 ElemType Type 483 } 484 485 func (t *MapType) String() string { return t.stringIntl(make(recCheck)) } 486 487 func (t *MapType) stringIntl(recCheck recCheck) string { 488 release := recCheck.acquire(t.CommonType.Offset) 489 if release == nil { 490 return cyclicalTypeStop 491 } 492 defer release() 493 if t.Name != "" { 494 return t.Name 495 } 496 return "map[" + t.KeyType.String() + "]" + t.ElemType.String() 497 } 498 499 // A ChanType represents a Go channel type. 500 type ChanType struct { 501 TypedefType 502 ElemType Type 503 } 504 505 func (t *ChanType) String() string { return t.stringIntl(make(recCheck)) } 506 507 func (t *ChanType) stringIntl(recCheck recCheck) string { 508 release := recCheck.acquire(t.CommonType.Offset) 509 if release == nil { 510 return cyclicalTypeStop 511 } 512 defer release() 513 if t.Name != "" { 514 return t.Name 515 } 516 return "chan " + t.ElemType.String() 517 } 518 519 type ParametricType struct { 520 TypedefType 521 DictIndex int64 522 } 523 524 // An UnsupportedType is a placeholder returned in situations where we 525 // encounter a type that isn't supported. 526 type UnsupportedType struct { 527 CommonType 528 Tag dwarf.Tag 529 } 530 531 func (t *UnsupportedType) stringIntl(recCheck) string { 532 if t.Name != "" { 533 return t.Name 534 } 535 return fmt.Sprintf("(unsupported type %s)", t.Tag.String()) 536 } 537 538 func (t *UnsupportedType) String() string { return t.stringIntl(nil) } 539 540 // ReadType reads the type at off in the DWARF “info” section. 541 func ReadType(d *dwarf.Data, index int, off dwarf.Offset, typeCache map[dwarf.Offset]Type) (Type, error) { 542 typ, err := readType(d, "info", d.Reader(), off, typeCache, nil) 543 if typ != nil { 544 typ.Common().Index = index 545 } 546 return typ, err 547 } 548 549 func getKind(e *dwarf.Entry) reflect.Kind { 550 integer, _ := e.Val(AttrGoKind).(int64) 551 return reflect.Kind(integer) 552 } 553 554 type delayedSize struct { 555 ct *CommonType // type that needs its size computed from ut 556 ut Type // underlying type 557 } 558 559 // readType reads a type from r at off of name using and updating a 560 // type cache, callers should pass nil to delayedSize, it is used for recursion. 561 func readType(d *dwarf.Data, name string, r *dwarf.Reader, off dwarf.Offset, typeCache map[dwarf.Offset]Type, delayedSizes *[]delayedSize) (Type, error) { 562 if t, ok := typeCache[off]; ok { 563 return t, nil 564 } 565 r.Seek(off) 566 e, err := r.Next() 567 if err != nil { 568 return nil, err 569 } 570 addressSize := r.AddressSize() 571 if e == nil || e.Offset != off { 572 return nil, dwarf.DecodeError{Name: name, Offset: off, Err: "no type at offset"} 573 } 574 575 // If this is the root of the recursion, prepare to resolve typedef sizes 576 // once the recursion is done. This must be done after the type graph is 577 // constructed because it may need to resolve cycles in a different order 578 // than readType encounters them. 579 if delayedSizes == nil { 580 var delayedSizeList []delayedSize 581 defer func() { 582 for _, ds := range delayedSizeList { 583 ds.ct.ByteSize = ds.ut.Size() 584 } 585 }() 586 delayedSizes = &delayedSizeList 587 } 588 589 // Parse type from dwarf.Entry. 590 // Must always set typeCache[off] before calling 591 // d.readType recursively, to handle circular types correctly. 592 var typ Type 593 594 nextDepth := 0 595 596 // Get next child; set err if error happens. 597 next := func() *dwarf.Entry { 598 if !e.Children { 599 return nil 600 } 601 // Only return direct children. 602 // Skip over composite entries that happen to be nested 603 // inside this one. Most DWARF generators wouldn't generate 604 // such a thing, but clang does. 605 // See golang.org/issue/6472. 606 for { 607 kid, err1 := r.Next() 608 if err1 != nil { 609 err = err1 610 return nil 611 } 612 if kid.Tag == 0 { 613 if nextDepth > 0 { 614 nextDepth-- 615 continue 616 } 617 return nil 618 } 619 if kid.Children { 620 nextDepth++ 621 } 622 if nextDepth > 0 { 623 continue 624 } 625 return kid 626 } 627 } 628 629 // Get Type referred to by dwarf.Entry's attr. 630 // Set err if error happens. Not having a type is an error. 631 typeOf := func(e *dwarf.Entry, attr dwarf.Attr) Type { 632 tval := e.Val(attr) 633 var t Type 634 switch toff := tval.(type) { 635 case dwarf.Offset: 636 if t, err = readType(d, name, d.Reader(), toff, typeCache, delayedSizes); err != nil { 637 return nil 638 } 639 case uint64: 640 err = dwarf.DecodeError{Name: name, Offset: e.Offset, Err: "DWARFv4 section debug_types unsupported"} 641 return nil 642 default: 643 // It appears that no Type means "void". 644 return new(VoidType) 645 } 646 return t 647 } 648 649 switch e.Tag { 650 case dwarf.TagArrayType: 651 // Multi-dimensional array. (DWARF v2 §5.4) 652 // Attributes: 653 // AttrType:subtype [required] 654 // AttrStrideSize: distance in bits between each element of the array 655 // AttrStride: distance in bytes between each element of the array 656 // AttrByteSize: size of entire array 657 // Children: 658 // TagSubrangeType or TagEnumerationType giving one dimension. 659 // dimensions are in left to right order. 660 t := new(ArrayType) 661 t.Name, _ = e.Val(dwarf.AttrName).(string) 662 t.ReflectKind = getKind(e) 663 typ = t 664 typeCache[off] = t 665 if t.Type = typeOf(e, dwarf.AttrType); err != nil { 666 goto Error 667 } 668 if bytes, ok := e.Val(dwarf.AttrStride).(int64); ok { 669 t.StrideBitSize = 8 * bytes 670 } else if bits, ok := e.Val(dwarf.AttrStrideSize).(int64); ok { 671 t.StrideBitSize = bits 672 } else { 673 // If there's no stride specified, assume it's the size of the 674 // array's element type. 675 t.StrideBitSize = 8 * t.Type.Size() 676 } 677 678 // Accumulate dimensions, 679 ndim := 0 680 for kid := next(); kid != nil; kid = next() { 681 // TODO(rsc): Can also be TagEnumerationType 682 // but haven't seen that in the wild yet. 683 switch kid.Tag { 684 case dwarf.TagSubrangeType: 685 count, ok := kid.Val(dwarf.AttrCount).(int64) 686 if !ok { 687 // Old binaries may have an upper bound instead. 688 count, ok = kid.Val(dwarf.AttrUpperBound).(int64) 689 if ok { 690 count++ // Length is one more than upper bound. 691 } else { 692 count = -1 // As in x[]. 693 } 694 } 695 if ndim == 0 { 696 t.Count = count 697 } else { 698 // Multidimensional array. 699 // Create new array type underneath this one. 700 t.Type = &ArrayType{Type: t.Type, Count: count} 701 } 702 ndim++ 703 case dwarf.TagEnumerationType: 704 err = dwarf.DecodeError{Name: name, Offset: kid.Offset, Err: "cannot handle enumeration type as array bound"} 705 goto Error 706 } 707 } 708 if ndim == 0 { 709 // LLVM generates this for x[]. 710 t.Count = -1 711 } 712 713 case dwarf.TagBaseType: 714 // Basic type. (DWARF v2 §5.1) 715 // Attributes: 716 // AttrName: name of base type in programming language of the compilation unit [required] 717 // AttrEncoding: encoding value for type (encFloat etc) [required] 718 // AttrByteSize: size of type in bytes [required] 719 // AttrBitOffset: for sub-byte types, size in bits 720 // AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes 721 name, _ := e.Val(dwarf.AttrName).(string) 722 enc, ok := e.Val(dwarf.AttrEncoding).(int64) 723 if !ok { 724 err = dwarf.DecodeError{Name: name, Offset: e.Offset, Err: "missing encoding attribute for " + name} 725 goto Error 726 } 727 switch enc { 728 default: 729 err = dwarf.DecodeError{Name: name, Offset: e.Offset, Err: "unrecognized encoding attribute value"} 730 goto Error 731 732 case encAddress: 733 typ = new(AddrType) 734 case encBoolean: 735 typ = new(BoolType) 736 case encComplexFloat: 737 typ = new(ComplexType) 738 if name == "complex" { 739 // clang writes out 'complex' instead of 'complex float' or 'complex double'. 740 // clang also writes out a byte size that we can use to distinguish. 741 // See issue 8694. 742 switch byteSize, _ := e.Val(dwarf.AttrByteSize).(int64); byteSize { 743 case 8: 744 name = "complex float" 745 case 16: 746 name = "complex double" 747 } 748 } 749 case encFloat: 750 typ = new(FloatType) 751 case encSigned: 752 typ = new(IntType) 753 case encUnsigned: 754 typ = new(UintType) 755 case encSignedChar: 756 typ = new(CharType) 757 case encUnsignedChar: 758 typ = new(UcharType) 759 } 760 typeCache[off] = typ 761 t := typ.(interface { 762 Basic() *BasicType 763 }).Basic() 764 t.Name = name 765 t.BitSize, _ = e.Val(dwarf.AttrBitSize).(int64) 766 t.BitOffset, _ = e.Val(dwarf.AttrBitOffset).(int64) 767 t.ReflectKind = getKind(e) 768 769 case dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType: 770 // Structure, union, or class type. (DWARF v2 §5.5) 771 // Also Slices and Strings (Go-specific). 772 // Attributes: 773 // AttrName: name of struct, union, or class 774 // AttrByteSize: byte size [required] 775 // AttrDeclaration: if true, struct/union/class is incomplete 776 // AttrGoElem: present for slices only. 777 // Children: 778 // TagMember to describe one member. 779 // AttrName: name of member [required] 780 // AttrType: type of member [required] 781 // AttrByteSize: size in bytes 782 // AttrBitOffset: bit offset within bytes for bit fields 783 // AttrBitSize: bit size for bit fields 784 // AttrDataMemberLoc: location within struct [required for struct, class] 785 // There is much more to handle C++, all ignored for now. 786 t := new(StructType) 787 t.ReflectKind = getKind(e) 788 switch t.ReflectKind { 789 case reflect.Slice: 790 slice := new(SliceType) 791 typ = slice 792 typeCache[off] = slice 793 slice.ElemType = typeOf(e, AttrGoElem) 794 t = &slice.StructType 795 case reflect.String: 796 str := new(StringType) 797 t = &str.StructType 798 str.ReflectKind = reflect.String 799 typ = str 800 default: 801 typ = t 802 } 803 typeCache[off] = typ 804 switch e.Tag { 805 case dwarf.TagClassType: 806 t.Kind = "class" 807 case dwarf.TagStructType: 808 t.Kind = "struct" 809 case dwarf.TagUnionType: 810 t.Kind = "union" 811 } 812 t.Name, _ = e.Val(dwarf.AttrName).(string) 813 t.StructName, _ = e.Val(dwarf.AttrName).(string) 814 t.Incomplete = e.Val(dwarf.AttrDeclaration) != nil 815 t.Field = make([]*StructField, 0, 8) 816 var lastFieldType Type 817 var lastFieldBitOffset int64 818 for kid := next(); kid != nil; kid = next() { 819 if kid.Tag == dwarf.TagMember { 820 f := new(StructField) 821 if f.Type = typeOf(kid, dwarf.AttrType); err != nil { 822 goto Error 823 } 824 switch loc := kid.Val(dwarf.AttrDataMemberLoc).(type) { 825 case []byte: 826 // TODO: Should have original compilation 827 // unit here, not unknownFormat. 828 if len(loc) == 0 { 829 // Empty exprloc. f.ByteOffset=0. 830 break 831 } 832 b := makeBuf(d, unknownFormat{}, "location", 0, loc) 833 op_ := op.Opcode(b.Uint8()) 834 switch op_ { 835 case op.DW_OP_plus_uconst: 836 // Handle opcode sequence [DW_OP_plus_uconst <uleb128>] 837 f.ByteOffset = int64(b.Uint()) 838 b.AssertEmpty() 839 case op.DW_OP_consts: 840 // Handle opcode sequence [DW_OP_consts <sleb128> DW_OP_plus] 841 f.ByteOffset = b.Int() 842 op_ = op.Opcode(b.Uint8()) 843 if op_ != op.DW_OP_plus { 844 err = dwarf.DecodeError{Name: name, Offset: kid.Offset, Err: fmt.Sprintf("unexpected opcode 0x%x", op_)} 845 goto Error 846 } 847 b.AssertEmpty() 848 default: 849 err = dwarf.DecodeError{Name: name, Offset: kid.Offset, Err: fmt.Sprintf("unexpected opcode 0x%x", op_)} 850 goto Error 851 } 852 if b.Err != nil { 853 err = b.Err 854 goto Error 855 } 856 case int64: 857 f.ByteOffset = loc 858 } 859 860 haveBitOffset := false 861 f.Name, _ = kid.Val(dwarf.AttrName).(string) 862 f.ByteSize, _ = kid.Val(dwarf.AttrByteSize).(int64) 863 f.BitOffset, haveBitOffset = kid.Val(dwarf.AttrBitOffset).(int64) 864 f.BitSize, _ = kid.Val(dwarf.AttrBitSize).(int64) 865 f.Embedded, _ = kid.Val(AttrGoEmbeddedField).(bool) 866 t.Field = append(t.Field, f) 867 868 bito := f.BitOffset 869 if !haveBitOffset { 870 bito = f.ByteOffset * 8 871 } 872 if bito == lastFieldBitOffset && t.Kind != "union" { 873 // Last field was zero width. Fix array length. 874 // (DWARF writes out 0-length arrays as if they were 1-length arrays.) 875 zeroArray(lastFieldType) 876 } 877 lastFieldType = f.Type 878 lastFieldBitOffset = bito 879 } 880 } 881 if t.Kind != "union" { 882 b, ok := e.Val(dwarf.AttrByteSize).(int64) 883 if ok && b*8 == lastFieldBitOffset { 884 // Final field must be zero width. Fix array length. 885 zeroArray(lastFieldType) 886 } 887 } 888 889 case dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType: 890 // Type modifier (DWARF v2 §5.2) 891 // Attributes: 892 // AttrType: subtype 893 t := new(QualType) 894 t.Name, _ = e.Val(dwarf.AttrName).(string) 895 t.ReflectKind = getKind(e) 896 typ = t 897 typeCache[off] = t 898 if t.Type = typeOf(e, dwarf.AttrType); err != nil { 899 goto Error 900 } 901 switch e.Tag { 902 case dwarf.TagConstType: 903 t.Qual = "const" 904 case dwarf.TagRestrictType: 905 t.Qual = "restrict" 906 case dwarf.TagVolatileType: 907 t.Qual = "volatile" 908 } 909 910 case dwarf.TagEnumerationType: 911 // Enumeration type (DWARF v2 §5.6) 912 // Attributes: 913 // AttrName: enum name if any 914 // AttrByteSize: bytes required to represent largest value 915 // Children: 916 // TagEnumerator: 917 // AttrName: name of constant 918 // AttrConstValue: value of constant 919 t := new(EnumType) 920 t.ReflectKind = getKind(e) 921 typ = t 922 typeCache[off] = t 923 t.Name, _ = e.Val(dwarf.AttrName).(string) 924 t.EnumName, _ = e.Val(dwarf.AttrName).(string) 925 t.Val = make([]*EnumValue, 0, 8) 926 for kid := next(); kid != nil; kid = next() { 927 if kid.Tag == dwarf.TagEnumerator { 928 f := new(EnumValue) 929 f.Name, _ = kid.Val(dwarf.AttrName).(string) 930 f.Val, _ = kid.Val(dwarf.AttrConstValue).(int64) 931 n := len(t.Val) 932 if n >= cap(t.Val) { 933 val := make([]*EnumValue, n, n*2) 934 copy(val, t.Val) 935 t.Val = val 936 } 937 t.Val = t.Val[0 : n+1] 938 t.Val[n] = f 939 } 940 } 941 942 case dwarf.TagPointerType: 943 // Type modifier (DWARF v2 §5.2) 944 // Attributes: 945 // AttrType: subtype [not required! void* has no AttrType] 946 // AttrAddrClass: address class [ignored] 947 t := new(PtrType) 948 t.Name, _ = e.Val(dwarf.AttrName).(string) 949 t.ReflectKind = getKind(e) 950 typ = t 951 typeCache[off] = t 952 if e.Val(dwarf.AttrType) == nil { 953 t.Type = &VoidType{} 954 break 955 } 956 t.Type = typeOf(e, dwarf.AttrType) 957 958 case dwarf.TagSubroutineType: 959 // Subroutine type. (DWARF v2 §5.7) 960 // Attributes: 961 // AttrType: type of return value if any 962 // AttrName: possible name of type [ignored] 963 // AttrPrototyped: whether used ANSI C prototype [ignored] 964 // Children: 965 // TagFormalParameter: typed parameter 966 // AttrType: type of parameter 967 // TagUnspecifiedParameter: final ... 968 t := new(FuncType) 969 t.Name, _ = e.Val(dwarf.AttrName).(string) 970 t.ReflectKind = getKind(e) 971 typ = t 972 typeCache[off] = t 973 if t.ReturnType = typeOf(e, dwarf.AttrType); err != nil { 974 goto Error 975 } 976 t.ParamType = make([]Type, 0, 8) 977 for kid := next(); kid != nil; kid = next() { 978 var tkid Type 979 switch kid.Tag { 980 default: 981 continue 982 case dwarf.TagFormalParameter: 983 if tkid = typeOf(kid, dwarf.AttrType); err != nil { 984 goto Error 985 } 986 case dwarf.TagUnspecifiedParameters: 987 tkid = &DotDotDotType{} 988 } 989 t.ParamType = append(t.ParamType, tkid) 990 } 991 992 case dwarf.TagTypedef: 993 // Typedef (DWARF v2 §5.3) 994 // Also maps and channels (Go-specific). 995 // Attributes: 996 // AttrName: name [required] 997 // AttrType: type definition [required] 998 // AttrGoKey: present for maps. 999 // AttrGoElem: present for maps and channels. 1000 t := new(TypedefType) 1001 t.ReflectKind = getKind(e) 1002 switch t.ReflectKind { 1003 case reflect.Map: 1004 m := new(MapType) 1005 typ = m 1006 typeCache[off] = typ 1007 m.KeyType = typeOf(e, AttrGoKey) 1008 m.ElemType = typeOf(e, AttrGoElem) 1009 t = &m.TypedefType 1010 case reflect.Chan: 1011 c := new(ChanType) 1012 typ = c 1013 typeCache[off] = typ 1014 c.ElemType = typeOf(e, AttrGoElem) 1015 t = &c.TypedefType 1016 case reflect.Interface: 1017 it := new(InterfaceType) 1018 typ = it 1019 typeCache[off] = it 1020 t = &it.TypedefType 1021 default: 1022 if dictIndex, ok := e.Val(AttrGoDictIndex).(int64); ok { 1023 pt := new(ParametricType) 1024 pt.DictIndex = dictIndex 1025 typ = pt 1026 typeCache[off] = pt 1027 t = &pt.TypedefType 1028 } else { 1029 typ = t 1030 } 1031 } 1032 typeCache[off] = typ 1033 t.Name, _ = e.Val(dwarf.AttrName).(string) 1034 t.Type = typeOf(e, dwarf.AttrType) 1035 1036 case dwarf.TagUnspecifiedType: 1037 // Unspecified type (DWARF v3 §5.2) 1038 // Attributes: 1039 // AttrName: name 1040 t := new(UnspecifiedType) 1041 typ = t 1042 typeCache[off] = t 1043 t.Name, _ = e.Val(dwarf.AttrName).(string) 1044 1045 default: 1046 // This is some other type DIE that we're currently not 1047 // equipped to handle. Return an abstract "unsupported type" 1048 // object in such cases. 1049 t := new(UnsupportedType) 1050 typ = t 1051 typeCache[off] = t 1052 t.Tag = e.Tag 1053 t.Name, _ = e.Val(dwarf.AttrName).(string) 1054 } 1055 1056 if err != nil { 1057 goto Error 1058 } 1059 1060 typ.Common().Offset = off 1061 1062 { 1063 b, ok := e.Val(dwarf.AttrByteSize).(int64) 1064 if !ok { 1065 b = -1 1066 switch t := typ.(type) { 1067 case *TypedefType: 1068 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1069 case *MapType: 1070 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1071 case *ChanType: 1072 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1073 case *InterfaceType: 1074 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1075 case *PtrType: 1076 b = int64(addressSize) 1077 case *FuncType: 1078 // on Go < 1.10 function types do not have a DW_AT_byte_size attribute. 1079 b = int64(addressSize) 1080 } 1081 } 1082 typ.Common().ByteSize = b 1083 } 1084 return typ, nil 1085 1086 Error: 1087 // If the parse fails, take the type out of the cache 1088 // so that the next call with this offset doesn't hit 1089 // the cache and return success. 1090 delete(typeCache, off) 1091 return nil, err 1092 } 1093 1094 func zeroArray(t Type) { 1095 for { 1096 at, ok := t.(*ArrayType) 1097 if !ok { 1098 break 1099 } 1100 at.Count = 0 1101 t = at.Type 1102 } 1103 }