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