mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 02:58:08 +00:00
persistent qemu should now works as expected
This commit is contained in:
@ -71,7 +71,8 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
|
||||||
|
defined(__NetBSD__)
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
|
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
|
||||||
|
|
||||||
|
@ -510,8 +510,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
? 24
|
? 24
|
||||||
: sizeInBits == 64
|
: sizeInBits == 64
|
||||||
? 53
|
? 53
|
||||||
: sizeInBits == 128 ? 113 : sizeInBits == 16 ? 11
|
: sizeInBits == 128 ? 113
|
||||||
/* sizeInBits == 80 */ : 65;
|
: sizeInBits == 16 ? 11
|
||||||
|
/* sizeInBits == 80 */
|
||||||
|
: 65;
|
||||||
|
|
||||||
const unsigned shiftR_exponent = precision - 1;
|
const unsigned shiftR_exponent = precision - 1;
|
||||||
const unsigned long long mask_fraction =
|
const unsigned long long mask_fraction =
|
||||||
@ -522,17 +524,17 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
// round up sizes to the next power of two
|
// round up sizes to the next power of two
|
||||||
// this should help with integer compare splitting
|
// this should help with integer compare splitting
|
||||||
size_t exTySizeBytes = ((sizeInBits - precision + 7) >> 3);
|
size_t exTySizeBytes = ((sizeInBits - precision + 7) >> 3);
|
||||||
size_t frTySizeBytes = ((precision - 1ULL + 7) >> 3);
|
size_t frTySizeBytes = ((precision - 1ULL + 7) >> 3);
|
||||||
|
|
||||||
IntegerType *IntExponentTy =
|
IntegerType *IntExponentTy =
|
||||||
IntegerType::get(C, nextPowerOfTwo(exTySizeBytes) << 3);
|
IntegerType::get(C, nextPowerOfTwo(exTySizeBytes) << 3);
|
||||||
IntegerType *IntFractionTy =
|
IntegerType *IntFractionTy =
|
||||||
IntegerType::get(C, nextPowerOfTwo(frTySizeBytes) << 3);
|
IntegerType::get(C, nextPowerOfTwo(frTySizeBytes) << 3);
|
||||||
|
|
||||||
// errs() << "Fractions: IntFractionTy size " <<
|
// errs() << "Fractions: IntFractionTy size " <<
|
||||||
// IntFractionTy->getPrimitiveSizeInBits() << ", op_size " << op_size <<
|
// IntFractionTy->getPrimitiveSizeInBits() << ", op_size " << op_size <<
|
||||||
// ", mask " << mask_fraction <<
|
// ", mask " << mask_fraction <<
|
||||||
// ", precision " << precision << "\n";
|
// ", precision " << precision << "\n";
|
||||||
|
|
||||||
BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst));
|
BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst));
|
||||||
|
|
||||||
@ -552,16 +554,16 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
* the original operands so only the first bit remains.*/
|
* the original operands so only the first bit remains.*/
|
||||||
Instruction *s_s0, *t_s0, *s_s1, *t_s1, *icmp_sign_bit;
|
Instruction *s_s0, *t_s0, *s_s1, *t_s1, *icmp_sign_bit;
|
||||||
|
|
||||||
s_s0 = BinaryOperator::Create(
|
s_s0 =
|
||||||
Instruction::LShr, b_op0,
|
BinaryOperator::Create(Instruction::LShr, b_op0,
|
||||||
ConstantInt::get(b_op0->getType(), op_size - 1));
|
ConstantInt::get(b_op0->getType(), op_size - 1));
|
||||||
bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s0);
|
bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s0);
|
||||||
t_s0 = new TruncInst(s_s0, Int1Ty);
|
t_s0 = new TruncInst(s_s0, Int1Ty);
|
||||||
bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s0);
|
bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s0);
|
||||||
|
|
||||||
s_s1 = BinaryOperator::Create(
|
s_s1 =
|
||||||
Instruction::LShr, b_op1,
|
BinaryOperator::Create(Instruction::LShr, b_op1,
|
||||||
ConstantInt::get(b_op1->getType(), op_size - 1));
|
ConstantInt::get(b_op1->getType(), op_size - 1));
|
||||||
bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s1);
|
bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s1);
|
||||||
t_s1 = new TruncInst(s_s1, Int1Ty);
|
t_s1 = new TruncInst(s_s1, Int1Ty);
|
||||||
bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s1);
|
bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s1);
|
||||||
|
@ -88,7 +88,7 @@ unsigned char afl_fork_child;
|
|||||||
unsigned int afl_forksrv_pid;
|
unsigned int afl_forksrv_pid;
|
||||||
unsigned char is_persistent;
|
unsigned char is_persistent;
|
||||||
target_long persistent_stack_offset;
|
target_long persistent_stack_offset;
|
||||||
unsigned char persistent_first_pass;
|
unsigned char persistent_first_pass = 1;
|
||||||
unsigned char persistent_save_gpr;
|
unsigned char persistent_save_gpr;
|
||||||
target_ulong persistent_saved_gpr[AFL_REGS_NUM];
|
target_ulong persistent_saved_gpr[AFL_REGS_NUM];
|
||||||
int persisent_retaddr_offset;
|
int persisent_retaddr_offset;
|
||||||
@ -210,10 +210,10 @@ static void afl_setup(void) {
|
|||||||
|
|
||||||
if (is_persistent) {
|
if (is_persistent) {
|
||||||
|
|
||||||
afl_persistent_addr = strtoll(getenv("AFL_QEMU_PERSISTENT_ADDR"), NULL, 16);
|
afl_persistent_addr = strtoll(getenv("AFL_QEMU_PERSISTENT_ADDR"), NULL, 0);
|
||||||
if (getenv("AFL_QEMU_PERSISTENT_RET"))
|
if (getenv("AFL_QEMU_PERSISTENT_RET"))
|
||||||
afl_persistent_ret_addr =
|
afl_persistent_ret_addr =
|
||||||
strtoll(getenv("AFL_QEMU_PERSISTENT_RET"), NULL, 16);
|
strtoll(getenv("AFL_QEMU_PERSISTENT_RET"), NULL, 0);
|
||||||
/* If AFL_QEMU_PERSISTENT_RET is not specified patch the return addr */
|
/* If AFL_QEMU_PERSISTENT_RET is not specified patch the return addr */
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -222,20 +222,19 @@ static void afl_setup(void) {
|
|||||||
|
|
||||||
if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"))
|
if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"))
|
||||||
persisent_retaddr_offset =
|
persisent_retaddr_offset =
|
||||||
strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 16);
|
strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 0);
|
||||||
|
|
||||||
if (getenv("AFL_QEMU_PERSISTENT_CNT"))
|
if (getenv("AFL_QEMU_PERSISTENT_CNT"))
|
||||||
afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 16);
|
afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 0);
|
||||||
else
|
else
|
||||||
afl_persistent_cnt = PERSISTENT_DEFAULT_MAX_CNT;
|
afl_persistent_cnt = PERSISTENT_DEFAULT_MAX_CNT;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_mappings(void) {
|
static void print_mappings(void) {
|
||||||
|
|
||||||
u8 buf[MAX_LINE];
|
u8 buf[MAX_LINE];
|
||||||
FILE* f = fopen("/proc/self/maps", "r");
|
FILE *f = fopen("/proc/self/maps", "r");
|
||||||
|
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
|
|
||||||
@ -254,9 +253,8 @@ static void afl_forkserver(CPUState *cpu) {
|
|||||||
|
|
||||||
if (forkserver_installed == 1) return;
|
if (forkserver_installed == 1) return;
|
||||||
forkserver_installed = 1;
|
forkserver_installed = 1;
|
||||||
|
|
||||||
if (getenv("AFL_QEMU_DEBUG_MAPS"))
|
if (getenv("AFL_QEMU_DEBUG_MAPS")) print_mappings();
|
||||||
print_mappings();
|
|
||||||
|
|
||||||
// if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer
|
// if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer
|
||||||
|
|
||||||
@ -394,6 +392,7 @@ void afl_persistent_loop() {
|
|||||||
sizeof(struct afl_tsl)) {
|
sizeof(struct afl_tsl)) {
|
||||||
|
|
||||||
/* Exit the persistent loop on pipe error */
|
/* Exit the persistent loop on pipe error */
|
||||||
|
afl_area_ptr = dummy;
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -405,6 +404,7 @@ void afl_persistent_loop() {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
afl_area_ptr = dummy;
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ static void afl_compcov_log_32(target_ulong cur_loc, target_ulong arg1,
|
|||||||
|
|
||||||
if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) {
|
if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) {
|
||||||
|
|
||||||
INC_AFL_AREA(idx +2);
|
INC_AFL_AREA(idx + 2);
|
||||||
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
|
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
|
||||||
|
|
||||||
INC_AFL_AREA(idx + 1);
|
INC_AFL_AREA(idx + 1);
|
||||||
@ -70,7 +70,7 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1,
|
|||||||
|
|
||||||
if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) {
|
if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) {
|
||||||
|
|
||||||
INC_AFL_AREA(idx +6);
|
INC_AFL_AREA(idx + 6);
|
||||||
if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) {
|
if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) {
|
||||||
|
|
||||||
INC_AFL_AREA(idx + 5);
|
INC_AFL_AREA(idx + 5);
|
||||||
@ -86,11 +86,7 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1,
|
|||||||
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
|
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
|
||||||
|
|
||||||
INC_AFL_AREA(idx + 1);
|
INC_AFL_AREA(idx + 1);
|
||||||
if ((arg1 & 0xff00) == (arg2 & 0xff00)) {
|
if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); }
|
||||||
|
|
||||||
INC_AFL_AREA(idx);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +130,58 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Routines for debug */
|
||||||
|
/*
|
||||||
|
static void log_x86_saved_gpr(void) {
|
||||||
|
|
||||||
|
static const char reg_names[CPU_NB_REGS][4] = {
|
||||||
|
|
||||||
|
#ifdef TARGET_X86_64
|
||||||
|
[R_EAX] = "rax",
|
||||||
|
[R_EBX] = "rbx",
|
||||||
|
[R_ECX] = "rcx",
|
||||||
|
[R_EDX] = "rdx",
|
||||||
|
[R_ESI] = "rsi",
|
||||||
|
[R_EDI] = "rdi",
|
||||||
|
[R_EBP] = "rbp",
|
||||||
|
[R_ESP] = "rsp",
|
||||||
|
[8] = "r8",
|
||||||
|
[9] = "r9",
|
||||||
|
[10] = "r10",
|
||||||
|
[11] = "r11",
|
||||||
|
[12] = "r12",
|
||||||
|
[13] = "r13",
|
||||||
|
[14] = "r14",
|
||||||
|
[15] = "r15",
|
||||||
|
#else
|
||||||
|
[R_EAX] = "eax",
|
||||||
|
[R_EBX] = "ebx",
|
||||||
|
[R_ECX] = "ecx",
|
||||||
|
[R_EDX] = "edx",
|
||||||
|
[R_ESI] = "esi",
|
||||||
|
[R_EDI] = "edi",
|
||||||
|
[R_EBP] = "ebp",
|
||||||
|
[R_ESP] = "esp",
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < CPU_NB_REGS; ++i) {
|
||||||
|
|
||||||
|
fprintf(stderr, "%s = %lx\n", reg_names[i], persistent_saved_gpr[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_x86_sp_content(void) {
|
||||||
|
|
||||||
|
fprintf(stderr, ">> SP = %lx -> %lx\n", persistent_saved_gpr[R_ESP],
|
||||||
|
*(unsigned long*)persistent_saved_gpr[R_ESP]);
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
#define I386_RESTORE_STATE_FOR_PERSISTENT \
|
#define I386_RESTORE_STATE_FOR_PERSISTENT \
|
||||||
do { \
|
do { \
|
||||||
\
|
\
|
||||||
@ -154,7 +202,7 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
|
|||||||
for (i = 0; i < CPU_NB_REGS; ++i) { \
|
for (i = 0; i < CPU_NB_REGS; ++i) { \
|
||||||
\
|
\
|
||||||
gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); \
|
gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); \
|
||||||
tcg_gen_ld_tl(gpr_sv, cpu_regs[i], 0); \
|
tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); \
|
||||||
\
|
\
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@ -172,8 +220,7 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
|
|||||||
gen_set_label(lbl_finish_restore_gpr); \
|
gen_set_label(lbl_finish_restore_gpr); \
|
||||||
tcg_temp_free(first_pass); \
|
tcg_temp_free(first_pass); \
|
||||||
\
|
\
|
||||||
} \
|
} else if (afl_persistent_ret_addr == 0) { \
|
||||||
if (afl_persistent_ret_addr == 0) { \
|
|
||||||
\
|
\
|
||||||
TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); \
|
TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); \
|
||||||
TCGv stack_off = tcg_temp_new(); \
|
TCGv stack_off = tcg_temp_new(); \
|
||||||
@ -191,6 +238,8 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
|
|||||||
if (s->pc == afl_persistent_addr) { \
|
if (s->pc == afl_persistent_addr) { \
|
||||||
\
|
\
|
||||||
I386_RESTORE_STATE_FOR_PERSISTENT; \
|
I386_RESTORE_STATE_FOR_PERSISTENT; \
|
||||||
|
/*tcg_gen_afl_call0(log_x86_saved_gpr); \
|
||||||
|
tcg_gen_afl_call0(log_x86_sp_content);*/ \
|
||||||
\
|
\
|
||||||
if (afl_persistent_ret_addr == 0) { \
|
if (afl_persistent_ret_addr == 0) { \
|
||||||
\
|
\
|
||||||
@ -199,6 +248,7 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
|
|||||||
\
|
\
|
||||||
} \
|
} \
|
||||||
tcg_gen_afl_call0(&afl_persistent_loop); \
|
tcg_gen_afl_call0(&afl_persistent_loop); \
|
||||||
|
/*tcg_gen_afl_call0(log_x86_sp_content);*/ \
|
||||||
\
|
\
|
||||||
} else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \
|
} else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \
|
||||||
\
|
\
|
||||||
|
@ -35,7 +35,7 @@ void bind_to_free_cpu(void) {
|
|||||||
#if defined(__linux__) || defined(__FreeBSD__)
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
cpu_set_t c;
|
cpu_set_t c;
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
cpuset_t *c;
|
cpuset_t* c;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u8 cpu_used[4096] = {0};
|
u8 cpu_used[4096] = {0};
|
||||||
@ -147,8 +147,10 @@ void bind_to_free_cpu(void) {
|
|||||||
struct kinfo_proc2* procs;
|
struct kinfo_proc2* procs;
|
||||||
size_t nprocs;
|
size_t nprocs;
|
||||||
size_t proccount;
|
size_t proccount;
|
||||||
int s_name[] = {CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0};
|
int s_name[] = {
|
||||||
size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]);
|
|
||||||
|
CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0};
|
||||||
|
size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]);
|
||||||
|
|
||||||
if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return;
|
if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return;
|
||||||
proccount = nprocs / sizeof(struct kinfo_proc2);
|
proccount = nprocs / sizeof(struct kinfo_proc2);
|
||||||
|
Reference in New Issue
Block a user