Early return from libafl edge generation if no exec hooks (#85)
* bug with edges in systemmode, not fixed yet * timeout request only for systemmode
This commit is contained in:
parent
f58a6859f3
commit
d663793952
@ -1039,13 +1039,13 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
int has_libafl_edge = 0;
|
||||
bool libafl_edge_generated = false;
|
||||
TranslationBlock *edge;
|
||||
|
||||
/* See if we can patch the calling TB. */
|
||||
if (last_tb) {
|
||||
// tb_add_jump(last_tb, tb_exit, tb);
|
||||
|
||||
|
||||
if (last_tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
|
||||
mmap_lock();
|
||||
edge = libafl_gen_edge(cpu, last_tb->pc, pc, tb_exit, cs_base, flags, cflags);
|
||||
@ -1054,7 +1054,7 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
|
||||
if (edge) {
|
||||
tb_add_jump(last_tb, tb_exit, edge);
|
||||
tb_add_jump(edge, 0, tb);
|
||||
has_libafl_edge = 1;
|
||||
libafl_edge_generated = true;
|
||||
} else {
|
||||
tb_add_jump(last_tb, tb_exit, tb);
|
||||
}
|
||||
@ -1063,7 +1063,7 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
|
||||
}
|
||||
}
|
||||
|
||||
if (has_libafl_edge) {
|
||||
if (libafl_edge_generated) {
|
||||
// execute the edge to make sure to log it the first execution
|
||||
// the edge will then jump to the translated block
|
||||
cpu_loop_exec_tb(cpu, edge, pc, &last_tb, &tb_exit);
|
||||
|
@ -378,11 +378,20 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
|
||||
int64_t ti;
|
||||
void *host_pc;
|
||||
|
||||
// edge hooks generation callbacks
|
||||
// early check if it should be skipped or not
|
||||
bool no_exec_hook = libafl_qemu_hook_edge_gen(src_block, dst_block);
|
||||
if (no_exec_hook) {
|
||||
// no exec hooks to run for edges, not point in generating a TB
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_ulong pc = src_block ^ reverse_bits((target_ulong)exit_n);
|
||||
|
||||
assert_memory_lock();
|
||||
qemu_thread_jit_write();
|
||||
|
||||
// TODO: this (get_page_addr_code_hostp) is a bottleneck in systemmode, investigate why
|
||||
phys_pc = get_page_addr_code_hostp(env, src_block, &host_pc);
|
||||
phys_pc ^= reverse_bits((tb_page_addr_t)exit_n);
|
||||
|
||||
@ -401,11 +410,6 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
|
||||
}
|
||||
QEMU_BUILD_BUG_ON(CF_COUNT_MASK + 1 != TCG_MAX_INSNS);
|
||||
|
||||
// edge hooks generation callbacks
|
||||
bool no_exec_hook = libafl_qemu_hook_edge_gen(src_block, dst_block);
|
||||
if (no_exec_hook)
|
||||
return NULL;
|
||||
|
||||
buffer_overflow:
|
||||
assert_no_pages_locked();
|
||||
tb = tcg_tb_alloc(tcg_ctx);
|
||||
|
@ -21,15 +21,7 @@ enum libafl_exit_reason_kind {
|
||||
INTERNAL = 0,
|
||||
BREAKPOINT = 1,
|
||||
SYNC_EXIT = 2,
|
||||
};
|
||||
|
||||
// A breakpoint has been triggered.
|
||||
struct libafl_exit_reason_breakpoint {
|
||||
target_ulong addr;
|
||||
};
|
||||
|
||||
// A synchronous exit has been triggered.
|
||||
struct libafl_exit_reason_sync_exit {
|
||||
TIMEOUT = 3,
|
||||
};
|
||||
|
||||
// QEMU exited on its own for some reason.
|
||||
@ -38,14 +30,26 @@ struct libafl_exit_reason_internal {
|
||||
int signal; // valid if cause == SHUTDOWN_CAUSE_HOST_SIGNAL
|
||||
};
|
||||
|
||||
// A breakpoint has been triggered.
|
||||
struct libafl_exit_reason_breakpoint {
|
||||
target_ulong addr;
|
||||
};
|
||||
|
||||
// A synchronous exit has been triggered.
|
||||
struct libafl_exit_reason_sync_exit {};
|
||||
|
||||
// A timeout occured and we were asked to exit on timeout
|
||||
struct libafl_exit_reason_timeout {};
|
||||
|
||||
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.
|
||||
union {
|
||||
struct libafl_exit_reason_internal internal;
|
||||
struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT
|
||||
struct libafl_exit_reason_sync_exit sync_exit; // kind == SYNC_EXIT
|
||||
struct libafl_exit_reason_internal internal; // kind == INTERNAL
|
||||
struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT
|
||||
struct libafl_exit_reason_sync_exit sync_exit; // kind == SYNC_EXIT
|
||||
struct libafl_exit_reason_timeout timeout; // kind == TIMEOUT
|
||||
} data;
|
||||
};
|
||||
|
||||
@ -59,6 +63,11 @@ void libafl_sync_exit_cpu(void);
|
||||
|
||||
void libafl_exit_request_internal(CPUState* cpu, uint64_t pc,
|
||||
ShutdownCause cause, int signal);
|
||||
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc);
|
||||
void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc);
|
||||
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void libafl_exit_request_timeout(void);
|
||||
#endif
|
||||
|
||||
struct libafl_exit_reason* libafl_get_exit_reason(void);
|
||||
|
@ -81,6 +81,7 @@ static void prepare_qemu_exit(CPUState* cpu, target_ulong next_pc)
|
||||
qemu_system_debug_request();
|
||||
cpu->stopped = true; // TODO check if still needed
|
||||
#endif
|
||||
|
||||
// in usermode, this may be called from the syscall hook, thus already out
|
||||
// of the cpu_exec but still in the cpu_loop
|
||||
if (cpu->running) {
|
||||
@ -125,6 +126,17 @@ void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc)
|
||||
prepare_qemu_exit(cpu, pc);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void libafl_exit_request_timeout(void)
|
||||
{
|
||||
expected_exit = true;
|
||||
last_exit_reason.kind = TIMEOUT;
|
||||
last_exit_reason.cpu = current_cpu;
|
||||
|
||||
qemu_system_debug_request();
|
||||
}
|
||||
#endif
|
||||
|
||||
void libafl_qemu_trigger_breakpoint(CPUState* cpu)
|
||||
{
|
||||
CPUClass* cc = CPU_GET_CLASS(cpu);
|
||||
|
@ -71,8 +71,11 @@ void libafl_qemu_hook_block_run(target_ulong pc)
|
||||
|
||||
while (hook) {
|
||||
uint64_t cur_id = 0;
|
||||
if (hook->gen)
|
||||
|
||||
if (hook->gen) {
|
||||
cur_id = hook->gen(hook->data, pc);
|
||||
}
|
||||
|
||||
if (cur_id != (uint64_t)-1 && hook->helper_info.func) {
|
||||
TCGv_i64 tmp0 = tcg_constant_i64(hook->data);
|
||||
TCGv_i64 tmp1 = tcg_constant_i64(cur_id);
|
||||
@ -81,9 +84,11 @@ void libafl_qemu_hook_block_run(target_ulong pc)
|
||||
tcg_temp_free_i64(tmp0);
|
||||
tcg_temp_free_i64(tmp1);
|
||||
}
|
||||
|
||||
if (cur_id != (uint64_t)-1 && hook->jit) {
|
||||
hook->jit(hook->data, cur_id);
|
||||
}
|
||||
|
||||
hook = hook->next;
|
||||
}
|
||||
}
|
||||
|
@ -56,15 +56,22 @@ bool libafl_qemu_hook_edge_gen(target_ulong src_block, target_ulong dst_block)
|
||||
{
|
||||
struct libafl_edge_hook* hook = libafl_edge_hooks;
|
||||
bool no_exec_hook = true;
|
||||
|
||||
while (hook) {
|
||||
hook->cur_id = 0;
|
||||
if (hook->gen)
|
||||
|
||||
if (hook->gen) {
|
||||
hook->cur_id = hook->gen(hook->data, src_block, dst_block);
|
||||
}
|
||||
|
||||
if (hook->cur_id != (uint64_t)-1 &&
|
||||
(hook->helper_info.func || hook->jit))
|
||||
(hook->helper_info.func || hook->jit)) {
|
||||
no_exec_hook = false;
|
||||
}
|
||||
|
||||
hook = hook->next;
|
||||
}
|
||||
|
||||
return no_exec_hook;
|
||||
}
|
||||
|
||||
|
@ -713,8 +713,8 @@ SyxSnapshotCheckResult syx_snapshot_check(SyxSnapshot* ref_snapshot)
|
||||
void syx_snapshot_root_restore(SyxSnapshot* snapshot)
|
||||
{
|
||||
// health check.
|
||||
CPUState* cpu;
|
||||
CPU_FOREACH(cpu) { assert(cpu->stopped); }
|
||||
// CPUState* cpu;
|
||||
// CPU_FOREACH(cpu) { assert(cpu->stopped); }
|
||||
|
||||
bool must_unlock_bql = false;
|
||||
|
||||
|
@ -8,13 +8,18 @@ add_project_arguments(cc.get_supported_arguments('-Wsign-compare',
|
||||
'-Wstrict-aliasing'),
|
||||
native: false, language: 'c')
|
||||
|
||||
#### --- Begin LibAFL code ---
|
||||
keyval = import('keyval')
|
||||
config_host = keyval.load(meson.global_build_root() / 'config-host.mak')
|
||||
#### --- End LibAFL code ---
|
||||
|
||||
libvduse = static_library('vduse',
|
||||
files('libvduse.c'),
|
||||
c_args: '-D_GNU_SOURCE',
|
||||
pic: 'AS_SHARED_LIB' in config_host)
|
||||
#### --- Begin LibAFL code ---
|
||||
pic: 'AS_SHARED_LIB' in config_host
|
||||
#### --- End LibAFL code ---
|
||||
)
|
||||
|
||||
libvduse_dep = declare_dependency(link_with: libvduse,
|
||||
include_directories: include_directories('.'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user