Source file src/pkg/debug/dwarf/type.go
1
2
3
4
5
6
7
8
9 package dwarf
10
11 import "strconv"
12
13
14
15 type Type interface {
16 Common() *CommonType
17 String() string
18 Size() int64
19 }
20
21
22
23
24 type CommonType struct {
25 ByteSize int64
26 Name string
27 }
28
29 func (c *CommonType) Common() *CommonType { return c }
30
31 func (c *CommonType) Size() int64 { return c.ByteSize }
32
33
34
35
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
52 type CharType struct {
53 BasicType
54 }
55
56
57 type UcharType struct {
58 BasicType
59 }
60
61
62 type IntType struct {
63 BasicType
64 }
65
66
67 type UintType struct {
68 BasicType
69 }
70
71
72 type FloatType struct {
73 BasicType
74 }
75
76
77 type ComplexType struct {
78 BasicType
79 }
80
81
82 type BoolType struct {
83 BasicType
84 }
85
86
87 type AddrType struct {
88 BasicType
89 }
90
91
92 type UnspecifiedType struct {
93 BasicType
94 }
95
96
97
98
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
110 type ArrayType struct {
111 CommonType
112 Type Type
113 StrideBitSize int64
114 Count int64
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
129 type VoidType struct {
130 CommonType
131 }
132
133 func (t *VoidType) String() string { return "void" }
134
135
136 type PtrType struct {
137 CommonType
138 Type Type
139 }
140
141 func (t *PtrType) String() string { return "*" + t.Type.String() }
142
143
144 type StructType struct {
145 CommonType
146 StructName string
147 Kind string
148 Field []*StructField
149 Incomplete bool
150 }
151
152
153 type StructField struct {
154 Name string
155 Type Type
156 ByteOffset int64
157 ByteSize int64
158 BitOffset int64
159 BitSize int64
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
195
196
197 type EnumType struct {
198 CommonType
199 EnumName string
200 Val []*EnumValue
201 }
202
203
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
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
248 type DotDotDotType struct {
249 CommonType
250 }
251
252 func (t *DotDotDotType) String() string { return "..." }
253
254
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
265
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
279
280 type typeReader interface {
281 Seek(Offset)
282 Next() (*Entry, error)
283 clone() typeReader
284 offset() Offset
285
286
287 AddressSize() int
288 }
289
290
291 func (d *Data) Type(off Offset) (Type, error) {
292 return d.readType("info", d.Reader(), off, d.typeCache, nil)
293 }
294
295
296
297
298
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
314
315
316
317
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
329
330
331 var typ Type
332
333 nextDepth := 0
334
335
336 next := func() *Entry {
337 if !e.Children {
338 return nil
339 }
340
341
342
343
344
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
373
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
388 return new(VoidType)
389 }
390 return t
391 }
392
393 switch e.Tag {
394 case TagArrayType:
395
396
397
398
399
400
401
402
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
412 var dims []int64
413 for kid := next(); kid != nil; kid = next() {
414
415
416 switch kid.Tag {
417 case TagSubrangeType:
418 count, ok := kid.Val(AttrCount).(int64)
419 if !ok {
420
421 count, ok = kid.Val(AttrUpperBound).(int64)
422 if ok {
423 count++
424 } else if len(dims) == 0 {
425 count = -1
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
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
446
447
448
449
450
451
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
471
472
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
501
502
503
504
505
506
507
508
509
510
511
512
513
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
541
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
569
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
579 zeroArray(lastFieldType)
580 }
581 }
582
583 case TagConstType, TagVolatileType, TagRestrictType:
584
585
586
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
604
605
606
607
608
609
610
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
634
635
636
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
648
649
650
651
652
653
654
655
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
680
681
682
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
691
692
693 t := new(UnspecifiedType)
694 typ = t
695 typeCache[off] = t
696 t.Name, _ = e.Val(AttrName).(string)
697
698 default:
699
700
701
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
720
721
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
733
734
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
748 tt := *at
749 tt.Count = 0
750 *t = &tt
751 }
752
View as plain text