Lines Matching refs:insn
38 static bool is_string_insn(struct insn *insn) in is_string_insn() argument
40 insn_get_opcode(insn); in is_string_insn()
43 if (insn->opcode.nbytes != 1) in is_string_insn()
46 switch (insn->opcode.bytes[0]) { in is_string_insn()
64 bool insn_has_rep_prefix(struct insn *insn) in insn_has_rep_prefix() argument
69 insn_get_prefixes(insn); in insn_has_rep_prefix()
71 for_each_insn_prefix(insn, i, p) { in insn_has_rep_prefix()
93 static int get_seg_reg_override_idx(struct insn *insn) in get_seg_reg_override_idx() argument
99 insn_get_prefixes(insn); in get_seg_reg_override_idx()
102 for_each_insn_prefix(insn, i, p) { in get_seg_reg_override_idx()
156 static bool check_seg_overrides(struct insn *insn, int regoff) in check_seg_overrides() argument
158 if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn)) in check_seg_overrides()
181 static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off) in resolve_default_seg() argument
204 if (insn->addr_bytes == 2) in resolve_default_seg()
215 if (is_string_insn(insn)) in resolve_default_seg()
283 static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff) in resolve_seg_reg() argument
300 if (!insn) in resolve_seg_reg()
303 if (!check_seg_overrides(insn, regoff)) in resolve_seg_reg()
304 return resolve_default_seg(insn, regs, regoff); in resolve_seg_reg()
306 idx = get_seg_reg_override_idx(insn); in resolve_seg_reg()
311 return resolve_default_seg(insn, regs, regoff); in resolve_seg_reg()
415 static int get_reg_offset(struct insn *insn, struct pt_regs *regs, in get_reg_offset() argument
445 if (IS_ENABLED(CONFIG_X86_64) && !insn->x86_64) in get_reg_offset()
450 regno = X86_MODRM_RM(insn->modrm.value); in get_reg_offset()
456 if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5) in get_reg_offset()
459 if (X86_REX_B(insn->rex_prefix.value)) in get_reg_offset()
464 regno = X86_MODRM_REG(insn->modrm.value); in get_reg_offset()
466 if (X86_REX_R(insn->rex_prefix.value)) in get_reg_offset()
471 regno = X86_SIB_INDEX(insn->sib.value); in get_reg_offset()
472 if (X86_REX_X(insn->rex_prefix.value)) in get_reg_offset()
481 if (X86_MODRM_MOD(insn->modrm.value) != 3 && regno == 4) in get_reg_offset()
486 regno = X86_SIB_BASE(insn->sib.value); in get_reg_offset()
492 if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5) in get_reg_offset()
495 if (X86_REX_B(insn->rex_prefix.value)) in get_reg_offset()
528 static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs, in get_reg_offset_16() argument
562 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_reg_offset_16()
563 *offs1 = insn_get_modrm_rm_off(insn, regs); in get_reg_offset_16()
568 *offs1 = regoff1[X86_MODRM_RM(insn->modrm.value)]; in get_reg_offset_16()
569 *offs2 = regoff2[X86_MODRM_RM(insn->modrm.value)]; in get_reg_offset_16()
578 if ((X86_MODRM_MOD(insn->modrm.value) == 0) && in get_reg_offset_16()
579 (X86_MODRM_RM(insn->modrm.value) == 6)) in get_reg_offset_16()
833 int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs) in insn_get_modrm_rm_off() argument
835 return get_reg_offset(insn, regs, REG_TYPE_RM); in insn_get_modrm_rm_off()
848 int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs) in insn_get_modrm_reg_off() argument
850 return get_reg_offset(insn, regs, REG_TYPE_REG); in insn_get_modrm_reg_off()
874 static int get_seg_base_limit(struct insn *insn, struct pt_regs *regs, in get_seg_base_limit() argument
883 seg_reg_idx = resolve_seg_reg(insn, regs, regoff); in get_seg_base_limit()
924 static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs, in get_eff_addr_reg() argument
929 ret = insn_get_modrm(insn); in get_eff_addr_reg()
933 if (X86_MODRM_MOD(insn->modrm.value) != 3) in get_eff_addr_reg()
936 *regoff = get_reg_offset(insn, regs, REG_TYPE_RM); in get_eff_addr_reg()
941 if (insn->addr_bytes == 2) in get_eff_addr_reg()
943 else if (insn->addr_bytes == 4) in get_eff_addr_reg()
973 static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs, in get_eff_addr_modrm() argument
979 if (insn->addr_bytes != 8 && insn->addr_bytes != 4) in get_eff_addr_modrm()
982 ret = insn_get_modrm(insn); in get_eff_addr_modrm()
986 if (X86_MODRM_MOD(insn->modrm.value) > 2) in get_eff_addr_modrm()
989 *regoff = get_reg_offset(insn, regs, REG_TYPE_RM); in get_eff_addr_modrm()
998 tmp = regs->ip + insn->length; in get_eff_addr_modrm()
1007 if (insn->addr_bytes == 4) { in get_eff_addr_modrm()
1008 int addr32 = (int)(tmp & 0xffffffff) + insn->displacement.value; in get_eff_addr_modrm()
1012 *eff_addr = tmp + insn->displacement.value; in get_eff_addr_modrm()
1040 static int get_eff_addr_modrm_16(struct insn *insn, struct pt_regs *regs, in get_eff_addr_modrm_16() argument
1046 if (insn->addr_bytes != 2) in get_eff_addr_modrm_16()
1049 insn_get_modrm(insn); in get_eff_addr_modrm_16()
1051 if (!insn->modrm.nbytes) in get_eff_addr_modrm_16()
1054 if (X86_MODRM_MOD(insn->modrm.value) > 2) in get_eff_addr_modrm_16()
1057 ret = get_reg_offset_16(insn, regs, &addr_offset1, &addr_offset2); in get_eff_addr_modrm_16()
1072 displacement = insn->displacement.value & 0xffff; in get_eff_addr_modrm_16()
1108 static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs, in get_eff_addr_sib() argument
1115 if (insn->addr_bytes != 8 && insn->addr_bytes != 4) in get_eff_addr_sib()
1118 ret = insn_get_modrm(insn); in get_eff_addr_sib()
1122 if (!insn->modrm.nbytes) in get_eff_addr_sib()
1125 if (X86_MODRM_MOD(insn->modrm.value) > 2) in get_eff_addr_sib()
1128 ret = insn_get_sib(insn); in get_eff_addr_sib()
1132 if (!insn->sib.nbytes) in get_eff_addr_sib()
1135 *base_offset = get_reg_offset(insn, regs, REG_TYPE_BASE); in get_eff_addr_sib()
1136 indx_offset = get_reg_offset(insn, regs, REG_TYPE_INDEX); in get_eff_addr_sib()
1157 if (insn->addr_bytes == 4) { in get_eff_addr_sib()
1163 addr32 = base32 + idx32 * (1 << X86_SIB_SCALE(insn->sib.value)); in get_eff_addr_sib()
1164 addr32 += insn->displacement.value; in get_eff_addr_sib()
1168 *eff_addr = base + indx * (1 << X86_SIB_SCALE(insn->sib.value)); in get_eff_addr_sib()
1169 *eff_addr += insn->displacement.value; in get_eff_addr_sib()
1192 static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *regs) in get_addr_ref_16() argument
1199 if (insn_get_displacement(insn)) in get_addr_ref_16()
1202 if (insn->addr_bytes != 2) in get_addr_ref_16()
1205 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_addr_ref_16()
1206 ret = get_eff_addr_reg(insn, regs, ®off, &tmp); in get_addr_ref_16()
1212 ret = get_eff_addr_modrm_16(insn, regs, ®off, &eff_addr); in get_addr_ref_16()
1217 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit); in get_addr_ref_16()
1256 static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs) in get_addr_ref_32() argument
1263 if (insn->addr_bytes != 4) in get_addr_ref_32()
1266 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_addr_ref_32()
1267 ret = get_eff_addr_reg(insn, regs, ®off, &tmp); in get_addr_ref_32()
1274 if (insn->sib.nbytes) { in get_addr_ref_32()
1275 ret = get_eff_addr_sib(insn, regs, ®off, &tmp); in get_addr_ref_32()
1281 ret = get_eff_addr_modrm(insn, regs, ®off, &tmp); in get_addr_ref_32()
1289 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit); in get_addr_ref_32()
1345 static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs) in get_addr_ref_64() argument
1350 static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs) in get_addr_ref_64() argument
1356 if (insn->addr_bytes != 8) in get_addr_ref_64()
1359 if (X86_MODRM_MOD(insn->modrm.value) == 3) { in get_addr_ref_64()
1360 ret = get_eff_addr_reg(insn, regs, ®off, &eff_addr); in get_addr_ref_64()
1365 if (insn->sib.nbytes) { in get_addr_ref_64()
1366 ret = get_eff_addr_sib(insn, regs, ®off, &eff_addr); in get_addr_ref_64()
1370 ret = get_eff_addr_modrm(insn, regs, ®off, &eff_addr); in get_addr_ref_64()
1377 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, NULL); in get_addr_ref_64()
1403 void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) in insn_get_addr_ref() argument
1405 if (!insn || !regs) in insn_get_addr_ref()
1408 switch (insn->addr_bytes) { in insn_get_addr_ref()
1410 return get_addr_ref_16(insn, regs); in insn_get_addr_ref()
1412 return get_addr_ref_32(insn, regs); in insn_get_addr_ref()
1414 return get_addr_ref_64(insn, regs); in insn_get_addr_ref()
1510 bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, in insn_decode_from_regs() argument
1515 insn_init(insn, buf, buf_size, user_64bit_mode(regs)); in insn_decode_from_regs()
1531 insn->addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs); in insn_decode_from_regs()
1532 insn->opnd_bytes = INSN_CODE_SEG_OPND_SZ(seg_defs); in insn_decode_from_regs()
1534 if (insn_get_length(insn)) in insn_decode_from_regs()
1537 if (buf_size < insn->length) in insn_decode_from_regs()