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