do not use syscall to quit emulation. this can fix issues #147 & #148

This commit is contained in:
Nguyen Anh Quynh 2015-09-26 16:49:00 +08:00
parent 79b81e6ae4
commit 886946dcf4
22 changed files with 57 additions and 29 deletions

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_AARCH64_H
#define UNICORN_AUTOGEN_AARCH64_H
#define helper_power_down helper_power_down_aarch64
#define check_exit_request check_exit_request_aarch64
#define address_space_unregister address_space_unregister_aarch64
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_aarch64

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_ARM_H
#define UNICORN_AUTOGEN_ARM_H
#define helper_power_down helper_power_down_arm
#define check_exit_request check_exit_request_arm
#define address_space_unregister address_space_unregister_arm
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_arm

View file

@ -108,18 +108,6 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
break;
}
if ((uc->arch == UC_ARCH_X86 && cpu->exception_index == 0x99) || // X86's Int 0x99
(uc->arch == UC_ARCH_ARM && cpu->exception_index == 2) || /* ARM's EXCP_SWI */
(uc->arch == UC_ARCH_ARM64 && cpu->exception_index == 2) || /* ARM's EXCP_SWI */
(uc->arch == UC_ARCH_MIPS && cpu->exception_index == 17) || /* Mips's EXCP_SYSCALL */
(uc->arch == UC_ARCH_SPARC && cpu->exception_index == 0x80) || /* Sparc's TT_TRAP */
(uc->arch == UC_ARCH_SPARC && cpu->exception_index == 0x100) || /* Sparc64's TT_TRAP */
(uc->arch == UC_ARCH_M68K && cpu->exception_index == 0x2f) /* M68K's EXCP_TRAP15 */
) {
cpu->halted = 1;
ret = EXCP_HLT;
break;
}
if (cpu->exception_index >= EXCP_INTERRUPT) {
/* exit request from the cpu execution loop */
ret = cpu->exception_index;

View file

@ -7,6 +7,7 @@
import sys
symbols = (
'helper_power_down',
'check_exit_request',
'address_space_unregister',
'tb_invalidate_phys_page_fast',

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_M68K_H
#define UNICORN_AUTOGEN_M68K_H
#define helper_power_down helper_power_down_m68k
#define check_exit_request check_exit_request_m68k
#define address_space_unregister address_space_unregister_m68k
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_m68k

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_MIPS_H
#define UNICORN_AUTOGEN_MIPS_H
#define helper_power_down helper_power_down_mips
#define check_exit_request check_exit_request_mips
#define address_space_unregister address_space_unregister_mips
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_MIPS64_H
#define UNICORN_AUTOGEN_MIPS64_H
#define helper_power_down helper_power_down_mips64
#define check_exit_request check_exit_request_mips64
#define address_space_unregister address_space_unregister_mips64
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips64

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_MIPS64EL_H
#define UNICORN_AUTOGEN_MIPS64EL_H
#define helper_power_down helper_power_down_mips64el
#define check_exit_request check_exit_request_mips64el
#define address_space_unregister address_space_unregister_mips64el
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips64el

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_MIPSEL_H
#define UNICORN_AUTOGEN_MIPSEL_H
#define helper_power_down helper_power_down_mipsel
#define check_exit_request check_exit_request_mipsel
#define address_space_unregister address_space_unregister_mipsel
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mipsel

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_POWERPC_H
#define UNICORN_AUTOGEN_POWERPC_H
#define helper_power_down helper_power_down_powerpc
#define check_exit_request check_exit_request_powerpc
#define address_space_unregister address_space_unregister_powerpc
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_powerpc

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_SPARC_H
#define UNICORN_AUTOGEN_SPARC_H
#define helper_power_down helper_power_down_sparc
#define check_exit_request check_exit_request_sparc
#define address_space_unregister address_space_unregister_sparc
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_sparc

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_SPARC64_H
#define UNICORN_AUTOGEN_SPARC64_H
#define helper_power_down helper_power_down_sparc64
#define check_exit_request check_exit_request_sparc64
#define address_space_unregister address_space_unregister_sparc64
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_sparc64

View file

@ -10974,7 +10974,8 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
// Unicorn: end address tells us to stop emulation
if (s->pc == s->uc->addr_end) {
gen_exception_insn(s, 0, EXCP_SWI, 0);
// imitate WFI instruction to halt emulation
s->is_jmp = DISAS_WFI;
return;
}
@ -11107,8 +11108,9 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
// Unicorn: early check to see if the address of this block is the until address
if (tb->pc == env->uc->addr_end) {
// imitate WFI instruction to halt emulation
gen_tb_start(tcg_ctx);
gen_exception_insn(dc, 0, EXCP_SWI, 0);
dc->is_jmp = DISAS_WFI;
goto done_generating;
}

View file

@ -10396,7 +10396,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
// Unicorn: end address tells us to stop emulation
if (s->pc == s->uc->addr_end) {
gen_exception_insn(s, 0, EXCP_SWI, 0);
// imitate WFI instruction to halt emulation
s->is_jmp = DISAS_WFI;
return;
}
@ -11230,8 +11231,9 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
// Unicorn: early check to see if the address of this block is the until address
if (tb->pc == env->uc->addr_end) {
// imitate WFI instruction to halt emulation
gen_tb_start(tcg_ctx);
gen_exception_insn(dc, 0, EXCP_SWI, 0);
dc->is_jmp = DISAS_WFI;
goto done_generating;
}
@ -11289,6 +11291,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
store_cpu_field(tcg_ctx, tmp, condexec_bits);
}
do {
//printf(">>> arm pc = %x\n", dc->pc);
#ifdef CONFIG_USER_ONLY
/* Intercept jump to the magic kernel page. */
if (dc->pc >= 0xffff0000) {
@ -11370,7 +11373,8 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
// end address tells us to stop emulation
if (dc->pc == dc->uc->addr_end) {
gen_exception_insn(dc, 0, EXCP_SWI, 0);
// imitate WFI instruction to halt emulation
dc->is_jmp = DISAS_WFI;
} else {
insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
dc->pc += 4;

View file

@ -4751,7 +4751,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
// end address tells us to stop emulation
if (s->pc == s->uc->addr_end) {
gen_interrupt(s, 0x99, pc_start - s->cs_base, pc_start - s->cs_base);
// imitate the HLT instruction
gen_update_cc_op(s);
gen_jmp_im(s, pc_start - s->cs_base);
gen_helper_hlt(tcg_ctx, cpu_env, tcg_const_i32(tcg_ctx, s->pc - pc_start));
s->is_jmp = DISAS_TB_JUMP;
return s->pc;
}
@ -8361,8 +8365,11 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op,
// early check to see if the address of this block is the until address
if (tb->pc == env->uc->addr_end) {
// imitate the HLT instruction
gen_tb_start(tcg_ctx);
gen_interrupt(dc, 0x99, tb->pc - tb->cs_base, tb->pc - tb->cs_base);
gen_jmp_im(dc, tb->pc - tb->cs_base);
gen_helper_hlt(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, 0));
dc->is_jmp = DISAS_TB_JUMP;
goto done_generating;
}

View file

@ -3038,7 +3038,7 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
// Unicorn: end address tells us to stop emulation
if (s->pc == s->uc->addr_end) {
gen_exception(s, s->pc, EXCP_TRAP15);
gen_exception(s, s->pc, EXCP_HLT);
return;
}
@ -3104,7 +3104,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
// Unicorn: early check to see if the address of this block is the until address
if (tb->pc == env->uc->addr_end) {
gen_tb_start(tcg_ctx);
gen_exception(dc, dc->pc, EXCP_TRAP15);
gen_exception(dc, dc->pc, EXCP_HLT);
goto done_generating;
}

View file

@ -19211,7 +19211,8 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
// Unicorn: early check to see if the address of this block is the until address
if (tb->pc == env->uc->addr_end) {
gen_tb_start(tcg_ctx);
generate_exception(&ctx, EXCP_SYSCALL);
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
ctx.bstate = BS_EXCP;
goto done_generating;
}
@ -19229,6 +19230,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
gen_tb_start(tcg_ctx);
while (ctx.bstate == BS_NONE) {
// printf(">>> mips pc = %x\n", ctx.pc);
if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == ctx.pc) {
@ -19261,7 +19263,8 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
// Unicorn: end address tells us to stop emulation
if (ctx.pc == ctx.uc->addr_end) {
generate_exception(&ctx, EXCP_SYSCALL);
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
ctx.bstate = BS_EXCP;
break;
} else {
// Unicorn: save param buffer

View file

@ -241,7 +241,7 @@ target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1,
helper_raise_exception(env, TT_TOVF);
}
#ifndef TARGET_SPARC64
//#ifndef TARGET_SPARC64
void helper_power_down(CPUSPARCState *env)
{
CPUState *cs = CPU(sparc_env_get_cpu(env));
@ -252,4 +252,4 @@ void helper_power_down(CPUSPARCState *env)
env->npc = env->pc + 4;
cpu_loop_exit(cs);
}
#endif
//#endif

View file

@ -1,10 +1,10 @@
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
DEF_HELPER_1(power_down, void, env)
#ifndef TARGET_SPARC64
DEF_HELPER_1(rett, void, env)
DEF_HELPER_2(wrpsr, void, env, tl)
DEF_HELPER_1(rdpsr, tl, env)
DEF_HELPER_1(power_down, void, env)
#else
DEF_HELPER_2(wrpil, void, env, tl)
DEF_HELPER_2(wrpstate, void, env, tl)

View file

@ -5405,6 +5405,14 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
// Unicorn: early check to see if the address of this block is the until address
if (tb->pc == env->uc->addr_end) {
gen_tb_start(tcg_ctx);
save_state(dc);
gen_helper_power_down(tcg_ctx, tcg_ctx->cpu_env);
goto done_generating;
}
// Unicorn: trace this block on request
// Only hook this block if it is not broken from previous translation due to
// full translation cache
@ -5448,7 +5456,9 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
// gen_io_start();
// Unicorn: end address tells us to stop emulation
if (dc->pc == dc->uc->addr_end) {
insn = 0x91d02000; // generate TRAP to end this TB
save_state(dc);
gen_helper_power_down(tcg_ctx, tcg_ctx->cpu_env);
break;
} else {
last_pc = dc->pc;
insn = cpu_ldl_code(env, dc->pc);
@ -5497,6 +5507,8 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
tcg_gen_exit_tb(tcg_ctx, 0);
}
}
done_generating:
gen_tb_end(tcg_ctx, tb, num_insns);
*tcg_ctx->gen_opc_ptr = INDEX_op_end;
if (spc) {

View file

@ -1,6 +1,7 @@
/* Autogen header for Unicorn Engine - DONOT MODIFY */
#ifndef UNICORN_AUTOGEN_X86_64_H
#define UNICORN_AUTOGEN_X86_64_H
#define helper_power_down helper_power_down_x86_64
#define check_exit_request check_exit_request_x86_64
#define address_space_unregister address_space_unregister_x86_64
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_x86_64

View file

@ -59,8 +59,8 @@ static void test_sparc(void)
// tracing all basic blocks with customized callback
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// tracing all instructions with customized callback
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.