type.mx raw

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