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
37
38
39 type BasicType struct {
40 CommonType
41 BitSize int64
42 BitOffset int64
43 DataBitOffset int64
44 }
45
46 func (b *BasicType) Basic() *BasicType { return b }
47
48 func (t *BasicType) String() string {
49 if t.Name != "" {
50 return t.Name
51 }
52 return "?"
53 }
54
55
56 type CharType struct {
57 BasicType
58 }
59
60
61 type UcharType struct {
62 BasicType
63 }
64
65
66 type IntType struct {
67 BasicType
68 }
69
70
71 type UintType struct {
72 BasicType
73 }
74
75
76 type FloatType struct {
77 BasicType
78 }
79
80
81 type ComplexType struct {
82 BasicType
83 }
84
85
86 type BoolType struct {
87 BasicType
88 }
89
90
91 type AddrType struct {
92 BasicType
93 }
94
95
96 type UnspecifiedType struct {
97 BasicType
98 }
99
100
101
102
103 type QualType struct {
104 CommonType
105 Qual string
106 Type Type
107 }
108
109 func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
110
111 func (t *QualType) Size() int64 { return t.Type.Size() }
112
113
114 type ArrayType struct {
115 CommonType
116 Type Type
117 StrideBitSize int64
118 Count int64
119 }
120
121 func (t *ArrayType) String() string {
122 return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
123 }
124
125 func (t *ArrayType) Size() int64 {
126 if t.Count == -1 {
127 return 0
128 }
129 return t.Count * t.Type.Size()
130 }
131
132
133 type VoidType struct {
134 CommonType
135 }
136
137 func (t *VoidType) String() string { return "void" }
138
139
140 type PtrType struct {
141 CommonType
142 Type Type
143 }
144
145 func (t *PtrType) String() string { return "*" + t.Type.String() }
146
147
148 type StructType struct {
149 CommonType
150 StructName string
151 Kind string
152 Field []*StructField
153 Incomplete bool
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 type StructField struct {
231 Name string
232 Type Type
233 ByteOffset int64
234 ByteSize int64
235 BitOffset int64
236 DataBitOffset int64
237 BitSize int64
238 }
239
240 func (t *StructType) String() string {
241 if t.StructName != "" {
242 return t.Kind + " " + t.StructName
243 }
244 return t.Defn()
245 }
246
247 func (f *StructField) bitOffset() int64 {
248 if f.BitOffset != 0 {
249 return f.BitOffset
250 }
251 return f.DataBitOffset
252 }
253
254 func (t *StructType) Defn() string {
255 s := t.Kind
256 if t.StructName != "" {
257 s += " " + t.StructName
258 }
259 if t.Incomplete {
260 s += " /*incomplete*/"
261 return s
262 }
263 s += " {"
264 for i, f := range t.Field {
265 if i > 0 {
266 s += "; "
267 }
268 s += f.Name + " " + f.Type.String()
269 s += "@" + strconv.FormatInt(f.ByteOffset, 10)
270 if f.BitSize > 0 {
271 s += " : " + strconv.FormatInt(f.BitSize, 10)
272 s += "@" + strconv.FormatInt(f.bitOffset(), 10)
273 }
274 }
275 s += "}"
276 return s
277 }
278
279
280
281
282 type EnumType struct {
283 CommonType
284 EnumName string
285 Val []*EnumValue
286 }
287
288
289 type EnumValue struct {
290 Name string
291 Val int64
292 }
293
294 func (t *EnumType) String() string {
295 s := "enum"
296 if t.EnumName != "" {
297 s += " " + t.EnumName
298 }
299 s += " {"
300 for i, v := range t.Val {
301 if i > 0 {
302 s += "; "
303 }
304 s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
305 }
306 s += "}"
307 return s
308 }
309
310
311 type FuncType struct {
312 CommonType
313 ReturnType Type
314 ParamType []Type
315 }
316
317 func (t *FuncType) String() string {
318 s := "func("
319 for i, t := range t.ParamType {
320 if i > 0 {
321 s += ", "
322 }
323 s += t.String()
324 }
325 s += ")"
326 if t.ReturnType != nil {
327 s += " " + t.ReturnType.String()
328 }
329 return s
330 }
331
332
333 type DotDotDotType struct {
334 CommonType
335 }
336
337 func (t *DotDotDotType) String() string { return "..." }
338
339
340 type TypedefType struct {
341 CommonType
342 Type Type
343 }
344
345 func (t *TypedefType) String() string { return t.Name }
346
347 func (t *TypedefType) Size() int64 { return t.Type.Size() }
348
349
350
351 type UnsupportedType struct {
352 CommonType
353 Tag Tag
354 }
355
356 func (t *UnsupportedType) String() string {
357 if t.Name != "" {
358 return t.Name
359 }
360 return t.Name + "(unsupported type " + t.Tag.String() + ")"
361 }
362
363
364
365 type typeReader interface {
366 Seek(Offset)
367 Next() (*Entry, error)
368 clone() typeReader
369 offset() Offset
370
371
372 AddressSize() int
373 }
374
375
376 func (d *Data) Type(off Offset) (Type, error) {
377 return d.readType("info", d.Reader(), off, d.typeCache, nil)
378 }
379
380 type typeFixer struct {
381 typedefs []*TypedefType
382 arraytypes []*Type
383 }
384
385 func (tf *typeFixer) recordArrayType(t *Type) {
386 if t == nil {
387 return
388 }
389 _, ok := (*t).(*ArrayType)
390 if ok {
391 tf.arraytypes = append(tf.arraytypes, t)
392 }
393 }
394
395 func (tf *typeFixer) apply() {
396 for _, t := range tf.typedefs {
397 t.Common().ByteSize = t.Type.Size()
398 }
399 for _, t := range tf.arraytypes {
400 zeroArray(t)
401 }
402 }
403
404
405
406
407
408 func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, fixups *typeFixer) (Type, error) {
409 if t, ok := typeCache[off]; ok {
410 return t, nil
411 }
412 r.Seek(off)
413 e, err := r.Next()
414 if err != nil {
415 return nil, err
416 }
417 addressSize := r.AddressSize()
418 if e == nil || e.Offset != off {
419 return nil, DecodeError{name, off, "no type at offset"}
420 }
421
422
423
424
425
426
427 if fixups == nil {
428 var fixer typeFixer
429 defer func() {
430 fixer.apply()
431 }()
432 fixups = &fixer
433 }
434
435
436
437
438 var typ Type
439
440 nextDepth := 0
441
442
443 next := func() *Entry {
444 if !e.Children {
445 return nil
446 }
447
448
449
450
451
452 for {
453 kid, err1 := r.Next()
454 if err1 != nil {
455 err = err1
456 return nil
457 }
458 if kid == nil {
459 err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
460 return nil
461 }
462 if kid.Tag == 0 {
463 if nextDepth > 0 {
464 nextDepth--
465 continue
466 }
467 return nil
468 }
469 if kid.Children {
470 nextDepth++
471 }
472 if nextDepth > 0 {
473 continue
474 }
475 return kid
476 }
477 }
478
479
480
481 typeOf := func(e *Entry) Type {
482 tval := e.Val(AttrType)
483 var t Type
484 switch toff := tval.(type) {
485 case Offset:
486 if t, err = d.readType(name, r.clone(), toff, typeCache, fixups); err != nil {
487 return nil
488 }
489 case uint64:
490 if t, err = d.sigToType(toff); err != nil {
491 return nil
492 }
493 default:
494
495 return new(VoidType)
496 }
497 return t
498 }
499
500 switch e.Tag {
501 case TagArrayType:
502
503
504
505
506
507
508
509
510 t := new(ArrayType)
511 typ = t
512 typeCache[off] = t
513 if t.Type = typeOf(e); err != nil {
514 goto Error
515 }
516 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
517
518
519 var dims []int64
520 for kid := next(); kid != nil; kid = next() {
521
522
523 switch kid.Tag {
524 case TagSubrangeType:
525 count, ok := kid.Val(AttrCount).(int64)
526 if !ok {
527
528 count, ok = kid.Val(AttrUpperBound).(int64)
529 if ok {
530 count++
531 } else if len(dims) == 0 {
532 count = -1
533 }
534 }
535 dims = append(dims, count)
536 case TagEnumerationType:
537 err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
538 goto Error
539 }
540 }
541 if len(dims) == 0 {
542
543 dims = []int64{-1}
544 }
545
546 t.Count = dims[0]
547 for i := len(dims) - 1; i >= 1; i-- {
548 t.Type = &ArrayType{Type: t.Type, Count: dims[i]}
549 }
550
551 case TagBaseType:
552
553
554
555
556
557
558
559
560
561
562
563 name, _ := e.Val(AttrName).(string)
564 enc, ok := e.Val(AttrEncoding).(int64)
565 if !ok {
566 err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
567 goto Error
568 }
569 switch enc {
570 default:
571 err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
572 goto Error
573
574 case encAddress:
575 typ = new(AddrType)
576 case encBoolean:
577 typ = new(BoolType)
578 case encComplexFloat:
579 typ = new(ComplexType)
580 if name == "complex" {
581
582
583
584 switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
585 case 8:
586 name = "complex float"
587 case 16:
588 name = "complex double"
589 }
590 }
591 case encFloat:
592 typ = new(FloatType)
593 case encSigned:
594 typ = new(IntType)
595 case encUnsigned:
596 typ = new(UintType)
597 case encSignedChar:
598 typ = new(CharType)
599 case encUnsignedChar:
600 typ = new(UcharType)
601 }
602 typeCache[off] = typ
603 t := typ.(interface {
604 Basic() *BasicType
605 }).Basic()
606 t.Name = name
607 t.BitSize, _ = e.Val(AttrBitSize).(int64)
608 haveBitOffset := false
609 haveDataBitOffset := false
610 t.BitOffset, haveBitOffset = e.Val(AttrBitOffset).(int64)
611 t.DataBitOffset, haveDataBitOffset = e.Val(AttrDataBitOffset).(int64)
612 if haveBitOffset && haveDataBitOffset {
613 err = DecodeError{name, e.Offset, "duplicate bit offset attributes"}
614 goto Error
615 }
616
617 case TagClassType, TagStructType, TagUnionType:
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633 t := new(StructType)
634 typ = t
635 typeCache[off] = t
636 switch e.Tag {
637 case TagClassType:
638 t.Kind = "class"
639 case TagStructType:
640 t.Kind = "struct"
641 case TagUnionType:
642 t.Kind = "union"
643 }
644 t.StructName, _ = e.Val(AttrName).(string)
645 t.Incomplete = e.Val(AttrDeclaration) != nil
646 t.Field = make([]*StructField, 0, 8)
647 var lastFieldType *Type
648 var lastFieldBitSize int64
649 var lastFieldByteOffset int64
650 for kid := next(); kid != nil; kid = next() {
651 if kid.Tag != TagMember {
652 continue
653 }
654 f := new(StructField)
655 if f.Type = typeOf(kid); err != nil {
656 goto Error
657 }
658 switch loc := kid.Val(AttrDataMemberLoc).(type) {
659 case []byte:
660
661
662 b := makeBuf(d, unknownFormat{}, "location", 0, loc)
663 if b.uint8() != opPlusUconst {
664 err = DecodeError{name, kid.Offset, "unexpected opcode"}
665 goto Error
666 }
667 f.ByteOffset = int64(b.uint())
668 if b.err != nil {
669 err = b.err
670 goto Error
671 }
672 case int64:
673 f.ByteOffset = loc
674 }
675
676 f.Name, _ = kid.Val(AttrName).(string)
677 f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
678 haveBitOffset := false
679 haveDataBitOffset := false
680 f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
681 f.DataBitOffset, haveDataBitOffset = kid.Val(AttrDataBitOffset).(int64)
682 if haveBitOffset && haveDataBitOffset {
683 err = DecodeError{name, e.Offset, "duplicate bit offset attributes"}
684 goto Error
685 }
686 f.BitSize, _ = kid.Val(AttrBitSize).(int64)
687 t.Field = append(t.Field, f)
688
689 if lastFieldBitSize == 0 && lastFieldByteOffset == f.ByteOffset && t.Kind != "union" {
690
691
692 fixups.recordArrayType(lastFieldType)
693 }
694 lastFieldType = &f.Type
695 lastFieldByteOffset = f.ByteOffset
696 lastFieldBitSize = f.BitSize
697 }
698 if t.Kind != "union" {
699 b, ok := e.Val(AttrByteSize).(int64)
700 if ok && b == lastFieldByteOffset {
701
702 fixups.recordArrayType(lastFieldType)
703 }
704 }
705
706 case TagConstType, TagVolatileType, TagRestrictType:
707
708
709
710 t := new(QualType)
711 typ = t
712 typeCache[off] = t
713 if t.Type = typeOf(e); err != nil {
714 goto Error
715 }
716 switch e.Tag {
717 case TagConstType:
718 t.Qual = "const"
719 case TagRestrictType:
720 t.Qual = "restrict"
721 case TagVolatileType:
722 t.Qual = "volatile"
723 }
724
725 case TagEnumerationType:
726
727
728
729
730
731
732
733
734 t := new(EnumType)
735 typ = t
736 typeCache[off] = t
737 t.EnumName, _ = e.Val(AttrName).(string)
738 t.Val = make([]*EnumValue, 0, 8)
739 for kid := next(); kid != nil; kid = next() {
740 if kid.Tag == TagEnumerator {
741 f := new(EnumValue)
742 f.Name, _ = kid.Val(AttrName).(string)
743 f.Val, _ = kid.Val(AttrConstValue).(int64)
744 n := len(t.Val)
745 if n >= cap(t.Val) {
746 val := make([]*EnumValue, n, n*2)
747 copy(val, t.Val)
748 t.Val = val
749 }
750 t.Val = t.Val[0 : n+1]
751 t.Val[n] = f
752 }
753 }
754
755 case TagPointerType:
756
757
758
759
760 t := new(PtrType)
761 typ = t
762 typeCache[off] = t
763 if e.Val(AttrType) == nil {
764 t.Type = &VoidType{}
765 break
766 }
767 t.Type = typeOf(e)
768
769 case TagSubroutineType:
770
771
772
773
774
775
776
777
778
779 t := new(FuncType)
780 typ = t
781 typeCache[off] = t
782 if t.ReturnType = typeOf(e); err != nil {
783 goto Error
784 }
785 t.ParamType = make([]Type, 0, 8)
786 for kid := next(); kid != nil; kid = next() {
787 var tkid Type
788 switch kid.Tag {
789 default:
790 continue
791 case TagFormalParameter:
792 if tkid = typeOf(kid); err != nil {
793 goto Error
794 }
795 case TagUnspecifiedParameters:
796 tkid = &DotDotDotType{}
797 }
798 t.ParamType = append(t.ParamType, tkid)
799 }
800
801 case TagTypedef:
802
803
804
805
806 t := new(TypedefType)
807 typ = t
808 typeCache[off] = t
809 t.Name, _ = e.Val(AttrName).(string)
810 t.Type = typeOf(e)
811
812 case TagUnspecifiedType:
813
814
815
816 t := new(UnspecifiedType)
817 typ = t
818 typeCache[off] = t
819 t.Name, _ = e.Val(AttrName).(string)
820
821 default:
822
823
824
825 t := new(UnsupportedType)
826 typ = t
827 typeCache[off] = t
828 t.Tag = e.Tag
829 t.Name, _ = e.Val(AttrName).(string)
830 }
831
832 if err != nil {
833 goto Error
834 }
835
836 {
837 b, ok := e.Val(AttrByteSize).(int64)
838 if !ok {
839 b = -1
840 switch t := typ.(type) {
841 case *TypedefType:
842
843
844
845 fixups.typedefs = append(fixups.typedefs, t)
846 case *PtrType:
847 b = int64(addressSize)
848 }
849 }
850 typ.Common().ByteSize = b
851 }
852 return typ, nil
853
854 Error:
855
856
857
858 delete(typeCache, off)
859 return nil, err
860 }
861
862 func zeroArray(t *Type) {
863 at := (*t).(*ArrayType)
864 if at.Type.Size() == 0 {
865 return
866 }
867
868 tt := *at
869 tt.Count = 0
870 *t = &tt
871 }
872
View as plain text