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