2 * Copyright (c) 2013-2019, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * * Neither the name of Intel Corporation nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
30 #include "pti-imm-defs.h"
32 #include "pti-modrm-defs.h"
33 #include "pti-modrm.h"
34 #include "pti-disp-defs.h"
36 #include "pti-disp_default.h"
42 static const uint8_t eamode_table[2][4] = {
44 /* ptem_unknown = */ ptem_unknown,
45 /* ptem_16bit = */ ptem_16bit,
46 /* ptem_32bit = */ ptem_32bit,
47 /* ptem_64bit = */ ptem_64bit
50 /* With Address-size prefix (0x67): */ {
51 /* ptem_unknown = */ ptem_unknown,
52 /* ptem_16bit = */ ptem_32bit,
53 /* ptem_32bit = */ ptem_16bit,
54 /* ptem_64bit = */ ptem_32bit
60 static inline uint8_t get_byte(const struct pt_ild *ild, uint8_t i)
65 static inline uint8_t const *get_byte_ptr(const struct pt_ild *ild, uint8_t i)
67 return ild->itext + i;
70 static inline int mode_64b(const struct pt_ild *ild)
72 return ild->mode == ptem_64bit;
75 static inline int mode_32b(const struct pt_ild *ild)
77 return ild->mode == ptem_32bit;
80 static inline int bits_match(uint8_t x, uint8_t mask, uint8_t target)
82 return (x & mask) == target;
85 static inline enum pt_exec_mode
86 pti_get_nominal_eosz_non64(const struct pt_ild *ild)
98 static inline enum pt_exec_mode
99 pti_get_nominal_eosz(const struct pt_ild *ild)
108 return pti_get_nominal_eosz_non64(ild);
111 static inline enum pt_exec_mode
112 pti_get_nominal_eosz_df64(const struct pt_ild *ild)
119 /* only this next line of code is different relative
120 to pti_get_nominal_eosz(), above */
123 return pti_get_nominal_eosz_non64(ild);
126 static inline enum pt_exec_mode
127 pti_get_nominal_easz_non64(const struct pt_ild *ild)
139 static inline enum pt_exec_mode
140 pti_get_nominal_easz(const struct pt_ild *ild)
147 return pti_get_nominal_easz_non64(ild);
150 static inline int resolve_z(uint8_t *pbytes, enum pt_exec_mode eosz)
152 static const uint8_t bytes[] = { 2, 4, 4 };
156 return -pte_internal;
158 idx = (unsigned int) eosz - 1;
159 if (sizeof(bytes) <= idx)
160 return -pte_bad_insn;
162 *pbytes = bytes[idx];
166 static inline int resolve_v(uint8_t *pbytes, enum pt_exec_mode eosz)
168 static const uint8_t bytes[] = { 2, 4, 8 };
172 return -pte_internal;
174 idx = (unsigned int) eosz - 1;
175 if (sizeof(bytes) <= idx)
176 return -pte_bad_insn;
178 *pbytes = bytes[idx];
184 static int set_imm_bytes(struct pt_ild *ild)
186 /*: set ild->imm1_bytes and ild->imm2_bytes for maps 0/1 */
187 static uint8_t const *const map_map[] = {
188 /* map 0 */ imm_bytes_map_0x0,
189 /* map 1 */ imm_bytes_map_0x0F
191 uint8_t map, imm_code;
194 return -pte_internal;
198 if ((sizeof(map_map) / sizeof(*map_map)) <= map)
201 imm_code = map_map[map][ild->nominal_opcode];
204 case PTI_0_IMM_WIDTH_CONST_l2:
208 case PTI_UIMM8_IMM_WIDTH_CONST_l2:
212 case PTI_SIMM8_IMM_WIDTH_CONST_l2:
216 case PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2:
218 return resolve_z(&ild->imm1_bytes, pti_get_nominal_eosz(ild));
220 case PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2:
222 return resolve_v(&ild->imm1_bytes, pti_get_nominal_eosz(ild));
224 case PTI_UIMM16_IMM_WIDTH_CONST_l2:
228 case PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_DF64_EOSZ_l2:
229 /* push defaults to eosz64 in 64b mode, then uses SIMMz */
230 return resolve_z(&ild->imm1_bytes,
231 pti_get_nominal_eosz_df64(ild));
233 case PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xf7_l1:
234 if (ild->map == PTI_MAP_0 && pti_get_modrm_reg(ild) < 2) {
235 return resolve_z(&ild->imm1_bytes,
236 pti_get_nominal_eosz(ild));
240 case PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xc7_l1:
241 if (ild->map == PTI_MAP_0 && pti_get_modrm_reg(ild) == 0) {
242 return resolve_z(&ild->imm1_bytes,
243 pti_get_nominal_eosz(ild));
247 case PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xf6_l1:
248 if (ild->map == PTI_MAP_0 && pti_get_modrm_reg(ild) < 2)
253 case PTI_IMM_hasimm_map0x0_op0xc8_l1:
254 if (ild->map == PTI_MAP_0) {
255 /*enter -> imm1=2, imm2=1 */
261 case PTI_IMM_hasimm_map0x0F_op0x78_l1:
262 /* AMD SSE4a (insertq/extrq use osz/f2) vs vmread
265 if (ild->map == PTI_MAP_1) {
266 if (ild->u.s.osz || ild->u.s.last_f2f3 == 2) {
275 static int imm_dec(struct pt_ild *ild, uint8_t length)
280 return -pte_internal;
282 if (ild->map == PTI_MAP_AMD3DNOW) {
283 if (ild->max_bytes <= length)
284 return -pte_bad_insn;
286 ild->nominal_opcode = get_byte(ild, length);
290 errcode = set_imm_bytes(ild);
294 length += ild->imm1_bytes;
295 length += ild->imm2_bytes;
296 if (ild->max_bytes < length)
297 return -pte_bad_insn;
302 static int compute_disp_dec(struct pt_ild *ild)
304 /* set ild->disp_bytes for maps 0 and 1. */
305 static uint8_t const *const map_map[] = {
306 /* map 0 */ disp_bytes_map_0x0,
307 /* map 1 */ disp_bytes_map_0x0F
309 uint8_t map, disp_kind;
312 return -pte_internal;
314 if (0 < ild->disp_bytes)
319 if ((sizeof(map_map) / sizeof(*map_map)) <= map)
322 disp_kind = map_map[map][ild->nominal_opcode];
328 case PTI_PRESERVE_DEFAULT:
336 case PTI_DISP_BUCKET_0_l1:
337 /* BRDISPz(eosz) for 16/32 modes, and BRDISP32 for 64b mode */
343 return resolve_z(&ild->disp_bytes,
344 pti_get_nominal_eosz(ild));
346 case PTI_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2:
348 return resolve_v(&ild->disp_bytes, pti_get_nominal_easz(ild));
350 case PTI_BRDISPz_BRDISP_WIDTH_OSZ_NONTERM_EOSZ_l2:
351 /* BRDISPz(eosz) for 16/32/64 modes */
352 return resolve_z(&ild->disp_bytes, pti_get_nominal_eosz(ild));
354 case PTI_RESOLVE_BYREG_DISP_map0x0_op0xc7_l1:
355 /* reg=0 -> preserve, reg=7 -> BRDISPz(eosz) */
356 if (ild->map == PTI_MAP_0 && pti_get_modrm_reg(ild) == 7) {
357 return resolve_z(&ild->disp_bytes,
358 pti_get_nominal_eosz(ild));
363 return -pte_bad_insn;
367 static int disp_dec(struct pt_ild *ild, uint8_t length)
373 return -pte_internal;
375 errcode = compute_disp_dec(ild);
379 disp_bytes = ild->disp_bytes;
381 return imm_dec(ild, length);
383 if (length + disp_bytes > ild->max_bytes)
384 return -pte_bad_insn;
386 /*Record only position; must be able to re-read itext bytes for actual
387 value. (SMC/CMC issue). */
388 ild->disp_pos = length;
390 return imm_dec(ild, length + disp_bytes);
393 static int sib_dec(struct pt_ild *ild, uint8_t length)
398 return -pte_internal;
400 if (ild->max_bytes <= length)
401 return -pte_bad_insn;
403 sib = get_byte(ild, length);
404 if ((sib & 0x07) == 0x05 && pti_get_modrm_mod(ild) == 0)
407 return disp_dec(ild, length + 1);
410 static int modrm_dec(struct pt_ild *ild, uint8_t length)
412 static uint8_t const *const has_modrm_2d[2] = {
416 int has_modrm = PTI_MODRM_FALSE;
420 return -pte_internal;
422 map = pti_get_map(ild);
423 if (map >= PTI_MAP_2)
424 has_modrm = PTI_MODRM_TRUE;
426 has_modrm = has_modrm_2d[map][ild->nominal_opcode];
428 if (has_modrm == PTI_MODRM_FALSE || has_modrm == PTI_MODRM_UNDEF)
429 return disp_dec(ild, length);
431 /* really >= here because we have not eaten the byte yet */
432 if (length >= ild->max_bytes)
433 return -pte_bad_insn;
435 ild->modrm_byte = get_byte(ild, length);
437 if (has_modrm != PTI_MODRM_IGNORE_MOD) {
438 /* set disp_bytes and sib using simple tables */
440 uint8_t eamode = eamode_table[ild->u.s.asz][ild->mode];
441 uint8_t mod = (uint8_t) pti_get_modrm_mod(ild);
442 uint8_t rm = (uint8_t) pti_get_modrm_rm(ild);
445 ild->disp_bytes = disp_default[eamode][mod][rm];
447 sib = has_sib[eamode][mod][rm];
449 return sib_dec(ild, length + 1);
452 return disp_dec(ild, length + 1);
455 static inline int get_next_as_opcode(struct pt_ild *ild, uint8_t length)
458 return -pte_internal;
460 if (ild->max_bytes <= length)
461 return -pte_bad_insn;
463 ild->nominal_opcode = get_byte(ild, length);
465 return modrm_dec(ild, length + 1);
468 static int opcode_dec(struct pt_ild *ild, uint8_t length)
473 return -pte_internal;
475 /*no need to check max_bytes - it was checked in previous scanners */
476 b = get_byte(ild, length);
477 if (b != 0x0F) { /* 1B opcodes, map 0 */
478 ild->map = PTI_MAP_0;
479 ild->nominal_opcode = b;
481 return modrm_dec(ild, length + 1);
484 length++; /* eat the 0x0F */
486 if (ild->max_bytes <= length)
487 return -pte_bad_insn;
489 /* 0x0F opcodes MAPS 1,2,3 */
490 m = get_byte(ild, length);
492 ild->map = PTI_MAP_2;
494 return get_next_as_opcode(ild, length + 1);
495 } else if (m == 0x3A) {
496 ild->map = PTI_MAP_3;
499 return get_next_as_opcode(ild, length + 1);
500 } else if (bits_match(m, 0xf8, 0x38)) {
501 ild->map = PTI_MAP_INVALID;
503 return get_next_as_opcode(ild, length + 1);
504 } else if (m == 0x0F) { /* 3dNow */
505 ild->map = PTI_MAP_AMD3DNOW;
507 /* real opcode is in immediate later on, but we need an
509 ild->nominal_opcode = 0x0F;
511 return modrm_dec(ild, length + 1);
512 } else { /* map 1 (simple two byte opcodes) */
513 ild->nominal_opcode = m;
514 ild->map = PTI_MAP_1;
516 return modrm_dec(ild, length + 1);
520 typedef int (*prefix_decoder)(struct pt_ild *ild, uint8_t length, uint8_t rex);
522 static int prefix_osz(struct pt_ild *ild, uint8_t length, uint8_t rex);
523 static int prefix_asz(struct pt_ild *ild, uint8_t length, uint8_t rex);
524 static int prefix_lock(struct pt_ild *ild, uint8_t length, uint8_t rex);
525 static int prefix_f2(struct pt_ild *ild, uint8_t length, uint8_t rex);
526 static int prefix_f3(struct pt_ild *ild, uint8_t length, uint8_t rex);
527 static int prefix_rex(struct pt_ild *ild, uint8_t length, uint8_t rex);
528 static int prefix_vex_c4(struct pt_ild *ild, uint8_t length, uint8_t rex);
529 static int prefix_vex_c5(struct pt_ild *ild, uint8_t length, uint8_t rex);
530 static int prefix_evex(struct pt_ild *ild, uint8_t length, uint8_t rex);
531 static int prefix_ignore(struct pt_ild *ild, uint8_t length, uint8_t rex);
532 static int prefix_done(struct pt_ild *ild, uint8_t length, uint8_t rex);
534 static const prefix_decoder prefix_table[256] = {
535 /* 00 = */ prefix_done,
536 /* 01 = */ prefix_done,
537 /* 02 = */ prefix_done,
538 /* 03 = */ prefix_done,
539 /* 04 = */ prefix_done,
540 /* 05 = */ prefix_done,
541 /* 06 = */ prefix_done,
542 /* 07 = */ prefix_done,
543 /* 08 = */ prefix_done,
544 /* 09 = */ prefix_done,
545 /* 0a = */ prefix_done,
546 /* 0b = */ prefix_done,
547 /* 0c = */ prefix_done,
548 /* 0d = */ prefix_done,
549 /* 0e = */ prefix_done,
550 /* 0f = */ prefix_done,
552 /* 10 = */ prefix_done,
553 /* 11 = */ prefix_done,
554 /* 12 = */ prefix_done,
555 /* 13 = */ prefix_done,
556 /* 14 = */ prefix_done,
557 /* 15 = */ prefix_done,
558 /* 16 = */ prefix_done,
559 /* 17 = */ prefix_done,
560 /* 18 = */ prefix_done,
561 /* 19 = */ prefix_done,
562 /* 1a = */ prefix_done,
563 /* 1b = */ prefix_done,
564 /* 1c = */ prefix_done,
565 /* 1d = */ prefix_done,
566 /* 1e = */ prefix_done,
567 /* 1f = */ prefix_done,
569 /* 20 = */ prefix_done,
570 /* 21 = */ prefix_done,
571 /* 22 = */ prefix_done,
572 /* 23 = */ prefix_done,
573 /* 24 = */ prefix_done,
574 /* 25 = */ prefix_done,
575 /* 26 = */ prefix_ignore,
576 /* 27 = */ prefix_done,
577 /* 28 = */ prefix_done,
578 /* 29 = */ prefix_done,
579 /* 2a = */ prefix_done,
580 /* 2b = */ prefix_done,
581 /* 2c = */ prefix_done,
582 /* 2d = */ prefix_done,
583 /* 2e = */ prefix_ignore,
584 /* 2f = */ prefix_done,
586 /* 30 = */ prefix_done,
587 /* 31 = */ prefix_done,
588 /* 32 = */ prefix_done,
589 /* 33 = */ prefix_done,
590 /* 34 = */ prefix_done,
591 /* 35 = */ prefix_done,
592 /* 36 = */ prefix_ignore,
593 /* 37 = */ prefix_done,
594 /* 38 = */ prefix_done,
595 /* 39 = */ prefix_done,
596 /* 3a = */ prefix_done,
597 /* 3b = */ prefix_done,
598 /* 3c = */ prefix_done,
599 /* 3d = */ prefix_done,
600 /* 3e = */ prefix_ignore,
601 /* 3f = */ prefix_done,
603 /* 40 = */ prefix_rex,
604 /* 41 = */ prefix_rex,
605 /* 42 = */ prefix_rex,
606 /* 43 = */ prefix_rex,
607 /* 44 = */ prefix_rex,
608 /* 45 = */ prefix_rex,
609 /* 46 = */ prefix_rex,
610 /* 47 = */ prefix_rex,
611 /* 48 = */ prefix_rex,
612 /* 49 = */ prefix_rex,
613 /* 4a = */ prefix_rex,
614 /* 4b = */ prefix_rex,
615 /* 4c = */ prefix_rex,
616 /* 4d = */ prefix_rex,
617 /* 4e = */ prefix_rex,
618 /* 4f = */ prefix_rex,
620 /* 50 = */ prefix_done,
621 /* 51 = */ prefix_done,
622 /* 52 = */ prefix_done,
623 /* 53 = */ prefix_done,
624 /* 54 = */ prefix_done,
625 /* 55 = */ prefix_done,
626 /* 56 = */ prefix_done,
627 /* 57 = */ prefix_done,
628 /* 58 = */ prefix_done,
629 /* 59 = */ prefix_done,
630 /* 5a = */ prefix_done,
631 /* 5b = */ prefix_done,
632 /* 5c = */ prefix_done,
633 /* 5d = */ prefix_done,
634 /* 5e = */ prefix_done,
635 /* 5f = */ prefix_done,
637 /* 60 = */ prefix_done,
638 /* 61 = */ prefix_done,
639 /* 62 = */ prefix_evex,
640 /* 63 = */ prefix_done,
641 /* 64 = */ prefix_ignore,
642 /* 65 = */ prefix_ignore,
643 /* 66 = */ prefix_osz,
644 /* 67 = */ prefix_asz,
645 /* 68 = */ prefix_done,
646 /* 69 = */ prefix_done,
647 /* 6a = */ prefix_done,
648 /* 6b = */ prefix_done,
649 /* 6c = */ prefix_done,
650 /* 6d = */ prefix_done,
651 /* 6e = */ prefix_done,
652 /* 6f = */ prefix_done,
654 /* 70 = */ prefix_done,
655 /* 71 = */ prefix_done,
656 /* 72 = */ prefix_done,
657 /* 73 = */ prefix_done,
658 /* 74 = */ prefix_done,
659 /* 75 = */ prefix_done,
660 /* 76 = */ prefix_done,
661 /* 77 = */ prefix_done,
662 /* 78 = */ prefix_done,
663 /* 79 = */ prefix_done,
664 /* 7a = */ prefix_done,
665 /* 7b = */ prefix_done,
666 /* 7c = */ prefix_done,
667 /* 7d = */ prefix_done,
668 /* 7e = */ prefix_done,
669 /* 7f = */ prefix_done,
671 /* 80 = */ prefix_done,
672 /* 81 = */ prefix_done,
673 /* 82 = */ prefix_done,
674 /* 83 = */ prefix_done,
675 /* 84 = */ prefix_done,
676 /* 85 = */ prefix_done,
677 /* 86 = */ prefix_done,
678 /* 87 = */ prefix_done,
679 /* 88 = */ prefix_done,
680 /* 89 = */ prefix_done,
681 /* 8a = */ prefix_done,
682 /* 8b = */ prefix_done,
683 /* 8c = */ prefix_done,
684 /* 8d = */ prefix_done,
685 /* 8e = */ prefix_done,
686 /* 8f = */ prefix_done,
688 /* 90 = */ prefix_done,
689 /* 91 = */ prefix_done,
690 /* 92 = */ prefix_done,
691 /* 93 = */ prefix_done,
692 /* 94 = */ prefix_done,
693 /* 95 = */ prefix_done,
694 /* 96 = */ prefix_done,
695 /* 97 = */ prefix_done,
696 /* 98 = */ prefix_done,
697 /* 99 = */ prefix_done,
698 /* 9a = */ prefix_done,
699 /* 9b = */ prefix_done,
700 /* 9c = */ prefix_done,
701 /* 9d = */ prefix_done,
702 /* 9e = */ prefix_done,
703 /* 9f = */ prefix_done,
705 /* a0 = */ prefix_done,
706 /* a1 = */ prefix_done,
707 /* a2 = */ prefix_done,
708 /* a3 = */ prefix_done,
709 /* a4 = */ prefix_done,
710 /* a5 = */ prefix_done,
711 /* a6 = */ prefix_done,
712 /* a7 = */ prefix_done,
713 /* a8 = */ prefix_done,
714 /* a9 = */ prefix_done,
715 /* aa = */ prefix_done,
716 /* ab = */ prefix_done,
717 /* ac = */ prefix_done,
718 /* ad = */ prefix_done,
719 /* ae = */ prefix_done,
720 /* af = */ prefix_done,
722 /* b0 = */ prefix_done,
723 /* b1 = */ prefix_done,
724 /* b2 = */ prefix_done,
725 /* b3 = */ prefix_done,
726 /* b4 = */ prefix_done,
727 /* b5 = */ prefix_done,
728 /* b6 = */ prefix_done,
729 /* b7 = */ prefix_done,
730 /* b8 = */ prefix_done,
731 /* b9 = */ prefix_done,
732 /* ba = */ prefix_done,
733 /* bb = */ prefix_done,
734 /* bc = */ prefix_done,
735 /* bd = */ prefix_done,
736 /* be = */ prefix_done,
737 /* bf = */ prefix_done,
739 /* c0 = */ prefix_done,
740 /* c1 = */ prefix_done,
741 /* c2 = */ prefix_done,
742 /* c3 = */ prefix_done,
743 /* c4 = */ prefix_vex_c4,
744 /* c5 = */ prefix_vex_c5,
745 /* c6 = */ prefix_done,
746 /* c7 = */ prefix_done,
747 /* c8 = */ prefix_done,
748 /* c9 = */ prefix_done,
749 /* ca = */ prefix_done,
750 /* cb = */ prefix_done,
751 /* cc = */ prefix_done,
752 /* cd = */ prefix_done,
753 /* ce = */ prefix_done,
754 /* cf = */ prefix_done,
756 /* d0 = */ prefix_done,
757 /* d1 = */ prefix_done,
758 /* d2 = */ prefix_done,
759 /* d3 = */ prefix_done,
760 /* d4 = */ prefix_done,
761 /* d5 = */ prefix_done,
762 /* d6 = */ prefix_done,
763 /* d7 = */ prefix_done,
764 /* d8 = */ prefix_done,
765 /* d9 = */ prefix_done,
766 /* da = */ prefix_done,
767 /* db = */ prefix_done,
768 /* dc = */ prefix_done,
769 /* dd = */ prefix_done,
770 /* de = */ prefix_done,
771 /* df = */ prefix_done,
773 /* e0 = */ prefix_done,
774 /* e1 = */ prefix_done,
775 /* e2 = */ prefix_done,
776 /* e3 = */ prefix_done,
777 /* e4 = */ prefix_done,
778 /* e5 = */ prefix_done,
779 /* e6 = */ prefix_done,
780 /* e7 = */ prefix_done,
781 /* e8 = */ prefix_done,
782 /* e9 = */ prefix_done,
783 /* ea = */ prefix_done,
784 /* eb = */ prefix_done,
785 /* ec = */ prefix_done,
786 /* ed = */ prefix_done,
787 /* ee = */ prefix_done,
788 /* ef = */ prefix_done,
790 /* f0 = */ prefix_lock,
791 /* f1 = */ prefix_done,
792 /* f2 = */ prefix_f2,
793 /* f3 = */ prefix_f3,
794 /* f4 = */ prefix_done,
795 /* f5 = */ prefix_done,
796 /* f6 = */ prefix_done,
797 /* f7 = */ prefix_done,
798 /* f8 = */ prefix_done,
799 /* f9 = */ prefix_done,
800 /* fa = */ prefix_done,
801 /* fb = */ prefix_done,
802 /* fc = */ prefix_done,
803 /* fd = */ prefix_done,
804 /* fe = */ prefix_done,
805 /* ff = */ prefix_done
808 static inline int prefix_decode(struct pt_ild *ild, uint8_t length, uint8_t rex)
813 return -pte_internal;
815 if (ild->max_bytes <= length)
816 return -pte_bad_insn;
818 byte = get_byte(ild, length);
820 return prefix_table[byte](ild, length, rex);
823 static inline int prefix_next(struct pt_ild *ild, uint8_t length, uint8_t rex)
825 return prefix_decode(ild, length + 1, rex);
828 static int prefix_osz(struct pt_ild *ild, uint8_t length, uint8_t rex)
833 return -pte_internal;
837 return prefix_next(ild, length, 0);
840 static int prefix_asz(struct pt_ild *ild, uint8_t length, uint8_t rex)
845 return -pte_internal;
849 return prefix_next(ild, length, 0);
852 static int prefix_lock(struct pt_ild *ild, uint8_t length, uint8_t rex)
857 return -pte_internal;
861 return prefix_next(ild, length, 0);
864 static int prefix_f2(struct pt_ild *ild, uint8_t length, uint8_t rex)
869 return -pte_internal;
872 ild->u.s.last_f2f3 = 2;
874 return prefix_next(ild, length, 0);
877 static int prefix_f3(struct pt_ild *ild, uint8_t length, uint8_t rex)
882 return -pte_internal;
885 ild->u.s.last_f2f3 = 3;
887 return prefix_next(ild, length, 0);
890 static int prefix_ignore(struct pt_ild *ild, uint8_t length, uint8_t rex)
894 return prefix_next(ild, length, 0);
897 static int prefix_done(struct pt_ild *ild, uint8_t length, uint8_t rex)
900 return -pte_internal;
907 return opcode_dec(ild, length);
910 static int prefix_rex(struct pt_ild *ild, uint8_t length, uint8_t rex)
915 return -pte_internal;
918 return prefix_next(ild, length, get_byte(ild, length));
920 return opcode_dec(ild, length);
923 static inline int prefix_vex_done(struct pt_ild *ild, uint8_t length)
926 return -pte_internal;
928 ild->nominal_opcode = get_byte(ild, length);
930 return modrm_dec(ild, length + 1);
933 static int prefix_vex_c5(struct pt_ild *ild, uint8_t length, uint8_t rex)
941 return -pte_internal;
943 max_bytes = ild->max_bytes;
945 /* Read the next byte to validate that this is indeed VEX. */
946 if (max_bytes <= (length + 1))
947 return -pte_bad_insn;
949 p1 = get_byte(ild, length + 1);
951 /* If p1[7:6] is not 11b in non-64-bit mode, this is LDS, not VEX. */
952 if (!mode_64b(ild) && !bits_match(p1, 0xc0, 0xc0))
953 return opcode_dec(ild, length);
955 /* We need at least 3 bytes
956 * - 2 for the VEX prefix and payload and
957 * - 1 for the opcode.
959 if (max_bytes < (length + 3))
960 return -pte_bad_insn;
966 ild->map = PTI_MAP_1;
970 return prefix_vex_done(ild, length);
973 static int prefix_vex_c4(struct pt_ild *ild, uint8_t length, uint8_t rex)
981 return -pte_internal;
983 max_bytes = ild->max_bytes;
985 /* Read the next byte to validate that this is indeed VEX. */
986 if (max_bytes <= (length + 1))
987 return -pte_bad_insn;
989 p1 = get_byte(ild, length + 1);
991 /* If p1[7:6] is not 11b in non-64-bit mode, this is LES, not VEX. */
992 if (!mode_64b(ild) && !bits_match(p1, 0xc0, 0xc0))
993 return opcode_dec(ild, length);
995 /* We need at least 4 bytes
996 * - 3 for the VEX prefix and payload and
997 * - 1 for the opcode.
999 if (max_bytes < (length + 4))
1000 return -pte_bad_insn;
1002 p2 = get_byte(ild, length + 2);
1011 if (PTI_MAP_INVALID <= map)
1012 return -pte_bad_insn;
1015 if (map == PTI_MAP_3)
1016 ild->imm1_bytes = 1;
1020 return prefix_vex_done(ild, length);
1023 static int prefix_evex(struct pt_ild *ild, uint8_t length, uint8_t rex)
1026 uint8_t p1, p2, map;
1031 return -pte_internal;
1033 max_bytes = ild->max_bytes;
1035 /* Read the next byte to validate that this is indeed EVEX. */
1036 if (max_bytes <= (length + 1))
1037 return -pte_bad_insn;
1039 p1 = get_byte(ild, length + 1);
1041 /* If p1[7:6] is not 11b in non-64-bit mode, this is BOUND, not EVEX. */
1042 if (!mode_64b(ild) && !bits_match(p1, 0xc0, 0xc0))
1043 return opcode_dec(ild, length);
1045 /* We need at least 5 bytes
1046 * - 4 for the EVEX prefix and payload and
1047 * - 1 for the opcode.
1049 if (max_bytes < (length + 5))
1050 return -pte_bad_insn;
1052 p2 = get_byte(ild, length + 2);
1063 if (map == PTI_MAP_3)
1064 ild->imm1_bytes = 1;
1068 return prefix_vex_done(ild, length);
1071 static int decode(struct pt_ild *ild)
1073 return prefix_decode(ild, 0, 0);
1076 static int set_branch_target(struct pt_insn_ext *iext, const struct pt_ild *ild)
1079 return -pte_internal;
1081 iext->variant.branch.is_direct = 1;
1083 if (ild->disp_bytes == 1) {
1084 const int8_t *b = (const int8_t *)
1085 get_byte_ptr(ild, ild->disp_pos);
1087 iext->variant.branch.displacement = *b;
1088 } else if (ild->disp_bytes == 2) {
1089 const int16_t *w = (const int16_t *)
1090 get_byte_ptr(ild, ild->disp_pos);
1092 iext->variant.branch.displacement = *w;
1093 } else if (ild->disp_bytes == 4) {
1094 const int32_t *d = (const int32_t *)
1095 get_byte_ptr(ild, ild->disp_pos);
1097 iext->variant.branch.displacement = *d;
1099 return -pte_bad_insn;
1104 static int pt_instruction_length_decode(struct pt_ild *ild)
1107 return -pte_internal;
1110 ild->imm1_bytes = 0;
1111 ild->imm2_bytes = 0;
1112 ild->disp_bytes = 0;
1113 ild->modrm_byte = 0;
1114 ild->map = PTI_MAP_INVALID;
1117 return -pte_bad_insn;
1122 static int pt_instruction_decode(struct pt_insn *insn, struct pt_insn_ext *iext,
1123 const struct pt_ild *ild)
1125 uint8_t opcode, map;
1128 return -pte_internal;
1130 iext->iclass = PTI_INST_INVALID;
1131 memset(&iext->variant, 0, sizeof(iext->variant));
1133 insn->iclass = ptic_other;
1135 opcode = ild->nominal_opcode;
1138 if (map > PTI_MAP_1)
1139 return 0; /* uninteresting */
1141 return 0; /* uninteresting */
1143 /* PTI_INST_JCC, 70...7F, 0F (0x80...0x8F) */
1144 if (opcode >= 0x70 && opcode <= 0x7F) {
1145 if (map == PTI_MAP_0) {
1146 insn->iclass = ptic_cond_jump;
1147 iext->iclass = PTI_INST_JCC;
1149 return set_branch_target(iext, ild);
1153 if (opcode >= 0x80 && opcode <= 0x8F) {
1154 if (map == PTI_MAP_1) {
1155 insn->iclass = ptic_cond_jump;
1156 iext->iclass = PTI_INST_JCC;
1158 return set_branch_target(iext, ild);
1163 switch (ild->nominal_opcode) {
1165 if (map == PTI_MAP_0) {
1166 insn->iclass = ptic_far_call;
1167 iext->iclass = PTI_INST_CALL_9A;
1172 if (map == PTI_MAP_0) {
1173 uint8_t reg = pti_get_modrm_reg(ild);
1176 insn->iclass = ptic_call;
1177 iext->iclass = PTI_INST_CALL_FFr2;
1178 } else if (reg == 3) {
1179 insn->iclass = ptic_far_call;
1180 iext->iclass = PTI_INST_CALL_FFr3;
1181 } else if (reg == 4) {
1182 insn->iclass = ptic_jump;
1183 iext->iclass = PTI_INST_JMP_FFr4;
1184 } else if (reg == 5) {
1185 insn->iclass = ptic_far_jump;
1186 iext->iclass = PTI_INST_JMP_FFr5;
1192 if (map == PTI_MAP_0) {
1193 insn->iclass = ptic_call;
1194 iext->iclass = PTI_INST_CALL_E8;
1196 return set_branch_target(iext, ild);
1201 if (map == PTI_MAP_0) {
1202 insn->iclass = ptic_far_call;
1203 iext->iclass = PTI_INST_INT;
1209 if (map == PTI_MAP_0) {
1210 insn->iclass = ptic_far_call;
1211 iext->iclass = PTI_INST_INT3;
1217 if (map == PTI_MAP_0) {
1218 insn->iclass = ptic_far_call;
1219 iext->iclass = PTI_INST_INTO;
1225 if (map == PTI_MAP_0) {
1226 insn->iclass = ptic_far_call;
1227 iext->iclass = PTI_INST_INT1;
1233 if (map == PTI_MAP_0) {
1234 insn->iclass = ptic_far_return;
1235 iext->iclass = PTI_INST_IRET;
1240 if (map == PTI_MAP_0) {
1241 insn->iclass = ptic_jump;
1242 iext->iclass = PTI_INST_JMP_E9;
1244 return set_branch_target(iext, ild);
1249 if (map == PTI_MAP_0) {
1250 /* Far jumps are treated as indirect jumps. */
1251 insn->iclass = ptic_far_jump;
1252 iext->iclass = PTI_INST_JMP_EA;
1257 if (map == PTI_MAP_0) {
1258 insn->iclass = ptic_jump;
1259 iext->iclass = PTI_INST_JMP_EB;
1261 return set_branch_target(iext, ild);
1266 if (map == PTI_MAP_0) {
1267 insn->iclass = ptic_cond_jump;
1268 iext->iclass = PTI_INST_JrCXZ;
1270 return set_branch_target(iext, ild);
1275 if (map == PTI_MAP_0) {
1276 insn->iclass = ptic_cond_jump;
1277 iext->iclass = PTI_INST_LOOPNE;
1279 return set_branch_target(iext, ild);
1284 if (map == PTI_MAP_0) {
1285 insn->iclass = ptic_cond_jump;
1286 iext->iclass = PTI_INST_LOOPE;
1288 return set_branch_target(iext, ild);
1293 if (map == PTI_MAP_0) {
1294 insn->iclass = ptic_cond_jump;
1295 iext->iclass = PTI_INST_LOOP;
1297 return set_branch_target(iext, ild);
1302 if (map == PTI_MAP_1)
1303 if (pti_get_modrm_reg(ild) == 3)
1304 if (!ild->u.s.rex_r)
1305 iext->iclass = PTI_INST_MOV_CR3;
1310 if (map == PTI_MAP_0) {
1311 insn->iclass = ptic_return;
1312 iext->iclass = PTI_INST_RET_C3;
1317 if (map == PTI_MAP_0) {
1318 insn->iclass = ptic_return;
1319 iext->iclass = PTI_INST_RET_C2;
1324 if (map == PTI_MAP_0) {
1325 insn->iclass = ptic_far_return;
1326 iext->iclass = PTI_INST_RET_CB;
1331 if (map == PTI_MAP_0) {
1332 insn->iclass = ptic_far_return;
1333 iext->iclass = PTI_INST_RET_CA;
1338 if (map == PTI_MAP_1) {
1339 insn->iclass = ptic_far_call;
1340 iext->iclass = PTI_INST_SYSCALL;
1345 if (map == PTI_MAP_1) {
1346 insn->iclass = ptic_far_call;
1347 iext->iclass = PTI_INST_SYSENTER;
1352 if (map == PTI_MAP_1) {
1353 insn->iclass = ptic_far_return;
1354 iext->iclass = PTI_INST_SYSEXIT;
1359 if (map == PTI_MAP_1) {
1360 insn->iclass = ptic_far_return;
1361 iext->iclass = PTI_INST_SYSRET;
1366 if (map == PTI_MAP_1) {
1367 switch (ild->modrm_byte) {
1369 insn->iclass = ptic_far_call;
1370 iext->iclass = PTI_INST_VMCALL;
1374 insn->iclass = ptic_far_return;
1375 iext->iclass = PTI_INST_VMLAUNCH;
1379 insn->iclass = ptic_far_return;
1380 iext->iclass = PTI_INST_VMRESUME;
1390 if (map == PTI_MAP_1 &&
1391 pti_get_modrm_mod(ild) != 3 &&
1392 pti_get_modrm_reg(ild) == 6)
1393 iext->iclass = PTI_INST_VMPTRLD;
1398 if (map == PTI_MAP_1 && ild->u.s.f3 && !ild->u.s.osz &&
1399 pti_get_modrm_reg(ild) == 4) {
1400 insn->iclass = ptic_ptwrite;
1401 iext->iclass = PTI_INST_PTWRITE;
1410 int pt_ild_decode(struct pt_insn *insn, struct pt_insn_ext *iext)
1416 return -pte_internal;
1418 ild.mode = insn->mode;
1419 ild.itext = insn->raw;
1420 ild.max_bytes = insn->size;
1422 size = pt_instruction_length_decode(&ild);
1426 insn->size = (uint8_t) size;
1428 return pt_instruction_decode(insn, iext, &ild);