github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/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  // qualifiers
    92  
    93  // A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
    94  type QualType struct {
    95  	CommonType
    96  	Qual string
    97  	Type Type
    98  }
    99  
   100  func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
   101  
   102  func (t *QualType) Size() int64 { return t.Type.Size() }
   103  
   104  // An ArrayType represents a fixed size array type.
   105  type ArrayType struct {
   106  	CommonType
   107  	Type          Type
   108  	StrideBitSize int64 // if > 0, number of bits to hold each element
   109  	Count         int64 // if == -1, an incomplete array, like char x[].
   110  }
   111  
   112  func (t *ArrayType) String() string {
   113  	return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
   114  }
   115  
   116  func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
   117  
   118  // A VoidType represents the C void type.
   119  type VoidType struct {
   120  	CommonType
   121  }
   122  
   123  func (t *VoidType) String() string { return "void" }
   124  
   125  // A PtrType represents a pointer type.
   126  type PtrType struct {
   127  	CommonType
   128  	Type Type
   129  }
   130  
   131  func (t *PtrType) String() string { return "*" + t.Type.String() }
   132  
   133  // A StructType represents a struct, union, or C++ class type.
   134  type StructType struct {
   135  	CommonType
   136  	StructName string
   137  	Kind       string // "struct", "union", or "class".
   138  	Field      []*StructField
   139  	Incomplete bool // if true, struct, union, class is declared but not defined
   140  }
   141  
   142  // A StructField represents a field in a struct, union, or C++ class type.
   143  type StructField struct {
   144  	Name       string
   145  	Type       Type
   146  	ByteOffset int64
   147  	ByteSize   int64
   148  	BitOffset  int64 // within the ByteSize bytes at ByteOffset
   149  	BitSize    int64 // zero if not a bit field
   150  }
   151  
   152  func (t *StructType) String() string {
   153  	if t.StructName != "" {
   154  		return t.Kind + " " + t.StructName
   155  	}
   156  	return t.Defn()
   157  }
   158  
   159  func (t *StructType) Defn() string {
   160  	s := t.Kind
   161  	if t.StructName != "" {
   162  		s += " " + t.StructName
   163  	}
   164  	if t.Incomplete {
   165  		s += " /*incomplete*/"
   166  		return s
   167  	}
   168  	s += " {"
   169  	for i, f := range t.Field {
   170  		if i > 0 {
   171  			s += "; "
   172  		}
   173  		s += f.Name + " " + f.Type.String()
   174  		s += "@" + strconv.FormatInt(f.ByteOffset, 10)
   175  		if f.BitSize > 0 {
   176  			s += " : " + strconv.FormatInt(f.BitSize, 10)
   177  			s += "@" + strconv.FormatInt(f.BitOffset, 10)
   178  		}
   179  	}
   180  	s += "}"
   181  	return s
   182  }
   183  
   184  // An EnumType represents an enumerated type.
   185  // The only indication of its native integer type is its ByteSize
   186  // (inside CommonType).
   187  type EnumType struct {
   188  	CommonType
   189  	EnumName string
   190  	Val      []*EnumValue
   191  }
   192  
   193  // An EnumValue represents a single enumeration value.
   194  type EnumValue struct {
   195  	Name string
   196  	Val  int64
   197  }
   198  
   199  func (t *EnumType) String() string {
   200  	s := "enum"
   201  	if t.EnumName != "" {
   202  		s += " " + t.EnumName
   203  	}
   204  	s += " {"
   205  	for i, v := range t.Val {
   206  		if i > 0 {
   207  			s += "; "
   208  		}
   209  		s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
   210  	}
   211  	s += "}"
   212  	return s
   213  }
   214  
   215  // A FuncType represents a function type.
   216  type FuncType struct {
   217  	CommonType
   218  	ReturnType Type
   219  	ParamType  []Type
   220  }
   221  
   222  func (t *FuncType) String() string {
   223  	s := "func("
   224  	for i, t := range t.ParamType {
   225  		if i > 0 {
   226  			s += ", "
   227  		}
   228  		s += t.String()
   229  	}
   230  	s += ")"
   231  	if t.ReturnType != nil {
   232  		s += " " + t.ReturnType.String()
   233  	}
   234  	return s
   235  }
   236  
   237  // A DotDotDotType represents the variadic ... function parameter.
   238  type DotDotDotType struct {
   239  	CommonType
   240  }
   241  
   242  func (t *DotDotDotType) String() string { return "..." }
   243  
   244  // A TypedefType represents a named type.
   245  type TypedefType struct {
   246  	CommonType
   247  	Type Type
   248  }
   249  
   250  func (t *TypedefType) String() string { return t.Name }
   251  
   252  func (t *TypedefType) Size() int64 { return t.Type.Size() }
   253  
   254  // typeReader is used to read from either the info section or the
   255  // types section.
   256  type typeReader interface {
   257  	Seek(Offset)
   258  	Next() (*Entry, error)
   259  	clone() typeReader
   260  	offset() Offset
   261  }
   262  
   263  // Type reads the type at off in the DWARF ``info'' section.
   264  func (d *Data) Type(off Offset) (Type, error) {
   265  	return d.readType("info", d.Reader(), off, d.typeCache)
   266  }
   267  
   268  // readType reads a type from r at off of name using and updating a
   269  // type cache.
   270  func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) {
   271  	if t, ok := typeCache[off]; ok {
   272  		return t, nil
   273  	}
   274  	r.Seek(off)
   275  	e, err := r.Next()
   276  	if err != nil {
   277  		return nil, err
   278  	}
   279  	if e == nil || e.Offset != off {
   280  		return nil, DecodeError{name, off, "no type at offset"}
   281  	}
   282  
   283  	// Parse type from Entry.
   284  	// Must always set typeCache[off] before calling
   285  	// d.Type recursively, to handle circular types correctly.
   286  	var typ Type
   287  
   288  	nextDepth := 0
   289  
   290  	// Get next child; set err if error happens.
   291  	next := func() *Entry {
   292  		if !e.Children {
   293  			return nil
   294  		}
   295  		// Only return direct children.
   296  		// Skip over composite entries that happen to be nested
   297  		// inside this one. Most DWARF generators wouldn't generate
   298  		// such a thing, but clang does.
   299  		// See golang.org/issue/6472.
   300  		for {
   301  			kid, err1 := r.Next()
   302  			if err1 != nil {
   303  				err = err1
   304  				return nil
   305  			}
   306  			if kid == nil {
   307  				err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
   308  				return nil
   309  			}
   310  			if kid.Tag == 0 {
   311  				if nextDepth > 0 {
   312  					nextDepth--
   313  					continue
   314  				}
   315  				return nil
   316  			}
   317  			if kid.Children {
   318  				nextDepth++
   319  			}
   320  			if nextDepth > 0 {
   321  				continue
   322  			}
   323  			return kid
   324  		}
   325  	}
   326  
   327  	// Get Type referred to by Entry's AttrType field.
   328  	// Set err if error happens.  Not having a type is an error.
   329  	typeOf := func(e *Entry) Type {
   330  		tval := e.Val(AttrType)
   331  		var t Type
   332  		switch toff := tval.(type) {
   333  		case Offset:
   334  			if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
   335  				return nil
   336  			}
   337  		case uint64:
   338  			if t, err = d.sigToType(toff); err != nil {
   339  				return nil
   340  			}
   341  		default:
   342  			// It appears that no Type means "void".
   343  			return new(VoidType)
   344  		}
   345  		return t
   346  	}
   347  
   348  	switch e.Tag {
   349  	case TagArrayType:
   350  		// Multi-dimensional array.  (DWARF v2 §5.4)
   351  		// Attributes:
   352  		//	AttrType:subtype [required]
   353  		//	AttrStrideSize: size in bits of each element of the array
   354  		//	AttrByteSize: size of entire array
   355  		// Children:
   356  		//	TagSubrangeType or TagEnumerationType giving one dimension.
   357  		//	dimensions are in left to right order.
   358  		t := new(ArrayType)
   359  		typ = t
   360  		typeCache[off] = t
   361  		if t.Type = typeOf(e); err != nil {
   362  			goto Error
   363  		}
   364  		t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
   365  
   366  		// Accumulate dimensions,
   367  		ndim := 0
   368  		for kid := next(); kid != nil; kid = next() {
   369  			// TODO(rsc): Can also be TagEnumerationType
   370  			// but haven't seen that in the wild yet.
   371  			switch kid.Tag {
   372  			case TagSubrangeType:
   373  				max, ok := kid.Val(AttrUpperBound).(int64)
   374  				if !ok {
   375  					max = -2 // Count == -1, as in x[].
   376  				}
   377  				if ndim == 0 {
   378  					t.Count = max + 1
   379  				} else {
   380  					// Multidimensional array.
   381  					// Create new array type underneath this one.
   382  					t.Type = &ArrayType{Type: t.Type, Count: max + 1}
   383  				}
   384  				ndim++
   385  			case TagEnumerationType:
   386  				err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
   387  				goto Error
   388  			}
   389  		}
   390  		if ndim == 0 {
   391  			// LLVM generates this for x[].
   392  			t.Count = -1
   393  		}
   394  
   395  	case TagBaseType:
   396  		// Basic type.  (DWARF v2 §5.1)
   397  		// Attributes:
   398  		//	AttrName: name of base type in programming language of the compilation unit [required]
   399  		//	AttrEncoding: encoding value for type (encFloat etc) [required]
   400  		//	AttrByteSize: size of type in bytes [required]
   401  		//	AttrBitOffset: for sub-byte types, size in bits
   402  		//	AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
   403  		name, _ := e.Val(AttrName).(string)
   404  		enc, ok := e.Val(AttrEncoding).(int64)
   405  		if !ok {
   406  			err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
   407  			goto Error
   408  		}
   409  		switch enc {
   410  		default:
   411  			err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
   412  			goto Error
   413  
   414  		case encAddress:
   415  			typ = new(AddrType)
   416  		case encBoolean:
   417  			typ = new(BoolType)
   418  		case encComplexFloat:
   419  			typ = new(ComplexType)
   420  		case encFloat:
   421  			typ = new(FloatType)
   422  		case encSigned:
   423  			typ = new(IntType)
   424  		case encUnsigned:
   425  			typ = new(UintType)
   426  		case encSignedChar:
   427  			typ = new(CharType)
   428  		case encUnsignedChar:
   429  			typ = new(UcharType)
   430  		}
   431  		typeCache[off] = typ
   432  		t := typ.(interface {
   433  			Basic() *BasicType
   434  		}).Basic()
   435  		t.Name = name
   436  		t.BitSize, _ = e.Val(AttrBitSize).(int64)
   437  		t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
   438  
   439  	case TagClassType, TagStructType, TagUnionType:
   440  		// Structure, union, or class type.  (DWARF v2 §5.5)
   441  		// Attributes:
   442  		//	AttrName: name of struct, union, or class
   443  		//	AttrByteSize: byte size [required]
   444  		//	AttrDeclaration: if true, struct/union/class is incomplete
   445  		// Children:
   446  		//	TagMember to describe one member.
   447  		//		AttrName: name of member [required]
   448  		//		AttrType: type of member [required]
   449  		//		AttrByteSize: size in bytes
   450  		//		AttrBitOffset: bit offset within bytes for bit fields
   451  		//		AttrBitSize: bit size for bit fields
   452  		//		AttrDataMemberLoc: location within struct [required for struct, class]
   453  		// There is much more to handle C++, all ignored for now.
   454  		t := new(StructType)
   455  		typ = t
   456  		typeCache[off] = t
   457  		switch e.Tag {
   458  		case TagClassType:
   459  			t.Kind = "class"
   460  		case TagStructType:
   461  			t.Kind = "struct"
   462  		case TagUnionType:
   463  			t.Kind = "union"
   464  		}
   465  		t.StructName, _ = e.Val(AttrName).(string)
   466  		t.Incomplete = e.Val(AttrDeclaration) != nil
   467  		t.Field = make([]*StructField, 0, 8)
   468  		var lastFieldType Type
   469  		var lastFieldBitOffset int64
   470  		for kid := next(); kid != nil; kid = next() {
   471  			if kid.Tag == TagMember {
   472  				f := new(StructField)
   473  				if f.Type = typeOf(kid); err != nil {
   474  					goto Error
   475  				}
   476  				switch loc := kid.Val(AttrDataMemberLoc).(type) {
   477  				case []byte:
   478  					// TODO: Should have original compilation
   479  					// unit here, not unknownFormat.
   480  					b := makeBuf(d, unknownFormat{}, "location", 0, loc)
   481  					if b.uint8() != opPlusUconst {
   482  						err = DecodeError{name, kid.Offset, "unexpected opcode"}
   483  						goto Error
   484  					}
   485  					f.ByteOffset = int64(b.uint())
   486  					if b.err != nil {
   487  						err = b.err
   488  						goto Error
   489  					}
   490  				case int64:
   491  					f.ByteOffset = loc
   492  				}
   493  
   494  				haveBitOffset := false
   495  				f.Name, _ = kid.Val(AttrName).(string)
   496  				f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
   497  				f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
   498  				f.BitSize, _ = kid.Val(AttrBitSize).(int64)
   499  				t.Field = append(t.Field, f)
   500  
   501  				bito := f.BitOffset
   502  				if !haveBitOffset {
   503  					bito = f.ByteOffset * 8
   504  				}
   505  				if bito == lastFieldBitOffset && t.Kind != "union" {
   506  					// Last field was zero width.  Fix array length.
   507  					// (DWARF writes out 0-length arrays as if they were 1-length arrays.)
   508  					zeroArray(lastFieldType)
   509  				}
   510  				lastFieldType = f.Type
   511  				lastFieldBitOffset = bito
   512  			}
   513  		}
   514  		if t.Kind != "union" {
   515  			b, ok := e.Val(AttrByteSize).(int64)
   516  			if ok && b*8 == lastFieldBitOffset {
   517  				// Final field must be zero width.  Fix array length.
   518  				zeroArray(lastFieldType)
   519  			}
   520  		}
   521  
   522  	case TagConstType, TagVolatileType, TagRestrictType:
   523  		// Type modifier (DWARF v2 §5.2)
   524  		// Attributes:
   525  		//	AttrType: subtype
   526  		t := new(QualType)
   527  		typ = t
   528  		typeCache[off] = t
   529  		if t.Type = typeOf(e); err != nil {
   530  			goto Error
   531  		}
   532  		switch e.Tag {
   533  		case TagConstType:
   534  			t.Qual = "const"
   535  		case TagRestrictType:
   536  			t.Qual = "restrict"
   537  		case TagVolatileType:
   538  			t.Qual = "volatile"
   539  		}
   540  
   541  	case TagEnumerationType:
   542  		// Enumeration type (DWARF v2 §5.6)
   543  		// Attributes:
   544  		//	AttrName: enum name if any
   545  		//	AttrByteSize: bytes required to represent largest value
   546  		// Children:
   547  		//	TagEnumerator:
   548  		//		AttrName: name of constant
   549  		//		AttrConstValue: value of constant
   550  		t := new(EnumType)
   551  		typ = t
   552  		typeCache[off] = t
   553  		t.EnumName, _ = e.Val(AttrName).(string)
   554  		t.Val = make([]*EnumValue, 0, 8)
   555  		for kid := next(); kid != nil; kid = next() {
   556  			if kid.Tag == TagEnumerator {
   557  				f := new(EnumValue)
   558  				f.Name, _ = kid.Val(AttrName).(string)
   559  				f.Val, _ = kid.Val(AttrConstValue).(int64)
   560  				n := len(t.Val)
   561  				if n >= cap(t.Val) {
   562  					val := make([]*EnumValue, n, n*2)
   563  					copy(val, t.Val)
   564  					t.Val = val
   565  				}
   566  				t.Val = t.Val[0 : n+1]
   567  				t.Val[n] = f
   568  			}
   569  		}
   570  
   571  	case TagPointerType:
   572  		// Type modifier (DWARF v2 §5.2)
   573  		// Attributes:
   574  		//	AttrType: subtype [not required!  void* has no AttrType]
   575  		//	AttrAddrClass: address class [ignored]
   576  		t := new(PtrType)
   577  		typ = t
   578  		typeCache[off] = t
   579  		if e.Val(AttrType) == nil {
   580  			t.Type = &VoidType{}
   581  			break
   582  		}
   583  		t.Type = typeOf(e)
   584  
   585  	case TagSubroutineType:
   586  		// Subroutine type.  (DWARF v2 §5.7)
   587  		// Attributes:
   588  		//	AttrType: type of return value if any
   589  		//	AttrName: possible name of type [ignored]
   590  		//	AttrPrototyped: whether used ANSI C prototype [ignored]
   591  		// Children:
   592  		//	TagFormalParameter: typed parameter
   593  		//		AttrType: type of parameter
   594  		//	TagUnspecifiedParameter: final ...
   595  		t := new(FuncType)
   596  		typ = t
   597  		typeCache[off] = t
   598  		if t.ReturnType = typeOf(e); err != nil {
   599  			goto Error
   600  		}
   601  		t.ParamType = make([]Type, 0, 8)
   602  		for kid := next(); kid != nil; kid = next() {
   603  			var tkid Type
   604  			switch kid.Tag {
   605  			default:
   606  				continue
   607  			case TagFormalParameter:
   608  				if tkid = typeOf(kid); err != nil {
   609  					goto Error
   610  				}
   611  			case TagUnspecifiedParameters:
   612  				tkid = &DotDotDotType{}
   613  			}
   614  			t.ParamType = append(t.ParamType, tkid)
   615  		}
   616  
   617  	case TagTypedef:
   618  		// Typedef (DWARF v2 §5.3)
   619  		// Attributes:
   620  		//	AttrName: name [required]
   621  		//	AttrType: type definition [required]
   622  		t := new(TypedefType)
   623  		typ = t
   624  		typeCache[off] = t
   625  		t.Name, _ = e.Val(AttrName).(string)
   626  		t.Type = typeOf(e)
   627  	}
   628  
   629  	if err != nil {
   630  		goto Error
   631  	}
   632  
   633  	{
   634  		b, ok := e.Val(AttrByteSize).(int64)
   635  		if !ok {
   636  			b = -1
   637  		}
   638  		typ.Common().ByteSize = b
   639  	}
   640  	return typ, nil
   641  
   642  Error:
   643  	// If the parse fails, take the type out of the cache
   644  	// so that the next call with this offset doesn't hit
   645  	// the cache and return success.
   646  	delete(typeCache, off)
   647  	return nil, err
   648  }
   649  
   650  func zeroArray(t Type) {
   651  	for {
   652  		at, ok := t.(*ArrayType)
   653  		if !ok {
   654  			break
   655  		}
   656  		at.Count = 0
   657  		t = at.Type
   658  	}
   659  }