Lines Matching refs:insn
38 static bool is_string_insn(struct insn *insn) in is_string_insn() argument
41 if (insn->opcode.nbytes != 1) in is_string_insn()
44 switch (insn->opcode.bytes[0]) { in is_string_insn()
62 bool insn_has_rep_prefix(struct insn *insn) in insn_has_rep_prefix() argument
67 insn_get_prefixes(insn); in insn_has_rep_prefix()
69 for_each_insn_prefix(insn, i, p) { in insn_has_rep_prefix()
91 static int get_seg_reg_override_idx(struct insn *insn) in get_seg_reg_override_idx() argument
97 insn_get_prefixes(insn); in get_seg_reg_override_idx()
100 for_each_insn_prefix(insn, i, p) { in get_seg_reg_override_idx()
154 static bool check_seg_overrides(struct insn *insn, int regoff) in check_seg_overrides() argument
156 if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn)) in check_seg_overrides()
179 static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off) in resolve_default_seg() argument
202 if (insn->addr_bytes == 2) in resolve_default_seg()
213 if (is_string_insn(insn)) in resolve_default_seg()
281 static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff) in resolve_seg_reg() argument
298 if (!insn) in resolve_seg_reg()
301 if (!check_seg_overrides(insn, regoff)) in resolve_seg_reg()
302 return resolve_default_seg(insn, regs, regoff); in resolve_seg_reg()
304 idx = get_seg_reg_override_idx(insn); in resolve_seg_reg()
309 return resolve_default_seg(insn, regs, regoff); in resolve_seg_reg()
447 static int get_regno(struct insn *insn, enum reg_type type) in get_regno() argument
456 if (IS_ENABLED(CONFIG_X86_64) && !insn->x86_64) in get_regno()
461 regno = X86_MODRM_RM(insn->modrm.value); in get_regno()
467 if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5) in get_regno()
470 if (X86_REX_B(insn->rex_prefix.value)) in get_regno()
475 regno = X86_MODRM_REG(insn->modrm.value); in get_regno()
477 if (X86_REX_R(insn->rex_prefix.value)) in get_regno()
482 regno = X86_SIB_INDEX(insn->sib.value); in get_regno()
483 if (X86_REX_X(insn->rex_prefix.value)) in get_regno()
492 if (X86_MODRM_MOD(insn->modrm.value) != 3 && regno == 4) in get_regno()
497 regno = X86_SIB_BASE(insn->sib.value); in get_regno()
503 if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5) in get_regno()
506 if (X86_REX_B(insn->rex_prefix.value)) in get_regno()
522 static int get_reg_offset(struct insn *insn, struct pt_regs *regs, in get_reg_offset() argument
525 int regno = get_regno(insn, type); in get_reg_offset()
550 static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs, in get_reg_offset_16() argument
584 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_reg_offset_16()
585 *offs1 = insn_get_modrm_rm_off(insn, regs); in get_reg_offset_16()
590 *offs1 = regoff1[X86_MODRM_RM(insn->modrm.value)]; in get_reg_offset_16()
591 *offs2 = regoff2[X86_MODRM_RM(insn->modrm.value)]; in get_reg_offset_16()
600 if ((X86_MODRM_MOD(insn->modrm.value) == 0) && in get_reg_offset_16()
601 (X86_MODRM_RM(insn->modrm.value) == 6)) in get_reg_offset_16()
855 int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs) in insn_get_modrm_rm_off() argument
857 return get_reg_offset(insn, regs, REG_TYPE_RM); in insn_get_modrm_rm_off()
870 int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs) in insn_get_modrm_reg_off() argument
872 return get_reg_offset(insn, regs, REG_TYPE_REG); in insn_get_modrm_reg_off()
885 unsigned long *insn_get_modrm_reg_ptr(struct insn *insn, struct pt_regs *regs) in insn_get_modrm_reg_ptr() argument
889 offset = insn_get_modrm_reg_off(insn, regs); in insn_get_modrm_reg_ptr()
916 static int get_seg_base_limit(struct insn *insn, struct pt_regs *regs, in get_seg_base_limit() argument
925 seg_reg_idx = resolve_seg_reg(insn, regs, regoff); in get_seg_base_limit()
966 static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs, in get_eff_addr_reg() argument
971 ret = insn_get_modrm(insn); in get_eff_addr_reg()
975 if (X86_MODRM_MOD(insn->modrm.value) != 3) in get_eff_addr_reg()
978 *regoff = get_reg_offset(insn, regs, REG_TYPE_RM); in get_eff_addr_reg()
983 if (insn->addr_bytes == 2) in get_eff_addr_reg()
985 else if (insn->addr_bytes == 4) in get_eff_addr_reg()
1015 static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs, in get_eff_addr_modrm() argument
1021 if (insn->addr_bytes != 8 && insn->addr_bytes != 4) in get_eff_addr_modrm()
1024 ret = insn_get_modrm(insn); in get_eff_addr_modrm()
1028 if (X86_MODRM_MOD(insn->modrm.value) > 2) in get_eff_addr_modrm()
1031 *regoff = get_reg_offset(insn, regs, REG_TYPE_RM); in get_eff_addr_modrm()
1040 tmp = regs->ip + insn->length; in get_eff_addr_modrm()
1049 if (insn->addr_bytes == 4) { in get_eff_addr_modrm()
1050 int addr32 = (int)(tmp & 0xffffffff) + insn->displacement.value; in get_eff_addr_modrm()
1054 *eff_addr = tmp + insn->displacement.value; in get_eff_addr_modrm()
1082 static int get_eff_addr_modrm_16(struct insn *insn, struct pt_regs *regs, in get_eff_addr_modrm_16() argument
1088 if (insn->addr_bytes != 2) in get_eff_addr_modrm_16()
1091 insn_get_modrm(insn); in get_eff_addr_modrm_16()
1093 if (!insn->modrm.nbytes) in get_eff_addr_modrm_16()
1096 if (X86_MODRM_MOD(insn->modrm.value) > 2) in get_eff_addr_modrm_16()
1099 ret = get_reg_offset_16(insn, regs, &addr_offset1, &addr_offset2); in get_eff_addr_modrm_16()
1114 displacement = insn->displacement.value & 0xffff; in get_eff_addr_modrm_16()
1150 static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs, in get_eff_addr_sib() argument
1157 if (insn->addr_bytes != 8 && insn->addr_bytes != 4) in get_eff_addr_sib()
1160 ret = insn_get_modrm(insn); in get_eff_addr_sib()
1164 if (!insn->modrm.nbytes) in get_eff_addr_sib()
1167 if (X86_MODRM_MOD(insn->modrm.value) > 2) in get_eff_addr_sib()
1170 ret = insn_get_sib(insn); in get_eff_addr_sib()
1174 if (!insn->sib.nbytes) in get_eff_addr_sib()
1177 *base_offset = get_reg_offset(insn, regs, REG_TYPE_BASE); in get_eff_addr_sib()
1178 indx_offset = get_reg_offset(insn, regs, REG_TYPE_INDEX); in get_eff_addr_sib()
1199 if (insn->addr_bytes == 4) { in get_eff_addr_sib()
1205 addr32 = base32 + idx32 * (1 << X86_SIB_SCALE(insn->sib.value)); in get_eff_addr_sib()
1206 addr32 += insn->displacement.value; in get_eff_addr_sib()
1210 *eff_addr = base + indx * (1 << X86_SIB_SCALE(insn->sib.value)); in get_eff_addr_sib()
1211 *eff_addr += insn->displacement.value; in get_eff_addr_sib()
1234 static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *regs) in get_addr_ref_16() argument
1241 if (insn_get_displacement(insn)) in get_addr_ref_16()
1244 if (insn->addr_bytes != 2) in get_addr_ref_16()
1247 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_addr_ref_16()
1248 ret = get_eff_addr_reg(insn, regs, ®off, &tmp); in get_addr_ref_16()
1254 ret = get_eff_addr_modrm_16(insn, regs, ®off, &eff_addr); in get_addr_ref_16()
1259 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit); in get_addr_ref_16()
1298 static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs) in get_addr_ref_32() argument
1305 if (insn->addr_bytes != 4) in get_addr_ref_32()
1308 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_addr_ref_32()
1309 ret = get_eff_addr_reg(insn, regs, ®off, &tmp); in get_addr_ref_32()
1316 if (insn->sib.nbytes) { in get_addr_ref_32()
1317 ret = get_eff_addr_sib(insn, regs, ®off, &tmp); in get_addr_ref_32()
1323 ret = get_eff_addr_modrm(insn, regs, ®off, &tmp); in get_addr_ref_32()
1331 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit); in get_addr_ref_32()
1387 static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs) in get_addr_ref_64() argument
1392 static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs) in get_addr_ref_64() argument
1398 if (insn->addr_bytes != 8) in get_addr_ref_64()
1401 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_addr_ref_64()
1402 ret = get_eff_addr_reg(insn, regs, ®off, &eff_addr); in get_addr_ref_64()
1407 if (insn->sib.nbytes) { in get_addr_ref_64()
1408 ret = get_eff_addr_sib(insn, regs, ®off, &eff_addr); in get_addr_ref_64()
1412 ret = get_eff_addr_modrm(insn, regs, ®off, &eff_addr); in get_addr_ref_64()
1419 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, NULL); in get_addr_ref_64()
1445 void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) in insn_get_addr_ref() argument
1447 if (!insn || !regs) in insn_get_addr_ref()
1450 if (insn_get_opcode(insn)) in insn_get_addr_ref()
1453 switch (insn->addr_bytes) { in insn_get_addr_ref()
1455 return get_addr_ref_16(insn, regs); in insn_get_addr_ref()
1457 return get_addr_ref_32(insn, regs); in insn_get_addr_ref()
1459 return get_addr_ref_64(insn, regs); in insn_get_addr_ref()
1555 bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, in insn_decode_from_regs() argument
1560 insn_init(insn, buf, buf_size, user_64bit_mode(regs)); in insn_decode_from_regs()
1576 insn->addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs); in insn_decode_from_regs()
1577 insn->opnd_bytes = INSN_CODE_SEG_OPND_SZ(seg_defs); in insn_decode_from_regs()
1579 if (insn_get_length(insn)) in insn_decode_from_regs()
1582 if (buf_size < insn->length) in insn_decode_from_regs()
1600 enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes) in insn_decode_mmio() argument
1606 if (insn_get_opcode(insn)) in insn_decode_mmio()
1609 switch (insn->opcode.bytes[0]) { in insn_decode_mmio()
1615 *bytes = insn->opnd_bytes; in insn_decode_mmio()
1624 *bytes = insn->opnd_bytes; in insn_decode_mmio()
1633 *bytes = insn->opnd_bytes; in insn_decode_mmio()
1642 *bytes = insn->opnd_bytes; in insn_decode_mmio()
1647 switch (insn->opcode.bytes[1]) { in insn_decode_mmio()