mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-16 03:48:08 +00:00
first version of persistent QEMU
This commit is contained in:
@ -112,16 +112,19 @@
|
|||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
\
|
||||||
if (_p) { \
|
if (_p) { \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
\
|
||||||
if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\
|
if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
\
|
||||||
if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \
|
if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \
|
||||||
ABORT("Use after free."); \
|
ABORT("Use after free."); \
|
||||||
else ABORT("Corrupted head alloc canary."); \
|
else ABORT("Corrupted head alloc canary."); \
|
||||||
@ -130,6 +133,7 @@
|
|||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
\
|
||||||
if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \
|
if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \
|
||||||
ABORT("Corrupted tail alloc canary."); \
|
ABORT("Corrupted tail alloc canary."); \
|
||||||
\
|
\
|
||||||
@ -139,6 +143,7 @@
|
|||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -47,3 +47,24 @@
|
|||||||
#define INC_AFL_AREA(loc) afl_area_ptr[loc]++
|
#define INC_AFL_AREA(loc) afl_area_ptr[loc]++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Declared in afl-qemu-cpu-inl.h */
|
||||||
|
|
||||||
|
extern unsigned char *afl_area_ptr;
|
||||||
|
extern unsigned int afl_inst_rms;
|
||||||
|
extern abi_ulong afl_start_code, afl_end_code;
|
||||||
|
extern abi_ulong afl_persistent_addr;
|
||||||
|
extern abi_ulong afl_persistent_ret_addr;
|
||||||
|
extern u8 afl_compcov_level;
|
||||||
|
extern unsigned char afl_fork_child;
|
||||||
|
extern unsigned char is_persistent;
|
||||||
|
|
||||||
|
extern __thread abi_ulong afl_prev_loc;
|
||||||
|
|
||||||
|
void afl_persistent_loop();
|
||||||
|
|
||||||
|
void tcg_gen_afl_call0(void *func);
|
||||||
|
void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc,
|
||||||
|
TCGv_i64 arg1, TCGv_i64 arg2);
|
||||||
|
|
||||||
|
void tcg_gen_afl_maybe_log_call(target_ulong cur_loc);
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#include "../../config.h"
|
#include "../../config.h"
|
||||||
|
|
||||||
|
#define PERSISTENT_DEFAULT_MAX_CNT 1000
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
* VARIOUS AUXILIARY STUFF *
|
* VARIOUS AUXILIARY STUFF *
|
||||||
***************************/
|
***************************/
|
||||||
@ -71,13 +73,19 @@ abi_ulong afl_entry_point, /* ELF entry point (_start) */
|
|||||||
afl_start_code, /* .text start pointer */
|
afl_start_code, /* .text start pointer */
|
||||||
afl_end_code; /* .text end pointer */
|
afl_end_code; /* .text end pointer */
|
||||||
|
|
||||||
|
abi_ulong afl_persistent_addr, afl_persistent_ret_addr;
|
||||||
|
unsigned int afl_persistent_cnt;
|
||||||
|
|
||||||
u8 afl_compcov_level;
|
u8 afl_compcov_level;
|
||||||
|
|
||||||
|
__thread abi_ulong afl_prev_loc;
|
||||||
|
|
||||||
/* Set in the child process in forkserver mode: */
|
/* Set in the child process in forkserver mode: */
|
||||||
|
|
||||||
static int forkserver_installed = 0;
|
static int forkserver_installed = 0;
|
||||||
static unsigned char afl_fork_child;
|
unsigned char afl_fork_child;
|
||||||
unsigned int afl_forksrv_pid;
|
unsigned int afl_forksrv_pid;
|
||||||
|
unsigned char is_persistent;
|
||||||
|
|
||||||
/* Instrumentation ratio: */
|
/* Instrumentation ratio: */
|
||||||
|
|
||||||
@ -187,6 +195,22 @@ static void afl_setup(void) {
|
|||||||
|
|
||||||
rcu_disable_atfork();
|
rcu_disable_atfork();
|
||||||
|
|
||||||
|
is_persistent = getenv("AFL_QEMU_PERSISTENT_ADDR") != NULL;
|
||||||
|
|
||||||
|
if (is_persistent) {
|
||||||
|
|
||||||
|
afl_persistent_addr = strtoll(getenv("AFL_QEMU_PERSISTENT_ADDR"), NULL, 16);
|
||||||
|
if (getenv("AFL_QEMU_PERSISTENT_RET") == NULL) exit(1);
|
||||||
|
afl_persistent_ret_addr =
|
||||||
|
strtoll(getenv("AFL_QEMU_PERSISTENT_RET"), NULL, 16);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getenv("AFL_QEMU_PERSISTENT_CNT"))
|
||||||
|
afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 16);
|
||||||
|
else
|
||||||
|
afl_persistent_cnt = PERSISTENT_DEFAULT_MAX_CNT;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fork server logic, invoked once we hit _start. */
|
/* Fork server logic, invoked once we hit _start. */
|
||||||
@ -197,8 +221,13 @@ static void afl_forkserver(CPUState *cpu) {
|
|||||||
|
|
||||||
if (forkserver_installed == 1) return;
|
if (forkserver_installed == 1) return;
|
||||||
forkserver_installed = 1;
|
forkserver_installed = 1;
|
||||||
|
|
||||||
// if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer
|
// if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer
|
||||||
|
|
||||||
|
pid_t child_pid;
|
||||||
|
int t_fd[2];
|
||||||
|
u8 child_stopped = 0;
|
||||||
|
|
||||||
/* Tell the parent that we're alive. If the parent doesn't want
|
/* Tell the parent that we're alive. If the parent doesn't want
|
||||||
to talk, assume that we're not running in forkserver mode. */
|
to talk, assume that we're not running in forkserver mode. */
|
||||||
|
|
||||||
@ -210,12 +239,25 @@ static void afl_forkserver(CPUState *cpu) {
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
pid_t child_pid;
|
int status;
|
||||||
int status, t_fd[2];
|
u32 was_killed;
|
||||||
|
|
||||||
/* Whoops, parent dead? */
|
/* Whoops, parent dead? */
|
||||||
|
|
||||||
if (read(FORKSRV_FD, tmp, 4) != 4) exit(2);
|
if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2);
|
||||||
|
|
||||||
|
/* If we stopped the child in persistent mode, but there was a race
|
||||||
|
condition and afl-fuzz already issued SIGKILL, write off the old
|
||||||
|
process. */
|
||||||
|
|
||||||
|
if (child_stopped && was_killed) {
|
||||||
|
|
||||||
|
child_stopped = 0;
|
||||||
|
if (waitpid(child_pid, &status, 0) < 0) exit(8);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!child_stopped) {
|
||||||
|
|
||||||
/* Establish a channel with child to grab translation commands. We'll
|
/* Establish a channel with child to grab translation commands. We'll
|
||||||
read from t_fd[0], child will write to TSL_FD. */
|
read from t_fd[0], child will write to TSL_FD. */
|
||||||
@ -242,6 +284,18 @@ static void afl_forkserver(CPUState *cpu) {
|
|||||||
|
|
||||||
close(TSL_FD);
|
close(TSL_FD);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Special handling for persistent mode: if the child is alive but
|
||||||
|
currently stopped, simply restart it with SIGCONT. */
|
||||||
|
|
||||||
|
kill(child_pid, SIGCONT);
|
||||||
|
child_stopped = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parent. */
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5);
|
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5);
|
||||||
|
|
||||||
/* Collect translation requests until child dies and closes the pipe. */
|
/* Collect translation requests until child dies and closes the pipe. */
|
||||||
@ -250,13 +304,79 @@ static void afl_forkserver(CPUState *cpu) {
|
|||||||
|
|
||||||
/* Get and relay exit status to parent. */
|
/* Get and relay exit status to parent. */
|
||||||
|
|
||||||
if (waitpid(child_pid, &status, 0) < 0) exit(6);
|
if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) exit(6);
|
||||||
|
|
||||||
|
/* In persistent mode, the child stops itself with SIGSTOP to indicate
|
||||||
|
a successful run. In this case, we want to wake it up without forking
|
||||||
|
again. */
|
||||||
|
|
||||||
|
if (WIFSTOPPED(status)) child_stopped = 1;
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7);
|
if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A simplified persistent mode handler, used as explained in README.llvm. */
|
||||||
|
|
||||||
|
void afl_persistent_loop() {
|
||||||
|
|
||||||
|
static u8 first_pass = 1;
|
||||||
|
static u32 cycle_cnt;
|
||||||
|
static struct afl_tsl exit_cmd_tsl = {{-1, 0, 0, 0}, NULL};
|
||||||
|
|
||||||
|
if (!afl_fork_child) return;
|
||||||
|
|
||||||
|
if (first_pass) {
|
||||||
|
|
||||||
|
/* Make sure that every iteration of __AFL_LOOP() starts with a clean slate.
|
||||||
|
On subsequent calls, the parent will take care of that, but on the first
|
||||||
|
iteration, it's our job to erase any trace of whatever happened
|
||||||
|
before the loop. */
|
||||||
|
|
||||||
|
if (is_persistent) {
|
||||||
|
|
||||||
|
memset(afl_area_ptr, 0, MAP_SIZE);
|
||||||
|
afl_area_ptr[0] = 1;
|
||||||
|
afl_prev_loc = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cycle_cnt = afl_persistent_cnt;
|
||||||
|
first_pass = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_persistent) {
|
||||||
|
|
||||||
|
if (--cycle_cnt) {
|
||||||
|
|
||||||
|
if (write(TSL_FD, &exit_cmd_tsl, sizeof(struct afl_tsl)) !=
|
||||||
|
sizeof(struct afl_tsl)) {
|
||||||
|
|
||||||
|
/* Exit the persistent loop on pipe error */
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
raise(SIGSTOP);
|
||||||
|
|
||||||
|
afl_area_ptr[0] = 1;
|
||||||
|
afl_prev_loc = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* This code is invoked whenever QEMU decides that it doesn't have a
|
/* This code is invoked whenever QEMU decides that it doesn't have a
|
||||||
translation of a particular block and needs to compute it, or when it
|
translation of a particular block and needs to compute it, or when it
|
||||||
decides to chain two TBs together. When this happens, we tell the parent to
|
decides to chain two TBs together. When this happens, we tell the parent to
|
||||||
@ -330,6 +450,10 @@ static void afl_wait_tsl(CPUState *cpu, int fd) {
|
|||||||
|
|
||||||
if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) break;
|
if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) break;
|
||||||
|
|
||||||
|
/* Exit command for persistent */
|
||||||
|
|
||||||
|
if (t.tb.pc == (target_ulong)(-1)) return;
|
||||||
|
|
||||||
tb = tb_htable_lookup(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags, t.tb.cf_mask);
|
tb = tb_htable_lookup(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags, t.tb.cf_mask);
|
||||||
|
|
||||||
if (!tb) {
|
if (!tb) {
|
||||||
|
@ -35,15 +35,6 @@
|
|||||||
#include "tcg.h"
|
#include "tcg.h"
|
||||||
#include "tcg-op.h"
|
#include "tcg-op.h"
|
||||||
|
|
||||||
/* Declared in afl-qemu-cpu-inl.h */
|
|
||||||
extern unsigned char *afl_area_ptr;
|
|
||||||
extern unsigned int afl_inst_rms;
|
|
||||||
extern abi_ulong afl_start_code, afl_end_code;
|
|
||||||
extern u8 afl_compcov_level;
|
|
||||||
|
|
||||||
void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc,
|
|
||||||
TCGv_i64 arg1, TCGv_i64 arg2);
|
|
||||||
|
|
||||||
static void afl_compcov_log_16(target_ulong cur_loc, target_ulong arg1,
|
static void afl_compcov_log_16(target_ulong cur_loc, target_ulong arg1,
|
||||||
target_ulong arg2) {
|
target_ulong arg2) {
|
||||||
|
|
||||||
@ -137,3 +128,21 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AFL_QEMU_TARGET_i386_SNIPPET \
|
||||||
|
if (is_persistent) { \
|
||||||
|
\
|
||||||
|
if (s->pc == afl_persistent_addr) { \
|
||||||
|
\
|
||||||
|
fprintf(stderr, " IN TRANSLATING %p!\n", s->pc); \
|
||||||
|
tcg_gen_afl_call0(&afl_persistent_loop); \
|
||||||
|
\
|
||||||
|
} else if (s->pc == afl_persistent_ret_addr) { \
|
||||||
|
\
|
||||||
|
fprintf(stderr, " IN TRANSLATING RET %p!\n", s->pc); \
|
||||||
|
gen_jmp_im(s, afl_persistent_addr); \
|
||||||
|
gen_eob(s); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -191,6 +191,186 @@ void tcg_gen_afl_maybe_log_call(target_ulong cur_loc) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: we convert the 64 bit args to 32 bit and do some alignment
|
||||||
|
and endian swap. Maybe it would be better to do the alignment
|
||||||
|
and endian swap in tcg_reg_alloc_call(). */
|
||||||
|
void tcg_gen_afl_call0(void *func) {
|
||||||
|
|
||||||
|
int i, real_args, nb_rets, pi;
|
||||||
|
unsigned sizemask, flags;
|
||||||
|
TCGOp * op;
|
||||||
|
|
||||||
|
const int nargs = 0;
|
||||||
|
TCGTemp **args;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
sizemask = dh_sizemask(void, 0);
|
||||||
|
|
||||||
|
#if defined(__sparc__) && !defined(__arch64__) && \
|
||||||
|
!defined(CONFIG_TCG_INTERPRETER)
|
||||||
|
/* We have 64-bit values in one register, but need to pass as two
|
||||||
|
separate parameters. Split them. */
|
||||||
|
int orig_sizemask = sizemask;
|
||||||
|
int orig_nargs = nargs;
|
||||||
|
TCGv_i64 retl, reth;
|
||||||
|
TCGTemp *split_args[MAX_OPC_PARAM];
|
||||||
|
|
||||||
|
retl = NULL;
|
||||||
|
reth = NULL;
|
||||||
|
if (sizemask != 0) {
|
||||||
|
|
||||||
|
for (i = real_args = 0; i < nargs; ++i) {
|
||||||
|
|
||||||
|
int is_64bit = sizemask & (1 << (i + 1) * 2);
|
||||||
|
if (is_64bit) {
|
||||||
|
|
||||||
|
TCGv_i64 orig = temp_tcgv_i64(args[i]);
|
||||||
|
TCGv_i32 h = tcg_temp_new_i32();
|
||||||
|
TCGv_i32 l = tcg_temp_new_i32();
|
||||||
|
tcg_gen_extr_i64_i32(l, h, orig);
|
||||||
|
split_args[real_args++] = tcgv_i32_temp(h);
|
||||||
|
split_args[real_args++] = tcgv_i32_temp(l);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
split_args[real_args++] = args[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
nargs = real_args;
|
||||||
|
args = split_args;
|
||||||
|
sizemask = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
|
||||||
|
for (i = 0; i < nargs; ++i) {
|
||||||
|
|
||||||
|
int is_64bit = sizemask & (1 << (i + 1) * 2);
|
||||||
|
int is_signed = sizemask & (2 << (i + 1) * 2);
|
||||||
|
if (!is_64bit) {
|
||||||
|
|
||||||
|
TCGv_i64 temp = tcg_temp_new_i64();
|
||||||
|
TCGv_i64 orig = temp_tcgv_i64(args[i]);
|
||||||
|
if (is_signed) {
|
||||||
|
|
||||||
|
tcg_gen_ext32s_i64(temp, orig);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tcg_gen_ext32u_i64(temp, orig);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
args[i] = tcgv_i64_temp(temp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TCG_TARGET_EXTEND_ARGS */
|
||||||
|
|
||||||
|
op = tcg_emit_op(INDEX_op_call);
|
||||||
|
|
||||||
|
pi = 0;
|
||||||
|
nb_rets = 0;
|
||||||
|
TCGOP_CALLO(op) = nb_rets;
|
||||||
|
|
||||||
|
real_args = 0;
|
||||||
|
for (i = 0; i < nargs; i++) {
|
||||||
|
|
||||||
|
int is_64bit = sizemask & (1 << (i + 1) * 2);
|
||||||
|
if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
|
||||||
|
|
||||||
|
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
|
||||||
|
/* some targets want aligned 64 bit args */
|
||||||
|
if (real_args & 1) {
|
||||||
|
|
||||||
|
op->args[pi++] = TCG_CALL_DUMMY_ARG;
|
||||||
|
real_args++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* If stack grows up, then we will be placing successive
|
||||||
|
arguments at lower addresses, which means we need to
|
||||||
|
reverse the order compared to how we would normally
|
||||||
|
treat either big or little-endian. For those arguments
|
||||||
|
that will wind up in registers, this still works for
|
||||||
|
HPPA (the only current STACK_GROWSUP target) since the
|
||||||
|
argument registers are *also* allocated in decreasing
|
||||||
|
order. If another such target is added, this logic may
|
||||||
|
have to get more complicated to differentiate between
|
||||||
|
stack arguments and register arguments. */
|
||||||
|
#if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
|
||||||
|
op->args[pi++] = temp_arg(args[i] + 1);
|
||||||
|
op->args[pi++] = temp_arg(args[i]);
|
||||||
|
#else
|
||||||
|
op->args[pi++] = temp_arg(args[i]);
|
||||||
|
op->args[pi++] = temp_arg(args[i] + 1);
|
||||||
|
#endif
|
||||||
|
real_args += 2;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
op->args[pi++] = temp_arg(args[i]);
|
||||||
|
real_args++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
op->args[pi++] = (uintptr_t)func;
|
||||||
|
op->args[pi++] = flags;
|
||||||
|
TCGOP_CALLI(op) = real_args;
|
||||||
|
|
||||||
|
/* Make sure the fields didn't overflow. */
|
||||||
|
tcg_debug_assert(TCGOP_CALLI(op) == real_args);
|
||||||
|
tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
|
||||||
|
|
||||||
|
#if defined(__sparc__) && !defined(__arch64__) && \
|
||||||
|
!defined(CONFIG_TCG_INTERPRETER)
|
||||||
|
/* Free all of the parts we allocated above. */
|
||||||
|
for (i = real_args = 0; i < orig_nargs; ++i) {
|
||||||
|
|
||||||
|
int is_64bit = orig_sizemask & (1 << (i + 1) * 2);
|
||||||
|
if (is_64bit) {
|
||||||
|
|
||||||
|
tcg_temp_free_internal(args[real_args++]);
|
||||||
|
tcg_temp_free_internal(args[real_args++]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
real_args++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orig_sizemask & 1) {
|
||||||
|
|
||||||
|
/* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
|
||||||
|
Note that describing these as TCGv_i64 eliminates an unnecessary
|
||||||
|
zero-extension that tcg_gen_concat_i32_i64 would create. */
|
||||||
|
tcg_gen_concat32_i64(temp_tcgv_i64(NULL), retl, reth);
|
||||||
|
tcg_temp_free_i64(retl);
|
||||||
|
tcg_temp_free_i64(reth);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
|
||||||
|
for (i = 0; i < nargs; ++i) {
|
||||||
|
|
||||||
|
int is_64bit = sizemask & (1 << (i + 1) * 2);
|
||||||
|
if (!is_64bit) { tcg_temp_free_internal(args[i]); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TCG_TARGET_EXTEND_ARGS */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc,
|
void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc,
|
||||||
TCGv_i64 arg1, TCGv_i64 arg2) {
|
TCGv_i64 arg1, TCGv_i64 arg2) {
|
||||||
|
|
||||||
|
@ -34,22 +34,13 @@
|
|||||||
#include "afl-qemu-common.h"
|
#include "afl-qemu-common.h"
|
||||||
#include "tcg-op.h"
|
#include "tcg-op.h"
|
||||||
|
|
||||||
/* Declared in afl-qemu-cpu-inl.h */
|
|
||||||
extern unsigned char *afl_area_ptr;
|
|
||||||
extern unsigned int afl_inst_rms;
|
|
||||||
extern abi_ulong afl_start_code, afl_end_code;
|
|
||||||
|
|
||||||
void tcg_gen_afl_maybe_log_call(target_ulong cur_loc);
|
|
||||||
|
|
||||||
void afl_maybe_log(target_ulong cur_loc) {
|
void afl_maybe_log(target_ulong cur_loc) {
|
||||||
|
|
||||||
static __thread abi_ulong prev_loc;
|
register uintptr_t afl_idx = cur_loc ^ afl_prev_loc;
|
||||||
|
|
||||||
register uintptr_t afl_idx = cur_loc ^ prev_loc;
|
|
||||||
|
|
||||||
INC_AFL_AREA(afl_idx);
|
INC_AFL_AREA(afl_idx);
|
||||||
|
|
||||||
prev_loc = cur_loc >> 1;
|
afl_prev_loc = cur_loc >> 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
diff --git a/target/i386/translate.c b/target/i386/translate.c
|
diff --git a/target/i386/translate.c b/target/i386/translate.c
|
||||||
index 0dd5fbe4..b95d341e 100644
|
index 0dd5fbe4..a23da128 100644
|
||||||
--- a/target/i386/translate.c
|
--- a/target/i386/translate.c
|
||||||
+++ b/target/i386/translate.c
|
+++ b/target/i386/translate.c
|
||||||
@@ -32,6 +32,8 @@
|
@@ -32,6 +32,8 @@
|
||||||
@ -31,3 +31,12 @@ index 0dd5fbe4..b95d341e 100644
|
|||||||
set_cc_op(s1, CC_OP_SUBB + ot);
|
set_cc_op(s1, CC_OP_SUBB + ot);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -4508,6 +4513,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||||
|
rex_w = -1;
|
||||||
|
rex_r = 0;
|
||||||
|
|
||||||
|
+ AFL_QEMU_TARGET_i386_SNIPPET
|
||||||
|
+
|
||||||
|
next_byte:
|
||||||
|
b = x86_ldub_code(env, s);
|
||||||
|
/* Collect prefixes. */
|
||||||
|
@ -2288,13 +2288,14 @@ abandon_entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
||||||
u64* finds;
|
u64* finds;
|
||||||
u64* finds_v2;
|
u64* finds_v2;
|
||||||
u64* cycles;
|
u64* cycles;
|
||||||
u64* cycles_v2;
|
u64* cycles_v2;
|
||||||
u64* cycles_v3;
|
u64* cycles_v3;
|
||||||
} MOpt_globals;
|
|
||||||
|
|
||||||
|
} MOpt_globals;
|
||||||
|
|
||||||
#define AFL_PILOT_FUZZ
|
#define AFL_PILOT_FUZZ
|
||||||
#define common_fuzzing pilot_fuzzing
|
#define common_fuzzing pilot_fuzzing
|
||||||
|
@ -253,7 +253,8 @@ void write_to_testcase(void* mem, u32 len) {
|
|||||||
|
|
||||||
if (out_file) {
|
if (out_file) {
|
||||||
|
|
||||||
//unlink(out_file); /* Ignore errors. */
|
// unlink(out_file); /* Ignore errors.
|
||||||
|
// */
|
||||||
|
|
||||||
fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
|
||||||
@ -295,7 +296,8 @@ void write_with_gap(void* mem, u32 len, u32 skip_at, u32 skip_len) {
|
|||||||
|
|
||||||
if (out_file) {
|
if (out_file) {
|
||||||
|
|
||||||
//unlink(out_file); /* Ignore errors. */
|
// unlink(out_file); /* Ignore errors.
|
||||||
|
// */
|
||||||
|
|
||||||
fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
|
||||||
|
@ -334,11 +334,15 @@ static void edit_params(u32 argc, char** argv) {
|
|||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
if (argc == 2 && strcmp(argv[1], "-h") == 0) {
|
if (argc == 2 && strcmp(argv[1], "-h") == 0) {
|
||||||
|
|
||||||
printf("afl-cc" VERSION " by <lcamtuf@google.com>\n\n");
|
printf("afl-cc" VERSION " by <lcamtuf@google.com>\n\n");
|
||||||
printf("%s \n\n", argv[0]);
|
printf("%s \n\n", argv[0]);
|
||||||
printf("afl-gcc has no command line options\n");
|
printf("afl-gcc has no command line options\n");
|
||||||
printf("NOTE: afl-gcc is deprecated, llvm_mode is much faster and has more options\n");
|
printf(
|
||||||
|
"NOTE: afl-gcc is deprecated, llvm_mode is much faster and has more "
|
||||||
|
"options\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isatty(2) && !getenv("AFL_QUIET")) {
|
if (isatty(2) && !getenv("AFL_QUIET")) {
|
||||||
|
@ -128,11 +128,13 @@ repeat_loop:
|
|||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
|
||||||
printf("afl-gotcpu" VERSION " by <lcamtuf@google.com>\n");
|
printf("afl-gotcpu" VERSION " by <lcamtuf@google.com>\n");
|
||||||
printf("\n%s \n\n", argv[0]);
|
printf("\n%s \n\n", argv[0]);
|
||||||
printf("afl-gotcpu does not have command line options\n");
|
printf("afl-gotcpu does not have command line options\n");
|
||||||
printf("afl-gotcpu prints out which CPUs are available\n");
|
printf("afl-gotcpu prints out which CPUs are available\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_AFFINITY
|
#ifdef HAVE_AFFINITY
|
||||||
|
Reference in New Issue
Block a user