Lines Matching refs:insn
15 #include "../include/asm/insn.h" /* __ignore_sync_check__ */
37 #define validate_next(t, insn, n) \
38 ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
40 #define __get_next(t, insn) \
41 ({ t r = get_unaligned((t *)(insn)->next_byte); (insn)->next_byte += sizeof(t); leXX_to_cpu(t, r); })
43 #define __peek_nbyte_next(t, insn, n) \
44 ({ t r = get_unaligned((t *)(insn)->next_byte + n); leXX_to_cpu(t, r); })
46 #define get_next(t, insn) \
47 ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
49 #define peek_nbyte_next(t, insn, n) \
50 ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
52 #define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
55 * insn_init() - initialize struct insn
56 * @insn: &struct insn to be initialized
58 * @buf_len: length of the insn buffer at @kaddr
61 void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
70 memset(insn, 0, sizeof(*insn));
71 insn->kaddr = kaddr;
72 insn->end_kaddr = kaddr + buf_len;
73 insn->next_byte = kaddr;
74 insn->x86_64 = x86_64 ? 1 : 0;
75 insn->opnd_bytes = 4;
77 insn->addr_bytes = 8;
79 insn->addr_bytes = 4;
85 static int __insn_get_emulate_prefix(struct insn *insn,
91 if (peek_nbyte_next(insn_byte_t, insn, i) != prefix[i])
95 insn->emulate_prefix_size = len;
96 insn->next_byte += len;
104 static void insn_get_emulate_prefix(struct insn *insn)
106 if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix)))
109 __insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix));
114 * @insn: &struct insn containing instruction
116 * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
117 * to point to the (first) opcode. No effect if @insn->prefixes.got
124 int insn_get_prefixes(struct insn *insn)
126 struct insn_field *prefixes = &insn->prefixes;
134 insn_get_emulate_prefix(insn);
138 b = peek_next(insn_byte_t, insn);
151 if (insn->x86_64)
152 insn->addr_bytes ^= 12;
154 insn->addr_bytes ^= 6;
157 insn->opnd_bytes ^= 6;
161 insn->next_byte++;
163 b = peek_next(insn_byte_t, insn);
167 if (lb && lb != insn->prefixes.bytes[3]) {
168 if (unlikely(insn->prefixes.bytes[3])) {
170 b = insn->prefixes.bytes[3];
175 insn_set_byte(&insn->prefixes, 3, lb);
179 if (insn->x86_64) {
180 b = peek_next(insn_byte_t, insn);
183 insn_field_set(&insn->rex_prefix, b, 1);
184 insn->next_byte++;
187 insn->opnd_bytes = 8;
190 insn->rex_prefix.got = 1;
193 b = peek_next(insn_byte_t, insn);
196 insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
197 if (!insn->x86_64) {
206 insn_set_byte(&insn->vex_prefix, 0, b);
207 insn_set_byte(&insn->vex_prefix, 1, b2);
209 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
210 insn_set_byte(&insn->vex_prefix, 2, b2);
211 b2 = peek_nbyte_next(insn_byte_t, insn, 3);
212 insn_set_byte(&insn->vex_prefix, 3, b2);
213 insn->vex_prefix.nbytes = 4;
214 insn->next_byte += 4;
215 if (insn->x86_64 && X86_VEX_W(b2))
217 insn->opnd_bytes = 8;
219 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
220 insn_set_byte(&insn->vex_prefix, 2, b2);
221 insn->vex_prefix.nbytes = 3;
222 insn->next_byte += 3;
223 if (insn->x86_64 && X86_VEX_W(b2))
225 insn->opnd_bytes = 8;
232 insn_set_byte(&insn->vex_prefix, 2, b2 & 0x7f);
233 insn->vex_prefix.nbytes = 2;
234 insn->next_byte += 2;
238 insn->vex_prefix.got = 1;
250 * @insn: &struct insn containing instruction
252 * Populates @insn->opcode, updates @insn->next_byte to point past the
253 * opcode byte(s), and set @insn->attr (except for groups).
255 * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
262 int insn_get_opcode(struct insn *insn)
264 struct insn_field *opcode = &insn->opcode;
271 if (!insn->prefixes.got) {
272 ret = insn_get_prefixes(insn);
278 op = get_next(insn_byte_t, insn);
283 if (insn_is_avx(insn)) {
285 m = insn_vex_m_bits(insn);
286 p = insn_vex_p_bits(insn);
287 insn->attr = inat_get_avx_attribute(op, m, p);
288 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
289 (!inat_accept_vex(insn->attr) &&
290 !inat_is_group(insn->attr))) {
292 insn->attr = 0;
299 insn->attr = inat_get_opcode_attribute(op);
300 while (inat_is_escape(insn->attr)) {
302 op = get_next(insn_byte_t, insn);
304 pfx_id = insn_last_prefix_id(insn);
305 insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
308 if (inat_must_vex(insn->attr)) {
310 insn->attr = 0;
323 * @insn: &struct insn containing instruction
325 * Populates @insn->modrm and updates @insn->next_byte to point past the
327 * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
333 int insn_get_modrm(struct insn *insn)
335 struct insn_field *modrm = &insn->modrm;
342 if (!insn->opcode.got) {
343 ret = insn_get_opcode(insn);
348 if (inat_has_modrm(insn->attr)) {
349 mod = get_next(insn_byte_t, insn);
351 if (inat_is_group(insn->attr)) {
352 pfx_id = insn_last_prefix_id(insn);
353 insn->attr = inat_get_group_attribute(mod, pfx_id,
354 insn->attr);
355 if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) {
356 /* Bad insn */
357 insn->attr = 0;
363 if (insn->x86_64 && inat_is_force64(insn->attr))
364 insn->opnd_bytes = 8;
376 * @insn: &struct insn containing instruction
379 * ModRM byte. No effect if @insn->x86_64 is 0.
381 int insn_rip_relative(struct insn *insn)
383 struct insn_field *modrm = &insn->modrm;
386 if (!insn->x86_64)
390 ret = insn_get_modrm(insn);
403 * @insn: &struct insn containing instruction
412 int insn_get_sib(struct insn *insn)
417 if (insn->sib.got)
420 if (!insn->modrm.got) {
421 ret = insn_get_modrm(insn);
426 if (insn->modrm.nbytes) {
427 modrm = insn->modrm.bytes[0];
428 if (insn->addr_bytes != 2 &&
430 insn_field_set(&insn->sib,
431 get_next(insn_byte_t, insn), 1);
434 insn->sib.got = 1;
445 * @insn: &struct insn containing instruction
455 int insn_get_displacement(struct insn *insn)
460 if (insn->displacement.got)
463 if (!insn->sib.got) {
464 ret = insn_get_sib(insn);
469 if (insn->modrm.nbytes) {
487 mod = X86_MODRM_MOD(insn->modrm.value);
488 rm = X86_MODRM_RM(insn->modrm.value);
489 base = X86_SIB_BASE(insn->sib.value);
493 insn_field_set(&insn->displacement,
494 get_next(signed char, insn), 1);
495 } else if (insn->addr_bytes == 2) {
497 insn_field_set(&insn->displacement,
498 get_next(short, insn), 2);
503 insn_field_set(&insn->displacement,
504 get_next(int, insn), 4);
509 insn->displacement.got = 1;
517 static int __get_moffset(struct insn *insn)
519 switch (insn->addr_bytes) {
521 insn_field_set(&insn->moffset1, get_next(short, insn), 2);
524 insn_field_set(&insn->moffset1, get_next(int, insn), 4);
527 insn_field_set(&insn->moffset1, get_next(int, insn), 4);
528 insn_field_set(&insn->moffset2, get_next(int, insn), 4);
533 insn->moffset1.got = insn->moffset2.got = 1;
542 static int __get_immv32(struct insn *insn)
544 switch (insn->opnd_bytes) {
546 insn_field_set(&insn->immediate, get_next(short, insn), 2);
550 insn_field_set(&insn->immediate, get_next(int, insn), 4);
563 static int __get_immv(struct insn *insn)
565 switch (insn->opnd_bytes) {
567 insn_field_set(&insn->immediate1, get_next(short, insn), 2);
570 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
571 insn->immediate1.nbytes = 4;
574 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
575 insn_field_set(&insn->immediate2, get_next(int, insn), 4);
580 insn->immediate1.got = insn->immediate2.got = 1;
588 static int __get_immptr(struct insn *insn)
590 switch (insn->opnd_bytes) {
592 insn_field_set(&insn->immediate1, get_next(short, insn), 2);
595 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
603 insn_field_set(&insn->immediate2, get_next(unsigned short, insn), 2);
604 insn->immediate1.got = insn->immediate2.got = 1;
613 * @insn: &struct insn containing instruction
624 int insn_get_immediate(struct insn *insn)
628 if (insn->immediate.got)
631 if (!insn->displacement.got) {
632 ret = insn_get_displacement(insn);
637 if (inat_has_moffset(insn->attr)) {
638 if (!__get_moffset(insn))
643 if (!inat_has_immediate(insn->attr))
647 switch (inat_immediate_size(insn->attr)) {
649 insn_field_set(&insn->immediate, get_next(signed char, insn), 1);
652 insn_field_set(&insn->immediate, get_next(short, insn), 2);
655 insn_field_set(&insn->immediate, get_next(int, insn), 4);
658 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
659 insn_field_set(&insn->immediate2, get_next(int, insn), 4);
662 if (!__get_immptr(insn))
666 if (!__get_immv32(insn))
670 if (!__get_immv(insn))
674 /* Here, insn must have an immediate, but failed */
677 if (inat_has_second_immediate(insn->attr)) {
678 insn_field_set(&insn->immediate2, get_next(signed char, insn), 1);
681 insn->immediate.got = 1;
690 * @insn: &struct insn containing instruction
699 int insn_get_length(struct insn *insn)
703 if (insn->length)
706 if (!insn->immediate.got) {
707 ret = insn_get_immediate(insn);
712 insn->length = (unsigned char)((unsigned long)insn->next_byte
713 - (unsigned long)insn->kaddr);
719 static inline int insn_complete(struct insn *insn)
721 return insn->opcode.got && insn->modrm.got && insn->sib.got &&
722 insn->displacement.got && insn->immediate.got;
727 * @insn: &struct insn to be initialized
729 * @buf_len: length of the insn buffer at @kaddr
730 * @m: insn mode, see enum insn_mode
736 int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m)
743 insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64));
745 insn_init(insn, kaddr, buf_len, m == INSN_MODE_64);
747 ret = insn_get_length(insn);
751 if (insn_complete(insn))