1 /*
2 * Copyright (c) 2013-2019, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
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.
15 *
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.
27 */
28
29 #include "pt_ild.h"
30 #include "pti-imm-defs.h"
31 #include "pti-imm.h"
32 #include "pti-modrm-defs.h"
33 #include "pti-modrm.h"
34 #include "pti-disp-defs.h"
35 #include "pti-disp.h"
36 #include "pti-disp_default.h"
37 #include "pti-sib.h"
38
39 #include <string.h>
40
41
42 static const uint8_t eamode_table[2][4] = {
43 /* Default: */ {
44 /* ptem_unknown = */ ptem_unknown,
45 /* ptem_16bit = */ ptem_16bit,
46 /* ptem_32bit = */ ptem_32bit,
47 /* ptem_64bit = */ ptem_64bit
48 },
49
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
55 }
56 };
57
58 /* SOME ACCESSORS */
59
get_byte(const struct pt_ild * ild,uint8_t i)60 static inline uint8_t get_byte(const struct pt_ild *ild, uint8_t i)
61 {
62 return ild->itext[i];
63 }
64
get_byte_ptr(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)
66 {
67 return ild->itext + i;
68 }
69
mode_64b(const struct pt_ild * ild)70 static inline int mode_64b(const struct pt_ild *ild)
71 {
72 return ild->mode == ptem_64bit;
73 }
74
mode_32b(const struct pt_ild * ild)75 static inline int mode_32b(const struct pt_ild *ild)
76 {
77 return ild->mode == ptem_32bit;
78 }
79
bits_match(uint8_t x,uint8_t mask,uint8_t target)80 static inline int bits_match(uint8_t x, uint8_t mask, uint8_t target)
81 {
82 return (x & mask) == target;
83 }
84
85 static inline enum pt_exec_mode
pti_get_nominal_eosz_non64(const struct pt_ild * ild)86 pti_get_nominal_eosz_non64(const struct pt_ild *ild)
87 {
88 if (mode_32b(ild)) {
89 if (ild->u.s.osz)
90 return ptem_16bit;
91 return ptem_32bit;
92 }
93 if (ild->u.s.osz)
94 return ptem_32bit;
95 return ptem_16bit;
96 }
97
98 static inline enum pt_exec_mode
pti_get_nominal_eosz(const struct pt_ild * ild)99 pti_get_nominal_eosz(const struct pt_ild *ild)
100 {
101 if (mode_64b(ild)) {
102 if (ild->u.s.rex_w)
103 return ptem_64bit;
104 if (ild->u.s.osz)
105 return ptem_16bit;
106 return ptem_32bit;
107 }
108 return pti_get_nominal_eosz_non64(ild);
109 }
110
111 static inline enum pt_exec_mode
pti_get_nominal_eosz_df64(const struct pt_ild * ild)112 pti_get_nominal_eosz_df64(const struct pt_ild *ild)
113 {
114 if (mode_64b(ild)) {
115 if (ild->u.s.rex_w)
116 return ptem_64bit;
117 if (ild->u.s.osz)
118 return ptem_16bit;
119 /* only this next line of code is different relative
120 to pti_get_nominal_eosz(), above */
121 return ptem_64bit;
122 }
123 return pti_get_nominal_eosz_non64(ild);
124 }
125
126 static inline enum pt_exec_mode
pti_get_nominal_easz_non64(const struct pt_ild * ild)127 pti_get_nominal_easz_non64(const struct pt_ild *ild)
128 {
129 if (mode_32b(ild)) {
130 if (ild->u.s.asz)
131 return ptem_16bit;
132 return ptem_32bit;
133 }
134 if (ild->u.s.asz)
135 return ptem_32bit;
136 return ptem_16bit;
137 }
138
139 static inline enum pt_exec_mode
pti_get_nominal_easz(const struct pt_ild * ild)140 pti_get_nominal_easz(const struct pt_ild *ild)
141 {
142 if (mode_64b(ild)) {
143 if (ild->u.s.asz)
144 return ptem_32bit;
145 return ptem_64bit;
146 }
147 return pti_get_nominal_easz_non64(ild);
148 }
149
resolve_z(uint8_t * pbytes,enum pt_exec_mode eosz)150 static inline int resolve_z(uint8_t *pbytes, enum pt_exec_mode eosz)
151 {
152 static const uint8_t bytes[] = { 2, 4, 4 };
153 unsigned int idx;
154
155 if (!pbytes)
156 return -pte_internal;
157
158 idx = (unsigned int) eosz - 1;
159 if (sizeof(bytes) <= idx)
160 return -pte_bad_insn;
161
162 *pbytes = bytes[idx];
163 return 0;
164 }
165
resolve_v(uint8_t * pbytes,enum pt_exec_mode eosz)166 static inline int resolve_v(uint8_t *pbytes, enum pt_exec_mode eosz)
167 {
168 static const uint8_t bytes[] = { 2, 4, 8 };
169 unsigned int idx;
170
171 if (!pbytes)
172 return -pte_internal;
173
174 idx = (unsigned int) eosz - 1;
175 if (sizeof(bytes) <= idx)
176 return -pte_bad_insn;
177
178 *pbytes = bytes[idx];
179 return 0;
180 }
181
182 /* DECODERS */
183
set_imm_bytes(struct pt_ild * ild)184 static int set_imm_bytes(struct pt_ild *ild)
185 {
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
190 };
191 uint8_t map, imm_code;
192
193 if (!ild)
194 return -pte_internal;
195
196 map = ild->map;
197
198 if ((sizeof(map_map) / sizeof(*map_map)) <= map)
199 return 0;
200
201 imm_code = map_map[map][ild->nominal_opcode];
202 switch (imm_code) {
203 case PTI_IMM_NONE:
204 case PTI_0_IMM_WIDTH_CONST_l2:
205 default:
206 return 0;
207
208 case PTI_UIMM8_IMM_WIDTH_CONST_l2:
209 ild->imm1_bytes = 1;
210 return 0;
211
212 case PTI_SIMM8_IMM_WIDTH_CONST_l2:
213 ild->imm1_bytes = 1;
214 return 0;
215
216 case PTI_SIMMz_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2:
217 /* SIMMz(eosz) */
218 return resolve_z(&ild->imm1_bytes, pti_get_nominal_eosz(ild));
219
220 case PTI_UIMMv_IMM_WIDTH_OSZ_NONTERM_EOSZ_l2:
221 /* UIMMv(eosz) */
222 return resolve_v(&ild->imm1_bytes, pti_get_nominal_eosz(ild));
223
224 case PTI_UIMM16_IMM_WIDTH_CONST_l2:
225 ild->imm1_bytes = 2;
226 return 0;
227
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));
232
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));
237 }
238 return 0;
239
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));
244 }
245 return 0;
246
247 case PTI_RESOLVE_BYREG_IMM_WIDTH_map0x0_op0xf6_l1:
248 if (ild->map == PTI_MAP_0 && pti_get_modrm_reg(ild) < 2)
249 ild->imm1_bytes = 1;
250
251 return 0;
252
253 case PTI_IMM_hasimm_map0x0_op0xc8_l1:
254 if (ild->map == PTI_MAP_0) {
255 /*enter -> imm1=2, imm2=1 */
256 ild->imm1_bytes = 2;
257 ild->imm2_bytes = 1;
258 }
259 return 0;
260
261 case PTI_IMM_hasimm_map0x0F_op0x78_l1:
262 /* AMD SSE4a (insertq/extrq use osz/f2) vs vmread
263 * (no prefixes)
264 */
265 if (ild->map == PTI_MAP_1) {
266 if (ild->u.s.osz || ild->u.s.last_f2f3 == 2) {
267 ild->imm1_bytes = 1;
268 ild->imm2_bytes = 1;
269 }
270 }
271 return 0;
272 }
273 }
274
imm_dec(struct pt_ild * ild,uint8_t length)275 static int imm_dec(struct pt_ild *ild, uint8_t length)
276 {
277 int errcode;
278
279 if (!ild)
280 return -pte_internal;
281
282 if (ild->map == PTI_MAP_AMD3DNOW) {
283 if (ild->max_bytes <= length)
284 return -pte_bad_insn;
285
286 ild->nominal_opcode = get_byte(ild, length);
287 return length + 1;
288 }
289
290 errcode = set_imm_bytes(ild);
291 if (errcode < 0)
292 return errcode;
293
294 length += ild->imm1_bytes;
295 length += ild->imm2_bytes;
296 if (ild->max_bytes < length)
297 return -pte_bad_insn;
298
299 return length;
300 }
301
compute_disp_dec(struct pt_ild * ild)302 static int compute_disp_dec(struct pt_ild *ild)
303 {
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
308 };
309 uint8_t map, disp_kind;
310
311 if (!ild)
312 return -pte_internal;
313
314 if (0 < ild->disp_bytes)
315 return 0;
316
317 map = ild->map;
318
319 if ((sizeof(map_map) / sizeof(*map_map)) <= map)
320 return 0;
321
322 disp_kind = map_map[map][ild->nominal_opcode];
323 switch (disp_kind) {
324 case PTI_DISP_NONE:
325 ild->disp_bytes = 0;
326 return 0;
327
328 case PTI_PRESERVE_DEFAULT:
329 /* nothing to do */
330 return 0;
331
332 case PTI_BRDISP8:
333 ild->disp_bytes = 1;
334 return 0;
335
336 case PTI_DISP_BUCKET_0_l1:
337 /* BRDISPz(eosz) for 16/32 modes, and BRDISP32 for 64b mode */
338 if (mode_64b(ild)) {
339 ild->disp_bytes = 4;
340 return 0;
341 }
342
343 return resolve_z(&ild->disp_bytes,
344 pti_get_nominal_eosz(ild));
345
346 case PTI_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2:
347 /* MEMDISPv(easz) */
348 return resolve_v(&ild->disp_bytes, pti_get_nominal_easz(ild));
349
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));
353
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));
359 }
360 return 0;
361
362 default:
363 return -pte_bad_insn;
364 }
365 }
366
disp_dec(struct pt_ild * ild,uint8_t length)367 static int disp_dec(struct pt_ild *ild, uint8_t length)
368 {
369 uint8_t disp_bytes;
370 int errcode;
371
372 if (!ild)
373 return -pte_internal;
374
375 errcode = compute_disp_dec(ild);
376 if (errcode < 0)
377 return errcode;
378
379 disp_bytes = ild->disp_bytes;
380 if (disp_bytes == 0)
381 return imm_dec(ild, length);
382
383 if (length + disp_bytes > ild->max_bytes)
384 return -pte_bad_insn;
385
386 /*Record only position; must be able to re-read itext bytes for actual
387 value. (SMC/CMC issue). */
388 ild->disp_pos = length;
389
390 return imm_dec(ild, length + disp_bytes);
391 }
392
sib_dec(struct pt_ild * ild,uint8_t length)393 static int sib_dec(struct pt_ild *ild, uint8_t length)
394 {
395 uint8_t sib;
396
397 if (!ild)
398 return -pte_internal;
399
400 if (ild->max_bytes <= length)
401 return -pte_bad_insn;
402
403 sib = get_byte(ild, length);
404 if ((sib & 0x07) == 0x05 && pti_get_modrm_mod(ild) == 0)
405 ild->disp_bytes = 4;
406
407 return disp_dec(ild, length + 1);
408 }
409
modrm_dec(struct pt_ild * ild,uint8_t length)410 static int modrm_dec(struct pt_ild *ild, uint8_t length)
411 {
412 static uint8_t const *const has_modrm_2d[2] = {
413 has_modrm_map_0x0,
414 has_modrm_map_0x0F
415 };
416 int has_modrm = PTI_MODRM_FALSE;
417 pti_map_enum_t map;
418
419 if (!ild)
420 return -pte_internal;
421
422 map = pti_get_map(ild);
423 if (map >= PTI_MAP_2)
424 has_modrm = PTI_MODRM_TRUE;
425 else
426 has_modrm = has_modrm_2d[map][ild->nominal_opcode];
427
428 if (has_modrm == PTI_MODRM_FALSE || has_modrm == PTI_MODRM_UNDEF)
429 return disp_dec(ild, length);
430
431 /* really >= here because we have not eaten the byte yet */
432 if (length >= ild->max_bytes)
433 return -pte_bad_insn;
434
435 ild->modrm_byte = get_byte(ild, length);
436
437 if (has_modrm != PTI_MODRM_IGNORE_MOD) {
438 /* set disp_bytes and sib using simple tables */
439
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);
443 uint8_t sib;
444
445 ild->disp_bytes = disp_default[eamode][mod][rm];
446
447 sib = has_sib[eamode][mod][rm];
448 if (sib)
449 return sib_dec(ild, length + 1);
450 }
451
452 return disp_dec(ild, length + 1);
453 }
454
get_next_as_opcode(struct pt_ild * ild,uint8_t length)455 static inline int get_next_as_opcode(struct pt_ild *ild, uint8_t length)
456 {
457 if (!ild)
458 return -pte_internal;
459
460 if (ild->max_bytes <= length)
461 return -pte_bad_insn;
462
463 ild->nominal_opcode = get_byte(ild, length);
464
465 return modrm_dec(ild, length + 1);
466 }
467
opcode_dec(struct pt_ild * ild,uint8_t length)468 static int opcode_dec(struct pt_ild *ild, uint8_t length)
469 {
470 uint8_t b, m;
471
472 if (!ild)
473 return -pte_internal;
474
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;
480
481 return modrm_dec(ild, length + 1);
482 }
483
484 length++; /* eat the 0x0F */
485
486 if (ild->max_bytes <= length)
487 return -pte_bad_insn;
488
489 /* 0x0F opcodes MAPS 1,2,3 */
490 m = get_byte(ild, length);
491 if (m == 0x38) {
492 ild->map = PTI_MAP_2;
493
494 return get_next_as_opcode(ild, length + 1);
495 } else if (m == 0x3A) {
496 ild->map = PTI_MAP_3;
497 ild->imm1_bytes = 1;
498
499 return get_next_as_opcode(ild, length + 1);
500 } else if (bits_match(m, 0xf8, 0x38)) {
501 ild->map = PTI_MAP_INVALID;
502
503 return get_next_as_opcode(ild, length + 1);
504 } else if (m == 0x0F) { /* 3dNow */
505 ild->map = PTI_MAP_AMD3DNOW;
506 ild->imm1_bytes = 1;
507 /* real opcode is in immediate later on, but we need an
508 * opcode now. */
509 ild->nominal_opcode = 0x0F;
510
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;
515
516 return modrm_dec(ild, length + 1);
517 }
518 }
519
520 typedef int (*prefix_decoder)(struct pt_ild *ild, uint8_t length, uint8_t rex);
521
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);
533
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,
551
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,
568
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,
585
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,
602
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,
619
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,
636
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,
653
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,
670
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,
687
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,
704
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,
721
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,
738
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,
755
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,
772
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,
789
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
806 };
807
prefix_decode(struct pt_ild * ild,uint8_t length,uint8_t rex)808 static inline int prefix_decode(struct pt_ild *ild, uint8_t length, uint8_t rex)
809 {
810 uint8_t byte;
811
812 if (!ild)
813 return -pte_internal;
814
815 if (ild->max_bytes <= length)
816 return -pte_bad_insn;
817
818 byte = get_byte(ild, length);
819
820 return prefix_table[byte](ild, length, rex);
821 }
822
prefix_next(struct pt_ild * ild,uint8_t length,uint8_t rex)823 static inline int prefix_next(struct pt_ild *ild, uint8_t length, uint8_t rex)
824 {
825 return prefix_decode(ild, length + 1, rex);
826 }
827
prefix_osz(struct pt_ild * ild,uint8_t length,uint8_t rex)828 static int prefix_osz(struct pt_ild *ild, uint8_t length, uint8_t rex)
829 {
830 (void) rex;
831
832 if (!ild)
833 return -pte_internal;
834
835 ild->u.s.osz = 1;
836
837 return prefix_next(ild, length, 0);
838 }
839
prefix_asz(struct pt_ild * ild,uint8_t length,uint8_t rex)840 static int prefix_asz(struct pt_ild *ild, uint8_t length, uint8_t rex)
841 {
842 (void) rex;
843
844 if (!ild)
845 return -pte_internal;
846
847 ild->u.s.asz = 1;
848
849 return prefix_next(ild, length, 0);
850 }
851
prefix_lock(struct pt_ild * ild,uint8_t length,uint8_t rex)852 static int prefix_lock(struct pt_ild *ild, uint8_t length, uint8_t rex)
853 {
854 (void) rex;
855
856 if (!ild)
857 return -pte_internal;
858
859 ild->u.s.lock = 1;
860
861 return prefix_next(ild, length, 0);
862 }
863
prefix_f2(struct pt_ild * ild,uint8_t length,uint8_t rex)864 static int prefix_f2(struct pt_ild *ild, uint8_t length, uint8_t rex)
865 {
866 (void) rex;
867
868 if (!ild)
869 return -pte_internal;
870
871 ild->u.s.f2 = 1;
872 ild->u.s.last_f2f3 = 2;
873
874 return prefix_next(ild, length, 0);
875 }
876
prefix_f3(struct pt_ild * ild,uint8_t length,uint8_t rex)877 static int prefix_f3(struct pt_ild *ild, uint8_t length, uint8_t rex)
878 {
879 (void) rex;
880
881 if (!ild)
882 return -pte_internal;
883
884 ild->u.s.f3 = 1;
885 ild->u.s.last_f2f3 = 3;
886
887 return prefix_next(ild, length, 0);
888 }
889
prefix_ignore(struct pt_ild * ild,uint8_t length,uint8_t rex)890 static int prefix_ignore(struct pt_ild *ild, uint8_t length, uint8_t rex)
891 {
892 (void) rex;
893
894 return prefix_next(ild, length, 0);
895 }
896
prefix_done(struct pt_ild * ild,uint8_t length,uint8_t rex)897 static int prefix_done(struct pt_ild *ild, uint8_t length, uint8_t rex)
898 {
899 if (!ild)
900 return -pte_internal;
901
902 if (rex & 0x04)
903 ild->u.s.rex_r = 1;
904 if (rex & 0x08)
905 ild->u.s.rex_w = 1;
906
907 return opcode_dec(ild, length);
908 }
909
prefix_rex(struct pt_ild * ild,uint8_t length,uint8_t rex)910 static int prefix_rex(struct pt_ild *ild, uint8_t length, uint8_t rex)
911 {
912 (void) rex;
913
914 if (!ild)
915 return -pte_internal;
916
917 if (mode_64b(ild))
918 return prefix_next(ild, length, get_byte(ild, length));
919 else
920 return opcode_dec(ild, length);
921 }
922
prefix_vex_done(struct pt_ild * ild,uint8_t length)923 static inline int prefix_vex_done(struct pt_ild *ild, uint8_t length)
924 {
925 if (!ild)
926 return -pte_internal;
927
928 ild->nominal_opcode = get_byte(ild, length);
929
930 return modrm_dec(ild, length + 1);
931 }
932
prefix_vex_c5(struct pt_ild * ild,uint8_t length,uint8_t rex)933 static int prefix_vex_c5(struct pt_ild *ild, uint8_t length, uint8_t rex)
934 {
935 uint8_t max_bytes;
936 uint8_t p1;
937
938 (void) rex;
939
940 if (!ild)
941 return -pte_internal;
942
943 max_bytes = ild->max_bytes;
944
945 /* Read the next byte to validate that this is indeed VEX. */
946 if (max_bytes <= (length + 1))
947 return -pte_bad_insn;
948
949 p1 = get_byte(ild, length + 1);
950
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);
954
955 /* We need at least 3 bytes
956 * - 2 for the VEX prefix and payload and
957 * - 1 for the opcode.
958 */
959 if (max_bytes < (length + 3))
960 return -pte_bad_insn;
961
962 ild->u.s.vex = 1;
963 if (p1 & 0x80)
964 ild->u.s.rex_r = 1;
965
966 ild->map = PTI_MAP_1;
967
968 /* Eat the VEX. */
969 length += 2;
970 return prefix_vex_done(ild, length);
971 }
972
prefix_vex_c4(struct pt_ild * ild,uint8_t length,uint8_t rex)973 static int prefix_vex_c4(struct pt_ild *ild, uint8_t length, uint8_t rex)
974 {
975 uint8_t max_bytes;
976 uint8_t p1, p2, map;
977
978 (void) rex;
979
980 if (!ild)
981 return -pte_internal;
982
983 max_bytes = ild->max_bytes;
984
985 /* Read the next byte to validate that this is indeed VEX. */
986 if (max_bytes <= (length + 1))
987 return -pte_bad_insn;
988
989 p1 = get_byte(ild, length + 1);
990
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);
994
995 /* We need at least 4 bytes
996 * - 3 for the VEX prefix and payload and
997 * - 1 for the opcode.
998 */
999 if (max_bytes < (length + 4))
1000 return -pte_bad_insn;
1001
1002 p2 = get_byte(ild, length + 2);
1003
1004 ild->u.s.vex = 1;
1005 if (p1 & 0x80)
1006 ild->u.s.rex_r = 1;
1007 if (p2 & 0x80)
1008 ild->u.s.rex_w = 1;
1009
1010 map = p1 & 0x1f;
1011 if (PTI_MAP_INVALID <= map)
1012 return -pte_bad_insn;
1013
1014 ild->map = map;
1015 if (map == PTI_MAP_3)
1016 ild->imm1_bytes = 1;
1017
1018 /* Eat the VEX. */
1019 length += 3;
1020 return prefix_vex_done(ild, length);
1021 }
1022
prefix_evex(struct pt_ild * ild,uint8_t length,uint8_t rex)1023 static int prefix_evex(struct pt_ild *ild, uint8_t length, uint8_t rex)
1024 {
1025 uint8_t max_bytes;
1026 uint8_t p1, p2, map;
1027
1028 (void) rex;
1029
1030 if (!ild)
1031 return -pte_internal;
1032
1033 max_bytes = ild->max_bytes;
1034
1035 /* Read the next byte to validate that this is indeed EVEX. */
1036 if (max_bytes <= (length + 1))
1037 return -pte_bad_insn;
1038
1039 p1 = get_byte(ild, length + 1);
1040
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);
1044
1045 /* We need at least 5 bytes
1046 * - 4 for the EVEX prefix and payload and
1047 * - 1 for the opcode.
1048 */
1049 if (max_bytes < (length + 5))
1050 return -pte_bad_insn;
1051
1052 p2 = get_byte(ild, length + 2);
1053
1054 ild->u.s.vex = 1;
1055 if (p1 & 0x80)
1056 ild->u.s.rex_r = 1;
1057 if (p2 & 0x80)
1058 ild->u.s.rex_w = 1;
1059
1060 map = p1 & 0x03;
1061 ild->map = map;
1062
1063 if (map == PTI_MAP_3)
1064 ild->imm1_bytes = 1;
1065
1066 /* Eat the EVEX. */
1067 length += 4;
1068 return prefix_vex_done(ild, length);
1069 }
1070
decode(struct pt_ild * ild)1071 static int decode(struct pt_ild *ild)
1072 {
1073 return prefix_decode(ild, 0, 0);
1074 }
1075
set_branch_target(struct pt_insn_ext * iext,const struct pt_ild * ild)1076 static int set_branch_target(struct pt_insn_ext *iext, const struct pt_ild *ild)
1077 {
1078 if (!iext || !ild)
1079 return -pte_internal;
1080
1081 iext->variant.branch.is_direct = 1;
1082
1083 if (ild->disp_bytes == 1) {
1084 const int8_t *b = (const int8_t *)
1085 get_byte_ptr(ild, ild->disp_pos);
1086
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);
1091
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);
1096
1097 iext->variant.branch.displacement = *d;
1098 } else
1099 return -pte_bad_insn;
1100
1101 return 0;
1102 }
1103
pt_instruction_length_decode(struct pt_ild * ild)1104 static int pt_instruction_length_decode(struct pt_ild *ild)
1105 {
1106 if (!ild)
1107 return -pte_internal;
1108
1109 ild->u.i = 0;
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;
1115
1116 if (!ild->mode)
1117 return -pte_bad_insn;
1118
1119 return decode(ild);
1120 }
1121
pt_instruction_decode(struct pt_insn * insn,struct pt_insn_ext * iext,const struct pt_ild * ild)1122 static int pt_instruction_decode(struct pt_insn *insn, struct pt_insn_ext *iext,
1123 const struct pt_ild *ild)
1124 {
1125 uint8_t opcode, map;
1126
1127 if (!iext || !ild)
1128 return -pte_internal;
1129
1130 iext->iclass = PTI_INST_INVALID;
1131 memset(&iext->variant, 0, sizeof(iext->variant));
1132
1133 insn->iclass = ptic_other;
1134
1135 opcode = ild->nominal_opcode;
1136 map = ild->map;
1137
1138 if (map > PTI_MAP_1)
1139 return 0; /* uninteresting */
1140 if (ild->u.s.vex)
1141 return 0; /* uninteresting */
1142
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;
1148
1149 return set_branch_target(iext, ild);
1150 }
1151 return 0;
1152 }
1153 if (opcode >= 0x80 && opcode <= 0x8F) {
1154 if (map == PTI_MAP_1) {
1155 insn->iclass = ptic_cond_jump;
1156 iext->iclass = PTI_INST_JCC;
1157
1158 return set_branch_target(iext, ild);
1159 }
1160 return 0;
1161 }
1162
1163 switch (ild->nominal_opcode) {
1164 case 0x9A:
1165 if (map == PTI_MAP_0) {
1166 insn->iclass = ptic_far_call;
1167 iext->iclass = PTI_INST_CALL_9A;
1168 }
1169 return 0;
1170
1171 case 0xFF:
1172 if (map == PTI_MAP_0) {
1173 uint8_t reg = pti_get_modrm_reg(ild);
1174
1175 if (reg == 2) {
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;
1187 }
1188 }
1189 return 0;
1190
1191 case 0xE8:
1192 if (map == PTI_MAP_0) {
1193 insn->iclass = ptic_call;
1194 iext->iclass = PTI_INST_CALL_E8;
1195
1196 return set_branch_target(iext, ild);
1197 }
1198 return 0;
1199
1200 case 0xCD:
1201 if (map == PTI_MAP_0) {
1202 insn->iclass = ptic_far_call;
1203 iext->iclass = PTI_INST_INT;
1204 }
1205
1206 return 0;
1207
1208 case 0xCC:
1209 if (map == PTI_MAP_0) {
1210 insn->iclass = ptic_far_call;
1211 iext->iclass = PTI_INST_INT3;
1212 }
1213
1214 return 0;
1215
1216 case 0xCE:
1217 if (map == PTI_MAP_0) {
1218 insn->iclass = ptic_far_call;
1219 iext->iclass = PTI_INST_INTO;
1220 }
1221
1222 return 0;
1223
1224 case 0xF1:
1225 if (map == PTI_MAP_0) {
1226 insn->iclass = ptic_far_call;
1227 iext->iclass = PTI_INST_INT1;
1228 }
1229
1230 return 0;
1231
1232 case 0xCF:
1233 if (map == PTI_MAP_0) {
1234 insn->iclass = ptic_far_return;
1235 iext->iclass = PTI_INST_IRET;
1236 }
1237 return 0;
1238
1239 case 0xE9:
1240 if (map == PTI_MAP_0) {
1241 insn->iclass = ptic_jump;
1242 iext->iclass = PTI_INST_JMP_E9;
1243
1244 return set_branch_target(iext, ild);
1245 }
1246 return 0;
1247
1248 case 0xEA:
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;
1253 }
1254 return 0;
1255
1256 case 0xEB:
1257 if (map == PTI_MAP_0) {
1258 insn->iclass = ptic_jump;
1259 iext->iclass = PTI_INST_JMP_EB;
1260
1261 return set_branch_target(iext, ild);
1262 }
1263 return 0;
1264
1265 case 0xE3:
1266 if (map == PTI_MAP_0) {
1267 insn->iclass = ptic_cond_jump;
1268 iext->iclass = PTI_INST_JrCXZ;
1269
1270 return set_branch_target(iext, ild);
1271 }
1272 return 0;
1273
1274 case 0xE0:
1275 if (map == PTI_MAP_0) {
1276 insn->iclass = ptic_cond_jump;
1277 iext->iclass = PTI_INST_LOOPNE;
1278
1279 return set_branch_target(iext, ild);
1280 }
1281 return 0;
1282
1283 case 0xE1:
1284 if (map == PTI_MAP_0) {
1285 insn->iclass = ptic_cond_jump;
1286 iext->iclass = PTI_INST_LOOPE;
1287
1288 return set_branch_target(iext, ild);
1289 }
1290 return 0;
1291
1292 case 0xE2:
1293 if (map == PTI_MAP_0) {
1294 insn->iclass = ptic_cond_jump;
1295 iext->iclass = PTI_INST_LOOP;
1296
1297 return set_branch_target(iext, ild);
1298 }
1299 return 0;
1300
1301 case 0x22:
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;
1306
1307 return 0;
1308
1309 case 0xC3:
1310 if (map == PTI_MAP_0) {
1311 insn->iclass = ptic_return;
1312 iext->iclass = PTI_INST_RET_C3;
1313 }
1314 return 0;
1315
1316 case 0xC2:
1317 if (map == PTI_MAP_0) {
1318 insn->iclass = ptic_return;
1319 iext->iclass = PTI_INST_RET_C2;
1320 }
1321 return 0;
1322
1323 case 0xCB:
1324 if (map == PTI_MAP_0) {
1325 insn->iclass = ptic_far_return;
1326 iext->iclass = PTI_INST_RET_CB;
1327 }
1328 return 0;
1329
1330 case 0xCA:
1331 if (map == PTI_MAP_0) {
1332 insn->iclass = ptic_far_return;
1333 iext->iclass = PTI_INST_RET_CA;
1334 }
1335 return 0;
1336
1337 case 0x05:
1338 if (map == PTI_MAP_1) {
1339 insn->iclass = ptic_far_call;
1340 iext->iclass = PTI_INST_SYSCALL;
1341 }
1342 return 0;
1343
1344 case 0x34:
1345 if (map == PTI_MAP_1) {
1346 insn->iclass = ptic_far_call;
1347 iext->iclass = PTI_INST_SYSENTER;
1348 }
1349 return 0;
1350
1351 case 0x35:
1352 if (map == PTI_MAP_1) {
1353 insn->iclass = ptic_far_return;
1354 iext->iclass = PTI_INST_SYSEXIT;
1355 }
1356 return 0;
1357
1358 case 0x07:
1359 if (map == PTI_MAP_1) {
1360 insn->iclass = ptic_far_return;
1361 iext->iclass = PTI_INST_SYSRET;
1362 }
1363 return 0;
1364
1365 case 0x01:
1366 if (map == PTI_MAP_1) {
1367 switch (ild->modrm_byte) {
1368 case 0xc1:
1369 insn->iclass = ptic_far_call;
1370 iext->iclass = PTI_INST_VMCALL;
1371 break;
1372
1373 case 0xc2:
1374 insn->iclass = ptic_far_return;
1375 iext->iclass = PTI_INST_VMLAUNCH;
1376 break;
1377
1378 case 0xc3:
1379 insn->iclass = ptic_far_return;
1380 iext->iclass = PTI_INST_VMRESUME;
1381 break;
1382
1383 default:
1384 break;
1385 }
1386 }
1387 return 0;
1388
1389 case 0xc7:
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;
1394
1395 return 0;
1396
1397 case 0xae:
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;
1402 }
1403 return 0;
1404
1405 default:
1406 return 0;
1407 }
1408 }
1409
pt_ild_decode(struct pt_insn * insn,struct pt_insn_ext * iext)1410 int pt_ild_decode(struct pt_insn *insn, struct pt_insn_ext *iext)
1411 {
1412 struct pt_ild ild;
1413 int size;
1414
1415 if (!insn || !iext)
1416 return -pte_internal;
1417
1418 ild.mode = insn->mode;
1419 ild.itext = insn->raw;
1420 ild.max_bytes = insn->size;
1421
1422 size = pt_instruction_length_decode(&ild);
1423 if (size < 0)
1424 return size;
1425
1426 insn->size = (uint8_t) size;
1427
1428 return pt_instruction_decode(insn, iext, &ild);
1429 }
1430