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
1 change: 1 addition & 0 deletions qemu/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_aarch64
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_aarch64
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_aarch64
#define helper_uc_exit helper_uc_exit_aarch64
#define cpu_aarch64_init cpu_aarch64_init_aarch64
#define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_aarch64
#define arm_cpu_update_virq arm_cpu_update_virq_aarch64
Expand Down
1 change: 1 addition & 0 deletions qemu/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_arm
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_arm
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_arm
#define helper_uc_exit helper_uc_exit_arm
#define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_arm
#define arm_cpu_update_virq arm_cpu_update_virq_arm
#define arm_cpu_update_vfiq arm_cpu_update_vfiq_arm
Expand Down
1 change: 1 addition & 0 deletions qemu/include/exec/translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
typedef enum DisasJumpType {
DISAS_NEXT,
DISAS_TOO_MANY,
DISAS_UC_EXIT, // Unicorn: Special disas state for exiting in the middle of tb.
DISAS_NORETURN,
DISAS_TARGET_0,
DISAS_TARGET_1,
Expand Down
1 change: 1 addition & 0 deletions qemu/m68k.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_m68k
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_m68k
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_m68k
#define helper_uc_exit helper_uc_exit_m68k
#define cpu_m68k_init cpu_m68k_init_m68k
#define helper_reds32 helper_reds32_m68k
#define helper_redf32 helper_redf32_m68k
Expand Down
1 change: 1 addition & 0 deletions qemu/mips.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mips
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_mips
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_mips
#define helper_uc_exit helper_uc_exit_mips
#define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mips
#define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mips
#define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mips
Expand Down
1 change: 1 addition & 0 deletions qemu/mips64.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mips64
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_mips64
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_mips64
#define helper_uc_exit helper_uc_exit_mips64
#define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mips64
#define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mips64
#define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mips64
Expand Down
1 change: 1 addition & 0 deletions qemu/mips64el.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mips64el
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_mips64el
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_mips64el
#define helper_uc_exit helper_uc_exit_mips64el
#define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mips64el
#define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mips64el
#define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mips64el
Expand Down
1 change: 1 addition & 0 deletions qemu/mipsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mipsel
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_mipsel
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_mipsel
#define helper_uc_exit helper_uc_exit_mipsel
#define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mipsel
#define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mipsel
#define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mipsel
Expand Down
1 change: 1 addition & 0 deletions qemu/ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_ppc
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_ppc
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_ppc
#define helper_uc_exit helper_uc_exit_ppc
#define ppc_cpu_unrealize ppc_cpu_unrealize_ppc
#define ppc_cpu_instance_finalize ppc_cpu_instance_finalize_ppc
#define ppc_cpu_do_interrupt ppc_cpu_do_interrupt_ppc
Expand Down
1 change: 1 addition & 0 deletions qemu/ppc64.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_ppc64
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_ppc64
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_ppc64
#define helper_uc_exit helper_uc_exit_ppc64
#define ppc_cpu_unrealize ppc_cpu_unrealize_ppc64
#define ppc_cpu_instance_finalize ppc_cpu_instance_finalize_ppc64
#define ppc_cpu_do_interrupt ppc_cpu_do_interrupt_ppc64
Expand Down
2 changes: 1 addition & 1 deletion qemu/riscv32.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_riscv32
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_riscv32
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_riscv32
#define helper_uc_exit helper_uc_exit_riscv32
#define riscv_cpu_mmu_index riscv_cpu_mmu_index_riscv32
#define riscv_cpu_exec_interrupt riscv_cpu_exec_interrupt_riscv32
#define riscv_cpu_fp_enabled riscv_cpu_fp_enabled_riscv32
Expand Down Expand Up @@ -1360,7 +1361,6 @@
#define helper_fclass_d helper_fclass_d_riscv32
#define riscv_raise_exception riscv_raise_exception_riscv32
#define helper_raise_exception helper_raise_exception_riscv32
#define helper_uc_riscv_exit helper_uc_riscv_exit_riscv32
#define helper_csrrw helper_csrrw_riscv32
#define helper_csrrs helper_csrrs_riscv32
#define helper_csrrc helper_csrrc_riscv32
Expand Down
2 changes: 1 addition & 1 deletion qemu/riscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_riscv64
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_riscv64
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_riscv64
#define helper_uc_exit helper_uc_exit_riscv64
#define riscv_cpu_mmu_index riscv_cpu_mmu_index_riscv64
#define riscv_cpu_exec_interrupt riscv_cpu_exec_interrupt_riscv64
#define riscv_cpu_fp_enabled riscv_cpu_fp_enabled_riscv64
Expand Down Expand Up @@ -1360,7 +1361,6 @@
#define helper_fclass_d helper_fclass_d_riscv64
#define riscv_raise_exception riscv_raise_exception_riscv64
#define helper_raise_exception helper_raise_exception_riscv64
#define helper_uc_riscv_exit helper_uc_riscv_exit_riscv64
#define helper_csrrw helper_csrrw_riscv64
#define helper_csrrs helper_csrrs_riscv64
#define helper_csrrc helper_csrrc_riscv64
Expand Down
2 changes: 1 addition & 1 deletion qemu/s390x.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_s390x
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_s390x
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_s390x
#define helper_uc_s390x_exit helper_uc_s390x_exit_s390x
#define helper_uc_exit helper_uc_exit_s390x
#define tcg_s390_tod_updated tcg_s390_tod_updated_s390x
#define tcg_s390_program_interrupt tcg_s390_program_interrupt_s390x
#define tcg_s390_data_exception tcg_s390_data_exception_s390x
Expand Down
1 change: 1 addition & 0 deletions qemu/sparc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_sparc
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_sparc
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_sparc
#define helper_uc_exit helper_uc_exit_sparc
#define helper_compute_psr helper_compute_psr_sparc
#define helper_compute_C_icc helper_compute_C_icc_sparc
#define cpu_sparc_set_id cpu_sparc_set_id_sparc
Expand Down
1 change: 1 addition & 0 deletions qemu/sparc64.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@
#define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_sparc64
#define helper_stqcx_le_parallel helper_stqcx_le_parallel_sparc64
#define helper_stqcx_be_parallel helper_stqcx_be_parallel_sparc64
#define helper_uc_exit helper_uc_exit_sparc64
#define helper_compute_psr helper_compute_psr_sparc64
#define helper_compute_C_icc helper_compute_C_icc_sparc64
#define cpu_sparc_set_id cpu_sparc_set_id_sparc64
Expand Down
1 change: 1 addition & 0 deletions qemu/target/arm/helper.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64)
DEF_HELPER_1(uc_exit, void, env)

DEF_HELPER_FLAGS_1(sxtb16, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(uxtb16, TCG_CALL_NO_RWG_SE, i32, i32)
Expand Down
9 changes: 9 additions & 0 deletions qemu/target/arm/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -998,3 +998,12 @@ uint32_t HELPER(uc_hooksys64)(CPUARMState *env, uint32_t insn, void *hk)
JIT_CALLBACK_GUARD_VAR(ret, ((uc_cb_insn_sys_t)(hook->callback))(uc, uc_rt, &cp_reg, hook->user_data));
return ret;
}

void HELPER(uc_exit)(CPUARMState *env)
{
CPUState *cs = env_cpu(env);

cs->exception_index = EXCP_HLT;
cs->halted = 1;
cpu_loop_exit(cs);
}
8 changes: 7 additions & 1 deletion qemu/target/arm/translate-a64.c
Original file line number Diff line number Diff line change
Expand Up @@ -14737,7 +14737,7 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
// Unicorn: end address tells us to stop emulation
if (uc_addr_is_exit(dc->uc, dcbase->pc_next)) {
// imitate WFI instruction to halt emulation
dcbase->is_jmp = DISAS_WFI;
dcbase->is_jmp = DISAS_UC_EXIT;
} else {
if (dc->ss_active && !dc->pstate_ss) {
/* Singlestep state is Active-pending.
Expand Down Expand Up @@ -14830,6 +14830,12 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
break;
}
case DISAS_UC_EXIT:
{
gen_a64_set_pc_im(tcg_ctx, dc->base.pc_next);
gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env);
break;
}
}
}
}
Expand Down
59 changes: 33 additions & 26 deletions qemu/target/arm/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -11462,34 +11462,35 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
// Unicorn: end address tells us to stop emulation
if (uc_addr_is_exit(dc->uc, dcbase->pc_next)) {
// imitate WFI instruction to halt emulation
dcbase->is_jmp = DISAS_WFI;
} else {
dc->pc_curr = dc->base.pc_next;
insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
dc->insn = insn;

// Unicorn:
//
// If we get an error during fetching code, we have to skip the instruction decoding
// to ensure the PC remains unchanged.
//
// This is to keep the same behavior with Unicorn1, though, it's inconsistent with
// official arm documents.
//
// See discussion here: https://github.com/unicorn-engine/unicorn/issues/1536
if (dc->uc->invalid_error) {
dcbase->is_jmp = DISAS_WFI;
return;
}
dcbase->is_jmp = DISAS_UC_EXIT;
return;
}

dc->pc_curr = dc->base.pc_next;
insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
dc->insn = insn;

// Unicorn:
//
// If we get an error during fetching code, we have to skip the instruction decoding
// to ensure the PC remains unchanged.
//
// This is to keep the same behavior with Unicorn1, though, it's inconsistent with
// official arm documents.
//
// See discussion here: https://github.com/unicorn-engine/unicorn/issues/1536
if (dc->uc->invalid_error) {
dcbase->is_jmp = DISAS_UC_EXIT;
return;
}

dc->base.pc_next += 4;
disas_arm_insn(dc, insn);
dc->base.pc_next += 4;
disas_arm_insn(dc, insn);

arm_post_translate_insn(dc);
arm_post_translate_insn(dc);

/* ARM is a fixed-length ISA. We performed the cross-page check
in init_disas_context by adjusting max_insns. */
}
/* ARM is a fixed-length ISA. We performed the cross-page check
in init_disas_context by adjusting max_insns. */
}

static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
Expand Down Expand Up @@ -11555,7 +11556,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
// Unicorn: end address tells us to stop emulation
if (uc_addr_is_exit(uc, dcbase->pc_next)) {
// imitate WFI instruction to halt emulation
dcbase->is_jmp = DISAS_WFI;
dcbase->is_jmp = DISAS_UC_EXIT;
return;
}

Expand Down Expand Up @@ -11753,6 +11754,12 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
case DISAS_SMC:
gen_exception(tcg_ctx, EXCP_SMC, syn_aa32_smc(), 3);
break;
case DISAS_UC_EXIT:
{
gen_set_pc_im(dc, dc->base.pc_next);
gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env);
break;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions qemu/target/i386/helper.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64)
DEF_HELPER_1(uc_exit, void, env)

DEF_HELPER_FLAGS_4(cc_compute_all, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int)
DEF_HELPER_FLAGS_4(cc_compute_c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int)
Expand Down
9 changes: 9 additions & 0 deletions qemu/target/i386/misc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,3 +732,12 @@ void helper_wrpkru(CPUX86State *env, uint32_t ecx, uint64_t val)
env->pkru = val;
tlb_flush(cs);
}

void helper_uc_exit(CPUX86State *env)
{
X86CPU *cpu = env_archcpu(env);

cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC());

do_hlt(cpu);
}
29 changes: 18 additions & 11 deletions qemu/target/i386/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -4803,16 +4803,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)

s->uc = env->uc;

// Unicorn: end address tells us to stop emulation
if (uc_addr_is_exit(env->uc, s->pc)) {
// imitate the HLT instruction
gen_update_cc_op(s);
gen_sync_pc(tcg_ctx, pc_start - s->cs_base);
gen_helper_hlt(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, s->pc - pc_start));
s->base.is_jmp = DISAS_NORETURN;
return s->pc;
}

// Unicorn: callback might need to access to EFLAGS,
// or want to stop emulation immediately
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, pc_start)) {
Expand Down Expand Up @@ -9385,6 +9375,12 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
DisasContext *dc = container_of(dcbase, DisasContext, base);
target_ulong pc_next;

// Unicorn: end address tells us to stop emulation
if (uc_addr_is_exit(((CPUX86State *)cpu->env_ptr)->uc, dcbase->pc_next)) {
dc->base.is_jmp = DISAS_UC_EXIT;
return;
}

pc_next = disas_insn(dc, cpu);

if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
Expand Down Expand Up @@ -9416,10 +9412,21 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
TCGContext *tcg_ctx = dc->uc->tcg_ctx;

if (dc->base.is_jmp == DISAS_TOO_MANY) {
switch (dc->base.is_jmp) {
case DISAS_TOO_MANY:
gen_jmp_im(dc, dc->base.pc_next - dc->cs_base);
gen_eob(dc);
break;
case DISAS_UC_EXIT:
// imitate the HLT instruction
gen_update_cc_op(dc);
gen_jmp_im(dc, dc->base.pc_next - dc->cs_base);
gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env);
break;
default:
break; // suppress compiler warnings
}
}

Expand Down
5 changes: 4 additions & 1 deletion qemu/target/m68k/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -6325,7 +6325,7 @@ static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)

// Unicorn: end address tells us to stop emulation
if (uc_addr_is_exit(uc, dc->pc)) {
gen_exception(dc, dc->pc, EXCP_HLT);
dc->base.is_jmp = DISAS_UC_EXIT;
return;
}

Expand Down Expand Up @@ -6407,6 +6407,9 @@ static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
}
break;
case DISAS_UC_EXIT:
gen_exception(dc, dc->pc, EXCP_HLT);
break;
default:
g_assert_not_reached();
}
Expand Down
1 change: 1 addition & 0 deletions qemu/target/mips/helper.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64)
DEF_HELPER_1(uc_exit, void, env)

DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
DEF_HELPER_2(raise_exception, noreturn, env, i32)
Expand Down
13 changes: 13 additions & 0 deletions qemu/target/mips/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,19 @@ void helper_wait(CPUMIPSState *env)
raise_exception(env, EXCP_HLT);
}

void helper_uc_exit(CPUMIPSState *env)
{
CPUState *cs = env_cpu(env);

cs->halted = 1;
cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
/*
* Last instruction in the block, PC was updated before
* - no need to recover PC and icount.
*/
raise_exception(env, EXCP_HLT);
}

void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr)
Expand Down
Loading
Loading