Initial import unicornafl

This commit is contained in:
2021-10-25 00:51:16 +02:00
parent 91451aa2f5
commit dd7476a9bd
42 changed files with 2269 additions and 1 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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");