Source file src/debug/dwarf/type.go

     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 new(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 := new(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 = new(AddrType)
   575  		case encBoolean:
   576  			typ = new(BoolType)
   577  		case encComplexFloat:
   578  			typ = new(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 = new(FloatType)
   592  		case encSigned:
   593  			typ = new(IntType)
   594  		case encUnsigned:
   595  			typ = new(UintType)
   596  		case encSignedChar:
   597  			typ = new(CharType)
   598  		case encUnsignedChar:
   599  			typ = new(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 := new(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 = make([]*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 := new(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 := new(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 := new(EnumType)
   734  		typ = t
   735  		typeCache[off] = t
   736  		t.EnumName, _ = e.Val(AttrName).(string)
   737  		t.Val = make([]*EnumValue, 0, 8)
   738  		for kid := next(); kid != nil; kid = next() {
   739  			if kid.Tag == TagEnumerator {
   740  				f := new(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 := make([]*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 := new(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 := new(FuncType)
   779  		typ = t
   780  		typeCache[off] = t
   781  		if t.ReturnType = typeOf(e); err != nil {
   782  			goto Error
   783  		}
   784  		t.ParamType = make([]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 := new(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 := new(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 := new(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  

View as plain text