github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/debug/dwarf/type.go (about)

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