diff --git a/Makefile b/Makefile index 7d73782..fb3ccfd 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,10 @@ AR = llvm-ar LDFLAGS := -fsanitize=address ${LDFLAGS} endif +ifeq ($(UNICORN_AFL),yes) +UNICORN_CFLAGS += -DUNICORN_AFL +endif + ifeq ($(CROSS),) CC ?= cc AR ?= ar diff --git a/config.mk b/config.mk index c3621fb..c7b4f7e 100644 --- a/config.mk +++ b/config.mk @@ -8,7 +8,7 @@ # Compile with debug info when you want to debug code. # Change this to 'no' for release edition. -UNICORN_DEBUG ?= yes +UNICORN_DEBUG ?= no ################################################################################ # Specify which archs you want to compile in. By default, we build all archs. @@ -28,3 +28,9 @@ UNICORN_STATIC ?= yes # a shared library. UNICORN_SHARED ?= yes + + +################################################################################ +# Changing 'UNICORN_AFLL = yes' to 'UNICORN_AFL = no' disables AFL instrumentation + +UNICORN_AFL ?= yes diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c index 7755adf..8114b70 100644 --- a/qemu/cpu-exec.c +++ b/qemu/cpu-exec.c @@ -24,6 +24,11 @@ #include "uc_priv.h" +#if defined(UNICORN_AFL) +#include "../afl-unicorn-cpu-inl.h" +static int afl_first_instr = 0; +#endif + static tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr); static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc, target_ulong cs_base, uint64_t flags); @@ -231,6 +236,10 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq next_tb & TB_EXIT_MASK, tb); } +#if defined(UNICORN_AFL) + AFL_UNICORN_CPU_SNIPPET2; +#endif + /* cpu_interrupt might be called while translating the TB, but before it is linked into a potentially infinite loop and becomes env->current_tb. Avoid @@ -369,6 +378,11 @@ static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc, not_found: /* if no translated code available, then translate it now */ tb = tb_gen_code(cpu, pc, cs_base, (int)flags, 0); // qq + +#if defined(UNICORN_AFL) + /* There seems to be no chaining in unicorn ever? :( */ + AFL_UNICORN_CPU_SNIPPET1; +#endif found: /* Move the last found TB to the head of the list */ diff --git a/qemu/translate-all.c b/qemu/translate-all.c index 1a96c34..7ef4878 100644 --- a/qemu/translate-all.c +++ b/qemu/translate-all.c @@ -403,11 +403,25 @@ static PageDesc *page_find_alloc(struct uc_struct *uc, tb_page_addr_t index, int #if defined(CONFIG_USER_ONLY) /* We can't use g_malloc because it may recurse into a locked mutex. */ +#if defined(UNICORN_AFL) + /* This was added by unicorn-afl to bail out semi-gracefully if out of memory. */ +# define ALLOC(P, SIZE) \ + do { \ + void* _tmp = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ + if (_tmp == (void*)-1) { \ + qemu_log(">>> Out of memory for stack, bailing out. <<<\n"); \ + exit(1); \ + } \ + (P) = _tmp; \ + } while (0) +#else /* !UNICORN_AFL */ # define ALLOC(P, SIZE) \ do { \ P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ } while (0) +#endif /* UNICORN_AFL */ #else # define ALLOC(P, SIZE) \ do { P = g_malloc0(SIZE); } while (0)