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