• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
Eval(uint64_t start,uint64_t end)1482 bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end) {
1483   is_register_ = false;
1484   stack_.clear();
1485   memory_->set_cur_offset(start);
1486   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   if (memory_->cur_offset() < end) {
1494     if (!Decode()) {
1495       return false;
1496     }
1497   } else {
1498     return true;
1499   }
1500   bool check_for_drop;
1501   if (cur_op_ == 0x0c && operands_.back() == 0x31584544) {
1502     check_for_drop = true;
1503   } else {
1504     check_for_drop = false;
1505   }
1506   if (memory_->cur_offset() < end) {
1507     if (!Decode()) {
1508       return false;
1509     }
1510   } else {
1511     return true;
1512   }
1513 
1514   if (check_for_drop && cur_op_ == 0x13) {
1515     dex_pc_set_ = true;
1516   }
1517 
1518   uint32_t iterations = 2;
1519   while (memory_->cur_offset() < end) {
1520     if (!Decode()) {
1521       return false;
1522     }
1523     // To protect against a branch that creates an infinite loop,
1524     // terminate if the number of iterations gets too high.
1525     if (iterations++ == 1000) {
1526       last_error_.code = DWARF_ERROR_TOO_MANY_ITERATIONS;
1527       return false;
1528     }
1529   }
1530   return true;
1531 }
1532 
1533 template <typename AddressType>
Decode()1534 bool DwarfOp<AddressType>::Decode() {
1535   last_error_.code = DWARF_ERROR_NONE;
1536   if (!memory_->ReadBytes(&cur_op_, 1)) {
1537     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1538     last_error_.address = memory_->cur_offset();
1539     return false;
1540   }
1541 
1542   const auto* op = &kCallbackTable[cur_op_];
1543   if (op->handle_func == OP_ILLEGAL) {
1544     last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1545     return false;
1546   }
1547 
1548   const auto handle_func = kOpHandleFuncList[op->handle_func];
1549 
1550   // Make sure that the required number of stack elements is available.
1551   if (stack_.size() < op->num_required_stack_values) {
1552     last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID;
1553     return false;
1554   }
1555 
1556   operands_.clear();
1557   for (size_t i = 0; i < op->num_operands; i++) {
1558     uint64_t value;
1559     if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) {
1560       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1561       last_error_.address = memory_->cur_offset();
1562       return false;
1563     }
1564     operands_.push_back(value);
1565   }
1566   return (this->*handle_func)();
1567 }
1568 
1569 template <typename AddressType>
GetLogInfo(uint64_t start,uint64_t end,std::vector<std::string> * lines)1570 void DwarfOp<AddressType>::GetLogInfo(uint64_t start, uint64_t end,
1571                                       std::vector<std::string>* lines) {
1572   memory_->set_cur_offset(start);
1573   while (memory_->cur_offset() < end) {
1574     uint8_t cur_op;
1575     if (!memory_->ReadBytes(&cur_op, 1)) {
1576       return;
1577     }
1578 
1579     std::string raw_string(android::base::StringPrintf("Raw Data: 0x%02x", cur_op));
1580     std::string log_string;
1581     const auto* op = &kCallbackTable[cur_op];
1582     if (op->handle_func == OP_ILLEGAL) {
1583       log_string = "Illegal";
1584     } else {
1585       log_string = op->name;
1586       uint64_t start_offset = memory_->cur_offset();
1587       for (size_t i = 0; i < op->num_operands; i++) {
1588         uint64_t value;
1589         if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) {
1590           return;
1591         }
1592         log_string += ' ' + std::to_string(value);
1593       }
1594       uint64_t end_offset = memory_->cur_offset();
1595 
1596       memory_->set_cur_offset(start_offset);
1597       for (size_t i = start_offset; i < end_offset; i++) {
1598         uint8_t byte;
1599         if (!memory_->ReadBytes(&byte, 1)) {
1600           return;
1601         }
1602         raw_string += android::base::StringPrintf(" 0x%02x", byte);
1603       }
1604       memory_->set_cur_offset(end_offset);
1605     }
1606     lines->push_back(std::move(log_string));
1607     lines->push_back(std::move(raw_string));
1608   }
1609 }
1610 
1611 template <typename AddressType>
op_deref()1612 bool DwarfOp<AddressType>::op_deref() {
1613   // Read the address and dereference it.
1614   AddressType addr = StackPop();
1615   AddressType value;
1616   if (!regular_memory()->ReadFully(addr, &value, sizeof(value))) {
1617     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1618     last_error_.address = addr;
1619     return false;
1620   }
1621   stack_.push_front(value);
1622   return true;
1623 }
1624 
1625 template <typename AddressType>
op_deref_size()1626 bool DwarfOp<AddressType>::op_deref_size() {
1627   AddressType bytes_to_read = OperandAt(0);
1628   if (bytes_to_read > sizeof(AddressType) || bytes_to_read == 0) {
1629     last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1630     return false;
1631   }
1632   // Read the address and dereference it.
1633   AddressType addr = StackPop();
1634   AddressType value = 0;
1635   if (!regular_memory()->ReadFully(addr, &value, bytes_to_read)) {
1636     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
1637     last_error_.address = addr;
1638     return false;
1639   }
1640   stack_.push_front(value);
1641   return true;
1642 }
1643 
1644 template <typename AddressType>
op_push()1645 bool DwarfOp<AddressType>::op_push() {
1646   // Push all of the operands.
1647   for (auto operand : operands_) {
1648     stack_.push_front(operand);
1649   }
1650   return true;
1651 }
1652 
1653 template <typename AddressType>
op_dup()1654 bool DwarfOp<AddressType>::op_dup() {
1655   stack_.push_front(StackAt(0));
1656   return true;
1657 }
1658 
1659 template <typename AddressType>
op_drop()1660 bool DwarfOp<AddressType>::op_drop() {
1661   StackPop();
1662   return true;
1663 }
1664 
1665 template <typename AddressType>
op_over()1666 bool DwarfOp<AddressType>::op_over() {
1667   stack_.push_front(StackAt(1));
1668   return true;
1669 }
1670 
1671 template <typename AddressType>
op_pick()1672 bool DwarfOp<AddressType>::op_pick() {
1673   AddressType index = OperandAt(0);
1674   if (index >= StackSize()) {
1675     last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID;
1676     return false;
1677   }
1678   stack_.push_front(StackAt(index));
1679   return true;
1680 }
1681 
1682 template <typename AddressType>
op_swap()1683 bool DwarfOp<AddressType>::op_swap() {
1684   AddressType old_value = stack_[0];
1685   stack_[0] = stack_[1];
1686   stack_[1] = old_value;
1687   return true;
1688 }
1689 
1690 template <typename AddressType>
op_rot()1691 bool DwarfOp<AddressType>::op_rot() {
1692   AddressType top = stack_[0];
1693   stack_[0] = stack_[1];
1694   stack_[1] = stack_[2];
1695   stack_[2] = top;
1696   return true;
1697 }
1698 
1699 template <typename AddressType>
op_abs()1700 bool DwarfOp<AddressType>::op_abs() {
1701   SignedType signed_value = static_cast<SignedType>(stack_[0]);
1702   if (signed_value < 0) {
1703     signed_value = -signed_value;
1704   }
1705   stack_[0] = static_cast<AddressType>(signed_value);
1706   return true;
1707 }
1708 
1709 template <typename AddressType>
op_and()1710 bool DwarfOp<AddressType>::op_and() {
1711   AddressType top = StackPop();
1712   stack_[0] &= top;
1713   return true;
1714 }
1715 
1716 template <typename AddressType>
op_div()1717 bool DwarfOp<AddressType>::op_div() {
1718   AddressType top = StackPop();
1719   if (top == 0) {
1720     last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1721     return false;
1722   }
1723   SignedType signed_divisor = static_cast<SignedType>(top);
1724   SignedType signed_dividend = static_cast<SignedType>(stack_[0]);
1725   stack_[0] = static_cast<AddressType>(signed_dividend / signed_divisor);
1726   return true;
1727 }
1728 
1729 template <typename AddressType>
op_minus()1730 bool DwarfOp<AddressType>::op_minus() {
1731   AddressType top = StackPop();
1732   stack_[0] -= top;
1733   return true;
1734 }
1735 
1736 template <typename AddressType>
op_mod()1737 bool DwarfOp<AddressType>::op_mod() {
1738   AddressType top = StackPop();
1739   if (top == 0) {
1740     last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1741     return false;
1742   }
1743   stack_[0] %= top;
1744   return true;
1745 }
1746 
1747 template <typename AddressType>
op_mul()1748 bool DwarfOp<AddressType>::op_mul() {
1749   AddressType top = StackPop();
1750   stack_[0] *= top;
1751   return true;
1752 }
1753 
1754 template <typename AddressType>
op_neg()1755 bool DwarfOp<AddressType>::op_neg() {
1756   SignedType signed_value = static_cast<SignedType>(stack_[0]);
1757   stack_[0] = static_cast<AddressType>(-signed_value);
1758   return true;
1759 }
1760 
1761 template <typename AddressType>
op_not()1762 bool DwarfOp<AddressType>::op_not() {
1763   stack_[0] = ~stack_[0];
1764   return true;
1765 }
1766 
1767 template <typename AddressType>
op_or()1768 bool DwarfOp<AddressType>::op_or() {
1769   AddressType top = StackPop();
1770   stack_[0] |= top;
1771   return true;
1772 }
1773 
1774 template <typename AddressType>
op_plus()1775 bool DwarfOp<AddressType>::op_plus() {
1776   AddressType top = StackPop();
1777   stack_[0] += top;
1778   return true;
1779 }
1780 
1781 template <typename AddressType>
op_plus_uconst()1782 bool DwarfOp<AddressType>::op_plus_uconst() {
1783   stack_[0] += OperandAt(0);
1784   return true;
1785 }
1786 
1787 template <typename AddressType>
op_shl()1788 bool DwarfOp<AddressType>::op_shl() {
1789   AddressType top = StackPop();
1790   stack_[0] <<= top;
1791   return true;
1792 }
1793 
1794 template <typename AddressType>
op_shr()1795 bool DwarfOp<AddressType>::op_shr() {
1796   AddressType top = StackPop();
1797   stack_[0] >>= top;
1798   return true;
1799 }
1800 
1801 template <typename AddressType>
op_shra()1802 bool DwarfOp<AddressType>::op_shra() {
1803   AddressType top = StackPop();
1804   SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top;
1805   stack_[0] = static_cast<AddressType>(signed_value);
1806   return true;
1807 }
1808 
1809 template <typename AddressType>
op_xor()1810 bool DwarfOp<AddressType>::op_xor() {
1811   AddressType top = StackPop();
1812   stack_[0] ^= top;
1813   return true;
1814 }
1815 
1816 template <typename AddressType>
op_bra()1817 bool DwarfOp<AddressType>::op_bra() {
1818   // Requires one stack element.
1819   AddressType top = StackPop();
1820   int16_t offset = static_cast<int16_t>(OperandAt(0));
1821   uint64_t cur_offset;
1822   if (top != 0) {
1823     cur_offset = memory_->cur_offset() + offset;
1824   } else {
1825     cur_offset = memory_->cur_offset() - offset;
1826   }
1827   memory_->set_cur_offset(cur_offset);
1828   return true;
1829 }
1830 
1831 template <typename AddressType>
op_eq()1832 bool DwarfOp<AddressType>::op_eq() {
1833   AddressType top = StackPop();
1834   stack_[0] = bool_to_dwarf_bool(stack_[0] == top);
1835   return true;
1836 }
1837 
1838 template <typename AddressType>
op_ge()1839 bool DwarfOp<AddressType>::op_ge() {
1840   AddressType top = StackPop();
1841   stack_[0] = bool_to_dwarf_bool(stack_[0] >= top);
1842   return true;
1843 }
1844 
1845 template <typename AddressType>
op_gt()1846 bool DwarfOp<AddressType>::op_gt() {
1847   AddressType top = StackPop();
1848   stack_[0] = bool_to_dwarf_bool(stack_[0] > top);
1849   return true;
1850 }
1851 
1852 template <typename AddressType>
op_le()1853 bool DwarfOp<AddressType>::op_le() {
1854   AddressType top = StackPop();
1855   stack_[0] = bool_to_dwarf_bool(stack_[0] <= top);
1856   return true;
1857 }
1858 
1859 template <typename AddressType>
op_lt()1860 bool DwarfOp<AddressType>::op_lt() {
1861   AddressType top = StackPop();
1862   stack_[0] = bool_to_dwarf_bool(stack_[0] < top);
1863   return true;
1864 }
1865 
1866 template <typename AddressType>
op_ne()1867 bool DwarfOp<AddressType>::op_ne() {
1868   AddressType top = StackPop();
1869   stack_[0] = bool_to_dwarf_bool(stack_[0] != top);
1870   return true;
1871 }
1872 
1873 template <typename AddressType>
op_skip()1874 bool DwarfOp<AddressType>::op_skip() {
1875   int16_t offset = static_cast<int16_t>(OperandAt(0));
1876   uint64_t cur_offset = memory_->cur_offset() + offset;
1877   memory_->set_cur_offset(cur_offset);
1878   return true;
1879 }
1880 
1881 template <typename AddressType>
op_lit()1882 bool DwarfOp<AddressType>::op_lit() {
1883   stack_.push_front(cur_op() - 0x30);
1884   return true;
1885 }
1886 
1887 template <typename AddressType>
op_reg()1888 bool DwarfOp<AddressType>::op_reg() {
1889   is_register_ = true;
1890   stack_.push_front(cur_op() - 0x50);
1891   return true;
1892 }
1893 
1894 template <typename AddressType>
op_regx()1895 bool DwarfOp<AddressType>::op_regx() {
1896   is_register_ = true;
1897   stack_.push_front(OperandAt(0));
1898   return true;
1899 }
1900 
1901 // It's not clear for breg/bregx, if this op should read the current
1902 // value of the register, or where we think that register is located.
1903 // For simplicity, the code will read the value before doing the unwind.
1904 template <typename AddressType>
op_breg()1905 bool DwarfOp<AddressType>::op_breg() {
1906   uint16_t reg = cur_op() - 0x70;
1907   if (reg >= regs_info_->Total()) {
1908     last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1909     return false;
1910   }
1911   stack_.push_front(regs_info_->Get(reg) + OperandAt(0));
1912   return true;
1913 }
1914 
1915 template <typename AddressType>
op_bregx()1916 bool DwarfOp<AddressType>::op_bregx() {
1917   AddressType reg = OperandAt(0);
1918   if (reg >= regs_info_->Total()) {
1919     last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
1920     return false;
1921   }
1922   stack_.push_front(regs_info_->Get(reg) + OperandAt(1));
1923   return true;
1924 }
1925 
1926 template <typename AddressType>
op_nop()1927 bool DwarfOp<AddressType>::op_nop() {
1928   return true;
1929 }
1930 
1931 template <typename AddressType>
op_not_implemented()1932 bool DwarfOp<AddressType>::op_not_implemented() {
1933   last_error_.code = DWARF_ERROR_NOT_IMPLEMENTED;
1934   return false;
1935 }
1936 
1937 // Explicitly instantiate DwarfOp.
1938 template class DwarfOp<uint32_t>;
1939 template class DwarfOp<uint64_t>;
1940 
1941 }  // namespace unwindstack
1942