Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions qemu/target/i386/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -6009,15 +6009,12 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
ot = mo_b_d(b, dflag);
modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3;
reg = ((modrm >> 3) & 7) | rex_r;
reg = (modrm >> 3) & 7;
if (reg != 0)
goto illegal_op;
if (mod != 3) {
if (reg != 0)
goto illegal_op;
s->rip_offset = insn_const_size(ot);
gen_lea_modrm(env, s, modrm);
} else {
if (reg != 0 && reg != 7)
goto illegal_op;
}
val = insn_get(env, s, ot);
tcg_gen_movi_tl(tcg_ctx, s->T0, val);
Expand Down
66 changes: 66 additions & 0 deletions tests/unit/test_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -2732,6 +2732,70 @@ static void test_x86_lock_btc_reg(void)
OK(uc_close(uc));
}

static void test_x86_group_11_with_rex_r(void)
{
uc_engine *uc;

char code[] = {
// mov eax, 0x84030201
0x44, 0xc7, 0xc0, 0x01, 0x02, 0x03, 0x84,
// mov cl, 0xab
0x44, 0xc6, 0xc1, 0xab,
// mov rdx, 0xffffffff84030201
0x4c, 0xc7, 0xc2, 0x01, 0x02, 0x03, 0x84,
};

uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code));

OK(uc_mem_map(uc, code_start + code_len, 0x1000, UC_PROT_ALL));

uint64_t rcx = 0xabcdef01;
OK(uc_reg_write(uc, UC_X86_REG_RCX, &rcx));

OK(uc_emu_start(uc, code_start, code_start + sizeof(code), 0, 0));

uint64_t rax = 0;
uint64_t rdx = 0;
OK(uc_reg_read(uc, UC_X86_REG_RAX, &rax));
OK(uc_reg_read(uc, UC_X86_REG_RCX, &rcx));
OK(uc_reg_read(uc, UC_X86_REG_RDX, &rdx));
TEST_CHECK(rax == 0x84030201);
TEST_CHECK(rcx == 0xabcdefab);
TEST_CHECK(rdx == 0xffffffff84030201);

OK(uc_close(uc));
}

static void test_x86_group_11_with_modrm_reg_7(void)
{
uc_engine *uc;

// Assumes that XABORT and XBEGIN are not implemented in Unicorn yet
char xbegin_code[] = {
// xbegin +0x4030201
0xc7, 0xc0 | (7 << 3), 0x01, 0x02, 0x03, 0x04
};

char xabort_code[] = {
// xabort byte 0xff
0xc6, 0xc0 | (7 << 3), 0xff
};

uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, xbegin_code, sizeof(xbegin_code));

uc_assert_err(UC_ERR_INSN_INVALID,
uc_emu_start(uc, code_start, code_start + sizeof(xbegin_code), 0, 0));

OK(uc_close(uc));

uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, xabort_code, sizeof(xabort_code));

uc_assert_err(UC_ERR_INSN_INVALID,
uc_emu_start(uc, code_start, code_start + sizeof(xabort_code), 0, 0));

OK(uc_close(uc));
}

TEST_LIST = {
{"test_x86_in", test_x86_in},
{"test_x86_out", test_x86_out},
Expand Down Expand Up @@ -2814,4 +2878,6 @@ TEST_LIST = {
{"test_x86_lock_bt_reg", test_x86_lock_bt_reg},
{"test_x86_lock_btc_mem", test_x86_lock_btc_mem},
{"test_x86_lock_btc_reg", test_x86_lock_btc_reg},
{"test_x86_group_11_with_rex_r", test_x86_group_11_with_rex_r},
{"test_x86_group_11_with_modrm_reg_7", test_x86_group_11_with_modrm_reg_7},
{NULL, NULL}};
Loading