github.com/undoio/delve@v1.9.0/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/undoio/delve/pkg/dwarf/op" 20 "github.com/undoio/delve/pkg/dwarf/util" 21 ) 22 23 const ( 24 AttrGoKind dwarf.Attr = 0x2900 25 AttrGoKey dwarf.Attr = 0x2901 26 AttrGoElem dwarf.Attr = 0x2902 27 AttrGoEmbeddedField dwarf.Attr = 0x2903 28 AttrGoRuntimeType dwarf.Attr = 0x2904 29 AttrGoPackageName dwarf.Attr = 0x2905 30 AttrGoDictIndex dwarf.Attr = 0x2906 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 inifinite 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 (b *BasicType) Basic() *BasicType { return b } 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 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 { sz, _ := t.sizeAlignIntl(make(recCheck)); return sz } 462 463 func (t *TypedefType) sizeAlignIntl(recCheck recCheck) (int64, int64) { 464 release := recCheck.acquire(t.CommonType.Offset) 465 if release == nil { 466 return t.CommonType.ByteSize, t.CommonType.ByteSize 467 } 468 defer release() 469 if t.Type == nil { 470 return 0, 1 471 } 472 return t.Type.sizeAlignIntl(recCheck) 473 } 474 475 // A MapType represents a Go map type. It looks like a TypedefType, describing 476 // the runtime-internal structure, with extra fields. 477 type MapType struct { 478 TypedefType 479 KeyType Type 480 ElemType Type 481 } 482 483 func (t *MapType) String() string { return t.stringIntl(make(recCheck)) } 484 485 func (t *MapType) stringIntl(recCheck recCheck) string { 486 release := recCheck.acquire(t.CommonType.Offset) 487 if release == nil { 488 return cyclicalTypeStop 489 } 490 defer release() 491 if t.Name != "" { 492 return t.Name 493 } 494 return "map[" + t.KeyType.String() + "]" + t.ElemType.String() 495 } 496 497 // A ChanType represents a Go channel type. 498 type ChanType struct { 499 TypedefType 500 ElemType Type 501 } 502 503 func (t *ChanType) String() string { return t.stringIntl(make(recCheck)) } 504 505 func (t *ChanType) stringIntl(recCheck recCheck) string { 506 release := recCheck.acquire(t.CommonType.Offset) 507 if release == nil { 508 return cyclicalTypeStop 509 } 510 defer release() 511 if t.Name != "" { 512 return t.Name 513 } 514 return "chan " + t.ElemType.String() 515 } 516 517 type ParametricType struct { 518 TypedefType 519 DictIndex int64 520 } 521 522 // An UnsupportedType is a placeholder returned in situations where we 523 // encounter a type that isn't supported. 524 type UnsupportedType struct { 525 CommonType 526 Tag dwarf.Tag 527 } 528 529 func (t *UnsupportedType) stringIntl(recCheck) string { 530 if t.Name != "" { 531 return t.Name 532 } 533 return fmt.Sprintf("(unsupported type %s)", t.Tag.String()) 534 } 535 536 func (t *UnsupportedType) String() string { return t.stringIntl(nil) } 537 538 // ReadType reads the type at off in the DWARF “info” section. 539 func ReadType(d *dwarf.Data, index int, off dwarf.Offset, typeCache map[dwarf.Offset]Type) (Type, error) { 540 typ, err := readType(d, "info", d.Reader(), off, typeCache, nil) 541 if typ != nil { 542 typ.Common().Index = index 543 } 544 return typ, err 545 } 546 547 func getKind(e *dwarf.Entry) reflect.Kind { 548 integer, _ := e.Val(AttrGoKind).(int64) 549 return reflect.Kind(integer) 550 } 551 552 type delayedSize struct { 553 ct *CommonType // type that needs its size computed from ut 554 ut Type // underlying type 555 } 556 557 // readType reads a type from r at off of name using and updating a 558 // type cache, callers should pass nil to delayedSize, it is used for recursion. 559 func readType(d *dwarf.Data, name string, r *dwarf.Reader, off dwarf.Offset, typeCache map[dwarf.Offset]Type, delayedSizes *[]delayedSize) (Type, error) { 560 if t, ok := typeCache[off]; ok { 561 return t, nil 562 } 563 r.Seek(off) 564 e, err := r.Next() 565 if err != nil { 566 return nil, err 567 } 568 addressSize := r.AddressSize() 569 if e == nil || e.Offset != off { 570 return nil, dwarf.DecodeError{Name: name, Offset: off, Err: "no type at offset"} 571 } 572 573 // If this is the root of the recursion, prepare to resolve typedef sizes 574 // once the recursion is done. This must be done after the type graph is 575 // constructed because it may need to resolve cycles in a different order 576 // than readType encounters them. 577 if delayedSizes == nil { 578 var delayedSizeList []delayedSize 579 defer func() { 580 for _, ds := range delayedSizeList { 581 ds.ct.ByteSize = ds.ut.Size() 582 } 583 }() 584 delayedSizes = &delayedSizeList 585 } 586 587 // Parse type from dwarf.Entry. 588 // Must always set typeCache[off] before calling 589 // d.readType recursively, to handle circular types correctly. 590 var typ Type 591 592 nextDepth := 0 593 594 // Get next child; set err if error happens. 595 next := func() *dwarf.Entry { 596 if !e.Children { 597 return nil 598 } 599 // Only return direct children. 600 // Skip over composite entries that happen to be nested 601 // inside this one. Most DWARF generators wouldn't generate 602 // such a thing, but clang does. 603 // See golang.org/issue/6472. 604 for { 605 kid, err1 := r.Next() 606 if err1 != nil { 607 err = err1 608 return nil 609 } 610 if kid.Tag == 0 { 611 if nextDepth > 0 { 612 nextDepth-- 613 continue 614 } 615 return nil 616 } 617 if kid.Children { 618 nextDepth++ 619 } 620 if nextDepth > 0 { 621 continue 622 } 623 return kid 624 } 625 } 626 627 // Get Type referred to by dwarf.Entry's attr. 628 // Set err if error happens. Not having a type is an error. 629 typeOf := func(e *dwarf.Entry, attr dwarf.Attr) Type { 630 tval := e.Val(attr) 631 var t Type 632 switch toff := tval.(type) { 633 case dwarf.Offset: 634 if t, err = readType(d, name, d.Reader(), toff, typeCache, delayedSizes); err != nil { 635 return nil 636 } 637 case uint64: 638 err = dwarf.DecodeError{Name: name, Offset: e.Offset, Err: "DWARFv4 section debug_types unsupported"} 639 return nil 640 default: 641 // It appears that no Type means "void". 642 return new(VoidType) 643 } 644 return t 645 } 646 647 switch e.Tag { 648 case dwarf.TagArrayType: 649 // Multi-dimensional array. (DWARF v2 §5.4) 650 // Attributes: 651 // AttrType:subtype [required] 652 // AttrStrideSize: distance in bits between each element of the array 653 // AttrStride: distance in bytes between each element of the array 654 // AttrByteSize: size of entire array 655 // Children: 656 // TagSubrangeType or TagEnumerationType giving one dimension. 657 // dimensions are in left to right order. 658 t := new(ArrayType) 659 t.Name, _ = e.Val(dwarf.AttrName).(string) 660 t.ReflectKind = getKind(e) 661 typ = t 662 typeCache[off] = t 663 if t.Type = typeOf(e, dwarf.AttrType); err != nil { 664 goto Error 665 } 666 if bytes, ok := e.Val(dwarf.AttrStride).(int64); ok { 667 t.StrideBitSize = 8 * bytes 668 } else if bits, ok := e.Val(dwarf.AttrStrideSize).(int64); ok { 669 t.StrideBitSize = bits 670 } else { 671 // If there's no stride specified, assume it's the size of the 672 // array's element type. 673 t.StrideBitSize = 8 * t.Type.Size() 674 } 675 676 // Accumulate dimensions, 677 ndim := 0 678 for kid := next(); kid != nil; kid = next() { 679 // TODO(rsc): Can also be TagEnumerationType 680 // but haven't seen that in the wild yet. 681 switch kid.Tag { 682 case dwarf.TagSubrangeType: 683 count, ok := kid.Val(dwarf.AttrCount).(int64) 684 if !ok { 685 // Old binaries may have an upper bound instead. 686 count, ok = kid.Val(dwarf.AttrUpperBound).(int64) 687 if ok { 688 count++ // Length is one more than upper bound. 689 } else { 690 count = -1 // As in x[]. 691 } 692 } 693 if ndim == 0 { 694 t.Count = count 695 } else { 696 // Multidimensional array. 697 // Create new array type underneath this one. 698 t.Type = &ArrayType{Type: t.Type, Count: count} 699 } 700 ndim++ 701 case dwarf.TagEnumerationType: 702 err = dwarf.DecodeError{Name: name, Offset: kid.Offset, Err: "cannot handle enumeration type as array bound"} 703 goto Error 704 } 705 } 706 if ndim == 0 { 707 // LLVM generates this for x[]. 708 t.Count = -1 709 } 710 711 case dwarf.TagBaseType: 712 // Basic type. (DWARF v2 §5.1) 713 // Attributes: 714 // AttrName: name of base type in programming language of the compilation unit [required] 715 // AttrEncoding: encoding value for type (encFloat etc) [required] 716 // AttrByteSize: size of type in bytes [required] 717 // AttrBitOffset: for sub-byte types, size in bits 718 // AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes 719 name, _ := e.Val(dwarf.AttrName).(string) 720 enc, ok := e.Val(dwarf.AttrEncoding).(int64) 721 if !ok { 722 err = dwarf.DecodeError{Name: name, Offset: e.Offset, Err: "missing encoding attribute for " + name} 723 goto Error 724 } 725 switch enc { 726 default: 727 err = dwarf.DecodeError{Name: name, Offset: e.Offset, Err: "unrecognized encoding attribute value"} 728 goto Error 729 730 case encAddress: 731 typ = new(AddrType) 732 case encBoolean: 733 typ = new(BoolType) 734 case encComplexFloat: 735 typ = new(ComplexType) 736 if name == "complex" { 737 // clang writes out 'complex' instead of 'complex float' or 'complex double'. 738 // clang also writes out a byte size that we can use to distinguish. 739 // See issue 8694. 740 switch byteSize, _ := e.Val(dwarf.AttrByteSize).(int64); byteSize { 741 case 8: 742 name = "complex float" 743 case 16: 744 name = "complex double" 745 } 746 } 747 case encFloat: 748 typ = new(FloatType) 749 case encSigned: 750 typ = new(IntType) 751 case encUnsigned: 752 typ = new(UintType) 753 case encSignedChar: 754 typ = new(CharType) 755 case encUnsignedChar: 756 typ = new(UcharType) 757 } 758 typeCache[off] = typ 759 t := typ.(interface { 760 Basic() *BasicType 761 }).Basic() 762 t.Name = name 763 t.BitSize, _ = e.Val(dwarf.AttrBitSize).(int64) 764 t.BitOffset, _ = e.Val(dwarf.AttrBitOffset).(int64) 765 t.ReflectKind = getKind(e) 766 767 case dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType: 768 // Structure, union, or class type. (DWARF v2 §5.5) 769 // Also Slices and Strings (Go-specific). 770 // Attributes: 771 // AttrName: name of struct, union, or class 772 // AttrByteSize: byte size [required] 773 // AttrDeclaration: if true, struct/union/class is incomplete 774 // AttrGoElem: present for slices only. 775 // Children: 776 // TagMember to describe one member. 777 // AttrName: name of member [required] 778 // AttrType: type of member [required] 779 // AttrByteSize: size in bytes 780 // AttrBitOffset: bit offset within bytes for bit fields 781 // AttrBitSize: bit size for bit fields 782 // AttrDataMemberLoc: location within struct [required for struct, class] 783 // There is much more to handle C++, all ignored for now. 784 t := new(StructType) 785 t.ReflectKind = getKind(e) 786 switch t.ReflectKind { 787 case reflect.Slice: 788 slice := new(SliceType) 789 typ = slice 790 typeCache[off] = slice 791 slice.ElemType = typeOf(e, AttrGoElem) 792 t = &slice.StructType 793 case reflect.String: 794 str := new(StringType) 795 t = &str.StructType 796 str.ReflectKind = reflect.String 797 typ = str 798 default: 799 typ = t 800 } 801 typeCache[off] = typ 802 switch e.Tag { 803 case dwarf.TagClassType: 804 t.Kind = "class" 805 case dwarf.TagStructType: 806 t.Kind = "struct" 807 case dwarf.TagUnionType: 808 t.Kind = "union" 809 } 810 t.Name, _ = e.Val(dwarf.AttrName).(string) 811 t.StructName, _ = e.Val(dwarf.AttrName).(string) 812 t.Incomplete = e.Val(dwarf.AttrDeclaration) != nil 813 t.Field = make([]*StructField, 0, 8) 814 var lastFieldType Type 815 var lastFieldBitOffset int64 816 for kid := next(); kid != nil; kid = next() { 817 if kid.Tag == dwarf.TagMember { 818 f := new(StructField) 819 if f.Type = typeOf(kid, dwarf.AttrType); err != nil { 820 goto Error 821 } 822 switch loc := kid.Val(dwarf.AttrDataMemberLoc).(type) { 823 case []byte: 824 // TODO: Should have original compilation 825 // unit here, not unknownFormat. 826 if len(loc) == 0 { 827 // Empty exprloc. f.ByteOffset=0. 828 break 829 } 830 b := util.MakeBuf(d, util.UnknownFormat{}, "location", 0, loc) 831 op_ := op.Opcode(b.Uint8()) 832 switch op_ { 833 case op.DW_OP_plus_uconst: 834 // Handle opcode sequence [DW_OP_plus_uconst <uleb128>] 835 f.ByteOffset = int64(b.Uint()) 836 b.AssertEmpty() 837 case op.DW_OP_consts: 838 // Handle opcode sequence [DW_OP_consts <sleb128> DW_OP_plus] 839 f.ByteOffset = b.Int() 840 op_ = op.Opcode(b.Uint8()) 841 if op_ != op.DW_OP_plus { 842 err = dwarf.DecodeError{Name: name, Offset: kid.Offset, Err: fmt.Sprintf("unexpected opcode 0x%x", op_)} 843 goto Error 844 } 845 b.AssertEmpty() 846 default: 847 err = dwarf.DecodeError{Name: name, Offset: kid.Offset, Err: fmt.Sprintf("unexpected opcode 0x%x", op_)} 848 goto Error 849 } 850 if b.Err != nil { 851 err = b.Err 852 goto Error 853 } 854 case int64: 855 f.ByteOffset = loc 856 } 857 858 haveBitOffset := false 859 f.Name, _ = kid.Val(dwarf.AttrName).(string) 860 f.ByteSize, _ = kid.Val(dwarf.AttrByteSize).(int64) 861 f.BitOffset, haveBitOffset = kid.Val(dwarf.AttrBitOffset).(int64) 862 f.BitSize, _ = kid.Val(dwarf.AttrBitSize).(int64) 863 f.Embedded, _ = kid.Val(AttrGoEmbeddedField).(bool) 864 t.Field = append(t.Field, f) 865 866 bito := f.BitOffset 867 if !haveBitOffset { 868 bito = f.ByteOffset * 8 869 } 870 if bito == lastFieldBitOffset && t.Kind != "union" { 871 // Last field was zero width. Fix array length. 872 // (DWARF writes out 0-length arrays as if they were 1-length arrays.) 873 zeroArray(lastFieldType) 874 } 875 lastFieldType = f.Type 876 lastFieldBitOffset = bito 877 } 878 } 879 if t.Kind != "union" { 880 b, ok := e.Val(dwarf.AttrByteSize).(int64) 881 if ok && b*8 == lastFieldBitOffset { 882 // Final field must be zero width. Fix array length. 883 zeroArray(lastFieldType) 884 } 885 } 886 887 case dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType: 888 // Type modifier (DWARF v2 §5.2) 889 // Attributes: 890 // AttrType: subtype 891 t := new(QualType) 892 t.Name, _ = e.Val(dwarf.AttrName).(string) 893 t.ReflectKind = getKind(e) 894 typ = t 895 typeCache[off] = t 896 if t.Type = typeOf(e, dwarf.AttrType); err != nil { 897 goto Error 898 } 899 switch e.Tag { 900 case dwarf.TagConstType: 901 t.Qual = "const" 902 case dwarf.TagRestrictType: 903 t.Qual = "restrict" 904 case dwarf.TagVolatileType: 905 t.Qual = "volatile" 906 } 907 908 case dwarf.TagEnumerationType: 909 // Enumeration type (DWARF v2 §5.6) 910 // Attributes: 911 // AttrName: enum name if any 912 // AttrByteSize: bytes required to represent largest value 913 // Children: 914 // TagEnumerator: 915 // AttrName: name of constant 916 // AttrConstValue: value of constant 917 t := new(EnumType) 918 t.ReflectKind = getKind(e) 919 typ = t 920 typeCache[off] = t 921 t.Name, _ = e.Val(dwarf.AttrName).(string) 922 t.EnumName, _ = e.Val(dwarf.AttrName).(string) 923 t.Val = make([]*EnumValue, 0, 8) 924 for kid := next(); kid != nil; kid = next() { 925 if kid.Tag == dwarf.TagEnumerator { 926 f := new(EnumValue) 927 f.Name, _ = kid.Val(dwarf.AttrName).(string) 928 f.Val, _ = kid.Val(dwarf.AttrConstValue).(int64) 929 n := len(t.Val) 930 if n >= cap(t.Val) { 931 val := make([]*EnumValue, n, n*2) 932 copy(val, t.Val) 933 t.Val = val 934 } 935 t.Val = t.Val[0 : n+1] 936 t.Val[n] = f 937 } 938 } 939 940 case dwarf.TagPointerType: 941 // Type modifier (DWARF v2 §5.2) 942 // Attributes: 943 // AttrType: subtype [not required! void* has no AttrType] 944 // AttrAddrClass: address class [ignored] 945 t := new(PtrType) 946 t.Name, _ = e.Val(dwarf.AttrName).(string) 947 t.ReflectKind = getKind(e) 948 typ = t 949 typeCache[off] = t 950 if e.Val(dwarf.AttrType) == nil { 951 t.Type = &VoidType{} 952 break 953 } 954 t.Type = typeOf(e, dwarf.AttrType) 955 956 case dwarf.TagSubroutineType: 957 // Subroutine type. (DWARF v2 §5.7) 958 // Attributes: 959 // AttrType: type of return value if any 960 // AttrName: possible name of type [ignored] 961 // AttrPrototyped: whether used ANSI C prototype [ignored] 962 // Children: 963 // TagFormalParameter: typed parameter 964 // AttrType: type of parameter 965 // TagUnspecifiedParameter: final ... 966 t := new(FuncType) 967 t.Name, _ = e.Val(dwarf.AttrName).(string) 968 t.ReflectKind = getKind(e) 969 typ = t 970 typeCache[off] = t 971 if t.ReturnType = typeOf(e, dwarf.AttrType); err != nil { 972 goto Error 973 } 974 t.ParamType = make([]Type, 0, 8) 975 for kid := next(); kid != nil; kid = next() { 976 var tkid Type 977 switch kid.Tag { 978 default: 979 continue 980 case dwarf.TagFormalParameter: 981 if tkid = typeOf(kid, dwarf.AttrType); err != nil { 982 goto Error 983 } 984 case dwarf.TagUnspecifiedParameters: 985 tkid = &DotDotDotType{} 986 } 987 t.ParamType = append(t.ParamType, tkid) 988 } 989 990 case dwarf.TagTypedef: 991 // Typedef (DWARF v2 §5.3) 992 // Also maps and channels (Go-specific). 993 // Attributes: 994 // AttrName: name [required] 995 // AttrType: type definition [required] 996 // AttrGoKey: present for maps. 997 // AttrGoElem: present for maps and channels. 998 t := new(TypedefType) 999 t.ReflectKind = getKind(e) 1000 switch t.ReflectKind { 1001 case reflect.Map: 1002 m := new(MapType) 1003 typ = m 1004 typeCache[off] = typ 1005 m.KeyType = typeOf(e, AttrGoKey) 1006 m.ElemType = typeOf(e, AttrGoElem) 1007 t = &m.TypedefType 1008 case reflect.Chan: 1009 c := new(ChanType) 1010 typ = c 1011 typeCache[off] = typ 1012 c.ElemType = typeOf(e, AttrGoElem) 1013 t = &c.TypedefType 1014 case reflect.Interface: 1015 it := new(InterfaceType) 1016 typ = it 1017 typeCache[off] = it 1018 t = &it.TypedefType 1019 default: 1020 if dictIndex, ok := e.Val(AttrGoDictIndex).(int64); ok { 1021 pt := new(ParametricType) 1022 pt.DictIndex = dictIndex 1023 typ = pt 1024 typeCache[off] = pt 1025 t = &pt.TypedefType 1026 } else { 1027 typ = t 1028 } 1029 } 1030 typeCache[off] = typ 1031 t.Name, _ = e.Val(dwarf.AttrName).(string) 1032 t.Type = typeOf(e, dwarf.AttrType) 1033 1034 case dwarf.TagUnspecifiedType: 1035 // Unspecified type (DWARF v3 §5.2) 1036 // Attributes: 1037 // AttrName: name 1038 t := new(UnspecifiedType) 1039 typ = t 1040 typeCache[off] = t 1041 t.Name, _ = e.Val(dwarf.AttrName).(string) 1042 1043 default: 1044 // This is some other type DIE that we're currently not 1045 // equipped to handle. Return an abstract "unsupported type" 1046 // object in such cases. 1047 t := new(UnsupportedType) 1048 typ = t 1049 typeCache[off] = t 1050 t.Tag = e.Tag 1051 t.Name, _ = e.Val(dwarf.AttrName).(string) 1052 } 1053 1054 if err != nil { 1055 goto Error 1056 } 1057 1058 typ.Common().Offset = off 1059 1060 { 1061 b, ok := e.Val(dwarf.AttrByteSize).(int64) 1062 if !ok { 1063 b = -1 1064 switch t := typ.(type) { 1065 case *TypedefType: 1066 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1067 case *MapType: 1068 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1069 case *ChanType: 1070 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1071 case *InterfaceType: 1072 *delayedSizes = append(*delayedSizes, delayedSize{typ.Common(), t.Type}) 1073 case *PtrType: 1074 b = int64(addressSize) 1075 case *FuncType: 1076 // on Go < 1.10 function types do not have a DW_AT_byte_size attribute. 1077 b = int64(addressSize) 1078 } 1079 } 1080 typ.Common().ByteSize = b 1081 } 1082 return typ, nil 1083 1084 Error: 1085 // If the parse fails, take the type out of the cache 1086 // so that the next call with this offset doesn't hit 1087 // the cache and return success. 1088 delete(typeCache, off) 1089 return nil, err 1090 } 1091 1092 func zeroArray(t Type) { 1093 for { 1094 at, ok := t.(*ArrayType) 1095 if !ok { 1096 break 1097 } 1098 at.Count = 0 1099 t = at.Type 1100 } 1101 }