aboutsummaryrefslogtreecommitdiff
path: root/qemu_mode
diff options
context:
space:
mode:
authorAndrea Fioraldi <andreafioraldi@gmail.com>2020-02-08 18:07:31 +0100
committerAndrea Fioraldi <andreafioraldi@gmail.com>2020-02-08 18:07:31 +0100
commit5fa4f47baec7e3dc78e685f9f8a44bf34c3eba53 (patch)
tree272dbbc6a08595048a1ff081b46bc83e42663bad /qemu_mode
parent0403f008e3c68a9b212d38a5fc0de79eb2f40895 (diff)
downloadafl++-5fa4f47baec7e3dc78e685f9f8a44bf34c3eba53.tar.gz
persistent qemu mode arm/arm64 && compcov arm64
Diffstat (limited to 'qemu_mode')
-rwxr-xr-xqemu_mode/build_qemu_support.sh1
-rw-r--r--qemu_mode/patches/afl-qemu-common.h10
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-translate-inl.h119
-rw-r--r--qemu_mode/patches/arm-translate-a64.diff64
-rw-r--r--qemu_mode/patches/arm-translate.diff20
-rw-r--r--qemu_mode/patches/i386-translate.diff2
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);