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 type typeFixer struct {
296 typedefs []*TypedefType
297 arraytypes []*Type
298 }
299
300 func (tf *typeFixer) recordArrayType(t *Type) {
301 if t == nil {
302 return
303 }
304 _, ok := (*t).(*ArrayType)
305 if ok {
306 tf.arraytypes = append(tf.arraytypes, t)
307 }
308 }
309
310 func (tf *typeFixer) apply() {
311 for _, t := range tf.typedefs {
312 t.Common().ByteSize = t.Type.Size()
313 }
314 for _, t := range tf.arraytypes {
315 zeroArray(t)
316 }
317 }
318
319
320
321
322
323 func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, fixups *typeFixer) (Type, error) {
324 if t, ok := typeCache[off]; ok {
325 return t, nil
326 }
327 r.Seek(off)
328 e, err := r.Next()
329 if err != nil {
330 return nil, err
331 }
332 addressSize := r.AddressSize()
333 if e == nil || e.Offset != off {
334 return nil, DecodeError{name, off, "no type at offset"}
335 }
336
337
338
339
340
341
342 if fixups == nil {
343 var fixer typeFixer
344 defer func() {
345 fixer.apply()
346 }()
347 fixups = &fixer
348 }
349
350
351
352
353 var typ Type
354
355 nextDepth := 0
356
357
358 next := func() *Entry {
359 if !e.Children {
360 return nil
361 }
362
363
364
365
366
367 for {
368 kid, err1 := r.Next()
369 if err1 != nil {
370 err = err1
371 return nil
372 }
373 if kid == nil {
374 err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
375 return nil
376 }
377 if kid.Tag == 0 {
378 if nextDepth > 0 {
379 nextDepth--
380 continue
381 }
382 return nil
383 }
384 if kid.Children {
385 nextDepth++
386 }
387 if nextDepth > 0 {
388 continue
389 }
390 return kid
391 }
392 }
393
394
395
396 typeOf := func(e *Entry) Type {
397 tval := e.Val(AttrType)
398 var t Type
399 switch toff := tval.(type) {
400 case Offset:
401 if t, err = d.readType(name, r.clone(), toff, typeCache, fixups); err != nil {
402 return nil
403 }
404 case uint64:
405 if t, err = d.sigToType(toff); err != nil {
406 return nil
407 }
408 default:
409
410 return new(VoidType)
411 }
412 return t
413 }
414
415 switch e.Tag {
416 case TagArrayType:
417
418
419
420
421
422
423
424
425 t := new(ArrayType)
426 typ = t
427 typeCache[off] = t
428 if t.Type = typeOf(e); err != nil {
429 goto Error
430 }
431 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
432
433
434 var dims []int64
435 for kid := next(); kid != nil; kid = next() {
436
437
438 switch kid.Tag {
439 case TagSubrangeType:
440 count, ok := kid.Val(AttrCount).(int64)
441 if !ok {
442
443 count, ok = kid.Val(AttrUpperBound).(int64)
444 if ok {
445 count++
446 } else if len(dims) == 0 {
447 count = -1
448 }
449 }
450 dims = append(dims, count)
451 case TagEnumerationType:
452 err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
453 goto Error
454 }
455 }
456 if len(dims) == 0 {
457
458 dims = []int64{-1}
459 }
460
461 t.Count = dims[0]
462 for i := len(dims) - 1; i >= 1; i-- {
463 t.Type = &ArrayType{Type: t.Type, Count: dims[i]}
464 }
465
466 case TagBaseType:
467
468
469
470
471
472
473
474 name, _ := e.Val(AttrName).(string)
475 enc, ok := e.Val(AttrEncoding).(int64)
476 if !ok {
477 err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
478 goto Error
479 }
480 switch enc {
481 default:
482 err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
483 goto Error
484
485 case encAddress:
486 typ = new(AddrType)
487 case encBoolean:
488 typ = new(BoolType)
489 case encComplexFloat:
490 typ = new(ComplexType)
491 if name == "complex" {
492
493
494
495 switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
496 case 8:
497 name = "complex float"
498 case 16:
499 name = "complex double"
500 }
501 }
502 case encFloat:
503 typ = new(FloatType)
504 case encSigned:
505 typ = new(IntType)
506 case encUnsigned:
507 typ = new(UintType)
508 case encSignedChar:
509 typ = new(CharType)
510 case encUnsignedChar:
511 typ = new(UcharType)
512 }
513 typeCache[off] = typ
514 t := typ.(interface {
515 Basic() *BasicType
516 }).Basic()
517 t.Name = name
518 t.BitSize, _ = e.Val(AttrBitSize).(int64)
519 t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
520
521 case TagClassType, TagStructType, TagUnionType:
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 t := new(StructType)
537 typ = t
538 typeCache[off] = t
539 switch e.Tag {
540 case TagClassType:
541 t.Kind = "class"
542 case TagStructType:
543 t.Kind = "struct"
544 case TagUnionType:
545 t.Kind = "union"
546 }
547 t.StructName, _ = e.Val(AttrName).(string)
548 t.Incomplete = e.Val(AttrDeclaration) != nil
549 t.Field = make([]*StructField, 0, 8)
550 var lastFieldType *Type
551 var lastFieldBitOffset int64
552 for kid := next(); kid != nil; kid = next() {
553 if kid.Tag != TagMember {
554 continue
555 }
556 f := new(StructField)
557 if f.Type = typeOf(kid); err != nil {
558 goto Error
559 }
560 switch loc := kid.Val(AttrDataMemberLoc).(type) {
561 case []byte:
562
563
564 b := makeBuf(d, unknownFormat{}, "location", 0, loc)
565 if b.uint8() != opPlusUconst {
566 err = DecodeError{name, kid.Offset, "unexpected opcode"}
567 goto Error
568 }
569 f.ByteOffset = int64(b.uint())
570 if b.err != nil {
571 err = b.err
572 goto Error
573 }
574 case int64:
575 f.ByteOffset = loc
576 }
577
578 haveBitOffset := false
579 f.Name, _ = kid.Val(AttrName).(string)
580 f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
581 f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
582 f.BitSize, _ = kid.Val(AttrBitSize).(int64)
583 t.Field = append(t.Field, f)
584
585 bito := f.BitOffset
586 if !haveBitOffset {
587 bito = f.ByteOffset * 8
588 }
589 if bito == lastFieldBitOffset && t.Kind != "union" {
590
591
592 fixups.recordArrayType(lastFieldType)
593 }
594 lastFieldType = &f.Type
595 lastFieldBitOffset = bito
596 }
597 if t.Kind != "union" {
598 b, ok := e.Val(AttrByteSize).(int64)
599 if ok && b*8 == lastFieldBitOffset {
600
601 fixups.recordArrayType(lastFieldType)
602 }
603 }
604
605 case TagConstType, TagVolatileType, TagRestrictType:
606
607
608
609 t := new(QualType)
610 typ = t
611 typeCache[off] = t
612 if t.Type = typeOf(e); err != nil {
613 goto Error
614 }
615 switch e.Tag {
616 case TagConstType:
617 t.Qual = "const"
618 case TagRestrictType:
619 t.Qual = "restrict"
620 case TagVolatileType:
621 t.Qual = "volatile"
622 }
623
624 case TagEnumerationType:
625
626
627
628
629
630
631
632
633 t := new(EnumType)
634 typ = t
635 typeCache[off] = t
636 t.EnumName, _ = e.Val(AttrName).(string)
637 t.Val = make([]*EnumValue, 0, 8)
638 for kid := next(); kid != nil; kid = next() {
639 if kid.Tag == TagEnumerator {
640 f := new(EnumValue)
641 f.Name, _ = kid.Val(AttrName).(string)
642 f.Val, _ = kid.Val(AttrConstValue).(int64)
643 n := len(t.Val)
644 if n >= cap(t.Val) {
645 val := make([]*EnumValue, n, n*2)
646 copy(val, t.Val)
647 t.Val = val
648 }
649 t.Val = t.Val[0 : n+1]
650 t.Val[n] = f
651 }
652 }
653
654 case TagPointerType:
655
656
657
658
659 t := new(PtrType)
660 typ = t
661 typeCache[off] = t
662 if e.Val(AttrType) == nil {
663 t.Type = &VoidType{}
664 break
665 }
666 t.Type = typeOf(e)
667
668 case TagSubroutineType:
669
670
671
672
673
674
675
676
677
678 t := new(FuncType)
679 typ = t
680 typeCache[off] = t
681 if t.ReturnType = typeOf(e); err != nil {
682 goto Error
683 }
684 t.ParamType = make([]Type, 0, 8)
685 for kid := next(); kid != nil; kid = next() {
686 var tkid Type
687 switch kid.Tag {
688 default:
689 continue
690 case TagFormalParameter:
691 if tkid = typeOf(kid); err != nil {
692 goto Error
693 }
694 case TagUnspecifiedParameters:
695 tkid = &DotDotDotType{}
696 }
697 t.ParamType = append(t.ParamType, tkid)
698 }
699
700 case TagTypedef:
701
702
703
704
705 t := new(TypedefType)
706 typ = t
707 typeCache[off] = t
708 t.Name, _ = e.Val(AttrName).(string)
709 t.Type = typeOf(e)
710
711 case TagUnspecifiedType:
712
713
714
715 t := new(UnspecifiedType)
716 typ = t
717 typeCache[off] = t
718 t.Name, _ = e.Val(AttrName).(string)
719
720 default:
721
722
723
724 t := new(UnsupportedType)
725 typ = t
726 typeCache[off] = t
727 t.Tag = e.Tag
728 t.Name, _ = e.Val(AttrName).(string)
729 }
730
731 if err != nil {
732 goto Error
733 }
734
735 {
736 b, ok := e.Val(AttrByteSize).(int64)
737 if !ok {
738 b = -1
739 switch t := typ.(type) {
740 case *TypedefType:
741
742
743
744 fixups.typedefs = append(fixups.typedefs, t)
745 case *PtrType:
746 b = int64(addressSize)
747 }
748 }
749 typ.Common().ByteSize = b
750 }
751 return typ, nil
752
753 Error:
754
755
756
757 delete(typeCache, off)
758 return nil, err
759 }
760
761 func zeroArray(t *Type) {
762 at := (*t).(*ArrayType)
763 if at.Type.Size() == 0 {
764 return
765 }
766
767 tt := *at
768 tt.Count = 0
769 *t = &tt
770 }
771
View as plain text