| diff --git a/include/uc_priv.h b/include/uc_priv.h |
| index 22f494e..1aa7b3a 100644 |
| --- a/include/uc_priv.h |
| +++ b/include/uc_priv.h |
| @@ -245,6 +245,12 @@ struct uc_struct { |
| uint32_t target_page_align; |
| uint64_t next_pc; // save next PC for some special cases |
| bool hook_insert; // insert new hook at begin of the hook list (append by default) |
| + |
| +#ifdef UNICORN_AFL |
| + unsigned char *afl_area_ptr; |
| + int afl_compcov_level; |
| + unsigned int afl_inst_rms; |
| +#endif |
| }; |
| |
| // Metadata stub for the variable-size cpu context used with uc_context_*() |
| diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c |
| index 4995eda..06c7e63 100644 |
| --- a/qemu/target-arm/translate.c |
| +++ b/qemu/target-arm/translate.c |
| @@ -63,6 +63,12 @@ static TCGv_i64 cpu_exclusive_test; |
| static TCGv_i32 cpu_exclusive_info; |
| #endif |
| |
| +#if defined(UNICORN_AFL) |
| +#include "../../afl-unicorn-cpu-translate-inl.h" |
| +#else |
| +#define afl_gen_compcov(a,b,c,d,e,f) do {} while (0) |
| +#endif |
| + |
| |
| static const char *regnames[] = |
| { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
| @@ -8214,6 +8220,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq |
| } else { |
| if (set_cc) { |
| gen_sub_CC(s, tmp, tmp, tmp2); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); |
| } else { |
| tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); |
| } |
| @@ -8223,6 +8230,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq |
| case 0x03: |
| if (set_cc) { |
| gen_sub_CC(s, tmp, tmp2, tmp); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); |
| } else { |
| tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp); |
| } |
| @@ -8277,6 +8285,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq |
| case 0x0a: |
| if (set_cc) { |
| gen_sub_CC(s, tmp, tmp, tmp2); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); |
| } |
| tcg_temp_free_i32(tcg_ctx, tmp); |
| break; |
| @@ -9148,7 +9157,7 @@ thumb2_logic_op(int op) |
| |
| static int |
| gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, |
| - TCGv_i32 t0, TCGv_i32 t1) |
| + TCGv_i32 t0, TCGv_i32 t1, int has_imm) |
| { |
| TCGContext *tcg_ctx = s->uc->tcg_ctx; |
| int logic_cc; |
| @@ -9195,15 +9204,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, |
| } |
| break; |
| case 13: /* sub */ |
| - if (conds) |
| + if (conds) { |
| gen_sub_CC(s, t0, t0, t1); |
| - else |
| + afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm); |
| + } else |
| tcg_gen_sub_i32(tcg_ctx, t0, t0, t1); |
| break; |
| case 14: /* rsb */ |
| - if (conds) |
| + if (conds) { |
| gen_sub_CC(s, t0, t1, t0); |
| - else |
| + afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm); |
| + } else |
| tcg_gen_sub_i32(tcg_ctx, t0, t1, t0); |
| break; |
| default: /* 5, 6, 7, 9, 12, 15. */ |
| @@ -9572,7 +9583,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw |
| conds = (insn & (1 << 20)) != 0; |
| logic_cc = (conds && thumb2_logic_op(op)); |
| gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc); |
| - if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) |
| + if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2, insn & (1 << 10))) |
| goto illegal_op; |
| tcg_temp_free_i32(tcg_ctx, tmp2); |
| if (rd != 15) { |
| @@ -10215,7 +10226,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw |
| } |
| op = (insn >> 21) & 0xf; |
| if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, |
| - shifter_out, tmp, tmp2)) |
| + shifter_out, tmp, tmp2, insn & (1 << 10))) |
| goto illegal_op; |
| tcg_temp_free_i32(tcg_ctx, tmp2); |
| rd = (insn >> 8) & 0xf; |
| @@ -10471,8 +10482,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq |
| if (insn & (1 << 9)) { |
| if (s->condexec_mask) |
| tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); |
| - else |
| + else { |
| gen_sub_CC(s, tmp, tmp, tmp2); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 10)); |
| + } |
| } else { |
| if (s->condexec_mask) |
| tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2); |
| @@ -10509,6 +10522,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq |
| switch (op) { |
| case 1: /* cmp */ |
| gen_sub_CC(s, tmp, tmp, tmp2); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1); |
| tcg_temp_free_i32(tcg_ctx, tmp); |
| tcg_temp_free_i32(tcg_ctx, tmp2); |
| break; |
| @@ -10523,8 +10537,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq |
| case 3: /* sub */ |
| if (s->condexec_mask) |
| tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); |
| - else |
| + else { |
| gen_sub_CC(s, tmp, tmp, tmp2); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1); |
| + } |
| tcg_temp_free_i32(tcg_ctx, tmp2); |
| store_reg(s, rd, tmp); |
| break; |
| @@ -10562,6 +10578,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq |
| tmp = load_reg(s, rd); |
| tmp2 = load_reg(s, rm); |
| gen_sub_CC(s, tmp, tmp, tmp2); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0); |
| tcg_temp_free_i32(tcg_ctx, tmp2); |
| tcg_temp_free_i32(tcg_ctx, tmp); |
| break; |
| @@ -10680,6 +10697,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq |
| break; |
| case 0xa: /* cmp */ |
| gen_sub_CC(s, tmp, tmp, tmp2); |
| + afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0); |
| rd = 16; |
| break; |
| case 0xb: /* cmn */ |
| diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c |
| index 36fae09..196d346 100644 |
| --- a/qemu/target-i386/translate.c |
| +++ b/qemu/target-i386/translate.c |
| @@ -33,6 +33,12 @@ |
| |
| #include "uc_priv.h" |
| |
| +#if defined(UNICORN_AFL) |
| +#include "../../afl-unicorn-cpu-translate-inl.h" |
| +#else |
| +#define afl_gen_compcov(a,b,c,d,e,f) do {} while (0) |
| +#endif |
| + |
| #define PREFIX_REPZ 0x01 |
| #define PREFIX_REPNZ 0x02 |
| #define PREFIX_LOCK 0x04 |
| @@ -1555,6 +1561,7 @@ static void gen_op(DisasContext *s, int op, TCGMemOp ot, int d) |
| case OP_SUBL: |
| tcg_gen_mov_tl(tcg_ctx, cpu_cc_srcT, *cpu_T[0]); |
| tcg_gen_sub_tl(tcg_ctx, *cpu_T[0], *cpu_T[0], *cpu_T[1]); |
| + afl_gen_compcov(tcg_ctx, s->pc, *cpu_T[0], *cpu_T[1], ot, d == OR_EAX); |
| gen_op_st_rm_T0_A0(s, ot, d); |
| gen_op_update2_cc(tcg_ctx); |
| set_cc_op(s, CC_OP_SUBB + ot); |
| @@ -1582,6 +1589,7 @@ static void gen_op(DisasContext *s, int op, TCGMemOp ot, int d) |
| tcg_gen_mov_tl(tcg_ctx, cpu_cc_src, *cpu_T[1]); |
| tcg_gen_mov_tl(tcg_ctx, cpu_cc_srcT, *cpu_T[0]); |
| tcg_gen_sub_tl(tcg_ctx, cpu_cc_dst, *cpu_T[0], *cpu_T[1]); |
| + afl_gen_compcov(tcg_ctx, s->pc, *cpu_T[0], *cpu_T[1], ot, d == OR_EAX); |
| set_cc_op(s, CC_OP_SUBB + ot); |
| break; |
| } |
| diff --git a/qemu/tcg-runtime.c b/qemu/tcg-runtime.c |
| index 21b022a..14d7891 100644 |
| --- a/qemu/tcg-runtime.c |
| +++ b/qemu/tcg-runtime.c |
| @@ -31,9 +31,14 @@ |
| |
| #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ |
| dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)); |
| +#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ |
| + dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), dh_ctype(t4)); |
| |
| #include "tcg-runtime.h" |
| |
| +#ifdef UNICORN_AFL |
| +#include "../afl-unicorn-tcg-runtime-inl.h" |
| +#endif |
| |
| /* 32-bit helpers */ |
| |
| diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h |
| index 38b7dd9..c5a9af9 100644 |
| --- a/qemu/tcg/tcg-op.h |
| +++ b/qemu/tcg/tcg-op.h |
| @@ -27,6 +27,10 @@ |
| |
| int gen_new_label(TCGContext *); |
| |
| +#ifdef UNICORN_AFL |
| +#include "../../afl-unicorn-tcg-op-inl.h" |
| +#endif |
| + |
| static inline void gen_uc_tracecode(TCGContext *tcg_ctx, int32_t size, int32_t type, void *uc, uint64_t pc) |
| { |
| TCGv_i32 tsize = tcg_const_i32(tcg_ctx, size); |
| diff --git a/qemu/tcg/tcg-runtime.h b/qemu/tcg/tcg-runtime.h |
| index 23a0c37..90b993c 100644 |
| --- a/qemu/tcg/tcg-runtime.h |
| +++ b/qemu/tcg/tcg-runtime.h |
| @@ -14,3 +14,9 @@ DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) |
| |
| DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) |
| DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) |
| + |
| +#ifdef UNICORN_AFL |
| +DEF_HELPER_FLAGS_4(afl_compcov_log_16, 0, void, ptr, i64, i64, i64) |
| +DEF_HELPER_FLAGS_4(afl_compcov_log_32, 0, void, ptr, i64, i64, i64) |
| +DEF_HELPER_FLAGS_4(afl_compcov_log_64, 0, void, ptr, i64, i64, i64) |
| +#endif |
| diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h |
| index 8dcbb3e..11e18b4 100644 |
| --- a/qemu/unicorn_common.h |
| +++ b/qemu/unicorn_common.h |
| @@ -84,6 +84,10 @@ static inline void uc_common_init(struct uc_struct* uc) |
| |
| if (!uc->release) |
| uc->release = release_common; |
| + |
| +#ifdef UNICORN_AFL |
| + uc->afl_area_ptr = 0; |
| +#endif |
| } |
| |
| #endif |