...

Source file src/debug/dwarf/type.go

Documentation: debug/dwarf

		 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  		t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
	 520  
	 521  	case TagClassType, TagStructType, TagUnionType:
	 522  		// Structure, union, or class type.	(DWARF v2 §5.5)
	 523  		// Attributes:
	 524  		//	AttrName: name of struct, union, or class
	 525  		//	AttrByteSize: byte size [required]
	 526  		//	AttrDeclaration: if true, struct/union/class is incomplete
	 527  		// Children:
	 528  		//	TagMember to describe one member.
	 529  		//		AttrName: name of member [required]
	 530  		//		AttrType: type of member [required]
	 531  		//		AttrByteSize: size in bytes
	 532  		//		AttrBitOffset: bit offset within bytes for bit fields
	 533  		//		AttrBitSize: bit size for bit fields
	 534  		//		AttrDataMemberLoc: location within struct [required for struct, class]
	 535  		// There is much more to handle C++, all ignored for now.
	 536  		t := new(StructType)
	 537  		typ = t
	 538  		typeCache[off] = t
	 539  		switch e.Tag {
	 540  		case TagClassType:
	 541  			t.Kind = "class"
	 542  		case TagStructType:
	 543  			t.Kind = "struct"
	 544  		case TagUnionType:
	 545  			t.Kind = "union"
	 546  		}
	 547  		t.StructName, _ = e.Val(AttrName).(string)
	 548  		t.Incomplete = e.Val(AttrDeclaration) != nil
	 549  		t.Field = make([]*StructField, 0, 8)
	 550  		var lastFieldType *Type
	 551  		var lastFieldBitOffset int64
	 552  		for kid := next(); kid != nil; kid = next() {
	 553  			if kid.Tag != TagMember {
	 554  				continue
	 555  			}
	 556  			f := new(StructField)
	 557  			if f.Type = typeOf(kid); err != nil {
	 558  				goto Error
	 559  			}
	 560  			switch loc := kid.Val(AttrDataMemberLoc).(type) {
	 561  			case []byte:
	 562  				// TODO: Should have original compilation
	 563  				// unit here, not unknownFormat.
	 564  				b := makeBuf(d, unknownFormat{}, "location", 0, loc)
	 565  				if b.uint8() != opPlusUconst {
	 566  					err = DecodeError{name, kid.Offset, "unexpected opcode"}
	 567  					goto Error
	 568  				}
	 569  				f.ByteOffset = int64(b.uint())
	 570  				if b.err != nil {
	 571  					err = b.err
	 572  					goto Error
	 573  				}
	 574  			case int64:
	 575  				f.ByteOffset = loc
	 576  			}
	 577  
	 578  			haveBitOffset := false
	 579  			f.Name, _ = kid.Val(AttrName).(string)
	 580  			f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
	 581  			f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
	 582  			f.BitSize, _ = kid.Val(AttrBitSize).(int64)
	 583  			t.Field = append(t.Field, f)
	 584  
	 585  			bito := f.BitOffset
	 586  			if !haveBitOffset {
	 587  				bito = f.ByteOffset * 8
	 588  			}
	 589  			if bito == lastFieldBitOffset && t.Kind != "union" {
	 590  				// Last field was zero width. Fix array length.
	 591  				// (DWARF writes out 0-length arrays as if they were 1-length arrays.)
	 592  				fixups.recordArrayType(lastFieldType)
	 593  			}
	 594  			lastFieldType = &f.Type
	 595  			lastFieldBitOffset = bito
	 596  		}
	 597  		if t.Kind != "union" {
	 598  			b, ok := e.Val(AttrByteSize).(int64)
	 599  			if ok && b*8 == lastFieldBitOffset {
	 600  				// Final field must be zero width. Fix array length.
	 601  				fixups.recordArrayType(lastFieldType)
	 602  			}
	 603  		}
	 604  
	 605  	case TagConstType, TagVolatileType, TagRestrictType:
	 606  		// Type modifier (DWARF v2 §5.2)
	 607  		// Attributes:
	 608  		//	AttrType: subtype
	 609  		t := new(QualType)
	 610  		typ = t
	 611  		typeCache[off] = t
	 612  		if t.Type = typeOf(e); err != nil {
	 613  			goto Error
	 614  		}
	 615  		switch e.Tag {
	 616  		case TagConstType:
	 617  			t.Qual = "const"
	 618  		case TagRestrictType:
	 619  			t.Qual = "restrict"
	 620  		case TagVolatileType:
	 621  			t.Qual = "volatile"
	 622  		}
	 623  
	 624  	case TagEnumerationType:
	 625  		// Enumeration type (DWARF v2 §5.6)
	 626  		// Attributes:
	 627  		//	AttrName: enum name if any
	 628  		//	AttrByteSize: bytes required to represent largest value
	 629  		// Children:
	 630  		//	TagEnumerator:
	 631  		//		AttrName: name of constant
	 632  		//		AttrConstValue: value of constant
	 633  		t := new(EnumType)
	 634  		typ = t
	 635  		typeCache[off] = t
	 636  		t.EnumName, _ = e.Val(AttrName).(string)
	 637  		t.Val = make([]*EnumValue, 0, 8)
	 638  		for kid := next(); kid != nil; kid = next() {
	 639  			if kid.Tag == TagEnumerator {
	 640  				f := new(EnumValue)
	 641  				f.Name, _ = kid.Val(AttrName).(string)
	 642  				f.Val, _ = kid.Val(AttrConstValue).(int64)
	 643  				n := len(t.Val)
	 644  				if n >= cap(t.Val) {
	 645  					val := make([]*EnumValue, n, n*2)
	 646  					copy(val, t.Val)
	 647  					t.Val = val
	 648  				}
	 649  				t.Val = t.Val[0 : n+1]
	 650  				t.Val[n] = f
	 651  			}
	 652  		}
	 653  
	 654  	case TagPointerType:
	 655  		// Type modifier (DWARF v2 §5.2)
	 656  		// Attributes:
	 657  		//	AttrType: subtype [not required!	void* has no AttrType]
	 658  		//	AttrAddrClass: address class [ignored]
	 659  		t := new(PtrType)
	 660  		typ = t
	 661  		typeCache[off] = t
	 662  		if e.Val(AttrType) == nil {
	 663  			t.Type = &VoidType{}
	 664  			break
	 665  		}
	 666  		t.Type = typeOf(e)
	 667  
	 668  	case TagSubroutineType:
	 669  		// Subroutine type.	(DWARF v2 §5.7)
	 670  		// Attributes:
	 671  		//	AttrType: type of return value if any
	 672  		//	AttrName: possible name of type [ignored]
	 673  		//	AttrPrototyped: whether used ANSI C prototype [ignored]
	 674  		// Children:
	 675  		//	TagFormalParameter: typed parameter
	 676  		//		AttrType: type of parameter
	 677  		//	TagUnspecifiedParameter: final ...
	 678  		t := new(FuncType)
	 679  		typ = t
	 680  		typeCache[off] = t
	 681  		if t.ReturnType = typeOf(e); err != nil {
	 682  			goto Error
	 683  		}
	 684  		t.ParamType = make([]Type, 0, 8)
	 685  		for kid := next(); kid != nil; kid = next() {
	 686  			var tkid Type
	 687  			switch kid.Tag {
	 688  			default:
	 689  				continue
	 690  			case TagFormalParameter:
	 691  				if tkid = typeOf(kid); err != nil {
	 692  					goto Error
	 693  				}
	 694  			case TagUnspecifiedParameters:
	 695  				tkid = &DotDotDotType{}
	 696  			}
	 697  			t.ParamType = append(t.ParamType, tkid)
	 698  		}
	 699  
	 700  	case TagTypedef:
	 701  		// Typedef (DWARF v2 §5.3)
	 702  		// Attributes:
	 703  		//	AttrName: name [required]
	 704  		//	AttrType: type definition [required]
	 705  		t := new(TypedefType)
	 706  		typ = t
	 707  		typeCache[off] = t
	 708  		t.Name, _ = e.Val(AttrName).(string)
	 709  		t.Type = typeOf(e)
	 710  
	 711  	case TagUnspecifiedType:
	 712  		// Unspecified type (DWARF v3 §5.2)
	 713  		// Attributes:
	 714  		//	AttrName: name
	 715  		t := new(UnspecifiedType)
	 716  		typ = t
	 717  		typeCache[off] = t
	 718  		t.Name, _ = e.Val(AttrName).(string)
	 719  
	 720  	default:
	 721  		// This is some other type DIE that we're currently not
	 722  		// equipped to handle. Return an abstract "unsupported type"
	 723  		// object in such cases.
	 724  		t := new(UnsupportedType)
	 725  		typ = t
	 726  		typeCache[off] = t
	 727  		t.Tag = e.Tag
	 728  		t.Name, _ = e.Val(AttrName).(string)
	 729  	}
	 730  
	 731  	if err != nil {
	 732  		goto Error
	 733  	}
	 734  
	 735  	{
	 736  		b, ok := e.Val(AttrByteSize).(int64)
	 737  		if !ok {
	 738  			b = -1
	 739  			switch t := typ.(type) {
	 740  			case *TypedefType:
	 741  				// Record that we need to resolve this
	 742  				// type's size once the type graph is
	 743  				// constructed.
	 744  				fixups.typedefs = append(fixups.typedefs, t)
	 745  			case *PtrType:
	 746  				b = int64(addressSize)
	 747  			}
	 748  		}
	 749  		typ.Common().ByteSize = b
	 750  	}
	 751  	return typ, nil
	 752  
	 753  Error:
	 754  	// If the parse fails, take the type out of the cache
	 755  	// so that the next call with this offset doesn't hit
	 756  	// the cache and return success.
	 757  	delete(typeCache, off)
	 758  	return nil, err
	 759  }
	 760  
	 761  func zeroArray(t *Type) {
	 762  	at := (*t).(*ArrayType)
	 763  	if at.Type.Size() == 0 {
	 764  		return
	 765  	}
	 766  	// Make a copy to avoid invalidating typeCache.
	 767  	tt := *at
	 768  	tt.Count = 0
	 769  	*t = &tt
	 770  }
	 771  

View as plain text