]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/processor-trace/libipt/src/pt_ild.c
Update to 6.2-20200215
[FreeBSD/FreeBSD.git] / contrib / processor-trace / libipt / src / pt_ild.c
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
60 static inline uint8_t get_byte(const struct pt_ild *ild, uint8_t i)
61 {
62         return ild->itext[i];
63 }
64
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
70 static inline int mode_64b(const struct pt_ild *ild)
71 {
72         return ild->mode == ptem_64bit;
73 }
74
75 static inline int mode_32b(const struct pt_ild *ild)
76 {
77         return ild->mode == ptem_32bit;
78 }
79
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1071 static int decode(struct pt_ild *ild)
1072 {
1073         return prefix_decode(ild, 0, 0);
1074 }
1075
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
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
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
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 }