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