diff --git a/qemu/s390x.h b/qemu/s390x.h index b14ea4cf..4de8fd9d 100644 --- a/qemu/s390x.h +++ b/qemu/s390x.h @@ -1277,4 +1277,5 @@ #define gen_helper_vfp_set_fpscr gen_helper_vfp_set_fpscr_s390x #define gen_helper_cpsr_read gen_helper_cpsr_read_s390x #define gen_helper_cpsr_write gen_helper_cpsr_write_s390x +#define helper_uc_s390x_exit helper_uc_s390x_exit_s390x #endif diff --git a/qemu/target/s390x/excp_helper.c b/qemu/target/s390x/excp_helper.c index 83433271..30c61359 100644 --- a/qemu/target/s390x/excp_helper.c +++ b/qemu/target/s390x/excp_helper.c @@ -598,3 +598,12 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr, tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr); } + +void helper_uc_s390x_exit(CPUS390XState *env) +{ + CPUState *cs = env_cpu(env); + + cs->exception_index = EXCP_HLT; + cs->halted = 1; + cpu_loop_exit(cs); +} \ No newline at end of file diff --git a/qemu/target/s390x/helper.h b/qemu/target/s390x/helper.h index 2ab70698..abd8dd2a 100644 --- a/qemu/target/s390x/helper.h +++ b/qemu/target/s390x/helper.h @@ -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_s390x_exit, void, env) DEF_HELPER_2(exception, noreturn, env, i32) DEF_HELPER_2(data_exception, noreturn, env, i32) diff --git a/qemu/target/s390x/translate.c b/qemu/target/s390x/translate.c index 79b83b0b..3d819f23 100644 --- a/qemu/target/s390x/translate.c +++ b/qemu/target/s390x/translate.c @@ -6652,6 +6652,9 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s) /* Search for the insn in the table. */ insn = extract_insn(env, s); + /* Emit insn_start now that we know the ILEN. */ + tcg_gen_insn_start(tcg_ctx, s->base.pc_next, s->cc_op, s->ilen); + // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->base.pc_next)) { gen_uc_tracecode(tcg_ctx, s->ilen, UC_HOOK_CODE_IDX, s->uc, s->base.pc_next); @@ -6659,9 +6662,6 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s) check_exit_request(tcg_ctx); } - /* Emit insn_start now that we know the ILEN. */ - tcg_gen_insn_start(tcg_ctx, s->base.pc_next, s->cc_op, s->ilen); - /* Not found means unimplemented/illegal opcode. */ if (insn == NULL) { // qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n", @@ -6867,7 +6867,8 @@ static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) switch (dc->base.is_jmp) { case DISAS_UNICORN_HALT: - gen_exception(tcg_ctx, EXCP_PGM); + tcg_gen_insn_start(tcg_ctx, dc->base.pc_next, 0, 0); + gen_helper_uc_s390x_exit(tcg_ctx, tcg_ctx->cpu_env); break; case DISAS_GOTO_TB: case DISAS_NORETURN: diff --git a/qemu/target/s390x/unicorn.c b/qemu/target/s390x/unicorn.c index 5f1ace7f..9a718043 100644 --- a/qemu/target/s390x/unicorn.c +++ b/qemu/target/s390x/unicorn.c @@ -38,7 +38,7 @@ static void s390_release(void *ctx) release_common(ctx); - s390_cpu_model_finalize(cpu); + s390_cpu_model_finalize((CPUState *)cpu); // TODO: Anymore to free? } diff --git a/samples/sample_s390x.c b/samples/sample_s390x.c index da15965c..d8ac3ec5 100644 --- a/samples/sample_s390x.c +++ b/samples/sample_s390x.c @@ -65,7 +65,8 @@ static void test_s390x(void) // finishing all the code. err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(S390X_CODE) - 1, 0, 0); if (err) { - printf("Failed on uc_emu_start() with error returned: %u\n", err); + printf("Failed on uc_emu_start() with error returned: %u (%s)\n", err, + uc_strerror(err)); } // now print out some registers diff --git a/symbols.sh b/symbols.sh index 5ace5c89..32d615f1 100755 --- a/symbols.sh +++ b/symbols.sh @@ -6271,6 +6271,9 @@ ppc_irq_reset \ ppc64_SYMBOLS=${ppc_SYMBOLS} +s390x_SYMBOLS="helper_uc_s390x_exit \ +" + ARCHS="x86_64 arm armeb aarch64 aarch64eb riscv32 riscv64 mips mipsel mips64 mips64el sparc sparc64 m68k ppc ppc64 s390x" for arch in $ARCHS; do