Coverage Report

Created: 2025-12-31 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/perfetto/buildtools/android-unwinding/libunwindstack/DwarfOp.cpp
Line
Count
Source
1
/*
2
 * Copyright (C) 2017 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#include <stdint.h>
18
19
#include <deque>
20
#include <string>
21
#include <vector>
22
23
#include <android-base/stringprintf.h>
24
25
#include <unwindstack/DwarfError.h>
26
#include <unwindstack/DwarfMemory.h>
27
#include <unwindstack/Log.h>
28
#include <unwindstack/Memory.h>
29
#include <unwindstack/Regs.h>
30
31
#include "DwarfOp.h"
32
33
namespace unwindstack {
34
35
enum DwarfOpHandleFunc : uint8_t {
36
  OP_ILLEGAL = 0,
37
  OP_DEREF,
38
  OP_DEREF_SIZE,
39
  OP_PUSH,
40
  OP_DUP,
41
  OP_DROP,
42
  OP_OVER,
43
  OP_PICK,
44
  OP_SWAP,
45
  OP_ROT,
46
  OP_ABS,
47
  OP_AND,
48
  OP_DIV,
49
  OP_MINUS,
50
  OP_MOD,
51
  OP_MUL,
52
  OP_NEG,
53
  OP_NOT,
54
  OP_OR,
55
  OP_PLUS,
56
  OP_PLUS_UCONST,
57
  OP_SHL,
58
  OP_SHR,
59
  OP_SHRA,
60
  OP_XOR,
61
  OP_BRA,
62
  OP_EQ,
63
  OP_GE,
64
  OP_GT,
65
  OP_LE,
66
  OP_LT,
67
  OP_NE,
68
  OP_SKIP,
69
  OP_LIT,
70
  OP_REG,
71
  OP_REGX,
72
  OP_BREG,
73
  OP_BREGX,
74
  OP_NOP,
75
  OP_NOT_IMPLEMENTED,
76
};
77
78
struct OpCallback {
79
  // It may seem tempting to "clean this up" by replacing "const char[26]" with
80
  // "const char*", but doing so would place the entire callback table in
81
  // .data.rel.ro section, instead of .rodata section, and thus increase
82
  // dirty memory usage.  Libunwindstack is used by the linker and therefore
83
  // loaded for every running process, so every bit of memory counts.
84
  // Unlike C standard, C++ standard guarantees this array is big enough to
85
  // store the names, or else we would get a compilation error.
86
  const char name[26];
87
88
  // Similarily for this field, we do NOT want to directly store function
89
  // pointers here. Not only would that cause the callback table to be placed
90
  // in .data.rel.ro section, but it would be duplicated for each AddressType.
91
  // Instead, we use DwarfOpHandleFunc enum to decouple the callback table from
92
  // the function pointers.
93
  DwarfOpHandleFunc handle_func;
94
95
  uint8_t num_required_stack_values;
96
  uint8_t num_operands;
97
  uint8_t operands[2];
98
};
99
100
constexpr static OpCallback kCallbackTable[256] = {
101
    {"", OP_ILLEGAL, 0, 0, {}},  // 0x00 illegal op
102
    {"", OP_ILLEGAL, 0, 0, {}},  // 0x01 illegal op
103
    {"", OP_ILLEGAL, 0, 0, {}},  // 0x02 illegal op
104
    {
105
        // 0x03 DW_OP_addr
106
        "DW_OP_addr",
107
        OP_PUSH,
108
        0,
109
        1,
110
        {DW_EH_PE_absptr},
111
    },
112
    {"", OP_ILLEGAL, 0, 0, {}},  // 0x04 illegal op
113
    {"", OP_ILLEGAL, 0, 0, {}},  // 0x05 illegal op
114
    {
115
        // 0x06 DW_OP_deref
116
        "DW_OP_deref",
117
        OP_DEREF,
118
        1,
119
        0,
120
        {},
121
    },
122
    {"", OP_ILLEGAL, 0, 0, {}},  // 0x07 illegal op
123
    {
124
        // 0x08 DW_OP_const1u
125
        "DW_OP_const1u",
126
        OP_PUSH,
127
        0,
128
        1,
129
        {DW_EH_PE_udata1},
130
    },
131
    {
132
        // 0x09 DW_OP_const1s
133
        "DW_OP_const1s",
134
        OP_PUSH,
135
        0,
136
        1,
137
        {DW_EH_PE_sdata1},
138
    },
139
    {
140
        // 0x0a DW_OP_const2u
141
        "DW_OP_const2u",
142
        OP_PUSH,
143
        0,
144
        1,
145
        {DW_EH_PE_udata2},
146
    },
147
    {
148
        // 0x0b DW_OP_const2s
149
        "DW_OP_const2s",
150
        OP_PUSH,
151
        0,
152
        1,
153
        {DW_EH_PE_sdata2},
154
    },
155
    {
156
        // 0x0c DW_OP_const4u
157
        "DW_OP_const4u",
158
        OP_PUSH,
159
        0,
160
        1,
161
        {DW_EH_PE_udata4},
162
    },
163
    {
164
        // 0x0d DW_OP_const4s
165
        "DW_OP_const4s",
166
        OP_PUSH,
167
        0,
168
        1,
169
        {DW_EH_PE_sdata4},
170
    },
171
    {
172
        // 0x0e DW_OP_const8u
173
        "DW_OP_const8u",
174
        OP_PUSH,
175
        0,
176
        1,
177
        {DW_EH_PE_udata8},
178
    },
179
    {
180
        // 0x0f DW_OP_const8s
181
        "DW_OP_const8s",
182
        OP_PUSH,
183
        0,
184
        1,
185
        {DW_EH_PE_sdata8},
186
    },
187
    {
188
        // 0x10 DW_OP_constu
189
        "DW_OP_constu",
190
        OP_PUSH,
191
        0,
192
        1,
193
        {DW_EH_PE_uleb128},
194
    },
195
    {
196
        // 0x11 DW_OP_consts
197
        "DW_OP_consts",
198
        OP_PUSH,
199
        0,
200
        1,
201
        {DW_EH_PE_sleb128},
202
    },
203
    {
204
        // 0x12 DW_OP_dup
205
        "DW_OP_dup",
206
        OP_DUP,
207
        1,
208
        0,
209
        {},
210
    },
211
    {
212
        // 0x13 DW_OP_drop
213
        "DW_OP_drop",
214
        OP_DROP,
215
        1,
216
        0,
217
        {},
218
    },
219
    {
220
        // 0x14 DW_OP_over
221
        "DW_OP_over",
222
        OP_OVER,
223
        2,
224
        0,
225
        {},
226
    },
227
    {
228
        // 0x15 DW_OP_pick
229
        "DW_OP_pick",
230
        OP_PICK,
231
        0,
232
        1,
233
        {DW_EH_PE_udata1},
234
    },
235
    {
236
        // 0x16 DW_OP_swap
237
        "DW_OP_swap",
238
        OP_SWAP,
239
        2,
240
        0,
241
        {},
242
    },
243
    {
244
        // 0x17 DW_OP_rot
245
        "DW_OP_rot",
246
        OP_ROT,
247
        3,
248
        0,
249
        {},
250
    },
251
    {
252
        // 0x18 DW_OP_xderef
253
        "DW_OP_xderef",
254
        OP_NOT_IMPLEMENTED,
255
        2,
256
        0,
257
        {},
258
    },
259
    {
260
        // 0x19 DW_OP_abs
261
        "DW_OP_abs",
262
        OP_ABS,
263
        1,
264
        0,
265
        {},
266
    },
267
    {
268
        // 0x1a DW_OP_and
269
        "DW_OP_and",
270
        OP_AND,
271
        2,
272
        0,
273
        {},
274
    },
275
    {
276
        // 0x1b DW_OP_div
277
        "DW_OP_div",
278
        OP_DIV,
279
        2,
280
        0,
281
        {},
282
    },
283
    {
284
        // 0x1c DW_OP_minus
285
        "DW_OP_minus",
286
        OP_MINUS,
287
        2,
288
        0,
289
        {},
290
    },
291
    {
292
        // 0x1d DW_OP_mod
293
        "DW_OP_mod",
294
        OP_MOD,
295
        2,
296
        0,
297
        {},
298
    },
299
    {
300
        // 0x1e DW_OP_mul
301
        "DW_OP_mul",
302
        OP_MUL,
303
        2,
304
        0,
305
        {},
306
    },
307
    {
308
        // 0x1f DW_OP_neg
309
        "DW_OP_neg",
310
        OP_NEG,
311
        1,
312
        0,
313
        {},
314
    },
315
    {
316
        // 0x20 DW_OP_not
317
        "DW_OP_not",
318
        OP_NOT,
319
        1,
320
        0,
321
        {},
322
    },
323
    {
324
        // 0x21 DW_OP_or
325
        "DW_OP_or",
326
        OP_OR,
327
        2,
328
        0,
329
        {},
330
    },
331
    {
332
        // 0x22 DW_OP_plus
333
        "DW_OP_plus",
334
        OP_PLUS,
335
        2,
336
        0,
337
        {},
338
    },
339
    {
340
        // 0x23 DW_OP_plus_uconst
341
        "DW_OP_plus_uconst",
342
        OP_PLUS_UCONST,
343
        1,
344
        1,
345
        {DW_EH_PE_uleb128},
346
    },
347
    {
348
        // 0x24 DW_OP_shl
349
        "DW_OP_shl",
350
        OP_SHL,
351
        2,
352
        0,
353
        {},
354
    },
355
    {
356
        // 0x25 DW_OP_shr
357
        "DW_OP_shr",
358
        OP_SHR,
359
        2,
360
        0,
361
        {},
362
    },
363
    {
364
        // 0x26 DW_OP_shra
365
        "DW_OP_shra",
366
        OP_SHRA,
367
        2,
368
        0,
369
        {},
370
    },
371
    {
372
        // 0x27 DW_OP_xor
373
        "DW_OP_xor",
374
        OP_XOR,
375
        2,
376
        0,
377
        {},
378
    },
379
    {
380
        // 0x28 DW_OP_bra
381
        "DW_OP_bra",
382
        OP_BRA,
383
        1,
384
        1,
385
        {DW_EH_PE_sdata2},
386
    },
387
    {
388
        // 0x29 DW_OP_eq
389
        "DW_OP_eq",
390
        OP_EQ,
391
        2,
392
        0,
393
        {},
394
    },
395
    {
396
        // 0x2a DW_OP_ge
397
        "DW_OP_ge",
398
        OP_GE,
399
        2,
400
        0,
401
        {},
402
    },
403
    {
404
        // 0x2b DW_OP_gt
405
        "DW_OP_gt",
406
        OP_GT,
407
        2,
408
        0,
409
        {},
410
    },
411
    {
412
        // 0x2c DW_OP_le
413
        "DW_OP_le",
414
        OP_LE,
415
        2,
416
        0,
417
        {},
418
    },
419
    {
420
        // 0x2d DW_OP_lt
421
        "DW_OP_lt",
422
        OP_LT,
423
        2,
424
        0,
425
        {},
426
    },
427
    {
428
        // 0x2e DW_OP_ne
429
        "DW_OP_ne",
430
        OP_NE,
431
        2,
432
        0,
433
        {},
434
    },
435
    {
436
        // 0x2f DW_OP_skip
437
        "DW_OP_skip",
438
        OP_SKIP,
439
        0,
440
        1,
441
        {DW_EH_PE_sdata2},
442
    },
443
    {
444
        // 0x30 DW_OP_lit0
445
        "DW_OP_lit0",
446
        OP_LIT,
447
        0,
448
        0,
449
        {},
450
    },
451
    {
452
        // 0x31 DW_OP_lit1
453
        "DW_OP_lit1",
454
        OP_LIT,
455
        0,
456
        0,
457
        {},
458
    },
459
    {
460
        // 0x32 DW_OP_lit2
461
        "DW_OP_lit2",
462
        OP_LIT,
463
        0,
464
        0,
465
        {},
466
    },
467
    {
468
        // 0x33 DW_OP_lit3
469
        "DW_OP_lit3",
470
        OP_LIT,
471
        0,
472
        0,
473
        {},
474
    },
475
    {
476
        // 0x34 DW_OP_lit4
477
        "DW_OP_lit4",
478
        OP_LIT,
479
        0,
480
        0,
481
        {},
482
    },
483
    {
484
        // 0x35 DW_OP_lit5
485
        "DW_OP_lit5",
486
        OP_LIT,
487
        0,
488
        0,
489
        {},
490
    },
491
    {
492
        // 0x36 DW_OP_lit6
493
        "DW_OP_lit6",
494
        OP_LIT,
495
        0,
496
        0,
497
        {},
498
    },
499
    {
500
        // 0x37 DW_OP_lit7
501
        "DW_OP_lit7",
502
        OP_LIT,
503
        0,
504
        0,
505
        {},
506
    },
507
    {
508
        // 0x38 DW_OP_lit8
509
        "DW_OP_lit8",
510
        OP_LIT,
511
        0,
512
        0,
513
        {},
514
    },
515
    {
516
        // 0x39 DW_OP_lit9
517
        "DW_OP_lit9",
518
        OP_LIT,
519
        0,
520
        0,
521
        {},
522
    },
523
    {
524
        // 0x3a DW_OP_lit10
525
        "DW_OP_lit10",
526
        OP_LIT,
527
        0,
528
        0,
529
        {},
530
    },
531
    {
532
        // 0x3b DW_OP_lit11
533
        "DW_OP_lit11",
534
        OP_LIT,
535
        0,
536
        0,
537
        {},
538
    },
539
    {
540
        // 0x3c DW_OP_lit12
541
        "DW_OP_lit12",
542
        OP_LIT,
543
        0,
544
        0,
545
        {},
546
    },
547
    {
548
        // 0x3d DW_OP_lit13
549
        "DW_OP_lit13",
550
        OP_LIT,
551
        0,
552
        0,
553
        {},
554
    },
555
    {
556
        // 0x3e DW_OP_lit14
557
        "DW_OP_lit14",
558
        OP_LIT,
559
        0,
560
        0,
561
        {},
562
    },
563
    {
564
        // 0x3f DW_OP_lit15
565
        "DW_OP_lit15",
566
        OP_LIT,
567
        0,
568
        0,
569
        {},
570
    },
571
    {
572
        // 0x40 DW_OP_lit16
573
        "DW_OP_lit16",
574
        OP_LIT,
575
        0,
576
        0,
577
        {},
578
    },
579
    {
580
        // 0x41 DW_OP_lit17
581
        "DW_OP_lit17",
582
        OP_LIT,
583
        0,
584
        0,
585
        {},
586
    },
587
    {
588
        // 0x42 DW_OP_lit18
589
        "DW_OP_lit18",
590
        OP_LIT,
591
        0,
592
        0,
593
        {},
594
    },
595
    {
596
        // 0x43 DW_OP_lit19
597
        "DW_OP_lit19",
598
        OP_LIT,
599
        0,
600
        0,
601
        {},
602
    },
603
    {
604
        // 0x44 DW_OP_lit20
605
        "DW_OP_lit20",
606
        OP_LIT,
607
        0,
608
        0,
609
        {},
610
    },
611
    {
612
        // 0x45 DW_OP_lit21
613
        "DW_OP_lit21",
614
        OP_LIT,
615
        0,
616
        0,
617
        {},
618
    },
619
    {
620
        // 0x46 DW_OP_lit22
621
        "DW_OP_lit22",
622
        OP_LIT,
623
        0,
624
        0,
625
        {},
626
    },
627
    {
628
        // 0x47 DW_OP_lit23
629
        "DW_OP_lit23",
630
        OP_LIT,
631
        0,
632
        0,
633
        {},
634
    },
635
    {
636
        // 0x48 DW_OP_lit24
637
        "DW_OP_lit24",
638
        OP_LIT,
639
        0,
640
        0,
641
        {},
642
    },
643
    {
644
        // 0x49 DW_OP_lit25
645
        "DW_OP_lit25",
646
        OP_LIT,
647
        0,
648
        0,
649
        {},
650
    },
651
    {
652
        // 0x4a DW_OP_lit26
653
        "DW_OP_lit26",
654
        OP_LIT,
655
        0,
656
        0,
657
        {},
658
    },
659
    {
660
        // 0x4b DW_OP_lit27
661
        "DW_OP_lit27",
662
        OP_LIT,
663
        0,
664
        0,
665
        {},
666
    },
667
    {
668
        // 0x4c DW_OP_lit28
669
        "DW_OP_lit28",
670
        OP_LIT,
671
        0,
672
        0,
673
        {},
674
    },
675
    {
676
        // 0x4d DW_OP_lit29
677
        "DW_OP_lit29",
678
        OP_LIT,
679
        0,
680
        0,
681
        {},
682
    },
683
    {
684
        // 0x4e DW_OP_lit30
685
        "DW_OP_lit30",
686
        OP_LIT,
687
        0,
688
        0,
689
        {},
690
    },
691
    {
692
        // 0x4f DW_OP_lit31
693
        "DW_OP_lit31",
694
        OP_LIT,
695
        0,
696
        0,
697
        {},
698
    },
699
    {
700
        // 0x50 DW_OP_reg0
701
        "DW_OP_reg0",
702
        OP_REG,
703
        0,
704
        0,
705
        {},
706
    },
707
    {
708
        // 0x51 DW_OP_reg1
709
        "DW_OP_reg1",
710
        OP_REG,
711
        0,
712
        0,
713
        {},
714
    },
715
    {
716
        // 0x52 DW_OP_reg2
717
        "DW_OP_reg2",
718
        OP_REG,
719
        0,
720
        0,
721
        {},
722
    },
723
    {
724
        // 0x53 DW_OP_reg3
725
        "DW_OP_reg3",
726
        OP_REG,
727
        0,
728
        0,
729
        {},
730
    },
731
    {
732
        // 0x54 DW_OP_reg4
733
        "DW_OP_reg4",
734
        OP_REG,
735
        0,
736
        0,
737
        {},
738
    },
739
    {
740
        // 0x55 DW_OP_reg5
741
        "DW_OP_reg5",
742
        OP_REG,
743
        0,
744
        0,
745
        {},
746
    },
747
    {
748
        // 0x56 DW_OP_reg6
749
        "DW_OP_reg6",
750
        OP_REG,
751
        0,
752
        0,
753
        {},
754
    },
755
    {
756
        // 0x57 DW_OP_reg7
757
        "DW_OP_reg7",
758
        OP_REG,
759
        0,
760
        0,
761
        {},
762
    },
763
    {
764
        // 0x58 DW_OP_reg8
765
        "DW_OP_reg8",
766
        OP_REG,
767
        0,
768
        0,
769
        {},
770
    },
771
    {
772
        // 0x59 DW_OP_reg9
773
        "DW_OP_reg9",
774
        OP_REG,
775
        0,
776
        0,
777
        {},
778
    },
779
    {
780
        // 0x5a DW_OP_reg10
781
        "DW_OP_reg10",
782
        OP_REG,
783
        0,
784
        0,
785
        {},
786
    },
787
    {
788
        // 0x5b DW_OP_reg11
789
        "DW_OP_reg11",
790
        OP_REG,
791
        0,
792
        0,
793
        {},
794
    },
795
    {
796
        // 0x5c DW_OP_reg12
797
        "DW_OP_reg12",
798
        OP_REG,
799
        0,
800
        0,
801
        {},
802
    },
803
    {
804
        // 0x5d DW_OP_reg13
805
        "DW_OP_reg13",
806
        OP_REG,
807
        0,
808
        0,
809
        {},
810
    },
811
    {
812
        // 0x5e DW_OP_reg14
813
        "DW_OP_reg14",
814
        OP_REG,
815
        0,
816
        0,
817
        {},
818
    },
819
    {
820
        // 0x5f DW_OP_reg15
821
        "DW_OP_reg15",
822
        OP_REG,
823
        0,
824
        0,
825
        {},
826
    },
827
    {
828
        // 0x60 DW_OP_reg16
829
        "DW_OP_reg16",
830
        OP_REG,
831
        0,
832
        0,
833
        {},
834
    },
835
    {
836
        // 0x61 DW_OP_reg17
837
        "DW_OP_reg17",
838
        OP_REG,
839
        0,
840
        0,
841
        {},
842
    },
843
    {
844
        // 0x62 DW_OP_reg18
845
        "DW_OP_reg18",
846
        OP_REG,
847
        0,
848
        0,
849
        {},
850
    },
851
    {
852
        // 0x63 DW_OP_reg19
853
        "DW_OP_reg19",
854
        OP_REG,
855
        0,
856
        0,
857
        {},
858
    },
859
    {
860
        // 0x64 DW_OP_reg20
861
        "DW_OP_reg20",
862
        OP_REG,
863
        0,
864
        0,
865
        {},
866
    },
867
    {
868
        // 0x65 DW_OP_reg21
869
        "DW_OP_reg21",
870
        OP_REG,
871
        0,
872
        0,
873
        {},
874
    },
875
    {
876
        // 0x66 DW_OP_reg22
877
        "DW_OP_reg22",
878
        OP_REG,
879
        0,
880
        0,
881
        {},
882
    },
883
    {
884
        // 0x67 DW_OP_reg23
885
        "DW_OP_reg23",
886
        OP_REG,
887
        0,
888
        0,
889
        {},
890
    },
891
    {
892
        // 0x68 DW_OP_reg24
893
        "DW_OP_reg24",
894
        OP_REG,
895
        0,
896
        0,
897
        {},
898
    },
899
    {
900
        // 0x69 DW_OP_reg25
901
        "DW_OP_reg25",
902
        OP_REG,
903
        0,
904
        0,
905
        {},
906
    },
907
    {
908
        // 0x6a DW_OP_reg26
909
        "DW_OP_reg26",
910
        OP_REG,
911
        0,
912
        0,
913
        {},
914
    },
915
    {
916
        // 0x6b DW_OP_reg27
917
        "DW_OP_reg27",
918
        OP_REG,
919
        0,
920
        0,
921
        {},
922
    },
923
    {
924
        // 0x6c DW_OP_reg28
925
        "DW_OP_reg28",
926
        OP_REG,
927
        0,
928
        0,
929
        {},
930
    },
931
    {
932
        // 0x6d DW_OP_reg29
933
        "DW_OP_reg29",
934
        OP_REG,
935
        0,
936
        0,
937
        {},
938
    },
939
    {
940
        // 0x6e DW_OP_reg30
941
        "DW_OP_reg30",
942
        OP_REG,
943
        0,
944
        0,
945
        {},
946
    },
947
    {
948
        // 0x6f DW_OP_reg31
949
        "DW_OP_reg31",
950
        OP_REG,
951
        0,
952
        0,
953
        {},
954
    },
955
    {
956
        // 0x70 DW_OP_breg0
957
        "DW_OP_breg0",
958
        OP_BREG,
959
        0,
960
        1,
961
        {DW_EH_PE_sleb128},
962
    },
963
    {
964
        // 0x71 DW_OP_breg1
965
        "DW_OP_breg1",
966
        OP_BREG,
967
        0,
968
        1,
969
        {DW_EH_PE_sleb128},
970
    },
971
    {
972
        // 0x72 DW_OP_breg2
973
        "DW_OP_breg2",
974
        OP_BREG,
975
        0,
976
        1,
977
        {DW_EH_PE_sleb128},
978
    },
979
    {
980
        // 0x73 DW_OP_breg3
981
        "DW_OP_breg3",
982
        OP_BREG,
983
        0,
984
        1,
985
        {DW_EH_PE_sleb128},
986
    },
987
    {
988
        // 0x74 DW_OP_breg4
989
        "DW_OP_breg4",
990
        OP_BREG,
991
        0,
992
        1,
993
        {DW_EH_PE_sleb128},
994
    },
995
    {
996
        // 0x75 DW_OP_breg5
997
        "DW_OP_breg5",
998
        OP_BREG,
999
        0,
1000
        1,
1001
        {DW_EH_PE_sleb128},
1002
    },
1003
    {
1004
        // 0x76 DW_OP_breg6
1005
        "DW_OP_breg6",
1006
        OP_BREG,
1007
        0,
1008
        1,
1009
        {DW_EH_PE_sleb128},
1010
    },
1011
    {
1012
        // 0x77 DW_OP_breg7
1013
        "DW_OP_breg7",
1014
        OP_BREG,
1015
        0,
1016
        1,
1017
        {DW_EH_PE_sleb128},
1018
    },
1019
    {
1020
        // 0x78 DW_OP_breg8
1021
        "DW_OP_breg8",
1022
        OP_BREG,
1023
        0,
1024
        1,
1025
        {DW_EH_PE_sleb128},
1026
    },
1027
    {
1028
        // 0x79 DW_OP_breg9
1029
        "DW_OP_breg9",
1030
        OP_BREG,
1031
        0,
1032
        1,
1033
        {DW_EH_PE_sleb128},
1034
    },
1035
    {
1036
        // 0x7a DW_OP_breg10
1037
        "DW_OP_breg10",
1038
        OP_BREG,
1039
        0,
1040
        1,
1041
        {DW_EH_PE_sleb128},
1042
    },
1043
    {
1044
        // 0x7b DW_OP_breg11
1045
        "DW_OP_breg11",
1046
        OP_BREG,
1047
        0,
1048
        1,
1049
        {DW_EH_PE_sleb128},
1050
    },
1051
    {
1052
        // 0x7c DW_OP_breg12
1053
        "DW_OP_breg12",
1054
        OP_BREG,
1055
        0,
1056
        1,
1057
        {DW_EH_PE_sleb128},
1058
    },
1059
    {
1060
        // 0x7d DW_OP_breg13
1061
        "DW_OP_breg13",
1062
        OP_BREG,
1063
        0,
1064
        1,
1065
        {DW_EH_PE_sleb128},
1066
    },
1067
    {
1068
        // 0x7e DW_OP_breg14
1069
        "DW_OP_breg14",
1070
        OP_BREG,
1071
        0,
1072
        1,
1073
        {DW_EH_PE_sleb128},
1074
    },
1075
    {
1076
        // 0x7f DW_OP_breg15
1077
        "DW_OP_breg15",
1078
        OP_BREG,
1079
        0,
1080
        1,
1081
        {DW_EH_PE_sleb128},
1082
    },
1083
    {
1084
        // 0x80 DW_OP_breg16
1085
        "DW_OP_breg16",
1086
        OP_BREG,
1087
        0,
1088
        1,
1089
        {DW_EH_PE_sleb128},
1090
    },
1091
    {
1092
        // 0x81 DW_OP_breg17
1093
        "DW_OP_breg17",
1094
        OP_BREG,
1095
        0,
1096
        1,
1097
        {DW_EH_PE_sleb128},
1098
    },
1099
    {
1100
        // 0x82 DW_OP_breg18
1101
        "DW_OP_breg18",
1102
        OP_BREG,
1103
        0,
1104
        1,
1105
        {DW_EH_PE_sleb128},
1106
    },
1107
    {
1108
        // 0x83 DW_OP_breg19
1109
        "DW_OP_breg19",
1110
        OP_BREG,
1111
        0,
1112
        1,
1113
        {DW_EH_PE_sleb128},
1114
    },
1115
    {
1116
        // 0x84 DW_OP_breg20
1117
        "DW_OP_breg20",
1118
        OP_BREG,
1119
        0,
1120
        1,
1121
        {DW_EH_PE_sleb128},
1122
    },
1123
    {
1124
        // 0x85 DW_OP_breg21
1125
        "DW_OP_breg21",
1126
        OP_BREG,
1127
        0,
1128
        1,
1129
        {DW_EH_PE_sleb128},
1130
    },
1131
    {
1132
        // 0x86 DW_OP_breg22
1133
        "DW_OP_breg22",
1134
        OP_BREG,
1135
        0,
1136
        1,
1137
        {DW_EH_PE_sleb128},
1138
    },
1139
    {
1140
        // 0x87 DW_OP_breg23
1141
        "DW_OP_breg23",
1142
        OP_BREG,
1143
        0,
1144
        1,
1145
        {DW_EH_PE_sleb128},
1146
    },
1147
    {
1148
        // 0x88 DW_OP_breg24
1149
        "DW_OP_breg24",
1150
        OP_BREG,
1151
        0,
1152
        1,
1153
        {DW_EH_PE_sleb128},
1154
    },
1155
    {
1156
        // 0x89 DW_OP_breg25
1157
        "DW_OP_breg25",
1158
        OP_BREG,
1159
        0,
1160
        1,
1161
        {DW_EH_PE_sleb128},
1162
    },
1163
    {
1164
        // 0x8a DW_OP_breg26
1165
        "DW_OP_breg26",
1166
        OP_BREG,
1167
        0,
1168
        1,
1169
        {DW_EH_PE_sleb128},
1170
    },
1171
    {
1172
        // 0x8b DW_OP_breg27
1173
        "DW_OP_breg27",
1174
        OP_BREG,
1175
        0,
1176
        1,
1177
        {DW_EH_PE_sleb128},
1178
    },
1179
    {
1180
        // 0x8c DW_OP_breg28
1181
        "DW_OP_breg28",
1182
        OP_BREG,
1183
        0,
1184
        1,
1185
        {DW_EH_PE_sleb128},
1186
    },
1187
    {
1188
        // 0x8d DW_OP_breg29
1189
        "DW_OP_breg29",
1190
        OP_BREG,
1191
        0,
1192
        1,
1193
        {DW_EH_PE_sleb128},
1194
    },
1195
    {
1196
        // 0x8e DW_OP_breg30
1197
        "DW_OP_breg30",
1198
        OP_BREG,
1199
        0,
1200
        1,
1201
        {DW_EH_PE_sleb128},
1202
    },
1203
    {
1204
        // 0x8f DW_OP_breg31
1205
        "DW_OP_breg31",
1206
        OP_BREG,
1207
        0,
1208
        1,
1209
        {DW_EH_PE_sleb128},
1210
    },
1211
    {
1212
        // 0x90 DW_OP_regx
1213
        "DW_OP_regx",
1214
        OP_REGX,
1215
        0,
1216
        1,
1217
        {DW_EH_PE_uleb128},
1218
    },
1219
    {
1220
        // 0x91 DW_OP_fbreg
1221
        "DW_OP_fbreg",
1222
        OP_NOT_IMPLEMENTED,
1223
        0,
1224
        1,
1225
        {DW_EH_PE_sleb128},
1226
    },
1227
    {
1228
        // 0x92 DW_OP_bregx
1229
        "DW_OP_bregx",
1230
        OP_BREGX,
1231
        0,
1232
        2,
1233
        {DW_EH_PE_uleb128, DW_EH_PE_sleb128},
1234
    },
1235
    {
1236
        // 0x93 DW_OP_piece
1237
        "DW_OP_piece",
1238
        OP_NOT_IMPLEMENTED,
1239
        0,
1240
        1,
1241
        {DW_EH_PE_uleb128},
1242
    },
1243
    {
1244
        // 0x94 DW_OP_deref_size
1245
        "DW_OP_deref_size",
1246
        OP_DEREF_SIZE,
1247
        1,
1248
        1,
1249
        {DW_EH_PE_udata1},
1250
    },
1251
    {
1252
        // 0x95 DW_OP_xderef_size
1253
        "DW_OP_xderef_size",
1254
        OP_NOT_IMPLEMENTED,
1255
        0,
1256
        1,
1257
        {DW_EH_PE_udata1},
1258
    },
1259
    {
1260
        // 0x96 DW_OP_nop
1261
        "DW_OP_nop",
1262
        OP_NOP,
1263
        0,
1264
        0,
1265
        {},
1266
    },
1267
    {
1268
        // 0x97 DW_OP_push_object_address
1269
        "DW_OP_push_object_address",
1270
        OP_NOT_IMPLEMENTED,
1271
        0,
1272
        0,
1273
        {},
1274
    },
1275
    {
1276
        // 0x98 DW_OP_call2
1277
        "DW_OP_call2",
1278
        OP_NOT_IMPLEMENTED,
1279
        0,
1280
        1,
1281
        {DW_EH_PE_udata2},
1282
    },
1283
    {
1284
        // 0x99 DW_OP_call4
1285
        "DW_OP_call4",
1286
        OP_NOT_IMPLEMENTED,
1287
        0,
1288
        1,
1289
        {DW_EH_PE_udata4},
1290
    },
1291
    {
1292
        // 0x9a DW_OP_call_ref
1293
        "DW_OP_call_ref",
1294
        OP_NOT_IMPLEMENTED,
1295
        0,
1296
        0,  // Has a different sized operand (4 bytes or 8 bytes).
1297
        {},
1298
    },
1299
    {
1300
        // 0x9b DW_OP_form_tls_address
1301
        "DW_OP_form_tls_address",
1302
        OP_NOT_IMPLEMENTED,
1303
        0,
1304
        0,
1305
        {},
1306
    },
1307
    {
1308
        // 0x9c DW_OP_call_frame_cfa
1309
        "DW_OP_call_frame_cfa",
1310
        OP_NOT_IMPLEMENTED,
1311
        0,
1312
        0,
1313
        {},
1314
    },
1315
    {
1316
        // 0x9d DW_OP_bit_piece
1317
        "DW_OP_bit_piece",
1318
        OP_NOT_IMPLEMENTED,
1319
        0,
1320
        2,
1321
        {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
1322
    },
1323
    {
1324
        // 0x9e DW_OP_implicit_value
1325
        "DW_OP_implicit_value",
1326
        OP_NOT_IMPLEMENTED,
1327
        0,
1328
        1,
1329
        {DW_EH_PE_uleb128},
1330
    },
1331
    {
1332
        // 0x9f DW_OP_stack_value
1333
        "DW_OP_stack_value",
1334
        OP_NOT_IMPLEMENTED,
1335
        1,
1336
        0,
1337
        {},
1338
    },
1339
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa0 illegal op
1340
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa1 illegal op
1341
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa2 illegal op
1342
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa3 illegal op
1343
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa4 illegal op
1344
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa5 illegal op
1345
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa6 illegal op
1346
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa7 illegal op
1347
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa8 illegal op
1348
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xa9 illegal op
1349
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xaa illegal op
1350
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xab illegal op
1351
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xac illegal op
1352
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xad illegal op
1353
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xae illegal op
1354
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xaf illegal op
1355
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb0 illegal op
1356
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb1 illegal op
1357
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb2 illegal op
1358
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb3 illegal op
1359
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb4 illegal op
1360
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb5 illegal op
1361
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb6 illegal op
1362
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb7 illegal op
1363
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb8 illegal op
1364
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xb9 illegal op
1365
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xba illegal op
1366
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xbb illegal op
1367
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xbc illegal op
1368
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xbd illegal op
1369
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xbe illegal op
1370
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xbf illegal op
1371
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc0 illegal op
1372
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc1 illegal op
1373
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc2 illegal op
1374
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc3 illegal op
1375
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc4 illegal op
1376
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc5 illegal op
1377
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc6 illegal op
1378
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc7 illegal op
1379
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc8 illegal op
1380
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xc9 illegal op
1381
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xca illegal op
1382
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xcb illegal op
1383
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xcc illegal op
1384
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xcd illegal op
1385
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xce illegal op
1386
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xcf illegal op
1387
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd0 illegal op
1388
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd1 illegal op
1389
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd2 illegal op
1390
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd3 illegal op
1391
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd4 illegal op
1392
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd5 illegal op
1393
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd6 illegal op
1394
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd7 illegal op
1395
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd8 illegal op
1396
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xd9 illegal op
1397
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xda illegal op
1398
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xdb illegal op
1399
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xdc illegal op
1400
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xdd illegal op
1401
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xde illegal op
1402
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xdf illegal op
1403
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe0 DW_OP_lo_user
1404
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe1 illegal op
1405
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe2 illegal op
1406
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe3 illegal op
1407
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe4 illegal op
1408
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe5 illegal op
1409
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe6 illegal op
1410
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe7 illegal op
1411
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe8 illegal op
1412
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xe9 illegal op
1413
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xea illegal op
1414
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xeb illegal op
1415
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xec illegal op
1416
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xed illegal op
1417
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xee illegal op
1418
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xef illegal op
1419
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf0 illegal op
1420
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf1 illegal op
1421
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf2 illegal op
1422
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf3 illegal op
1423
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf4 illegal op
1424
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf5 illegal op
1425
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf6 illegal op
1426
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf7 illegal op
1427
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf8 illegal op
1428
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xf9 illegal op
1429
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xfa illegal op
1430
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xfb illegal op
1431
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xfc illegal op
1432
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xfd illegal op
1433
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xfe illegal op
1434
    {"", OP_ILLEGAL, 0, 0, {}},  // 0xff DW_OP_hi_user
1435
};
1436
1437
template <typename AddressType>
1438
const typename DwarfOp<AddressType>::OpHandleFuncPtr DwarfOp<AddressType>::kOpHandleFuncList[] = {
1439
    [OP_ILLEGAL] = nullptr,
1440
    [OP_DEREF] = &DwarfOp<AddressType>::op_deref,
1441
    [OP_DEREF_SIZE] = &DwarfOp<AddressType>::op_deref_size,
1442
    [OP_PUSH] = &DwarfOp<AddressType>::op_push,
1443
    [OP_DUP] = &DwarfOp<AddressType>::op_dup,
1444
    [OP_DROP] = &DwarfOp<AddressType>::op_drop,
1445
    [OP_OVER] = &DwarfOp<AddressType>::op_over,
1446
    [OP_PICK] = &DwarfOp<AddressType>::op_pick,
1447
    [OP_SWAP] = &DwarfOp<AddressType>::op_swap,
1448
    [OP_ROT] = &DwarfOp<AddressType>::op_rot,
1449
    [OP_ABS] = &DwarfOp<AddressType>::op_abs,
1450
    [OP_AND] = &DwarfOp<AddressType>::op_and,
1451
    [OP_DIV] = &DwarfOp<AddressType>::op_div,
1452
    [OP_MINUS] = &DwarfOp<AddressType>::op_minus,
1453
    [OP_MOD] = &DwarfOp<AddressType>::op_mod,
1454
    [OP_MUL] = &DwarfOp<AddressType>::op_mul,
1455
    [OP_NEG] = &DwarfOp<AddressType>::op_neg,
1456
    [OP_NOT] = &DwarfOp<AddressType>::op_not,
1457
    [OP_OR] = &DwarfOp<AddressType>::op_or,
1458
    [OP_PLUS] = &DwarfOp<AddressType>::op_plus,
1459
    [OP_PLUS_UCONST] = &DwarfOp<AddressType>::op_plus_uconst,
1460
    [OP_SHL] = &DwarfOp<AddressType>::op_shl,
1461
    [OP_SHR] = &DwarfOp<AddressType>::op_shr,
1462
    [OP_SHRA] = &DwarfOp<AddressType>::op_shra,
1463
    [OP_XOR] = &DwarfOp<AddressType>::op_xor,
1464
    [OP_BRA] = &DwarfOp<AddressType>::op_bra,
1465
    [OP_EQ] = &DwarfOp<AddressType>::op_eq,
1466
    [OP_GE] = &DwarfOp<AddressType>::op_ge,
1467
    [OP_GT] = &DwarfOp<AddressType>::op_gt,
1468
    [OP_LE] = &DwarfOp<AddressType>::op_le,
1469
    [OP_LT] = &DwarfOp<AddressType>::op_lt,
1470
    [OP_NE] = &DwarfOp<AddressType>::op_ne,
1471
    [OP_SKIP] = &DwarfOp<AddressType>::op_skip,
1472
    [OP_LIT] = &DwarfOp<AddressType>::op_lit,
1473
    [OP_REG] = &DwarfOp<AddressType>::op_reg,
1474
    [OP_REGX] = &DwarfOp<AddressType>::op_regx,
1475
    [OP_BREG] = &DwarfOp<AddressType>::op_breg,
1476
    [OP_BREGX] = &DwarfOp<AddressType>::op_bregx,
1477
    [OP_NOP] = &DwarfOp<AddressType>::op_nop,
1478
    [OP_NOT_IMPLEMENTED] = &DwarfOp<AddressType>::op_not_implemented,
1479
};
1480
1481
template <typename AddressType>
1482
109
bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end) {
1483
109
  is_register_ = false;
1484
109
  stack_.clear();
1485
109
  memory_->set_cur_offset(start);
1486
109
  dex_pc_set_ = false;
1487
1488
  // Unroll the first Decode calls to be able to check for a special
1489
  // sequence of ops and values that indicate this is the dex pc.
1490
  // The pattern is:
1491
  //   OP_const4u (0x0c)  'D' 'E' 'X' '1'
1492
  //   OP_drop (0x13)
1493
109
  if (memory_->cur_offset() < end) {
1494
107
    if (!Decode()) {
1495
17
      return false;
1496
17
    }
1497
107
  } else {
1498
2
    return true;
1499
2
  }
1500
90
  bool check_for_drop;
1501
90
  if (cur_op_ == 0x0c && operands_.back() == 0x31584544) {
1502
0
    check_for_drop = true;
1503
90
  } else {
1504
90
    check_for_drop = false;
1505
90
  }
1506
90
  if (memory_->cur_offset() < end) {
1507
90
    if (!Decode()) {
1508
1
      return false;
1509
1
    }
1510
90
  } else {
1511
0
    return true;
1512
0
  }
1513
1514
89
  if (check_for_drop && cur_op_ == 0x13) {
1515
0
    dex_pc_set_ = true;
1516
0
  }
1517
1518
89
  uint32_t iterations = 2;
1519
2.06k
  while (memory_->cur_offset() < end) {
1520
1.99k
    if (!Decode()) {
1521
12
      return false;
1522
12
    }
1523
    // To protect against a branch that creates an infinite loop,
1524
    // terminate if the number of iterations gets too high.
1525
1.98k
    if (iterations++ == 1000) {
1526
0
      last_error_.code = DWARF_ERROR_TOO_MANY_ITERATIONS;
1527
0
      return false;
1528
0
    }
1529
1.98k
  }
1530
77
  return true;
1531
89
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::Eval(unsigned long, unsigned long)
unwindstack::DwarfOp<unsigned long>::Eval(unsigned long, unsigned long)
Line
Count
Source
1482
109
bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end) {
1483
109
  is_register_ = false;
1484
109
  stack_.clear();
1485
109
  memory_->set_cur_offset(start);
1486
109
  dex_pc_set_ = false;
1487
1488
  // Unroll the first Decode calls to be able to check for a special
1489
  // sequence of ops and values that indicate this is the dex pc.
1490
  // The pattern is:
1491
  //   OP_const4u (0x0c)  'D' 'E' 'X' '1'
1492
  //   OP_drop (0x13)
1493
109
  if (memory_->cur_offset() < end) {
1494
107
    if (!Decode()) {
1495
17
      return false;
1496
17
    }
1497
107
  } else {
1498
2
    return true;
1499
2
  }
1500
90
  bool check_for_drop;
1501
90
  if (cur_op_ == 0x0c && operands_.back() == 0x31584544) {
1502
0
    check_for_drop = true;
1503
90
  } else {
1504
90
    check_for_drop = false;
1505
90
  }
1506
90
  if (memory_->cur_offset() < end) {
1507
90
    if (!Decode()) {
1508
1
      return false;
1509
1
    }
1510
90
  } else {
1511
0
    return true;
1512
0
  }
1513
1514
89
  if (check_for_drop && cur_op_ == 0x13) {
1515
0
    dex_pc_set_ = true;
1516
0
  }
1517
1518
89
  uint32_t iterations = 2;
1519
2.06k
  while (memory_->cur_offset() < end) {
1520
1.99k
    if (!Decode()) {
1521
12
      return false;
1522
12
    }
1523
    // To protect against a branch that creates an infinite loop,
1524
    // terminate if the number of iterations gets too high.
1525
1.98k
    if (iterations++ == 1000) {
1526
0
      last_error_.code = DWARF_ERROR_TOO_MANY_ITERATIONS;
1527
0
      return false;
1528
0
    }
1529
1.98k
  }
1530
77
  return true;
1531
89
}
1532
1533
template <typename AddressType>
1534
2.18k
bool DwarfOp<AddressType>::Decode() {
1535
2.18k
  last_error_.code = DWARF_ERROR_NONE;
1536
2.18k
  if (!memory_->ReadBytes(&cur_op_, 1)) {
1537
0
    last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1538
0
    last_error_.address = memory_->cur_offset();
1539
0
    return false;
1540
0
  }
1541
1542
2.18k
  const auto* op = &kCallbackTable[cur_op_];
1543
2.18k
  if (op->handle_func == OP_ILLEGAL) {
1544
27
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1545
27
    return false;
1546
27
  }
1547
1548
2.16k
  const auto handle_func = kOpHandleFuncList[op->handle_func];
1549
1550
  // Make sure that the required number of stack elements is available.
1551
2.16k
  if (stack_.size() < op->num_required_stack_values) {
1552
3
    last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID;
1553
3
    return false;
1554
3
  }
1555
1556
2.15k
  operands_.clear();
1557
3.44k
  for (size_t i = 0; i < op->num_operands; i++) {
1558
1.28k
    uint64_t value;
1559
1.28k
    if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) {
1560
0
      last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1561
0
      last_error_.address = memory_->cur_offset();
1562
0
      return false;
1563
0
    }
1564
1.28k
    operands_.push_back(value);
1565
1.28k
  }
1566
2.15k
  return (this->*handle_func)();
1567
2.15k
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::Decode()
unwindstack::DwarfOp<unsigned long>::Decode()
Line
Count
Source
1534
2.18k
bool DwarfOp<AddressType>::Decode() {
1535
2.18k
  last_error_.code = DWARF_ERROR_NONE;
1536
2.18k
  if (!memory_->ReadBytes(&cur_op_, 1)) {
1537
0
    last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1538
0
    last_error_.address = memory_->cur_offset();
1539
0
    return false;
1540
0
  }
1541
1542
2.18k
  const auto* op = &kCallbackTable[cur_op_];
1543
2.18k
  if (op->handle_func == OP_ILLEGAL) {
1544
27
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1545
27
    return false;
1546
27
  }
1547
1548
2.16k
  const auto handle_func = kOpHandleFuncList[op->handle_func];
1549
1550
  // Make sure that the required number of stack elements is available.
1551
2.16k
  if (stack_.size() < op->num_required_stack_values) {
1552
3
    last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID;
1553
3
    return false;
1554
3
  }
1555
1556
2.15k
  operands_.clear();
1557
3.44k
  for (size_t i = 0; i < op->num_operands; i++) {
1558
1.28k
    uint64_t value;
1559
1.28k
    if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) {
1560
0
      last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1561
0
      last_error_.address = memory_->cur_offset();
1562
0
      return false;
1563
0
    }
1564
1.28k
    operands_.push_back(value);
1565
1.28k
  }
1566
2.15k
  return (this->*handle_func)();
1567
2.15k
}
1568
1569
template <typename AddressType>
1570
void DwarfOp<AddressType>::GetLogInfo(uint64_t start, uint64_t end,
1571
0
                                      std::vector<std::string>* lines) {
1572
0
  memory_->set_cur_offset(start);
1573
0
  while (memory_->cur_offset() < end) {
1574
0
    uint8_t cur_op;
1575
0
    if (!memory_->ReadBytes(&cur_op, 1)) {
1576
0
      return;
1577
0
    }
1578
1579
0
    std::string raw_string(android::base::StringPrintf("Raw Data: 0x%02x", cur_op));
1580
0
    std::string log_string;
1581
0
    const auto* op = &kCallbackTable[cur_op];
1582
0
    if (op->handle_func == OP_ILLEGAL) {
1583
0
      log_string = "Illegal";
1584
0
    } else {
1585
0
      log_string = op->name;
1586
0
      uint64_t start_offset = memory_->cur_offset();
1587
0
      for (size_t i = 0; i < op->num_operands; i++) {
1588
0
        uint64_t value;
1589
0
        if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) {
1590
0
          return;
1591
0
        }
1592
0
        log_string += ' ' + std::to_string(value);
1593
0
      }
1594
0
      uint64_t end_offset = memory_->cur_offset();
1595
1596
0
      memory_->set_cur_offset(start_offset);
1597
0
      for (size_t i = start_offset; i < end_offset; i++) {
1598
0
        uint8_t byte;
1599
0
        if (!memory_->ReadBytes(&byte, 1)) {
1600
0
          return;
1601
0
        }
1602
0
        raw_string += android::base::StringPrintf(" 0x%02x", byte);
1603
0
      }
1604
0
      memory_->set_cur_offset(end_offset);
1605
0
    }
1606
0
    lines->push_back(std::move(log_string));
1607
0
    lines->push_back(std::move(raw_string));
1608
0
  }
1609
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::GetLogInfo(unsigned long, unsigned long, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*)
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::GetLogInfo(unsigned long, unsigned long, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*)
1610
1611
template <typename AddressType>
1612
0
bool DwarfOp<AddressType>::op_deref() {
1613
  // Read the address and dereference it.
1614
0
  AddressType addr = StackPop();
1615
0
  AddressType value;
1616
0
  if (!regular_memory()->ReadFully(addr, &value, sizeof(value))) {
1617
0
    last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1618
0
    last_error_.address = addr;
1619
0
    return false;
1620
0
  }
1621
0
  stack_.push_front(value);
1622
0
  return true;
1623
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_deref()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_deref()
1624
1625
template <typename AddressType>
1626
0
bool DwarfOp<AddressType>::op_deref_size() {
1627
0
  AddressType bytes_to_read = OperandAt(0);
1628
0
  if (bytes_to_read > sizeof(AddressType) || bytes_to_read == 0) {
1629
0
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1630
0
    return false;
1631
0
  }
1632
  // Read the address and dereference it.
1633
0
  AddressType addr = StackPop();
1634
0
  AddressType value = 0;
1635
0
  if (!regular_memory()->ReadFully(addr, &value, bytes_to_read)) {
1636
0
    last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1637
0
    last_error_.address = addr;
1638
0
    return false;
1639
0
  }
1640
0
  stack_.push_front(value);
1641
0
  return true;
1642
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_deref_size()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_deref_size()
1643
1644
template <typename AddressType>
1645
1.13k
bool DwarfOp<AddressType>::op_push() {
1646
  // Push all of the operands.
1647
1.13k
  for (auto operand : operands_) {
1648
1.13k
    stack_.push_front(operand);
1649
1.13k
  }
1650
1.13k
  return true;
1651
1.13k
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_push()
unwindstack::DwarfOp<unsigned long>::op_push()
Line
Count
Source
1645
1.13k
bool DwarfOp<AddressType>::op_push() {
1646
  // Push all of the operands.
1647
1.13k
  for (auto operand : operands_) {
1648
1.13k
    stack_.push_front(operand);
1649
1.13k
  }
1650
1.13k
  return true;
1651
1.13k
}
1652
1653
template <typename AddressType>
1654
0
bool DwarfOp<AddressType>::op_dup() {
1655
0
  stack_.push_front(StackAt(0));
1656
0
  return true;
1657
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_dup()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_dup()
1658
1659
template <typename AddressType>
1660
0
bool DwarfOp<AddressType>::op_drop() {
1661
0
  StackPop();
1662
0
  return true;
1663
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_drop()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_drop()
1664
1665
template <typename AddressType>
1666
0
bool DwarfOp<AddressType>::op_over() {
1667
0
  stack_.push_front(StackAt(1));
1668
0
  return true;
1669
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_over()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_over()
1670
1671
template <typename AddressType>
1672
0
bool DwarfOp<AddressType>::op_pick() {
1673
0
  AddressType index = OperandAt(0);
1674
0
  if (index >= StackSize()) {
1675
0
    last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID;
1676
0
    return false;
1677
0
  }
1678
0
  stack_.push_front(StackAt(index));
1679
0
  return true;
1680
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_pick()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_pick()
1681
1682
template <typename AddressType>
1683
0
bool DwarfOp<AddressType>::op_swap() {
1684
0
  AddressType old_value = stack_[0];
1685
0
  stack_[0] = stack_[1];
1686
0
  stack_[1] = old_value;
1687
0
  return true;
1688
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_swap()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_swap()
1689
1690
template <typename AddressType>
1691
0
bool DwarfOp<AddressType>::op_rot() {
1692
0
  AddressType top = stack_[0];
1693
0
  stack_[0] = stack_[1];
1694
0
  stack_[1] = stack_[2];
1695
0
  stack_[2] = top;
1696
0
  return true;
1697
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_rot()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_rot()
1698
1699
template <typename AddressType>
1700
0
bool DwarfOp<AddressType>::op_abs() {
1701
0
  SignedType signed_value = static_cast<SignedType>(stack_[0]);
1702
0
  if (signed_value < 0) {
1703
0
    signed_value = -signed_value;
1704
0
  }
1705
0
  stack_[0] = static_cast<AddressType>(signed_value);
1706
0
  return true;
1707
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_abs()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_abs()
1708
1709
template <typename AddressType>
1710
224
bool DwarfOp<AddressType>::op_and() {
1711
224
  AddressType top = StackPop();
1712
224
  stack_[0] &= top;
1713
224
  return true;
1714
224
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_and()
unwindstack::DwarfOp<unsigned long>::op_and()
Line
Count
Source
1710
224
bool DwarfOp<AddressType>::op_and() {
1711
224
  AddressType top = StackPop();
1712
224
  stack_[0] &= top;
1713
224
  return true;
1714
224
}
1715
1716
template <typename AddressType>
1717
0
bool DwarfOp<AddressType>::op_div() {
1718
0
  AddressType top = StackPop();
1719
0
  if (top == 0) {
1720
0
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1721
0
    return false;
1722
0
  }
1723
0
  SignedType signed_divisor = static_cast<SignedType>(top);
1724
0
  SignedType signed_dividend = static_cast<SignedType>(stack_[0]);
1725
0
  stack_[0] = static_cast<AddressType>(signed_dividend / signed_divisor);
1726
0
  return true;
1727
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_div()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_div()
1728
1729
template <typename AddressType>
1730
0
bool DwarfOp<AddressType>::op_minus() {
1731
0
  AddressType top = StackPop();
1732
0
  stack_[0] -= top;
1733
0
  return true;
1734
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_minus()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_minus()
1735
1736
template <typename AddressType>
1737
0
bool DwarfOp<AddressType>::op_mod() {
1738
0
  AddressType top = StackPop();
1739
0
  if (top == 0) {
1740
0
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1741
0
    return false;
1742
0
  }
1743
0
  stack_[0] %= top;
1744
0
  return true;
1745
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_mod()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_mod()
1746
1747
template <typename AddressType>
1748
0
bool DwarfOp<AddressType>::op_mul() {
1749
0
  AddressType top = StackPop();
1750
0
  stack_[0] *= top;
1751
0
  return true;
1752
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_mul()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_mul()
1753
1754
template <typename AddressType>
1755
0
bool DwarfOp<AddressType>::op_neg() {
1756
0
  SignedType signed_value = static_cast<SignedType>(stack_[0]);
1757
0
  stack_[0] = static_cast<AddressType>(-signed_value);
1758
0
  return true;
1759
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_neg()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_neg()
1760
1761
template <typename AddressType>
1762
0
bool DwarfOp<AddressType>::op_not() {
1763
0
  stack_[0] = ~stack_[0];
1764
0
  return true;
1765
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_not()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_not()
1766
1767
template <typename AddressType>
1768
0
bool DwarfOp<AddressType>::op_or() {
1769
0
  AddressType top = StackPop();
1770
0
  stack_[0] |= top;
1771
0
  return true;
1772
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_or()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_or()
1773
1774
template <typename AddressType>
1775
0
bool DwarfOp<AddressType>::op_plus() {
1776
0
  AddressType top = StackPop();
1777
0
  stack_[0] += top;
1778
0
  return true;
1779
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_plus()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_plus()
1780
1781
template <typename AddressType>
1782
0
bool DwarfOp<AddressType>::op_plus_uconst() {
1783
0
  stack_[0] += OperandAt(0);
1784
0
  return true;
1785
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_plus_uconst()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_plus_uconst()
1786
1787
template <typename AddressType>
1788
0
bool DwarfOp<AddressType>::op_shl() {
1789
0
  AddressType top = StackPop();
1790
0
  stack_[0] <<= top;
1791
0
  return true;
1792
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_shl()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_shl()
1793
1794
template <typename AddressType>
1795
0
bool DwarfOp<AddressType>::op_shr() {
1796
0
  AddressType top = StackPop();
1797
0
  stack_[0] >>= top;
1798
0
  return true;
1799
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_shr()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_shr()
1800
1801
template <typename AddressType>
1802
2
bool DwarfOp<AddressType>::op_shra() {
1803
2
  AddressType top = StackPop();
1804
2
  SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top;
1805
2
  stack_[0] = static_cast<AddressType>(signed_value);
1806
2
  return true;
1807
2
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_shra()
unwindstack::DwarfOp<unsigned long>::op_shra()
Line
Count
Source
1802
2
bool DwarfOp<AddressType>::op_shra() {
1803
2
  AddressType top = StackPop();
1804
2
  SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top;
1805
2
  stack_[0] = static_cast<AddressType>(signed_value);
1806
2
  return true;
1807
2
}
1808
1809
template <typename AddressType>
1810
0
bool DwarfOp<AddressType>::op_xor() {
1811
0
  AddressType top = StackPop();
1812
0
  stack_[0] ^= top;
1813
0
  return true;
1814
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_xor()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_xor()
1815
1816
template <typename AddressType>
1817
0
bool DwarfOp<AddressType>::op_bra() {
1818
  // Requires one stack element.
1819
0
  AddressType top = StackPop();
1820
0
  if (top == 0) {
1821
0
    return true;
1822
0
  }
1823
1824
0
  int16_t offset = static_cast<int16_t>(OperandAt(0));
1825
0
  uint64_t cur_offset = memory_->cur_offset() + offset;
1826
0
  memory_->set_cur_offset(cur_offset);
1827
0
  return true;
1828
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_bra()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_bra()
1829
1830
template <typename AddressType>
1831
84
bool DwarfOp<AddressType>::op_eq() {
1832
84
  AddressType top = StackPop();
1833
84
  stack_[0] = bool_to_dwarf_bool(stack_[0] == top);
1834
84
  return true;
1835
84
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_eq()
unwindstack::DwarfOp<unsigned long>::op_eq()
Line
Count
Source
1831
84
bool DwarfOp<AddressType>::op_eq() {
1832
84
  AddressType top = StackPop();
1833
84
  stack_[0] = bool_to_dwarf_bool(stack_[0] == top);
1834
84
  return true;
1835
84
}
1836
1837
template <typename AddressType>
1838
28
bool DwarfOp<AddressType>::op_ge() {
1839
28
  AddressType top = StackPop();
1840
28
  stack_[0] = bool_to_dwarf_bool(stack_[0] >= top);
1841
28
  return true;
1842
28
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_ge()
unwindstack::DwarfOp<unsigned long>::op_ge()
Line
Count
Source
1838
28
bool DwarfOp<AddressType>::op_ge() {
1839
28
  AddressType top = StackPop();
1840
28
  stack_[0] = bool_to_dwarf_bool(stack_[0] >= top);
1841
28
  return true;
1842
28
}
1843
1844
template <typename AddressType>
1845
0
bool DwarfOp<AddressType>::op_gt() {
1846
0
  AddressType top = StackPop();
1847
0
  stack_[0] = bool_to_dwarf_bool(stack_[0] > top);
1848
0
  return true;
1849
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_gt()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_gt()
1850
1851
template <typename AddressType>
1852
0
bool DwarfOp<AddressType>::op_le() {
1853
0
  AddressType top = StackPop();
1854
0
  stack_[0] = bool_to_dwarf_bool(stack_[0] <= top);
1855
0
  return true;
1856
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_le()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_le()
1857
1858
template <typename AddressType>
1859
0
bool DwarfOp<AddressType>::op_lt() {
1860
0
  AddressType top = StackPop();
1861
0
  stack_[0] = bool_to_dwarf_bool(stack_[0] < top);
1862
0
  return true;
1863
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_lt()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_lt()
1864
1865
template <typename AddressType>
1866
336
bool DwarfOp<AddressType>::op_ne() {
1867
336
  AddressType top = StackPop();
1868
336
  stack_[0] = bool_to_dwarf_bool(stack_[0] != top);
1869
336
  return true;
1870
336
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_ne()
unwindstack::DwarfOp<unsigned long>::op_ne()
Line
Count
Source
1866
336
bool DwarfOp<AddressType>::op_ne() {
1867
336
  AddressType top = StackPop();
1868
336
  stack_[0] = bool_to_dwarf_bool(stack_[0] != top);
1869
336
  return true;
1870
336
}
1871
1872
template <typename AddressType>
1873
0
bool DwarfOp<AddressType>::op_skip() {
1874
0
  int16_t offset = static_cast<int16_t>(OperandAt(0));
1875
0
  uint64_t cur_offset = memory_->cur_offset() + offset;
1876
0
  memory_->set_cur_offset(cur_offset);
1877
0
  return true;
1878
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_skip()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_skip()
1879
1880
template <typename AddressType>
1881
1
bool DwarfOp<AddressType>::op_lit() {
1882
1
  stack_.push_front(cur_op() - 0x30);
1883
1
  return true;
1884
1
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_lit()
unwindstack::DwarfOp<unsigned long>::op_lit()
Line
Count
Source
1881
1
bool DwarfOp<AddressType>::op_lit() {
1882
1
  stack_.push_front(cur_op() - 0x30);
1883
1
  return true;
1884
1
}
1885
1886
template <typename AddressType>
1887
202
bool DwarfOp<AddressType>::op_reg() {
1888
202
  is_register_ = true;
1889
202
  stack_.push_front(cur_op() - 0x50);
1890
202
  return true;
1891
202
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_reg()
unwindstack::DwarfOp<unsigned long>::op_reg()
Line
Count
Source
1887
202
bool DwarfOp<AddressType>::op_reg() {
1888
202
  is_register_ = true;
1889
202
  stack_.push_front(cur_op() - 0x50);
1890
202
  return true;
1891
202
}
1892
1893
template <typename AddressType>
1894
0
bool DwarfOp<AddressType>::op_regx() {
1895
0
  is_register_ = true;
1896
0
  stack_.push_front(OperandAt(0));
1897
0
  return true;
1898
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_regx()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_regx()
1899
1900
// It's not clear for breg/bregx, if this op should read the current
1901
// value of the register, or where we think that register is located.
1902
// For simplicity, the code will read the value before doing the unwind.
1903
template <typename AddressType>
1904
151
bool DwarfOp<AddressType>::op_breg() {
1905
151
  uint16_t reg = regs_info_->regs->Convert(cur_op() - 0x70);
1906
151
  if (reg >= regs_info_->Total()) {
1907
0
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1908
0
    return false;
1909
0
  }
1910
151
  stack_.push_front(regs_info_->Get(reg) + OperandAt(0));
1911
151
  return true;
1912
151
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_breg()
unwindstack::DwarfOp<unsigned long>::op_breg()
Line
Count
Source
1904
151
bool DwarfOp<AddressType>::op_breg() {
1905
151
  uint16_t reg = regs_info_->regs->Convert(cur_op() - 0x70);
1906
151
  if (reg >= regs_info_->Total()) {
1907
0
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1908
0
    return false;
1909
0
  }
1910
151
  stack_.push_front(regs_info_->Get(reg) + OperandAt(0));
1911
151
  return true;
1912
151
}
1913
1914
template <typename AddressType>
1915
0
bool DwarfOp<AddressType>::op_bregx() {
1916
0
  uint16_t reg = regs_info_->regs->Convert(OperandAt(0));
1917
0
  if (reg >= regs_info_->Total()) {
1918
0
    last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1919
0
    return false;
1920
0
  }
1921
0
  stack_.push_front(regs_info_->Get(reg) + OperandAt(1));
1922
0
  return true;
1923
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_bregx()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_bregx()
1924
1925
template <typename AddressType>
1926
0
bool DwarfOp<AddressType>::op_nop() {
1927
0
  return true;
1928
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_nop()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_nop()
1929
1930
template <typename AddressType>
1931
0
bool DwarfOp<AddressType>::op_not_implemented() {
1932
0
  last_error_.code = DWARF_ERROR_NOT_IMPLEMENTED;
1933
0
  return false;
1934
0
}
Unexecuted instantiation: unwindstack::DwarfOp<unsigned int>::op_not_implemented()
Unexecuted instantiation: unwindstack::DwarfOp<unsigned long>::op_not_implemented()
1935
1936
// Explicitly instantiate DwarfOp.
1937
template class DwarfOp<uint32_t>;
1938
template class DwarfOp<uint64_t>;
1939
1940
}  // namespace unwindstack