diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c index 2ef77cb9248..e0ffe9581b9 100644 --- a/accel/tcg/tcg-runtime.c +++ b/accel/tcg/tcg-runtime.c @@ -178,6 +178,13 @@ void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc) libafl_qemu_trigger_breakpoint(cpu); } +void HELPER(libafl_qemu_sync_pc)(CPUArchState *env, uint64_t pc) +{ + CPUState* cpu = env_cpu(env); + CPUClass* cc = CPU_GET_CLASS(cpu); + cc->set_pc(cpu, THUMB_MASK(((target_ulong)pc))); +} + //// --- End LibAFL code --- /* 32-bit helpers */ diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h index 18fbaa82edb..88c215d08d0 100644 --- a/accel/tcg/tcg-runtime.h +++ b/accel/tcg/tcg-runtime.h @@ -328,5 +328,6 @@ DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_2(libafl_qemu_handle_breakpoint, TCG_CALL_NO_RWG, void, env, i64) +DEF_HELPER_FLAGS_2(libafl_qemu_sync_pc, TCG_CALL_NO_RWG, void, env, i64) //// --- End LibAFL code --- diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index d8f8edfe753..face3fa9f17 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -81,6 +81,16 @@ void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, TCGTemp **args); target_ulong libafl_gen_cur_pc; +int libafl_pc_synced; + +static void libafl_sync_pc(void) { + if (!libafl_pc_synced) { + TCGv_i64 tmp_pc = tcg_constant_i64((uint64_t)libafl_gen_cur_pc); + gen_helper_libafl_qemu_sync_pc(tcg_env, tmp_pc); + tcg_temp_free_i64(tmp_pc); + libafl_pc_synced = true; + } +} TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block, target_ulong dst_block, int exit_n, @@ -306,6 +316,8 @@ void libafl_gen_read(TCGTemp *addr, MemOpIdx oi) struct libafl_rw_hook* hook = libafl_read_hooks; while (hook) { + libafl_sync_pc(); + uint64_t cur_id = 0; if (hook->gen) cur_id = hook->gen(libafl_gen_cur_pc, oi, hook->data); @@ -411,6 +423,8 @@ void libafl_gen_write(TCGTemp *addr, MemOpIdx oi) struct libafl_rw_hook* hook = libafl_write_hooks; while (hook) { + libafl_sync_pc(); + uint64_t cur_id = 0; if (hook->gen) cur_id = hook->gen(libafl_gen_cur_pc, oi, hook->data); @@ -565,6 +579,8 @@ void libafl_gen_cmp(target_ulong pc, TCGv op0, TCGv op1, MemOp ot) struct libafl_cmp_hook* hook = libafl_cmp_hooks; while (hook) { + libafl_sync_pc(); + uint64_t cur_id = 0; if (hook->gen) cur_id = hook->gen(pc, size, hook->data); diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 6bc49f50643..252756d12d4 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -124,6 +124,7 @@ static void gen_tb_end(const TranslationBlock *tb, uint32_t cflags, void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, TCGTemp **args); extern target_ulong libafl_gen_cur_pc; +extern int libafl_pc_synced; struct libafl_breakpoint { target_ulong addr; @@ -214,8 +215,16 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, //// --- Begin LibAFL code --- + libafl_gen_cur_pc = db->pc_next; + libafl_pc_synced = false; + struct libafl_hook* hk = libafl_search_hook(db->pc_next); if (hk) { + TCGv_i64 tmp_pc = tcg_constant_i64((uint64_t)db->pc_next); + gen_helper_libafl_qemu_sync_pc(tcg_env, tmp_pc); + libafl_pc_synced = true; + tcg_temp_free_i64(tmp_pc); + TCGv_i64 tmp1 = tcg_constant_i64(hk->data); #if TARGET_LONG_BITS == 32 TCGv_i32 tmp0 = tcg_constant_i32(db->pc_next); @@ -237,15 +246,18 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, struct libafl_breakpoint* bp = libafl_qemu_breakpoints; while (bp) { if (bp->addr == db->pc_next) { - TCGv_i64 tmp0 = tcg_constant_i64((uint64_t)db->pc_next); - gen_helper_libafl_qemu_handle_breakpoint(tcg_env, tmp0); - tcg_temp_free_i64(tmp0); + TCGv_i64 tmp_pc = tcg_constant_i64((uint64_t)db->pc_next); + if (!libafl_pc_synced) { + gen_helper_libafl_qemu_sync_pc(tcg_env, tmp_pc); + libafl_pc_synced = true; + } + + gen_helper_libafl_qemu_handle_breakpoint(tcg_env, tmp_pc); + tcg_temp_free_i64(tmp_pc); } bp = bp->next; } - libafl_gen_cur_pc = db->pc_next; - // 0x0f, 0x3a, 0xf2, 0x44 uint8_t backdoor = translator_ldub(cpu_env(cpu), db, db->pc_next); if (backdoor == 0x0f) { @@ -257,6 +269,13 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, if (backdoor == 0x44) { struct libafl_backdoor_hook* hk = libafl_backdoor_hooks; while (hk) { + if (!libafl_pc_synced) { + TCGv_i64 tmp_pc = tcg_constant_i64((uint64_t)db->pc_next); + gen_helper_libafl_qemu_sync_pc(tcg_env, tmp_pc); + libafl_pc_synced = true; + tcg_temp_free_i64(tmp_pc); + } + TCGv_i64 tmp1 = tcg_constant_i64(hk->data); #if TARGET_LONG_BITS == 32 TCGv_i32 tmp0 = tcg_constant_i32(db->pc_next); @@ -282,7 +301,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, } } } - + //// --- End LibAFL code --- /* Disassemble one instruction. The translate_insn hook should @@ -296,6 +315,12 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, ops->translate_insn(db, cpu); post_translate_insn: + //// --- Begin LibAFL code --- + + libafl_gen_cur_pc = 0; + + //// --- End LibAFL code --- + /* * We can't instrument after instructions that change control * flow although this only really affects post-load operations.