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
9package dwarf
10
11import "strconv"
12
13// A Type conventionally represents a pointer to any of the
14// specific Type structures (CharType, StructType, etc.).
15type 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.
24type 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
29func (c *CommonType) Common() *CommonType { return c }
30
31func (c *CommonType) Size() int64 { return c.ByteSize }
32
33// Basic types
34
35// A BasicType holds fields common to all basic types.
36type BasicType struct {
37	CommonType
38	BitSize   int64
39	BitOffset int64
40}
41
42func (b *BasicType) Basic() *BasicType { return b }
43
44func (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.
52type CharType struct {
53	BasicType
54}
55
56// A UcharType represents an unsigned character type.
57type UcharType struct {
58	BasicType
59}
60
61// An IntType represents a signed integer type.
62type IntType struct {
63	BasicType
64}
65
66// A UintType represents an unsigned integer type.
67type UintType struct {
68	BasicType
69}
70
71// A FloatType represents a floating point type.
72type FloatType struct {
73	BasicType
74}
75
76// A ComplexType represents a complex floating point type.
77type ComplexType struct {
78	BasicType
79}
80
81// A BoolType represents a boolean type.
82type BoolType struct {
83	BasicType
84}
85
86// An AddrType represents a machine address type.
87type AddrType struct {
88	BasicType
89}
90
91// An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type.
92type 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.
99type QualType struct {
100	CommonType
101	Qual string
102	Type Type
103}
104
105func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
106
107func (t *QualType) Size() int64 { return t.Type.Size() }
108
109// An ArrayType represents a fixed size array type.
110type 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
117func (t *ArrayType) String() string {
118	return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
119}
120
121func (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.
129type VoidType struct {
130	CommonType
131}
132
133func (t *VoidType) String() string { return "void" }
134
135// A PtrType represents a pointer type.
136type PtrType struct {
137	CommonType
138	Type Type
139}
140
141func (t *PtrType) String() string { return "*" + t.Type.String() }
142
143// A StructType represents a struct, union, or C++ class type.
144type 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.
153type 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
162func (t *StructType) String() string {
163	if t.StructName != "" {
164		return t.Kind + " " + t.StructName
165	}
166	return t.Defn()
167}
168
169func (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).
197type EnumType struct {
198	CommonType
199	EnumName string
200	Val      []*EnumValue
201}
202
203// An EnumValue represents a single enumeration value.
204type EnumValue struct {
205	Name string
206	Val  int64
207}
208
209func (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.
226type FuncType struct {
227	CommonType
228	ReturnType Type
229	ParamType  []Type
230}
231
232func (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.
248type DotDotDotType struct {
249	CommonType
250}
251
252func (t *DotDotDotType) String() string { return "..." }
253
254// A TypedefType represents a named type.
255type TypedefType struct {
256	CommonType
257	Type Type
258}
259
260func (t *TypedefType) String() string { return t.Name }
261
262func (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.
266type UnsupportedType struct {
267	CommonType
268	Tag Tag
269}
270
271func (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.
280type 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.
291func (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.
299func (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
731Error:
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
739func 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