...

Source file src/pkg/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	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	// readType reads a type from r at off of name. It adds types to the
   296	// type cache, appends new typedef types to typedefs, and computes the
   297	// sizes of types. Callers should pass nil for typedefs; this is used
   298	// for internal recursion.
   299	func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, typedefs *[]*TypedefType) (Type, error) {
   300		if t, ok := typeCache[off]; ok {
   301			return t, nil
   302		}
   303		r.Seek(off)
   304		e, err := r.Next()
   305		if err != nil {
   306			return nil, err
   307		}
   308		addressSize := r.AddressSize()
   309		if e == nil || e.Offset != off {
   310			return nil, DecodeError{name, off, "no type at offset"}
   311		}
   312	
   313		// If this is the root of the recursion, prepare to resolve
   314		// typedef sizes once the recursion is done. This must be done
   315		// after the type graph is constructed because it may need to
   316		// resolve cycles in a different order than readType
   317		// encounters them.
   318		if typedefs == nil {
   319			var typedefList []*TypedefType
   320			defer func() {
   321				for _, t := range typedefList {
   322					t.Common().ByteSize = t.Type.Size()
   323				}
   324			}()
   325			typedefs = &typedefList
   326		}
   327	
   328		// Parse type from Entry.
   329		// Must always set typeCache[off] before calling
   330		// d.readType recursively, to handle circular types correctly.
   331		var typ Type
   332	
   333		nextDepth := 0
   334	
   335		// Get next child; set err if error happens.
   336		next := func() *Entry {
   337			if !e.Children {
   338				return nil
   339			}
   340			// Only return direct children.
   341			// Skip over composite entries that happen to be nested
   342			// inside this one. Most DWARF generators wouldn't generate
   343			// such a thing, but clang does.
   344			// See golang.org/issue/6472.
   345			for {
   346				kid, err1 := r.Next()
   347				if err1 != nil {
   348					err = err1
   349					return nil
   350				}
   351				if kid == nil {
   352					err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
   353					return nil
   354				}
   355				if kid.Tag == 0 {
   356					if nextDepth > 0 {
   357						nextDepth--
   358						continue
   359					}
   360					return nil
   361				}
   362				if kid.Children {
   363					nextDepth++
   364				}
   365				if nextDepth > 0 {
   366					continue
   367				}
   368				return kid
   369			}
   370		}
   371	
   372		// Get Type referred to by Entry's AttrType field.
   373		// Set err if error happens. Not having a type is an error.
   374		typeOf := func(e *Entry) Type {
   375			tval := e.Val(AttrType)
   376			var t Type
   377			switch toff := tval.(type) {
   378			case Offset:
   379				if t, err = d.readType(name, r.clone(), toff, typeCache, typedefs); err != nil {
   380					return nil
   381				}
   382			case uint64:
   383				if t, err = d.sigToType(toff); err != nil {
   384					return nil
   385				}
   386			default:
   387				// It appears that no Type means "void".
   388				return new(VoidType)
   389			}
   390			return t
   391		}
   392	
   393		switch e.Tag {
   394		case TagArrayType:
   395			// Multi-dimensional array.  (DWARF v2 §5.4)
   396			// Attributes:
   397			//	AttrType:subtype [required]
   398			//	AttrStrideSize: size in bits of each element of the array
   399			//	AttrByteSize: size of entire array
   400			// Children:
   401			//	TagSubrangeType or TagEnumerationType giving one dimension.
   402			//	dimensions are in left to right order.
   403			t := new(ArrayType)
   404			typ = t
   405			typeCache[off] = t
   406			if t.Type = typeOf(e); err != nil {
   407				goto Error
   408			}
   409			t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
   410	
   411			// Accumulate dimensions,
   412			var dims []int64
   413			for kid := next(); kid != nil; kid = next() {
   414				// TODO(rsc): Can also be TagEnumerationType
   415				// but haven't seen that in the wild yet.
   416				switch kid.Tag {
   417				case TagSubrangeType:
   418					count, ok := kid.Val(AttrCount).(int64)
   419					if !ok {
   420						// Old binaries may have an upper bound instead.
   421						count, ok = kid.Val(AttrUpperBound).(int64)
   422						if ok {
   423							count++ // Length is one more than upper bound.
   424						} else if len(dims) == 0 {
   425							count = -1 // As in x[].
   426						}
   427					}
   428					dims = append(dims, count)
   429				case TagEnumerationType:
   430					err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
   431					goto Error
   432				}
   433			}
   434			if len(dims) == 0 {
   435				// LLVM generates this for x[].
   436				dims = []int64{-1}
   437			}
   438	
   439			t.Count = dims[0]
   440			for i := len(dims) - 1; i >= 1; i-- {
   441				t.Type = &ArrayType{Type: t.Type, Count: dims[i]}
   442			}
   443	
   444		case TagBaseType:
   445			// Basic type.  (DWARF v2 §5.1)
   446			// Attributes:
   447			//	AttrName: name of base type in programming language of the compilation unit [required]
   448			//	AttrEncoding: encoding value for type (encFloat etc) [required]
   449			//	AttrByteSize: size of type in bytes [required]
   450			//	AttrBitOffset: for sub-byte types, size in bits
   451			//	AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
   452			name, _ := e.Val(AttrName).(string)
   453			enc, ok := e.Val(AttrEncoding).(int64)
   454			if !ok {
   455				err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
   456				goto Error
   457			}
   458			switch enc {
   459			default:
   460				err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
   461				goto Error
   462	
   463			case encAddress:
   464				typ = new(AddrType)
   465			case encBoolean:
   466				typ = new(BoolType)
   467			case encComplexFloat:
   468				typ = new(ComplexType)
   469				if name == "complex" {
   470					// clang writes out 'complex' instead of 'complex float' or 'complex double'.
   471					// clang also writes out a byte size that we can use to distinguish.
   472					// See issue 8694.
   473					switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
   474					case 8:
   475						name = "complex float"
   476					case 16:
   477						name = "complex double"
   478					}
   479				}
   480			case encFloat:
   481				typ = new(FloatType)
   482			case encSigned:
   483				typ = new(IntType)
   484			case encUnsigned:
   485				typ = new(UintType)
   486			case encSignedChar:
   487				typ = new(CharType)
   488			case encUnsignedChar:
   489				typ = new(UcharType)
   490			}
   491			typeCache[off] = typ
   492			t := typ.(interface {
   493				Basic() *BasicType
   494			}).Basic()
   495			t.Name = name
   496			t.BitSize, _ = e.Val(AttrBitSize).(int64)
   497			t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
   498	
   499		case TagClassType, TagStructType, TagUnionType:
   500			// Structure, union, or class type.  (DWARF v2 §5.5)
   501			// Attributes:
   502			//	AttrName: name of struct, union, or class
   503			//	AttrByteSize: byte size [required]
   504			//	AttrDeclaration: if true, struct/union/class is incomplete
   505			// Children:
   506			//	TagMember to describe one member.
   507			//		AttrName: name of member [required]
   508			//		AttrType: type of member [required]
   509			//		AttrByteSize: size in bytes
   510			//		AttrBitOffset: bit offset within bytes for bit fields
   511			//		AttrBitSize: bit size for bit fields
   512			//		AttrDataMemberLoc: location within struct [required for struct, class]
   513			// There is much more to handle C++, all ignored for now.
   514			t := new(StructType)
   515			typ = t
   516			typeCache[off] = t
   517			switch e.Tag {
   518			case TagClassType:
   519				t.Kind = "class"
   520			case TagStructType:
   521				t.Kind = "struct"
   522			case TagUnionType:
   523				t.Kind = "union"
   524			}
   525			t.StructName, _ = e.Val(AttrName).(string)
   526			t.Incomplete = e.Val(AttrDeclaration) != nil
   527			t.Field = make([]*StructField, 0, 8)
   528			var lastFieldType *Type
   529			var lastFieldBitOffset int64
   530			for kid := next(); kid != nil; kid = next() {
   531				if kid.Tag != TagMember {
   532					continue
   533				}
   534				f := new(StructField)
   535				if f.Type = typeOf(kid); err != nil {
   536					goto Error
   537				}
   538				switch loc := kid.Val(AttrDataMemberLoc).(type) {
   539				case []byte:
   540					// TODO: Should have original compilation
   541					// unit here, not unknownFormat.
   542					b := makeBuf(d, unknownFormat{}, "location", 0, loc)
   543					if b.uint8() != opPlusUconst {
   544						err = DecodeError{name, kid.Offset, "unexpected opcode"}
   545						goto Error
   546					}
   547					f.ByteOffset = int64(b.uint())
   548					if b.err != nil {
   549						err = b.err
   550						goto Error
   551					}
   552				case int64:
   553					f.ByteOffset = loc
   554				}
   555	
   556				haveBitOffset := false
   557				f.Name, _ = kid.Val(AttrName).(string)
   558				f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
   559				f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
   560				f.BitSize, _ = kid.Val(AttrBitSize).(int64)
   561				t.Field = append(t.Field, f)
   562	
   563				bito := f.BitOffset
   564				if !haveBitOffset {
   565					bito = f.ByteOffset * 8
   566				}
   567				if bito == lastFieldBitOffset && t.Kind != "union" {
   568					// Last field was zero width. Fix array length.
   569					// (DWARF writes out 0-length arrays as if they were 1-length arrays.)
   570					zeroArray(lastFieldType)
   571				}
   572				lastFieldType = &f.Type
   573				lastFieldBitOffset = bito
   574			}
   575			if t.Kind != "union" {
   576				b, ok := e.Val(AttrByteSize).(int64)
   577				if ok && b*8 == lastFieldBitOffset {
   578					// Final field must be zero width. Fix array length.
   579					zeroArray(lastFieldType)
   580				}
   581			}
   582	
   583		case TagConstType, TagVolatileType, TagRestrictType:
   584			// Type modifier (DWARF v2 §5.2)
   585			// Attributes:
   586			//	AttrType: subtype
   587			t := new(QualType)
   588			typ = t
   589			typeCache[off] = t
   590			if t.Type = typeOf(e); err != nil {
   591				goto Error
   592			}
   593			switch e.Tag {
   594			case TagConstType:
   595				t.Qual = "const"
   596			case TagRestrictType:
   597				t.Qual = "restrict"
   598			case TagVolatileType:
   599				t.Qual = "volatile"
   600			}
   601	
   602		case TagEnumerationType:
   603			// Enumeration type (DWARF v2 §5.6)
   604			// Attributes:
   605			//	AttrName: enum name if any
   606			//	AttrByteSize: bytes required to represent largest value
   607			// Children:
   608			//	TagEnumerator:
   609			//		AttrName: name of constant
   610			//		AttrConstValue: value of constant
   611			t := new(EnumType)
   612			typ = t
   613			typeCache[off] = t
   614			t.EnumName, _ = e.Val(AttrName).(string)
   615			t.Val = make([]*EnumValue, 0, 8)
   616			for kid := next(); kid != nil; kid = next() {
   617				if kid.Tag == TagEnumerator {
   618					f := new(EnumValue)
   619					f.Name, _ = kid.Val(AttrName).(string)
   620					f.Val, _ = kid.Val(AttrConstValue).(int64)
   621					n := len(t.Val)
   622					if n >= cap(t.Val) {
   623						val := make([]*EnumValue, n, n*2)
   624						copy(val, t.Val)
   625						t.Val = val
   626					}
   627					t.Val = t.Val[0 : n+1]
   628					t.Val[n] = f
   629				}
   630			}
   631	
   632		case TagPointerType:
   633			// Type modifier (DWARF v2 §5.2)
   634			// Attributes:
   635			//	AttrType: subtype [not required!  void* has no AttrType]
   636			//	AttrAddrClass: address class [ignored]
   637			t := new(PtrType)
   638			typ = t
   639			typeCache[off] = t
   640			if e.Val(AttrType) == nil {
   641				t.Type = &VoidType{}
   642				break
   643			}
   644			t.Type = typeOf(e)
   645	
   646		case TagSubroutineType:
   647			// Subroutine type.  (DWARF v2 §5.7)
   648			// Attributes:
   649			//	AttrType: type of return value if any
   650			//	AttrName: possible name of type [ignored]
   651			//	AttrPrototyped: whether used ANSI C prototype [ignored]
   652			// Children:
   653			//	TagFormalParameter: typed parameter
   654			//		AttrType: type of parameter
   655			//	TagUnspecifiedParameter: final ...
   656			t := new(FuncType)
   657			typ = t
   658			typeCache[off] = t
   659			if t.ReturnType = typeOf(e); err != nil {
   660				goto Error
   661			}
   662			t.ParamType = make([]Type, 0, 8)
   663			for kid := next(); kid != nil; kid = next() {
   664				var tkid Type
   665				switch kid.Tag {
   666				default:
   667					continue
   668				case TagFormalParameter:
   669					if tkid = typeOf(kid); err != nil {
   670						goto Error
   671					}
   672				case TagUnspecifiedParameters:
   673					tkid = &DotDotDotType{}
   674				}
   675				t.ParamType = append(t.ParamType, tkid)
   676			}
   677	
   678		case TagTypedef:
   679			// Typedef (DWARF v2 §5.3)
   680			// Attributes:
   681			//	AttrName: name [required]
   682			//	AttrType: type definition [required]
   683			t := new(TypedefType)
   684			typ = t
   685			typeCache[off] = t
   686			t.Name, _ = e.Val(AttrName).(string)
   687			t.Type = typeOf(e)
   688	
   689		case TagUnspecifiedType:
   690			// Unspecified type (DWARF v3 §5.2)
   691			// Attributes:
   692			//	AttrName: name
   693			t := new(UnspecifiedType)
   694			typ = t
   695			typeCache[off] = t
   696			t.Name, _ = e.Val(AttrName).(string)
   697	
   698		default:
   699			// This is some other type DIE that we're currently not
   700			// equipped to handle. Return an abstract "unsupported type"
   701			// object in such cases.
   702			t := new(UnsupportedType)
   703			typ = t
   704			typeCache[off] = t
   705			t.Tag = e.Tag
   706			t.Name, _ = e.Val(AttrName).(string)
   707		}
   708	
   709		if err != nil {
   710			goto Error
   711		}
   712	
   713		{
   714			b, ok := e.Val(AttrByteSize).(int64)
   715			if !ok {
   716				b = -1
   717				switch t := typ.(type) {
   718				case *TypedefType:
   719					// Record that we need to resolve this
   720					// type's size once the type graph is
   721					// constructed.
   722					*typedefs = append(*typedefs, t)
   723				case *PtrType:
   724					b = int64(addressSize)
   725				}
   726			}
   727			typ.Common().ByteSize = b
   728		}
   729		return typ, nil
   730	
   731	Error:
   732		// If the parse fails, take the type out of the cache
   733		// so that the next call with this offset doesn't hit
   734		// the cache and return success.
   735		delete(typeCache, off)
   736		return nil, err
   737	}
   738	
   739	func zeroArray(t *Type) {
   740		if t == nil {
   741			return
   742		}
   743		at, ok := (*t).(*ArrayType)
   744		if !ok || at.Type.Size() == 0 {
   745			return
   746		}
   747		// Make a copy to avoid invalidating typeCache.
   748		tt := *at
   749		tt.Count = 0
   750		*t = &tt
   751	}
   752	

View as plain text