1
2
3
4
5
6
7
8
9
10
11 package dwarf
12
13 import (
14 "encoding/binary"
15 "errors"
16 "strconv"
17 )
18
19
20 type abbrev struct {
21 tag Tag
22 children bool
23 field []afield
24 }
25
26 type afield struct {
27 attr Attr
28 fmt format
29 class Class
30 val int64
31 }
32
33
34 type abbrevTable map[uint32]abbrev
35
36
37
38 func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
39 if m, ok := d.abbrevCache[off]; ok {
40 return m, nil
41 }
42
43 data := d.abbrev
44 if off > uint64(len(data)) {
45 data = nil
46 } else {
47 data = data[off:]
48 }
49 b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
50
51
52
53 m := make(abbrevTable)
54 for {
55
56 id := uint32(b.uint())
57 if id == 0 {
58 break
59 }
60
61
62 n := 0
63 b1 := b
64 b1.uint()
65 b1.uint8()
66 for {
67 tag := b1.uint()
68 fmt := b1.uint()
69 if tag == 0 && fmt == 0 {
70 break
71 }
72 if format(fmt) == formImplicitConst {
73 b1.int()
74 }
75 n++
76 }
77 if b1.err != nil {
78 return nil, b1.err
79 }
80
81
82 var a abbrev
83 a.tag = Tag(b.uint())
84 a.children = b.uint8() != 0
85 a.field = make([]afield, n)
86 for i := range a.field {
87 a.field[i].attr = Attr(b.uint())
88 a.field[i].fmt = format(b.uint())
89 a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b)
90 if a.field[i].fmt == formImplicitConst {
91 a.field[i].val = b.int()
92 }
93 }
94 b.uint()
95 b.uint()
96
97 m[id] = a
98 }
99 if b.err != nil {
100 return nil, b.err
101 }
102 d.abbrevCache[off] = m
103 return m, nil
104 }
105
106
107
108
109 var attrIsExprloc = map[Attr]bool{
110 AttrLocation: true,
111 AttrByteSize: true,
112 AttrBitOffset: true,
113 AttrBitSize: true,
114 AttrStringLength: true,
115 AttrLowerBound: true,
116 AttrReturnAddr: true,
117 AttrStrideSize: true,
118 AttrUpperBound: true,
119 AttrCount: true,
120 AttrDataMemberLoc: true,
121 AttrFrameBase: true,
122 AttrSegment: true,
123 AttrStaticLink: true,
124 AttrUseLocation: true,
125 AttrVtableElemLoc: true,
126 AttrAllocated: true,
127 AttrAssociated: true,
128 AttrDataLocation: true,
129 AttrStride: true,
130 }
131
132
133
134 var attrPtrClass = map[Attr]Class{
135 AttrLocation: ClassLocListPtr,
136 AttrStmtList: ClassLinePtr,
137 AttrStringLength: ClassLocListPtr,
138 AttrReturnAddr: ClassLocListPtr,
139 AttrStartScope: ClassRangeListPtr,
140 AttrDataMemberLoc: ClassLocListPtr,
141 AttrFrameBase: ClassLocListPtr,
142 AttrMacroInfo: ClassMacPtr,
143 AttrSegment: ClassLocListPtr,
144 AttrStaticLink: ClassLocListPtr,
145 AttrUseLocation: ClassLocListPtr,
146 AttrVtableElemLoc: ClassLocListPtr,
147 AttrRanges: ClassRangeListPtr,
148
149 AttrStrOffsetsBase: ClassStrOffsetsPtr,
150 AttrAddrBase: ClassAddrPtr,
151 AttrRnglistsBase: ClassRngListsPtr,
152 AttrLoclistsBase: ClassLocListPtr,
153 }
154
155
156
157
158 func formToClass(form format, attr Attr, vers int, b *buf) Class {
159 switch form {
160 default:
161 b.error("cannot determine class of unknown attribute form")
162 return 0
163
164 case formIndirect:
165 return ClassUnknown
166
167 case formAddr, formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
168 return ClassAddress
169
170 case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock:
171
172
173
174
175
176
177 if attrIsExprloc[attr] {
178 return ClassExprLoc
179 }
180 return ClassBlock
181
182 case formData1, formData2, formData4, formData8, formSdata, formUdata, formData16, formImplicitConst:
183
184
185
186
187
188 if class, ok := attrPtrClass[attr]; vers < 4 && ok {
189 return class
190 }
191 return ClassConstant
192
193 case formFlag, formFlagPresent:
194 return ClassFlag
195
196 case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata, formRefSup4, formRefSup8:
197 return ClassReference
198
199 case formRefSig8:
200 return ClassReferenceSig
201
202 case formString, formStrp, formStrx, formStrpSup, formLineStrp, formStrx1, formStrx2, formStrx3, formStrx4:
203 return ClassString
204
205 case formSecOffset:
206
207
208
209 if class, ok := attrPtrClass[attr]; ok {
210 return class
211 }
212 return ClassUnknown
213
214 case formExprloc:
215 return ClassExprLoc
216
217 case formGnuRefAlt:
218 return ClassReferenceAlt
219
220 case formGnuStrpAlt:
221 return ClassStringAlt
222
223 case formLoclistx:
224 return ClassLocList
225
226 case formRnglistx:
227 return ClassRngList
228 }
229 }
230
231
232 type Entry struct {
233 Offset Offset
234 Tag Tag
235 Children bool
236 Field []Field
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 type Field struct {
263 Attr Attr
264 Val interface{}
265 Class Class
266 }
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 type Class int
283
284 const (
285
286 ClassUnknown Class = iota
287
288
289
290 ClassAddress
291
292
293
294 ClassBlock
295
296
297
298
299 ClassConstant
300
301
302
303 ClassExprLoc
304
305
306 ClassFlag
307
308
309
310 ClassLinePtr
311
312
313
314 ClassLocListPtr
315
316
317
318 ClassMacPtr
319
320
321
322 ClassRangeListPtr
323
324
325
326
327
328 ClassReference
329
330
331
332 ClassReferenceSig
333
334
335
336
337
338 ClassString
339
340
341
342
343 ClassReferenceAlt
344
345
346
347
348 ClassStringAlt
349
350
351
352 ClassAddrPtr
353
354
355
356 ClassLocList
357
358
359
360 ClassRngList
361
362
363
364
365 ClassRngListsPtr
366
367
368
369 ClassStrOffsetsPtr
370 )
371
372
373
374 func (i Class) GoString() string {
375 return "dwarf." + i.String()
376 }
377
378
379
380
381
382
383
384
385 func (e *Entry) Val(a Attr) interface{} {
386 if f := e.AttrField(a); f != nil {
387 return f.Val
388 }
389 return nil
390 }
391
392
393
394 func (e *Entry) AttrField(a Attr) *Field {
395 for i, f := range e.Field {
396 if f.Attr == a {
397 return &e.Field[i]
398 }
399 }
400 return nil
401 }
402
403
404
405 type Offset uint32
406
407
408
409 func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry {
410 off := b.off
411 id := uint32(b.uint())
412 if id == 0 {
413 return &Entry{}
414 }
415 a, ok := atab[id]
416 if !ok {
417 b.error("unknown abbreviation table index")
418 return nil
419 }
420 e := &Entry{
421 Offset: off,
422 Tag: a.tag,
423 Children: a.children,
424 Field: make([]Field, len(a.field)),
425 }
426
427
428
429
430 type delayed struct {
431 idx int
432 off uint64
433 fmt format
434 }
435 var delay []delayed
436
437 resolveStrx := func(strBase, off uint64) string {
438 off += strBase
439 if uint64(int(off)) != off {
440 b.error("DW_FORM_strx offset out of range")
441 }
442
443 b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
444 b1.skip(int(off))
445 is64, _ := b.format.dwarf64()
446 if is64 {
447 off = b1.uint64()
448 } else {
449 off = uint64(b1.uint32())
450 }
451 if b1.err != nil {
452 b.err = b1.err
453 return ""
454 }
455 if uint64(int(off)) != off {
456 b.error("DW_FORM_strx indirect offset out of range")
457 }
458 b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
459 b1.skip(int(off))
460 val := b1.string()
461 if b1.err != nil {
462 b.err = b1.err
463 }
464 return val
465 }
466
467 resolveRnglistx := func(rnglistsBase, off uint64) uint64 {
468 is64, _ := b.format.dwarf64()
469 if is64 {
470 off *= 8
471 } else {
472 off *= 4
473 }
474 off += rnglistsBase
475 if uint64(int(off)) != off {
476 b.error("DW_FORM_rnglistx offset out of range")
477 }
478
479 b1 := makeBuf(b.dwarf, b.format, "rnglists", 0, b.dwarf.rngLists)
480 b1.skip(int(off))
481 if is64 {
482 off = b1.uint64()
483 } else {
484 off = uint64(b1.uint32())
485 }
486 if b1.err != nil {
487 b.err = b1.err
488 return 0
489 }
490 if uint64(int(off)) != off {
491 b.error("DW_FORM_rnglistx indirect offset out of range")
492 }
493 return rnglistsBase + off
494 }
495
496 for i := range e.Field {
497 e.Field[i].Attr = a.field[i].attr
498 e.Field[i].Class = a.field[i].class
499 fmt := a.field[i].fmt
500 if fmt == formIndirect {
501 fmt = format(b.uint())
502 e.Field[i].Class = formToClass(fmt, a.field[i].attr, vers, b)
503 }
504 var val interface{}
505 switch fmt {
506 default:
507 b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16))
508
509
510 case formAddr:
511 val = b.addr()
512 case formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
513 var off uint64
514 switch fmt {
515 case formAddrx:
516 off = b.uint()
517 case formAddrx1:
518 off = uint64(b.uint8())
519 case formAddrx2:
520 off = uint64(b.uint16())
521 case formAddrx3:
522 off = uint64(b.uint24())
523 case formAddrx4:
524 off = uint64(b.uint32())
525 }
526 if b.dwarf.addr == nil {
527 b.error("DW_FORM_addrx with no .debug_addr section")
528 }
529 if b.err != nil {
530 return nil
531 }
532
533
534
535
536
537 var addrBase int64
538 if cu != nil {
539 addrBase, _ = cu.Val(AttrAddrBase).(int64)
540 } else if a.tag == TagCompileUnit {
541 delay = append(delay, delayed{i, off, formAddrx})
542 break
543 }
544
545 var err error
546 val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off)
547 if err != nil {
548 if b.err == nil {
549 b.err = err
550 }
551 return nil
552 }
553
554
555 case formDwarfBlock1:
556 val = b.bytes(int(b.uint8()))
557 case formDwarfBlock2:
558 val = b.bytes(int(b.uint16()))
559 case formDwarfBlock4:
560 val = b.bytes(int(b.uint32()))
561 case formDwarfBlock:
562 val = b.bytes(int(b.uint()))
563
564
565 case formData1:
566 val = int64(b.uint8())
567 case formData2:
568 val = int64(b.uint16())
569 case formData4:
570 val = int64(b.uint32())
571 case formData8:
572 val = int64(b.uint64())
573 case formData16:
574 val = b.bytes(16)
575 case formSdata:
576 val = int64(b.int())
577 case formUdata:
578 val = int64(b.uint())
579 case formImplicitConst:
580 val = a.field[i].val
581
582
583 case formFlag:
584 val = b.uint8() == 1
585
586 case formFlagPresent:
587
588
589 val = true
590
591
592 case formRefAddr:
593 vers := b.format.version()
594 if vers == 0 {
595 b.error("unknown version for DW_FORM_ref_addr")
596 } else if vers == 2 {
597 val = Offset(b.addr())
598 } else {
599 is64, known := b.format.dwarf64()
600 if !known {
601 b.error("unknown size for DW_FORM_ref_addr")
602 } else if is64 {
603 val = Offset(b.uint64())
604 } else {
605 val = Offset(b.uint32())
606 }
607 }
608 case formRef1:
609 val = Offset(b.uint8()) + ubase
610 case formRef2:
611 val = Offset(b.uint16()) + ubase
612 case formRef4:
613 val = Offset(b.uint32()) + ubase
614 case formRef8:
615 val = Offset(b.uint64()) + ubase
616 case formRefUdata:
617 val = Offset(b.uint()) + ubase
618
619
620 case formString:
621 val = b.string()
622 case formStrp, formLineStrp:
623 var off uint64
624 is64, known := b.format.dwarf64()
625 if !known {
626 b.error("unknown size for DW_FORM_strp/line_strp")
627 } else if is64 {
628 off = b.uint64()
629 } else {
630 off = uint64(b.uint32())
631 }
632 if uint64(int(off)) != off {
633 b.error("DW_FORM_strp/line_strp offset out of range")
634 }
635 if b.err != nil {
636 return nil
637 }
638 var b1 buf
639 if fmt == formStrp {
640 b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
641 } else {
642 if len(b.dwarf.lineStr) == 0 {
643 b.error("DW_FORM_line_strp with no .debug_line_str section")
644 }
645 b1 = makeBuf(b.dwarf, b.format, "line_str", 0, b.dwarf.lineStr)
646 }
647 b1.skip(int(off))
648 val = b1.string()
649 if b1.err != nil {
650 b.err = b1.err
651 return nil
652 }
653 case formStrx, formStrx1, formStrx2, formStrx3, formStrx4:
654 var off uint64
655 switch fmt {
656 case formStrx:
657 off = b.uint()
658 case formStrx1:
659 off = uint64(b.uint8())
660 case formStrx2:
661 off = uint64(b.uint16())
662 case formStrx3:
663 off = uint64(b.uint24())
664 case formStrx4:
665 off = uint64(b.uint32())
666 }
667 if len(b.dwarf.strOffsets) == 0 {
668 b.error("DW_FORM_strx with no .debug_str_offsets section")
669 }
670 is64, known := b.format.dwarf64()
671 if !known {
672 b.error("unknown offset size for DW_FORM_strx")
673 }
674 if b.err != nil {
675 return nil
676 }
677 if is64 {
678 off *= 8
679 } else {
680 off *= 4
681 }
682
683
684
685
686
687 var strBase int64
688 if cu != nil {
689 strBase, _ = cu.Val(AttrStrOffsetsBase).(int64)
690 } else if a.tag == TagCompileUnit {
691 delay = append(delay, delayed{i, off, formStrx})
692 break
693 }
694
695 val = resolveStrx(uint64(strBase), off)
696
697 case formStrpSup:
698 is64, known := b.format.dwarf64()
699 if !known {
700 b.error("unknown size for DW_FORM_strp_sup")
701 } else if is64 {
702 val = b.uint64()
703 } else {
704 val = b.uint32()
705 }
706
707
708
709
710 case formSecOffset, formGnuRefAlt, formGnuStrpAlt:
711 is64, known := b.format.dwarf64()
712 if !known {
713 b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16))
714 } else if is64 {
715 val = int64(b.uint64())
716 } else {
717 val = int64(b.uint32())
718 }
719
720
721
722 case formExprloc:
723 val = b.bytes(int(b.uint()))
724
725
726
727 case formRefSig8:
728
729 val = b.uint64()
730 case formRefSup4:
731 val = b.uint32()
732 case formRefSup8:
733 val = b.uint64()
734
735
736 case formLoclistx:
737 val = b.uint()
738
739
740 case formRnglistx:
741 off := b.uint()
742
743
744
745
746
747 var rnglistsBase int64
748 if cu != nil {
749 rnglistsBase, _ = cu.Val(AttrRnglistsBase).(int64)
750 } else if a.tag == TagCompileUnit {
751 delay = append(delay, delayed{i, off, formRnglistx})
752 break
753 }
754
755 val = resolveRnglistx(uint64(rnglistsBase), off)
756 }
757
758 e.Field[i].Val = val
759 }
760 if b.err != nil {
761 return nil
762 }
763
764 for _, del := range delay {
765 switch del.fmt {
766 case formAddrx:
767 addrBase, _ := e.Val(AttrAddrBase).(int64)
768 val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off)
769 if err != nil {
770 b.err = err
771 return nil
772 }
773 e.Field[del.idx].Val = val
774 case formStrx:
775 strBase, _ := e.Val(AttrStrOffsetsBase).(int64)
776 e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off)
777 if b.err != nil {
778 return nil
779 }
780 case formRnglistx:
781 rnglistsBase, _ := e.Val(AttrRnglistsBase).(int64)
782 e.Field[del.idx].Val = resolveRnglistx(uint64(rnglistsBase), del.off)
783 if b.err != nil {
784 return nil
785 }
786 }
787 }
788
789 return e
790 }
791
792
793
794
795
796
797 type Reader struct {
798 b buf
799 d *Data
800 err error
801 unit int
802 lastUnit bool
803 lastChildren bool
804 lastSibling Offset
805 cu *Entry
806 }
807
808
809
810 func (d *Data) Reader() *Reader {
811 r := &Reader{d: d}
812 r.Seek(0)
813 return r
814 }
815
816
817
818 func (r *Reader) AddressSize() int {
819 return r.d.unit[r.unit].asize
820 }
821
822
823 func (r *Reader) ByteOrder() binary.ByteOrder {
824 return r.b.order
825 }
826
827
828
829 func (r *Reader) Seek(off Offset) {
830 d := r.d
831 r.err = nil
832 r.lastChildren = false
833 if off == 0 {
834 if len(d.unit) == 0 {
835 return
836 }
837 u := &d.unit[0]
838 r.unit = 0
839 r.b = makeBuf(r.d, u, "info", u.off, u.data)
840 r.cu = nil
841 return
842 }
843
844 i := d.offsetToUnit(off)
845 if i == -1 {
846 r.err = errors.New("offset out of range")
847 return
848 }
849 if i != r.unit {
850 r.cu = nil
851 }
852 u := &d.unit[i]
853 r.unit = i
854 r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
855 }
856
857
858 func (r *Reader) maybeNextUnit() {
859 for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
860 r.nextUnit()
861 }
862 }
863
864
865 func (r *Reader) nextUnit() {
866 r.unit++
867 u := &r.d.unit[r.unit]
868 r.b = makeBuf(r.d, u, "info", u.off, u.data)
869 r.cu = nil
870 }
871
872
873
874
875
876 func (r *Reader) Next() (*Entry, error) {
877 if r.err != nil {
878 return nil, r.err
879 }
880 r.maybeNextUnit()
881 if len(r.b.data) == 0 {
882 return nil, nil
883 }
884 u := &r.d.unit[r.unit]
885 e := r.b.entry(r.cu, u.atable, u.base, u.vers)
886 if r.b.err != nil {
887 r.err = r.b.err
888 return nil, r.err
889 }
890 r.lastUnit = false
891 if e != nil {
892 r.lastChildren = e.Children
893 if r.lastChildren {
894 r.lastSibling, _ = e.Val(AttrSibling).(Offset)
895 }
896 if e.Tag == TagCompileUnit || e.Tag == TagPartialUnit {
897 r.lastUnit = true
898 r.cu = e
899 }
900 } else {
901 r.lastChildren = false
902 }
903 return e, nil
904 }
905
906
907
908
909 func (r *Reader) SkipChildren() {
910 if r.err != nil || !r.lastChildren {
911 return
912 }
913
914
915
916
917
918 if r.lastSibling >= r.b.off {
919 r.Seek(r.lastSibling)
920 return
921 }
922
923 if r.lastUnit && r.unit+1 < len(r.d.unit) {
924 r.nextUnit()
925 return
926 }
927
928 for {
929 e, err := r.Next()
930 if err != nil || e == nil || e.Tag == 0 {
931 break
932 }
933 if e.Children {
934 r.SkipChildren()
935 }
936 }
937 }
938
939
940
941 func (r *Reader) clone() typeReader {
942 return r.d.Reader()
943 }
944
945
946
947 func (r *Reader) offset() Offset {
948 return r.b.off
949 }
950
951
952
953
954
955
956
957
958
959
960
961
962
963 func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
964 unit := r.unit
965 for i := 0; i < len(r.d.unit); i++ {
966 if unit >= len(r.d.unit) {
967 unit = 0
968 }
969 r.err = nil
970 r.lastChildren = false
971 r.unit = unit
972 r.cu = nil
973 u := &r.d.unit[unit]
974 r.b = makeBuf(r.d, u, "info", u.off, u.data)
975 e, err := r.Next()
976 if err != nil {
977 return nil, err
978 }
979 ranges, err := r.d.Ranges(e)
980 if err != nil {
981 return nil, err
982 }
983 for _, pcs := range ranges {
984 if pcs[0] <= pc && pc < pcs[1] {
985 return e, nil
986 }
987 }
988 unit++
989 }
990 return nil, ErrUnknownPC
991 }
992
993
994
995
996 func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
997 var ret [][2]uint64
998
999 low, lowOK := e.Val(AttrLowpc).(uint64)
1000
1001 var high uint64
1002 var highOK bool
1003 highField := e.AttrField(AttrHighpc)
1004 if highField != nil {
1005 switch highField.Class {
1006 case ClassAddress:
1007 high, highOK = highField.Val.(uint64)
1008 case ClassConstant:
1009 off, ok := highField.Val.(int64)
1010 if ok {
1011 high = low + uint64(off)
1012 highOK = true
1013 }
1014 }
1015 }
1016
1017 if lowOK && highOK {
1018 ret = append(ret, [2]uint64{low, high})
1019 }
1020
1021 var u *unit
1022 if uidx := d.offsetToUnit(e.Offset); uidx >= 0 && uidx < len(d.unit) {
1023 u = &d.unit[uidx]
1024 }
1025
1026 if u != nil && u.vers >= 5 && d.rngLists != nil {
1027
1028 field := e.AttrField(AttrRanges)
1029 if field == nil {
1030 return ret, nil
1031 }
1032 switch field.Class {
1033 case ClassRangeListPtr:
1034 ranges, rangesOK := field.Val.(int64)
1035 if !rangesOK {
1036 return ret, nil
1037 }
1038 cu, base, err := d.baseAddressForEntry(e)
1039 if err != nil {
1040 return nil, err
1041 }
1042 return d.dwarf5Ranges(u, cu, base, ranges, ret)
1043
1044 case ClassRngList:
1045 rnglist, ok := field.Val.(uint64)
1046 if !ok {
1047 return ret, nil
1048 }
1049 cu, base, err := d.baseAddressForEntry(e)
1050 if err != nil {
1051 return nil, err
1052 }
1053 return d.dwarf5Ranges(u, cu, base, int64(rnglist), ret)
1054
1055 default:
1056 return ret, nil
1057 }
1058 }
1059
1060
1061 ranges, rangesOK := e.Val(AttrRanges).(int64)
1062 if rangesOK && d.ranges != nil {
1063 _, base, err := d.baseAddressForEntry(e)
1064 if err != nil {
1065 return nil, err
1066 }
1067 return d.dwarf2Ranges(u, base, ranges, ret)
1068 }
1069
1070 return ret, nil
1071 }
1072
1073
1074
1075
1076
1077
1078 func (d *Data) baseAddressForEntry(e *Entry) (*Entry, uint64, error) {
1079 var cu *Entry
1080 if e.Tag == TagCompileUnit {
1081 cu = e
1082 } else {
1083 i := d.offsetToUnit(e.Offset)
1084 if i == -1 {
1085 return nil, 0, errors.New("no unit for entry")
1086 }
1087 u := &d.unit[i]
1088 b := makeBuf(d, u, "info", u.off, u.data)
1089 cu = b.entry(nil, u.atable, u.base, u.vers)
1090 if b.err != nil {
1091 return nil, 0, b.err
1092 }
1093 }
1094
1095 if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK {
1096 return cu, cuEntry, nil
1097 } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK {
1098 return cu, cuLow, nil
1099 }
1100
1101 return cu, 0, nil
1102 }
1103
1104 func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
1105 buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
1106 for len(buf.data) > 0 {
1107 low := buf.addr()
1108 high := buf.addr()
1109
1110 if low == 0 && high == 0 {
1111 break
1112 }
1113
1114 if low == ^uint64(0)>>uint((8-u.addrsize())*8) {
1115 base = high
1116 } else {
1117 ret = append(ret, [2]uint64{base + low, base + high})
1118 }
1119 }
1120
1121 return ret, nil
1122 }
1123
1124
1125
1126 func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
1127 var addrBase int64
1128 if cu != nil {
1129 addrBase, _ = cu.Val(AttrAddrBase).(int64)
1130 }
1131
1132 buf := makeBuf(d, u, "rnglists", 0, d.rngLists)
1133 buf.skip(int(ranges))
1134 for {
1135 opcode := buf.uint8()
1136 switch opcode {
1137 case rleEndOfList:
1138 if buf.err != nil {
1139 return nil, buf.err
1140 }
1141 return ret, nil
1142
1143 case rleBaseAddressx:
1144 baseIdx := buf.uint()
1145 var err error
1146 base, err = d.debugAddr(u, uint64(addrBase), baseIdx)
1147 if err != nil {
1148 return nil, err
1149 }
1150
1151 case rleStartxEndx:
1152 startIdx := buf.uint()
1153 endIdx := buf.uint()
1154
1155 start, err := d.debugAddr(u, uint64(addrBase), startIdx)
1156 if err != nil {
1157 return nil, err
1158 }
1159 end, err := d.debugAddr(u, uint64(addrBase), endIdx)
1160 if err != nil {
1161 return nil, err
1162 }
1163 ret = append(ret, [2]uint64{start, end})
1164
1165 case rleStartxLength:
1166 startIdx := buf.uint()
1167 len := buf.uint()
1168 start, err := d.debugAddr(u, uint64(addrBase), startIdx)
1169 if err != nil {
1170 return nil, err
1171 }
1172 ret = append(ret, [2]uint64{start, start + len})
1173
1174 case rleOffsetPair:
1175 off1 := buf.uint()
1176 off2 := buf.uint()
1177 ret = append(ret, [2]uint64{base + off1, base + off2})
1178
1179 case rleBaseAddress:
1180 base = buf.addr()
1181
1182 case rleStartEnd:
1183 start := buf.addr()
1184 end := buf.addr()
1185 ret = append(ret, [2]uint64{start, end})
1186
1187 case rleStartLength:
1188 start := buf.addr()
1189 len := buf.uint()
1190 ret = append(ret, [2]uint64{start, start + len})
1191 }
1192 }
1193 }
1194
1195
1196 func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) {
1197 off := idx*uint64(format.addrsize()) + addrBase
1198
1199 if uint64(int(off)) != off {
1200 return 0, errors.New("offset out of range")
1201 }
1202
1203 b := makeBuf(d, format, "addr", 0, d.addr)
1204 b.skip(int(off))
1205 val := b.addr()
1206 if b.err != nil {
1207 return 0, b.err
1208 }
1209 return val, nil
1210 }
1211
View as plain text