diff options
-rwxr-xr-x | qemu_mode/build_qemu_support.sh | 1 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-common.h | 10 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-translate-inl.h | 119 | ||||
-rw-r--r-- | qemu_mode/patches/arm-translate-a64.diff | 64 | ||||
-rw-r--r-- | qemu_mode/patches/arm-translate.diff | 20 | ||||
-rw-r--r-- | qemu_mode/patches/i386-translate.diff | 2 |
6 files changed, 183 insertions, 33 deletions
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 0413228c..79993ce2 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -153,6 +153,7 @@ patch -p1 <../patches/translate-all.diff || exit 1 patch -p1 <../patches/tcg.diff || exit 1 patch -p1 <../patches/i386-translate.diff || exit 1 patch -p1 <../patches/arm-translate.diff || exit 1 +patch -p1 <../patches/arm-translate-a64.diff || exit 1 patch -p1 <../patches/i386-ops_sse.diff || exit 1 patch -p1 <../patches/i386-fpu_helper.diff || exit 1 patch -p1 <../patches/softfloat.diff || exit 1 diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h index da3d563e..4303a5e6 100644 --- a/qemu_mode/patches/afl-qemu-common.h +++ b/qemu_mode/patches/afl-qemu-common.h @@ -39,10 +39,14 @@ #define PERSISTENT_DEFAULT_MAX_CNT 1000 -#ifndef CPU_NB_REGS -#define AFL_REGS_NUM 1000 -#else +#ifdef CPU_NB_REGS #define AFL_REGS_NUM CPU_NB_REGS +#elif TARGET_ARM +#define AFL_REGS_NUM 32 +#elif TARGET_AARCH64 +#define AFL_REGS_NUM 32 +#else +#define AFL_REGS_NUM 100 #endif /* NeverZero */ diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h index 06e73831..2b9472b8 100644 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h @@ -67,7 +67,7 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1, target_ulong arg2) { register uintptr_t idx = cur_loc; - + if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) { INC_AFL_AREA(idx + 6); @@ -258,63 +258,72 @@ static void callback_to_persistent_hook(void) { } -static void i386_restore_state_for_persistent(TCGv *cpu_regs) { +static void gpr_saving(TCGv *cpu_regs, int regs_num) { - if (persistent_save_gpr) { + int i; + TCGv_ptr gpr_sv; - int i; - TCGv_ptr gpr_sv; + TCGv_ptr first_pass_ptr = tcg_const_ptr(&persistent_first_pass); + TCGv first_pass = tcg_temp_local_new(); + TCGv one = tcg_const_tl(1); + tcg_gen_ld8u_tl(first_pass, first_pass_ptr, 0); - TCGv_ptr first_pass_ptr = tcg_const_ptr(&persistent_first_pass); - TCGv first_pass = tcg_temp_local_new(); - TCGv one = tcg_const_tl(1); - tcg_gen_ld8u_tl(first_pass, first_pass_ptr, 0); + TCGLabel *lbl_restore_gpr = gen_new_label(); + tcg_gen_brcond_tl(TCG_COND_NE, first_pass, one, lbl_restore_gpr); - TCGLabel *lbl_restore_gpr = gen_new_label(); - tcg_gen_brcond_tl(TCG_COND_NE, first_pass, one, lbl_restore_gpr); + // save GPR registers + for (i = 0; i < regs_num; ++i) { - // save GRP registers - for (i = 0; i < AFL_REGS_NUM; ++i) { + gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); + tcg_gen_st_tl(cpu_regs[i], gpr_sv, 0); - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); - tcg_gen_st_tl(cpu_regs[i], gpr_sv, 0); + } - } + gen_set_label(lbl_restore_gpr); - gen_set_label(lbl_restore_gpr); + tcg_gen_afl_call0(&afl_persistent_loop); - tcg_gen_afl_call0(&afl_persistent_loop); + if (afl_persistent_hook_ptr) tcg_gen_afl_call0(callback_to_persistent_hook); - if (afl_persistent_hook_ptr) tcg_gen_afl_call0(callback_to_persistent_hook); + // restore GPR registers + for (i = 0; i < regs_num; ++i) { - // restore GRP registers - for (i = 0; i < AFL_REGS_NUM; ++i) { + gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); + tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); - tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); + } - } + tcg_temp_free_ptr(first_pass_ptr); + tcg_temp_free(first_pass); + tcg_temp_free(one); - tcg_temp_free(first_pass); +} + + +static void restore_state_for_persistent(TCGv *cpu_regs, int regs_num, int sp) { + + if (persistent_save_gpr) { + + gpr_saving(cpu_regs, regs_num); } else if (afl_persistent_ret_addr == 0) { TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); TCGv stack_off = tcg_temp_new(); tcg_gen_ld_tl(stack_off, stack_off_ptr, 0); - tcg_gen_sub_tl(cpu_regs[R_ESP], cpu_regs[R_ESP], stack_off); + tcg_gen_sub_tl(cpu_regs[sp], cpu_regs[sp], stack_off); tcg_temp_free(stack_off); } } -#define AFL_QEMU_TARGET_i386_SNIPPET \ +#define AFL_QEMU_TARGET_I386_SNIPPET \ if (is_persistent) { \ \ if (s->pc == afl_persistent_addr) { \ \ - i386_restore_state_for_persistent(cpu_regs); \ + restore_state_for_persistent(cpu_regs, AFL_REGS_NUM, R_ESP); \ /*tcg_gen_afl_call0(log_x86_saved_gpr); \ tcg_gen_afl_call0(log_x86_sp_content);*/ \ \ @@ -322,6 +331,7 @@ static void i386_restore_state_for_persistent(TCGv *cpu_regs) { \ TCGv_ptr paddr = tcg_const_ptr(afl_persistent_addr); \ tcg_gen_st_tl(paddr, cpu_regs[R_ESP], persisent_retaddr_offset); \ + tcg_temp_free_ptr(paddr); \ \ } \ \ @@ -337,3 +347,56 @@ static void i386_restore_state_for_persistent(TCGv *cpu_regs) { \ } +// SP = 13, LINK = 14 + +#define AFL_QEMU_TARGET_ARM_SNIPPET \ + if (is_persistent) { \ + \ + if (dc->pc == afl_persistent_addr) { \ + \ + if (persistent_save_gpr) gpr_saving(cpu_R, AFL_REGS_NUM); \ + \ + if (afl_persistent_ret_addr == 0) { \ + \ + TCGv_ptr paddr = tcg_const_ptr(afl_persistent_addr); \ + tcg_gen_mov_i32(cpu_R[14], paddr); \ + tcg_temp_free_ptr(paddr); \ + \ + } \ + \ + if (!persistent_save_gpr) tcg_gen_afl_call0(&afl_persistent_loop); \ + \ + } else if (afl_persistent_ret_addr && dc->pc == afl_persistent_ret_addr) {\ + \ + gen_bx_im(dc, afl_persistent_addr); \ + \ + } \ + \ + } + +// SP = 31, LINK = 30 + +#define AFL_QEMU_TARGET_ARM64_SNIPPET \ + if (is_persistent) { \ + \ + if (s->pc == afl_persistent_addr) { \ + \ + if (persistent_save_gpr) gpr_saving(cpu_X, AFL_REGS_NUM); \ + \ + if (afl_persistent_ret_addr == 0) { \ + \ + TCGv_ptr paddr = tcg_const_ptr(afl_persistent_addr); \ + tcg_gen_mov_i32(cpu_X[30], paddr); \ + tcg_temp_free_ptr(paddr); \ + \ + } \ + \ + if (!persistent_save_gpr) tcg_gen_afl_call0(&afl_persistent_loop); \ + \ + } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ + \ + gen_goto_tb(s, 0, afl_persistent_addr); \ + \ + } \ + \ + } diff --git a/qemu_mode/patches/arm-translate-a64.diff b/qemu_mode/patches/arm-translate-a64.diff new file mode 100644 index 00000000..83856217 --- /dev/null +++ b/qemu_mode/patches/arm-translate-a64.diff @@ -0,0 +1,64 @@ +diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c +index fd36425..992bf17 100644 +--- a/target/arm/translate-a64.c ++++ b/target/arm/translate-a64.c +@@ -39,6 +39,8 @@ + #include "translate-a64.h" + #include "qemu/atomic128.h" + ++#include "../patches/afl-qemu-cpu-translate-inl.h" ++ + static TCGv_i64 cpu_X[32]; + static TCGv_i64 cpu_pc; + +@@ -3365,6 +3367,12 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t insn) + return; + } + ++ if (rd == 31 && sub_op) { // cmp xX, imm ++ TCGv_i64 tcg_imm = tcg_const_i64(imm); ++ afl_gen_compcov(s->pc, tcg_rn, tcg_imm, is_64bit ? MO_64 : MO_32, 1); ++ tcg_temp_free_i64(tcg_imm); ++ } ++ + tcg_result = tcg_temp_new_i64(); + if (!setflags) { + if (sub_op) { +@@ -3972,6 +3980,9 @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) + + tcg_rm = read_cpu_reg(s, rm, sf); + ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3); ++ ++ if (rd == 31 && sub_op) // cmp xX, xY ++ afl_gen_compcov(s->pc, tcg_rn, tcg_rm, sf ? MO_64 : MO_32, 0); + + tcg_result = tcg_temp_new_i64(); + +@@ -4037,6 +4048,9 @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn) + + shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6); + ++ if (rd == 31 && sub_op) // cmp xX, xY ++ afl_gen_compcov(s->pc, tcg_rn, tcg_rm, sf ? MO_64 : MO_32, 0); ++ + tcg_result = tcg_temp_new_i64(); + + if (!setflags) { +@@ -4246,6 +4260,8 @@ static void disas_cc(DisasContext *s, uint32_t insn) + tcg_y = cpu_reg(s, y); + } + tcg_rn = cpu_reg(s, rn); ++ ++ afl_gen_compcov(s->pc, tcg_rn, tcg_y, sf ? MO_64 : MO_32, is_imm); + + /* Set the flags for the new comparison. */ + tcg_tmp = tcg_temp_new_i64(); +@@ -13317,6 +13333,8 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) + static void disas_a64_insn(CPUARMState *env, DisasContext *s) + { + uint32_t insn; ++ ++ AFL_QEMU_TARGET_ARM64_SNIPPET + + insn = arm_ldl_code(env, s->pc, s->sctlr_b); + s->insn = insn; diff --git a/qemu_mode/patches/arm-translate.diff b/qemu_mode/patches/arm-translate.diff index 58b4a873..daa5d43b 100644 --- a/qemu_mode/patches/arm-translate.diff +++ b/qemu_mode/patches/arm-translate.diff @@ -1,5 +1,5 @@ diff --git a/target/arm/translate.c b/target/arm/translate.c -index 7c4675ff..0f0928b6 100644 +index 7c4675f..e3d999a 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -59,6 +59,8 @@ @@ -132,3 +132,21 @@ index 7c4675ff..0f0928b6 100644 rd = 16; break; case 0xb: /* cmn */ +@@ -13233,6 +13247,8 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) + return; + } + ++ AFL_QEMU_TARGET_ARM_SNIPPET ++ + insn = arm_ldl_code(env, dc->pc, dc->sctlr_b); + dc->insn = insn; + dc->pc += 4; +@@ -13301,6 +13317,8 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) + return; + } + ++ AFL_QEMU_TARGET_ARM_SNIPPET ++ + insn = arm_lduw_code(env, dc->pc, dc->sctlr_b); + is_16bit = thumb_insn_is_16bit(dc, insn); + dc->pc += 2; diff --git a/qemu_mode/patches/i386-translate.diff b/qemu_mode/patches/i386-translate.diff index 00337e2c..8ccd6f4e 100644 --- a/qemu_mode/patches/i386-translate.diff +++ b/qemu_mode/patches/i386-translate.diff @@ -35,7 +35,7 @@ index 0dd5fbe4..a23da128 100644 rex_w = -1; rex_r = 0; -+ AFL_QEMU_TARGET_i386_SNIPPET ++ AFL_QEMU_TARGET_I386_SNIPPET + next_byte: b = x86_ldub_code(env, s); |