^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * x86 instruction analysis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) IBM Corporation, 2002, 2004, 2009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifdef __KERNEL__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/inat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/insn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/emulate_prefix.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* Verify next sizeof(t) bytes can be on the same instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define validate_next(t, insn, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define __get_next(t, insn) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define __peek_nbyte_next(t, insn, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ({ t r = *(t*)((insn)->next_byte + n); r; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define get_next(t, insn) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define peek_nbyte_next(t, insn, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * insn_init() - initialize struct insn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @insn: &struct insn to be initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @kaddr: address (in kernel memory) of instruction (or copy thereof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @x86_64: !0 for 64-bit kernel or 64-bit app
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * even if the input buffer is long enough to hold them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (buf_len > MAX_INSN_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) buf_len = MAX_INSN_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) memset(insn, 0, sizeof(*insn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) insn->kaddr = kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) insn->end_kaddr = kaddr + buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) insn->next_byte = kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) insn->x86_64 = x86_64 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) insn->opnd_bytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) insn->addr_bytes = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) insn->addr_bytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static const insn_byte_t xen_prefix[] = { __XEN_EMULATE_PREFIX };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static const insn_byte_t kvm_prefix[] = { __KVM_EMULATE_PREFIX };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int __insn_get_emulate_prefix(struct insn *insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const insn_byte_t *prefix, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (peek_nbyte_next(insn_byte_t, insn, i) != prefix[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) insn->emulate_prefix_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) insn->next_byte += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static void insn_get_emulate_prefix(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * insn_get_prefixes - scan x86 instruction prefix bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * to point to the (first) opcode. No effect if @insn->prefixes.got
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * is already set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void insn_get_prefixes(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct insn_field *prefixes = &insn->prefixes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) insn_attr_t attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) insn_byte_t b, lb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int i, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (prefixes->got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) insn_get_emulate_prefix(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) nb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) lb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) b = peek_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) attr = inat_get_opcode_attribute(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) while (inat_is_legacy_prefix(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Skip if same prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) for (i = 0; i < nb; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (prefixes->bytes[i] == b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (nb == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Invalid instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) prefixes->bytes[nb++] = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (inat_is_address_size_prefix(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* address size switches 2/4 or 4/8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (insn->x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) insn->addr_bytes ^= 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) insn->addr_bytes ^= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) } else if (inat_is_operand_size_prefix(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* oprand size switches 2/4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) insn->opnd_bytes ^= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) prefixes->nbytes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) insn->next_byte++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) lb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) b = peek_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) attr = inat_get_opcode_attribute(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Set the last prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (lb && lb != insn->prefixes.bytes[3]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (unlikely(insn->prefixes.bytes[3])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Swap the last prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) b = insn->prefixes.bytes[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) for (i = 0; i < nb; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (prefixes->bytes[i] == lb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) prefixes->bytes[i] = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) insn->prefixes.bytes[3] = lb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Decode REX prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (insn->x86_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) b = peek_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) attr = inat_get_opcode_attribute(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (inat_is_rex_prefix(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) insn->rex_prefix.value = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) insn->rex_prefix.nbytes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) insn->next_byte++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (X86_REX_W(b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* REX.W overrides opnd_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) insn->opnd_bytes = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) insn->rex_prefix.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Decode VEX prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) b = peek_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) attr = inat_get_opcode_attribute(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (inat_is_vex_prefix(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (!insn->x86_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * In 32-bits mode, if the [7:6] bits (mod bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * ModRM) on the second byte are not 11b, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * LDS or LES or BOUND.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (X86_MODRM_MOD(b2) != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) goto vex_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) insn->vex_prefix.bytes[0] = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) insn->vex_prefix.bytes[1] = b2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (inat_is_evex_prefix(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) b2 = peek_nbyte_next(insn_byte_t, insn, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) insn->vex_prefix.bytes[2] = b2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) b2 = peek_nbyte_next(insn_byte_t, insn, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) insn->vex_prefix.bytes[3] = b2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) insn->vex_prefix.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) insn->next_byte += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (insn->x86_64 && X86_VEX_W(b2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* VEX.W overrides opnd_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) insn->opnd_bytes = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else if (inat_is_vex3_prefix(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) b2 = peek_nbyte_next(insn_byte_t, insn, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) insn->vex_prefix.bytes[2] = b2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) insn->vex_prefix.nbytes = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) insn->next_byte += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (insn->x86_64 && X86_VEX_W(b2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* VEX.W overrides opnd_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) insn->opnd_bytes = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * For VEX2, fake VEX3-like byte#2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Makes it easier to decode vex.W, vex.vvvv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) insn->vex_prefix.bytes[2] = b2 & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) insn->vex_prefix.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) insn->next_byte += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) vex_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) insn->vex_prefix.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) prefixes->got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * insn_get_opcode - collect opcode(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Populates @insn->opcode, updates @insn->next_byte to point past the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * opcode byte(s), and set @insn->attr (except for groups).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * If necessary, first collects any preceding (prefix) bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * is already 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void insn_get_opcode(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct insn_field *opcode = &insn->opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) insn_byte_t op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int pfx_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (opcode->got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!insn->prefixes.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) insn_get_prefixes(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* Get first opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) op = get_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) opcode->bytes[0] = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) opcode->nbytes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Check if there is VEX prefix or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (insn_is_avx(insn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) insn_byte_t m, p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) m = insn_vex_m_bits(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) p = insn_vex_p_bits(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) insn->attr = inat_get_avx_attribute(op, m, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) (!inat_accept_vex(insn->attr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) !inat_is_group(insn->attr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) insn->attr = 0; /* This instruction is bad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) goto end; /* VEX has only 1 byte for opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) insn->attr = inat_get_opcode_attribute(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) while (inat_is_escape(insn->attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Get escaped opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) op = get_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) opcode->bytes[opcode->nbytes++] = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pfx_id = insn_last_prefix_id(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (inat_must_vex(insn->attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) insn->attr = 0; /* This instruction is bad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) opcode->got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * insn_get_modrm - collect ModRM byte, if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * Populates @insn->modrm and updates @insn->next_byte to point past the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * ModRM byte, if any. If necessary, first collects the preceding bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) void insn_get_modrm(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct insn_field *modrm = &insn->modrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) insn_byte_t pfx_id, mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (modrm->got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!insn->opcode.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) insn_get_opcode(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (inat_has_modrm(insn->attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) mod = get_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) modrm->value = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) modrm->nbytes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (inat_is_group(insn->attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) pfx_id = insn_last_prefix_id(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) insn->attr = inat_get_group_attribute(mod, pfx_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) insn->attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) insn->attr = 0; /* This is bad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (insn->x86_64 && inat_is_force64(insn->attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) insn->opnd_bytes = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) modrm->got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * If necessary, first collects the instruction up to and including the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * ModRM byte. No effect if @insn->x86_64 is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int insn_rip_relative(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct insn_field *modrm = &insn->modrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!insn->x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!modrm->got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * For rip-relative instructions, the mod field (top 2 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * is zero and the r/m field (bottom 3 bits) is 0x5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * insn_get_sib() - Get the SIB byte of instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * If necessary, first collects the instruction up to and including the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * ModRM byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) void insn_get_sib(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) insn_byte_t modrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (insn->sib.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!insn->modrm.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (insn->modrm.nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) modrm = (insn_byte_t)insn->modrm.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (insn->addr_bytes != 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) insn->sib.value = get_next(insn_byte_t, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) insn->sib.nbytes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) insn->sib.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * insn_get_displacement() - Get the displacement of instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * If necessary, first collects the instruction up to and including the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * SIB byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * Displacement value is sign-expanded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) void insn_get_displacement(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) insn_byte_t mod, rm, base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (insn->displacement.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!insn->sib.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) insn_get_sib(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (insn->modrm.nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * Interpreting the modrm byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * mod = 00 - no displacement fields (exceptions below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * mod = 01 - 1-byte displacement field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * mod = 10 - displacement field is 4 bytes, or 2 bytes if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * address size = 2 (0x67 prefix in 32-bit mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * mod = 11 - no memory operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * If address size = 2...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * mod = 00, r/m = 110 - displacement field is 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * If address size != 2...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * mod != 11, r/m = 100 - SIB byte exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * mod = 00, SIB base = 101 - displacement field is 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * mod = 00, r/m = 101 - rip-relative addressing, displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * field is 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) mod = X86_MODRM_MOD(insn->modrm.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) rm = X86_MODRM_RM(insn->modrm.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) base = X86_SIB_BASE(insn->sib.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (mod == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (mod == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) insn->displacement.value = get_next(signed char, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) insn->displacement.nbytes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) } else if (insn->addr_bytes == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if ((mod == 0 && rm == 6) || mod == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) insn->displacement.value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) get_next(short, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) insn->displacement.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if ((mod == 0 && rm == 5) || mod == 2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) (mod == 0 && base == 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) insn->displacement.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) insn->displacement.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) insn->displacement.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Decode moffset16/32/64. Return 0 if failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int __get_moffset(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) switch (insn->addr_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) insn->moffset1.value = get_next(short, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) insn->moffset1.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) insn->moffset1.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) insn->moffset1.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) insn->moffset1.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) insn->moffset1.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) insn->moffset2.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) insn->moffset2.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) default: /* opnd_bytes must be modified manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) insn->moffset1.got = insn->moffset2.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* Decode imm v32(Iz). Return 0 if failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int __get_immv32(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) switch (insn->opnd_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) insn->immediate.value = get_next(short, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) insn->immediate.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) insn->immediate.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) insn->immediate.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) default: /* opnd_bytes must be modified manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Decode imm v64(Iv/Ov), Return 0 if failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static int __get_immv(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) switch (insn->opnd_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) insn->immediate1.value = get_next(short, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) insn->immediate1.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) insn->immediate1.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) insn->immediate1.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) insn->immediate1.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) insn->immediate1.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) insn->immediate2.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) insn->immediate2.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) default: /* opnd_bytes must be modified manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) insn->immediate1.got = insn->immediate2.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* Decode ptr16:16/32(Ap) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int __get_immptr(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) switch (insn->opnd_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) insn->immediate1.value = get_next(short, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) insn->immediate1.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) insn->immediate1.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) insn->immediate1.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /* ptr16:64 is not exist (no segment) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) default: /* opnd_bytes must be modified manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) insn->immediate2.value = get_next(unsigned short, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) insn->immediate2.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) insn->immediate1.got = insn->immediate2.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * insn_get_immediate() - Get the immediates of instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * If necessary, first collects the instruction up to and including the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * displacement bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * Basically, most of immediates are sign-expanded. Unsigned-value can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * get by bit masking with ((1 << (nbytes * 8)) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) void insn_get_immediate(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (insn->immediate.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (!insn->displacement.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) insn_get_displacement(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (inat_has_moffset(insn->attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (!__get_moffset(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!inat_has_immediate(insn->attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* no immediates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) switch (inat_immediate_size(insn->attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) case INAT_IMM_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) insn->immediate.value = get_next(signed char, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) insn->immediate.nbytes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) case INAT_IMM_WORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) insn->immediate.value = get_next(short, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) insn->immediate.nbytes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) case INAT_IMM_DWORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) insn->immediate.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) insn->immediate.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) case INAT_IMM_QWORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) insn->immediate1.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) insn->immediate1.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) insn->immediate2.value = get_next(int, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) insn->immediate2.nbytes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case INAT_IMM_PTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!__get_immptr(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) case INAT_IMM_VWORD32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!__get_immv32(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) case INAT_IMM_VWORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (!__get_immv(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /* Here, insn must have an immediate, but failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (inat_has_second_immediate(insn->attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) insn->immediate2.value = get_next(signed char, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) insn->immediate2.nbytes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) insn->immediate.got = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * insn_get_length() - Get the length of instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * @insn: &struct insn containing instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * If necessary, first collects the instruction up to and including the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * immediates bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) void insn_get_length(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (insn->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (!insn->immediate.got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) insn_get_immediate(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) insn->length = (unsigned char)((unsigned long)insn->next_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) - (unsigned long)insn->kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }