Initial import unicornafl
This commit is contained in:
@@ -29,6 +29,10 @@
|
||||
#include "sysemu/cpus.h"
|
||||
#include "uc_priv.h"
|
||||
|
||||
#ifdef UNICORN_HAS_AFL
|
||||
#include "afl/afl-cpu-inl.h"
|
||||
#endif
|
||||
|
||||
/* -icount align implementation. */
|
||||
|
||||
typedef struct SyncClocks {
|
||||
@@ -254,6 +258,11 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
|
||||
/* We add the TB in the virtual pc hash table for the fast lookup */
|
||||
cpu->tb_jmp_cache[tb_jmp_cache_hash_func(cpu->uc, pc)] = tb;
|
||||
}
|
||||
|
||||
#if defined(UNICORN_HAS_AFL)
|
||||
afl_request_tsl(cpu, pc, cs_base, flags, cf_mask);
|
||||
#endif
|
||||
|
||||
/* We don't take care of direct jumps when address mapping changes in
|
||||
* system emulation. So it's not safe to make a direct jump to a TB
|
||||
* spanning two pages because the mapping for the second page can change.
|
||||
@@ -579,3 +588,31 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef UNICORN_HAS_AFL
|
||||
int afl_forkserver_start(struct uc_struct *uc)
|
||||
{
|
||||
// Not sure if we need all of this setup foo.
|
||||
CPUState *cpu = uc->cpu;
|
||||
if (!cpu->created) {
|
||||
cpu->created = true;
|
||||
cpu->halted = 0;
|
||||
qemu_init_vcpu(cpu);
|
||||
|
||||
}
|
||||
cpu_resume(cpu);
|
||||
|
||||
if (uc->count_hook != 0) {
|
||||
uc_hook_del(uc, uc->count_hook);
|
||||
uc->count_hook = 0;
|
||||
}
|
||||
|
||||
uc->quit_request = false;
|
||||
uc->cpu = cpu;
|
||||
smp_mb();
|
||||
|
||||
// Would love to not have the extra step in cpus.c, but it doesn't work otherwise(?)
|
||||
afl_setup(uc);
|
||||
return afl_forkserver(cpu);
|
||||
}
|
||||
#endif
|
||||
@@ -32,6 +32,10 @@
|
||||
|
||||
#include <uc_priv.h>
|
||||
|
||||
#ifdef UNICORN_HAS_AFL
|
||||
#include "afl/afl-tcg-runtime-inl.h"
|
||||
#endif
|
||||
|
||||
/* 32-bit helpers */
|
||||
|
||||
int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2)
|
||||
|
||||
@@ -259,3 +259,10 @@ DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
#if defined(UNICORN_HAS_AFL)
|
||||
DEF_HELPER_FLAGS_2(afl_maybe_log, 0, void, ptr, i64)
|
||||
DEF_HELPER_FLAGS_4(afl_compcov_log_16, 0, void, ptr, i64, i32, i32)
|
||||
DEF_HELPER_FLAGS_4(afl_compcov_log_32, 0, void, ptr, i64, i32, i32)
|
||||
DEF_HELPER_FLAGS_4(afl_compcov_log_64, 0, void, ptr, i64, i64, i64)
|
||||
#endif
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
#include <uc_priv.h>
|
||||
|
||||
#if defined(UNICORN_HAS_AFL)
|
||||
#undef ARCH_HAS_COMPCOV
|
||||
#include "afl/afl-cpu-translate-inl.h"
|
||||
#endif
|
||||
|
||||
/* Pairs with tcg_clear_temp_count.
|
||||
To be called by #TranslatorOps.{translate_insn,tb_stop} if
|
||||
(1) the target is sufficiently clean to support reporting,
|
||||
@@ -56,6 +61,27 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||
/* Reset the temp count so that we can identify leaks */
|
||||
tcg_clear_temp_count();
|
||||
|
||||
if (uc->mode & UC_MODE_AFL) {
|
||||
// UNICORN-AFL supports (and needs) multiple exits.
|
||||
uint64_t *exits = cpu->uc->exits;
|
||||
size_t exit_count = cpu->uc->exit_count;
|
||||
if (exit_count) {
|
||||
size_t i;
|
||||
for (i = 0; i < exit_count; i++) {
|
||||
if (tb->pc == exits[i]) {
|
||||
// This should catch that instruction is at the end
|
||||
// and generate appropriate halting code.
|
||||
gen_tb_start(tcg_ctx, db->tb);
|
||||
ops->tb_start(db, cpu);
|
||||
db->num_insns++;
|
||||
ops->insn_start(db, cpu);
|
||||
ops->translate_insn(db, cpu);
|
||||
goto _end_loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Unicorn: early check to see if the address of this block is
|
||||
* the "run until" address. */
|
||||
if (tb->pc == cpu->uc->addr_end) {
|
||||
@@ -81,6 +107,10 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||
|
||||
// tcg_dump_ops(tcg_ctx, false, "translator loop");
|
||||
|
||||
#ifdef UNICORN_HAS_AFL
|
||||
afl_gen_maybe_log(tcg_ctx, tb->pc);
|
||||
#endif
|
||||
|
||||
/* Start translating. */
|
||||
gen_tb_start(tcg_ctx, db->tb);
|
||||
// tcg_dump_ops(tcg_ctx, false, "tb start");
|
||||
|
||||
Reference in New Issue
Block a user