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