commit
4fc66b672e
@ -715,7 +715,7 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
void libafl_sync_breakpoint_cpu(void);
|
void libafl_sync_exit_cpu(void);
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
@ -723,13 +723,13 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
|
|||||||
{
|
{
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
if (cpu->exception_index == EXCP_LIBAFL_BP) {
|
if (cpu->exception_index == EXCP_LIBAFL_EXIT) {
|
||||||
*ret = cpu->exception_index;
|
*ret = cpu->exception_index;
|
||||||
cpu->exception_index = -1;
|
cpu->exception_index = -1;
|
||||||
|
|
||||||
libafl_sync_breakpoint_cpu();
|
libafl_sync_exit_cpu();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libafl_extras/exit.h"
|
||||||
|
|
||||||
void libafl_save_qemu_snapshot(char *name, bool sync);
|
void libafl_save_qemu_snapshot(char *name, bool sync);
|
||||||
void libafl_load_qemu_snapshot(char *name, bool sync);
|
void libafl_load_qemu_snapshot(char *name, bool sync);
|
||||||
|
|
||||||
@ -130,57 +132,24 @@ void libafl_load_qemu_snapshot(char *name, bool sync)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
__thread int libafl_qemu_break_asap = 0;
|
extern __thread int libafl_qemu_break_asap;
|
||||||
__thread CPUState* libafl_breakpoint_cpu;
|
|
||||||
__thread vaddr libafl_breakpoint_pc;
|
|
||||||
#else
|
#else
|
||||||
int libafl_qemu_break_asap = 0;
|
extern int libafl_qemu_break_asap;
|
||||||
CPUState* libafl_breakpoint_cpu;
|
|
||||||
vaddr libafl_breakpoint_pc;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TARGET_ARM
|
|
||||||
#define THUMB_MASK(value) (value | cpu_env(libafl_breakpoint_cpu)->thumb)
|
|
||||||
#else
|
|
||||||
#define THUMB_MASK(value) value
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void libafl_qemu_trigger_breakpoint(CPUState* cpu);
|
|
||||||
|
|
||||||
void libafl_sync_breakpoint_cpu(void);
|
|
||||||
|
|
||||||
void libafl_sync_breakpoint_cpu(void)
|
|
||||||
{
|
|
||||||
if (libafl_breakpoint_pc) {
|
|
||||||
CPUClass* cc = CPU_GET_CLASS(libafl_breakpoint_cpu);
|
|
||||||
cc->set_pc(libafl_breakpoint_cpu, THUMB_MASK(libafl_breakpoint_pc));
|
|
||||||
}
|
|
||||||
libafl_breakpoint_pc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void libafl_qemu_trigger_breakpoint(CPUState* cpu)
|
|
||||||
{
|
|
||||||
libafl_breakpoint_cpu = cpu;
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
qemu_system_debug_request();
|
|
||||||
cpu->stopped = true;
|
|
||||||
#endif
|
|
||||||
if (cpu->running) {
|
|
||||||
cpu->exception_index = EXCP_LIBAFL_BP;
|
|
||||||
cpu_loop_exit(cpu);
|
|
||||||
} else {
|
|
||||||
libafl_qemu_break_asap = 1;//TODO add a field to CPU
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc)
|
void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc)
|
||||||
{
|
{
|
||||||
CPUState* cpu = env_cpu(env);
|
CPUState* cpu = env_cpu(env);
|
||||||
libafl_breakpoint_pc = (target_ulong)pc;
|
libafl_exit_request_breakpoint(cpu, (target_ulong) pc);
|
||||||
libafl_qemu_trigger_breakpoint(cpu);
|
}
|
||||||
|
|
||||||
|
void HELPER(libafl_qemu_handle_sync_backdoor)(CPUArchState *env, uint64_t pc)
|
||||||
|
{
|
||||||
|
CPUState* cpu = env_cpu(env);
|
||||||
|
libafl_exit_request_sync_backdoor(cpu, (target_ulong) pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -327,6 +327,9 @@ DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
|||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
DEF_HELPER_FLAGS_2(libafl_qemu_handle_breakpoint, TCG_CALL_NO_RWG,
|
DEF_HELPER_FLAGS_2(libafl_qemu_handle_breakpoint, TCG_CALL_NO_RWG,
|
||||||
void, env, i64)
|
void, env, i64)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_2(libafl_qemu_handle_sync_backdoor, TCG_CALL_NO_RWG,
|
||||||
|
void, env, i64)
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -272,6 +272,13 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
|||||||
|
|
||||||
db->pc_next += 4;
|
db->pc_next += 4;
|
||||||
goto post_translate_insn;
|
goto post_translate_insn;
|
||||||
|
} else if (backdoor == 0x66) {
|
||||||
|
// First update pc_next to restart at next instruction
|
||||||
|
db->pc_next += 4;
|
||||||
|
|
||||||
|
TCGv_i64 tmp0 = tcg_constant_i64((uint64_t)db->pc_next);
|
||||||
|
gen_helper_libafl_qemu_handle_sync_backdoor(tcg_env, tmp0);
|
||||||
|
tcg_temp_free_i64(tmp0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "tcg/tcg-op.h"
|
#include "tcg/tcg-op.h"
|
||||||
#include "tcg/tcg-internal.h"
|
#include "tcg/tcg-internal.h"
|
||||||
#include "exec/helper-head.h"
|
#include "exec/helper-head.h"
|
||||||
|
#include "libafl_extras/exit.h"
|
||||||
|
|
||||||
#define LIBAFL_TABLES_SIZE 16384
|
#define LIBAFL_TABLES_SIZE 16384
|
||||||
#define LIBAFL_TABLES_HASH(p) (((13*((size_t)(p))) ^ (((size_t)(p)) >> 15)) % LIBAFL_TABLES_SIZE)
|
#define LIBAFL_TABLES_HASH(p) (((13*((size_t)(p))) ^ (((size_t)(p)) >> 15)) % LIBAFL_TABLES_SIZE)
|
||||||
@ -95,12 +96,6 @@ int libafl_qemu_remove_hook(size_t num, int invalidate);
|
|||||||
struct libafl_hook* libafl_search_hook(target_ulong addr);
|
struct libafl_hook* libafl_search_hook(target_ulong addr);
|
||||||
void libafl_flush_jit(void);
|
void libafl_flush_jit(void);
|
||||||
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
extern __thread CPUState* libafl_breakpoint_cpu;
|
|
||||||
#else
|
|
||||||
extern CPUState* libafl_breakpoint_cpu;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int libafl_restoring_devices;
|
extern int libafl_restoring_devices;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -146,7 +141,7 @@ CPUState* libafl_qemu_current_cpu(void)
|
|||||||
{
|
{
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
if (current_cpu == NULL) {
|
if (current_cpu == NULL) {
|
||||||
return libafl_breakpoint_cpu;
|
return libafl_last_exit_cpu();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return current_cpu;
|
return current_cpu;
|
||||||
|
93
libafl_extras/exit.c
Normal file
93
libafl_extras/exit.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "exit.h"
|
||||||
|
|
||||||
|
#include "sysemu/runstate.h"
|
||||||
|
|
||||||
|
// TODO: merge with definition in tcg-runtime.c
|
||||||
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
__thread int libafl_qemu_break_asap = 0;
|
||||||
|
__thread CPUState* libafl_breakpoint_cpu;
|
||||||
|
__thread vaddr libafl_breakpoint_pc;
|
||||||
|
__thread static struct libafl_exit_reason last_exit_reason;
|
||||||
|
#else
|
||||||
|
static struct libafl_exit_reason last_exit_reason;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TARGET_ARM
|
||||||
|
#define THUMB_MASK(value) (value | cpu_env(libafl_breakpoint_cpu)->thumb)
|
||||||
|
#else
|
||||||
|
#define THUMB_MASK(value) value
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool expected_exit = false;
|
||||||
|
|
||||||
|
void libafl_sync_exit_cpu(void)
|
||||||
|
{
|
||||||
|
if (last_exit_reason.next_pc) {
|
||||||
|
CPUClass* cc = CPU_GET_CLASS(last_exit_reason.cpu);
|
||||||
|
cc->set_pc(last_exit_reason.cpu, THUMB_MASK(last_exit_reason.next_pc));
|
||||||
|
}
|
||||||
|
last_exit_reason.next_pc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool libafl_exit_asap(void){
|
||||||
|
return last_exit_reason.exit_asap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void prepare_qemu_exit(CPUState* cpu, ulong next_pc)
|
||||||
|
{
|
||||||
|
expected_exit = true;
|
||||||
|
last_exit_reason.cpu = cpu;
|
||||||
|
last_exit_reason.next_pc = next_pc;
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
qemu_system_debug_request();
|
||||||
|
cpu->stopped = true;
|
||||||
|
#endif
|
||||||
|
if (cpu->running) {
|
||||||
|
cpu->exception_index = EXCP_LIBAFL_EXIT;
|
||||||
|
cpu_loop_exit(cpu);
|
||||||
|
} else {
|
||||||
|
last_exit_reason.exit_asap = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUState* libafl_last_exit_cpu(void)
|
||||||
|
{
|
||||||
|
if (expected_exit) {
|
||||||
|
return last_exit_reason.cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc)
|
||||||
|
{
|
||||||
|
last_exit_reason.kind = SYNC_BACKDOOR;
|
||||||
|
|
||||||
|
prepare_qemu_exit(cpu, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc)
|
||||||
|
{
|
||||||
|
last_exit_reason.kind = BREAKPOINT;
|
||||||
|
last_exit_reason.data.breakpoint.addr = pc;
|
||||||
|
|
||||||
|
prepare_qemu_exit(cpu, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void libafl_exit_signal_vm_start(void)
|
||||||
|
{
|
||||||
|
last_exit_reason.cpu = NULL;
|
||||||
|
expected_exit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct libafl_exit_reason* libafl_get_exit_reason(void)
|
||||||
|
{
|
||||||
|
if (expected_exit) {
|
||||||
|
return &last_exit_reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
38
libafl_extras/exit.h
Normal file
38
libafl_extras/exit.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "exec/cpu-defs.h"
|
||||||
|
|
||||||
|
enum libafl_exit_reason_kind {
|
||||||
|
BREAKPOINT = 0,
|
||||||
|
SYNC_BACKDOOR = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct libafl_exit_reason_breakpoint {
|
||||||
|
target_ulong addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct libafl_exit_reason_sync_backdoor { };
|
||||||
|
|
||||||
|
struct libafl_exit_reason {
|
||||||
|
enum libafl_exit_reason_kind kind;
|
||||||
|
CPUState* cpu; // CPU that triggered an exit.
|
||||||
|
vaddr next_pc; // The PC that should be stored in the CPU when re-entering.
|
||||||
|
int exit_asap; // TODO: add a field to CPU
|
||||||
|
union {
|
||||||
|
struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT
|
||||||
|
struct libafl_exit_reason_sync_backdoor backdoor; // kind == SYNC_BACKDOOR
|
||||||
|
} data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only makes sense to call if an exit was expected
|
||||||
|
// Will return NULL if there was no exit expected.
|
||||||
|
CPUState* libafl_last_exit_cpu(void);
|
||||||
|
|
||||||
|
void libafl_exit_signal_vm_start(void);
|
||||||
|
bool libafl_exit_asap(void);
|
||||||
|
void libafl_sync_exit_cpu(void);
|
||||||
|
|
||||||
|
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc);
|
||||||
|
void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc);
|
||||||
|
struct libafl_exit_reason* libafl_get_exit_reason(void);
|
@ -99,9 +99,9 @@ void cpu_loop(CPUARMState *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
case EXCP_LIBAFL_BP:
|
case EXCP_LIBAFL_EXIT:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -340,9 +340,9 @@ void cpu_loop(CPUARMState *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
case EXCP_LIBAFL_BP:
|
case EXCP_LIBAFL_EXIT:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -49,9 +49,9 @@ void cpu_loop(CPUHexagonState *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
case EXCP_LIBAFL_BP:
|
case EXCP_LIBAFL_EXIT:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -213,7 +213,7 @@ void cpu_loop(CPUX86State *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
if (libafl_qemu_break_asap) return;
|
if (libafl_exit_asap()) return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
@ -226,9 +226,9 @@ void cpu_loop(CPUX86State *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
case EXCP_LIBAFL_BP:
|
case EXCP_LIBAFL_EXIT:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -74,7 +74,7 @@ void cpu_loop(CPUMIPSState *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
if (libafl_qemu_break_asap) return;
|
if (libafl_exit_asap()) return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
@ -87,9 +87,9 @@ void cpu_loop(CPUMIPSState *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
case EXCP_LIBAFL_BP:
|
case EXCP_LIBAFL_EXIT:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -84,9 +84,9 @@ void cpu_loop(CPUPPCState *env)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
#define EXCP_LIBAFL_BP 0xf4775747
|
#define EXCP_LIBAFL_EXIT 0xf4775747
|
||||||
|
|
||||||
case EXCP_LIBAFL_BP:
|
case EXCP_LIBAFL_EXIT:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
@ -721,7 +721,8 @@ int vm_prepare_start(bool step_pending)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
extern CPUState* libafl_breakpoint_cpu;
|
void libafl_exit_signal_vm_start(void);
|
||||||
|
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
@ -730,7 +731,7 @@ void vm_start(void)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
libafl_breakpoint_cpu = NULL; // Rely on current_cpu in the hooks
|
libafl_exit_signal_vm_start();
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user