1
2
3
4
5
6
7
8
9
10
11 package dwarf
12
13 import (
14 "errors"
15 "strconv"
16 )
17
18
19 type abbrev struct {
20 tag Tag
21 children bool
22 field []afield
23 }
24
25 type afield struct {
26 attr Attr
27 fmt format
28 class Class
29 }
30
31
32 type abbrevTable map[uint32]abbrev
33
34
35
36 func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
37 if m, ok := d.abbrevCache[off]; ok {
38 return m, nil
39 }
40
41 data := d.abbrev
42 if off > uint64(len(data)) {
43 data = nil
44 } else {
45 data = data[off:]
46 }
47 b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
48
49
50
51 m := make(abbrevTable)
52 for {
53
54 id := uint32(b.uint())
55 if id == 0 {
56 break
57 }
58
59
60 n := 0
61 b1 := b
62 b1.uint()
63 b1.uint8()
64 for {
65 tag := b1.uint()
66 fmt := b1.uint()
67 if tag == 0 && fmt == 0 {
68 break
69 }
70 n++
71 }
72 if b1.err != nil {
73 return nil, b1.err
74 }
75
76
77 var a abbrev
78 a.tag = Tag(b.uint())
79 a.children = b.uint8() != 0
80 a.field = make([]afield, n)
81 for i := range a.field {
82 a.field[i].attr = Attr(b.uint())
83 a.field[i].fmt = format(b.uint())
84 a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b)
85 }
86 b.uint()
87 b.uint()
88
89 m[id] = a
90 }
91 if b.err != nil {
92 return nil, b.err
93 }
94 d.abbrevCache[off] = m
95 return m, nil
96 }
97
98
99
100
101 var attrIsExprloc = map[Attr]bool{
102 AttrLocation: true,
103 AttrByteSize: true,
104 AttrBitOffset: true,
105 AttrBitSize: true,
106 AttrStringLength: true,
107 AttrLowerBound: true,
108 AttrReturnAddr: true,
109 AttrStrideSize: true,
110 AttrUpperBound: true,
111 AttrCount: true,
112 AttrDataMemberLoc: true,
113 AttrFrameBase: true,
114 AttrSegment: true,
115 AttrStaticLink: true,
116 AttrUseLocation: true,
117 AttrVtableElemLoc: true,
118 AttrAllocated: true,
119 AttrAssociated: true,
120 AttrDataLocation: true,
121 AttrStride: true,
122 }
123
124
125
126 var attrPtrClass = map[Attr]Class{
127 AttrLocation: ClassLocListPtr,
128 AttrStmtList: ClassLinePtr,
129 AttrStringLength: ClassLocListPtr,
130 AttrReturnAddr: ClassLocListPtr,
131 AttrStartScope: ClassRangeListPtr,
132 AttrDataMemberLoc: ClassLocListPtr,
133 AttrFrameBase: ClassLocListPtr,
134 AttrMacroInfo: ClassMacPtr,
135 AttrSegment: ClassLocListPtr,
136 AttrStaticLink: ClassLocListPtr,
137 AttrUseLocation: ClassLocListPtr,
138 AttrVtableElemLoc: ClassLocListPtr,
139 AttrRanges: ClassRangeListPtr,
140 }
141
142
143
144
145 func formToClass(form format, attr Attr, vers int, b *buf) Class {
146 switch form {
147 default:
148 b.error("cannot determine class of unknown attribute form")
149 return 0
150
151 case formAddr:
152 return ClassAddress
153
154 case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock:
155
156
157
158
159
160
161 if attrIsExprloc[attr] {
162 return ClassExprLoc
163 }
164 return ClassBlock
165
166 case formData1, formData2, formData4, formData8, formSdata, formUdata:
167
168
169
170
171
172 if class, ok := attrPtrClass[attr]; vers < 4 && ok {
173 return class
174 }
175 return ClassConstant
176
177 case formFlag, formFlagPresent:
178 return ClassFlag
179
180 case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata:
181 return ClassReference
182
183 case formRefSig8:
184 return ClassReferenceSig
185
186 case formString, formStrp:
187 return ClassString
188
189 case formSecOffset:
190
191
192
193 if class, ok := attrPtrClass[attr]; ok {
194 return class
195 }
196 return ClassUnknown
197
198 case formExprloc:
199 return ClassExprLoc
200
201 case formGnuRefAlt:
202 return ClassReferenceAlt
203
204 case formGnuStrpAlt:
205 return ClassStringAlt
206 }
207 }
208
209
210 type Entry struct {
211 Offset Offset
212 Tag Tag
213 Children bool
214 Field []Field
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240 type Field struct {
241 Attr Attr
242 Val interface{}
243 Class Class
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 type Class int
261
262 const (
263
264 ClassUnknown Class = iota
265
266
267
268 ClassAddress
269
270
271
272 ClassBlock
273
274
275
276
277 ClassConstant
278
279
280
281 ClassExprLoc
282
283
284 ClassFlag
285
286
287
288 ClassLinePtr
289
290
291
292 ClassLocListPtr
293
294
295
296 ClassMacPtr
297
298
299
300 ClassRangeListPtr
301
302
303
304
305
306 ClassReference
307
308
309
310 ClassReferenceSig
311
312
313
314
315
316 ClassString
317
318
319
320
321 ClassReferenceAlt
322
323
324
325
326 ClassStringAlt
327 )
328
329
330
331 func (i Class) GoString() string {
332 return "dwarf." + i.String()
333 }
334
335
336
337
338
339
340
341
342 func (e *Entry) Val(a Attr) interface{} {
343 if f := e.AttrField(a); f != nil {
344 return f.Val
345 }
346 return nil
347 }
348
349
350
351 func (e *Entry) AttrField(a Attr) *Field {
352 for i, f := range e.Field {
353 if f.Attr == a {
354 return &e.Field[i]
355 }
356 }
357 return nil
358 }
359
360
361
362 type Offset uint32
363
364
365
366 func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
367 off := b.off
368 id := uint32(b.uint())
369 if id == 0 {
370 return &Entry{}
371 }
372 a, ok := atab[id]
373 if !ok {
374 b.error("unknown abbreviation table index")
375 return nil
376 }
377 e := &Entry{
378 Offset: off,
379 Tag: a.tag,
380 Children: a.children,
381 Field: make([]Field, len(a.field)),
382 }
383 for i := range e.Field {
384 e.Field[i].Attr = a.field[i].attr
385 e.Field[i].Class = a.field[i].class
386 fmt := a.field[i].fmt
387 if fmt == formIndirect {
388 fmt = format(b.uint())
389 }
390 var val interface{}
391 switch fmt {
392 default:
393 b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16))
394
395
396 case formAddr:
397 val = b.addr()
398
399
400 case formDwarfBlock1:
401 val = b.bytes(int(b.uint8()))
402 case formDwarfBlock2:
403 val = b.bytes(int(b.uint16()))
404 case formDwarfBlock4:
405 val = b.bytes(int(b.uint32()))
406 case formDwarfBlock:
407 val = b.bytes(int(b.uint()))
408
409
410 case formData1:
411 val = int64(b.uint8())
412 case formData2:
413 val = int64(b.uint16())
414 case formData4:
415 val = int64(b.uint32())
416 case formData8:
417 val = int64(b.uint64())
418 case formSdata:
419 val = int64(b.int())
420 case formUdata:
421 val = int64(b.uint())
422
423
424 case formFlag:
425 val = b.uint8() == 1
426
427 case formFlagPresent:
428
429
430 val = true
431
432
433 case formRefAddr:
434 vers := b.format.version()
435 if vers == 0 {
436 b.error("unknown version for DW_FORM_ref_addr")
437 } else if vers == 2 {
438 val = Offset(b.addr())
439 } else {
440 is64, known := b.format.dwarf64()
441 if !known {
442 b.error("unknown size for DW_FORM_ref_addr")
443 } else if is64 {
444 val = Offset(b.uint64())
445 } else {
446 val = Offset(b.uint32())
447 }
448 }
449 case formRef1:
450 val = Offset(b.uint8()) + ubase
451 case formRef2:
452 val = Offset(b.uint16()) + ubase
453 case formRef4:
454 val = Offset(b.uint32()) + ubase
455 case formRef8:
456 val = Offset(b.uint64()) + ubase
457 case formRefUdata:
458 val = Offset(b.uint()) + ubase
459
460
461 case formString:
462 val = b.string()
463 case formStrp:
464 off := b.uint32()
465 if b.err != nil {
466 return nil
467 }
468 b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str)
469 b1.skip(int(off))
470 val = b1.string()
471 if b1.err != nil {
472 b.err = b1.err
473 return nil
474 }
475
476
477
478
479 case formSecOffset, formGnuRefAlt, formGnuStrpAlt:
480 is64, known := b.format.dwarf64()
481 if !known {
482 b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16))
483 } else if is64 {
484 val = int64(b.uint64())
485 } else {
486 val = int64(b.uint32())
487 }
488
489
490
491 case formExprloc:
492 val = b.bytes(int(b.uint()))
493
494
495
496 case formRefSig8:
497
498 val = b.uint64()
499 }
500 e.Field[i].Val = val
501 }
502 if b.err != nil {
503 return nil
504 }
505 return e
506 }
507
508
509
510
511
512
513 type Reader struct {
514 b buf
515 d *Data
516 err error
517 unit int
518 lastChildren bool
519 lastSibling Offset
520 }
521
522
523
524 func (d *Data) Reader() *Reader {
525 r := &Reader{d: d}
526 r.Seek(0)
527 return r
528 }
529
530
531
532 func (r *Reader) AddressSize() int {
533 return r.d.unit[r.unit].asize
534 }
535
536
537
538 func (r *Reader) Seek(off Offset) {
539 d := r.d
540 r.err = nil
541 r.lastChildren = false
542 if off == 0 {
543 if len(d.unit) == 0 {
544 return
545 }
546 u := &d.unit[0]
547 r.unit = 0
548 r.b = makeBuf(r.d, u, "info", u.off, u.data)
549 return
550 }
551
552 i := d.offsetToUnit(off)
553 if i == -1 {
554 r.err = errors.New("offset out of range")
555 return
556 }
557 u := &d.unit[i]
558 r.unit = i
559 r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
560 }
561
562
563 func (r *Reader) maybeNextUnit() {
564 for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
565 r.unit++
566 u := &r.d.unit[r.unit]
567 r.b = makeBuf(r.d, u, "info", u.off, u.data)
568 }
569 }
570
571
572
573
574
575 func (r *Reader) Next() (*Entry, error) {
576 if r.err != nil {
577 return nil, r.err
578 }
579 r.maybeNextUnit()
580 if len(r.b.data) == 0 {
581 return nil, nil
582 }
583 u := &r.d.unit[r.unit]
584 e := r.b.entry(u.atable, u.base)
585 if r.b.err != nil {
586 r.err = r.b.err
587 return nil, r.err
588 }
589 if e != nil {
590 r.lastChildren = e.Children
591 if r.lastChildren {
592 r.lastSibling, _ = e.Val(AttrSibling).(Offset)
593 }
594 } else {
595 r.lastChildren = false
596 }
597 return e, nil
598 }
599
600
601
602
603 func (r *Reader) SkipChildren() {
604 if r.err != nil || !r.lastChildren {
605 return
606 }
607
608
609
610
611
612 if r.lastSibling >= r.b.off {
613 r.Seek(r.lastSibling)
614 return
615 }
616
617 for {
618 e, err := r.Next()
619 if err != nil || e == nil || e.Tag == 0 {
620 break
621 }
622 if e.Children {
623 r.SkipChildren()
624 }
625 }
626 }
627
628
629
630 func (r *Reader) clone() typeReader {
631 return r.d.Reader()
632 }
633
634
635
636 func (r *Reader) offset() Offset {
637 return r.b.off
638 }
639
640
641
642
643
644
645
646
647
648
649
650
651
652 func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
653 unit := r.unit
654 for i := 0; i < len(r.d.unit); i++ {
655 if unit >= len(r.d.unit) {
656 unit = 0
657 }
658 r.err = nil
659 r.lastChildren = false
660 r.unit = unit
661 u := &r.d.unit[unit]
662 r.b = makeBuf(r.d, u, "info", u.off, u.data)
663 e, err := r.Next()
664 if err != nil {
665 return nil, err
666 }
667 ranges, err := r.d.Ranges(e)
668 if err != nil {
669 return nil, err
670 }
671 for _, pcs := range ranges {
672 if pcs[0] <= pc && pc < pcs[1] {
673 return e, nil
674 }
675 }
676 unit++
677 }
678 return nil, ErrUnknownPC
679 }
680
681
682
683
684 func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
685 var ret [][2]uint64
686
687 low, lowOK := e.Val(AttrLowpc).(uint64)
688
689 var high uint64
690 var highOK bool
691 highField := e.AttrField(AttrHighpc)
692 if highField != nil {
693 switch highField.Class {
694 case ClassAddress:
695 high, highOK = highField.Val.(uint64)
696 case ClassConstant:
697 off, ok := highField.Val.(int64)
698 if ok {
699 high = low + uint64(off)
700 highOK = true
701 }
702 }
703 }
704
705 if lowOK && highOK {
706 ret = append(ret, [2]uint64{low, high})
707 }
708
709 ranges, rangesOK := e.Val(AttrRanges).(int64)
710 if rangesOK && d.ranges != nil {
711
712
713
714
715
716 var cu *Entry
717 if e.Tag == TagCompileUnit {
718 cu = e
719 } else {
720 i := d.offsetToUnit(e.Offset)
721 if i == -1 {
722 return nil, errors.New("no unit for entry")
723 }
724 u := &d.unit[i]
725 b := makeBuf(d, u, "info", u.off, u.data)
726 cu = b.entry(u.atable, u.base)
727 if b.err != nil {
728 return nil, b.err
729 }
730 }
731
732 var base uint64
733 if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK {
734 base = cuEntry
735 } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK {
736 base = cuLow
737 }
738
739 u := &d.unit[d.offsetToUnit(e.Offset)]
740 buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
741 for len(buf.data) > 0 {
742 low = buf.addr()
743 high = buf.addr()
744
745 if low == 0 && high == 0 {
746 break
747 }
748
749 if low == ^uint64(0)>>uint((8-u.addrsize())*8) {
750 base = high
751 } else {
752 ret = append(ret, [2]uint64{base + low, base + high})
753 }
754 }
755 }
756
757 return ret, nil
758 }
759
View as plain text