Skip to content

Commit

Permalink
Second round of cleanups (#83)
Browse files Browse the repository at this point in the history
* get rid of as many extern / function definition in QEMU codebase.

* mostly moved cpu / gdb related code.

* move qemu snapshot code in dedicated files.
  • Loading branch information
rmalmain authored Aug 14, 2024
1 parent 86d38fb commit 7f468eb
Show file tree
Hide file tree
Showing 26 changed files with 449 additions and 401 deletions.
93 changes: 0 additions & 93 deletions accel/tcg/tcg-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,99 +39,6 @@

#include "libafl/exit.h"

#ifndef CONFIG_USER_ONLY

#include "sysemu/runstate.h"
#include "migration/snapshot.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
#include "sysemu/hw_accel.h"
#include <stdlib.h>
#include <string.h>

void libafl_save_qemu_snapshot(char *name, bool sync);
void libafl_load_qemu_snapshot(char *name, bool sync);

static void save_snapshot_cb(void* opaque)
{
char* name = (char*)opaque;
Error *err = NULL;
if(!save_snapshot(name, true, NULL, false, NULL, &err)) {
error_report_err(err);
error_report("Could not save snapshot");
}
free(opaque);
}

void libafl_save_qemu_snapshot(char *name, bool sync)
{
// use snapshots synchronously, use if main loop is not running
if (sync) {
//TODO: eliminate this code duplication
//by passing a heap-allocated buffer from rust to c,
//which c needs to free
Error *err = NULL;
if(!save_snapshot(name, true, NULL, false, NULL, &err)) {
error_report_err(err);
error_report("Could not save snapshot");
}
return;
}
char* name_buffer = malloc(strlen(name)+1);
strcpy(name_buffer, name);
aio_bh_schedule_oneshot_full(qemu_get_aio_context(), save_snapshot_cb, (void*)name_buffer, "save_snapshot");
}

static void load_snapshot_cb(void* opaque)
{
char* name = (char*)opaque;
Error *err = NULL;

int saved_vm_running = runstate_is_running();
vm_stop(RUN_STATE_RESTORE_VM);

bool loaded = load_snapshot(name, NULL, false, NULL, &err);

if(!loaded) {
error_report_err(err);
error_report("Could not load snapshot");
}
if (loaded && saved_vm_running) {
vm_start();
}
free(opaque);
}

void libafl_load_qemu_snapshot(char *name, bool sync)
{
// use snapshots synchronously, use if main loop is not running
if (sync) {
//TODO: see libafl_save_qemu_snapshot
Error *err = NULL;

int saved_vm_running = runstate_is_running();
vm_stop(RUN_STATE_RESTORE_VM);

bool loaded = load_snapshot(name, NULL, false, NULL, &err);

if(!loaded) {
error_report_err(err);
error_report("Could not load snapshot");
}
if (loaded && saved_vm_running) {
vm_start();
}
return;
}
char* name_buffer = malloc(strlen(name)+1);
strcpy(name_buffer, name);
aio_bh_schedule_oneshot_full(qemu_get_aio_context(), load_snapshot_cb, (void*)name_buffer, "load_snapshot");
}

#endif

void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc)
{
CPUState* cpu = env_cpu(env);
Expand Down
152 changes: 4 additions & 148 deletions cpu-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,139 +47,10 @@

//// --- Begin LibAFL code ---

#include "exec/gdbstub.h"

#include "libafl/exit.h"
#include "libafl/hook.h"

int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg);

static __thread GByteArray *libafl_qemu_mem_buf = NULL;

target_ulong libafl_page_from_addr(target_ulong addr);

CPUState* libafl_qemu_get_cpu(int cpu_index);
int libafl_qemu_num_cpus(void);
CPUState* libafl_qemu_current_cpu(void);
int libafl_qemu_cpu_index(CPUState*);

int libafl_qemu_write_reg(CPUState* cpu, int reg, uint8_t* val);
int libafl_qemu_read_reg(CPUState* cpu, int reg, uint8_t* val);
int libafl_qemu_num_regs(CPUState* cpu);

#ifndef CONFIG_USER_ONLY
hwaddr libafl_qemu_current_paging_id(CPUState* cpu);
#include "libafl/syx-snapshot/device-save.h"
#endif

void libafl_flush_jit(void);

extern int libafl_restoring_devices;

/*
void* libafl_qemu_g2h(CPUState *cpu, target_ulong x);
target_ulong libafl_qemu_h2g(CPUState *cpu, void* x);
void* libafl_qemu_g2h(CPUState *cpu, target_ulong x)
{
return g2h(cpu, x);
}
target_ulong libafl_qemu_h2g(CPUState *cpu, void* x)
{
return h2g(cpu, x);
}
*/

target_ulong libafl_page_from_addr(target_ulong addr) {
return addr & TARGET_PAGE_MASK;
}

CPUState* libafl_qemu_get_cpu(int cpu_index)
{
CPUState *cpu;
CPU_FOREACH(cpu) {
if (cpu->cpu_index == cpu_index)
return cpu;
}
return NULL;
}

int libafl_qemu_num_cpus(void)
{
CPUState *cpu;
int num = 0;
CPU_FOREACH(cpu) {
num++;
}
return num;
}

CPUState* libafl_qemu_current_cpu(void)
{
#ifndef CONFIG_USER_ONLY
if (current_cpu == NULL) {
return libafl_last_exit_cpu();
}
#endif
return current_cpu;
}

int libafl_qemu_cpu_index(CPUState* cpu)
{
if (cpu) return cpu->cpu_index;
return -1;
}

int libafl_qemu_write_reg(CPUState* cpu, int reg, uint8_t* val)
{
return gdb_write_register(cpu, val, reg);
}

int libafl_qemu_read_reg(CPUState* cpu, int reg, uint8_t* val)
{
int len;

if (libafl_qemu_mem_buf == NULL) {
libafl_qemu_mem_buf = g_byte_array_sized_new(64);
}

g_byte_array_set_size(libafl_qemu_mem_buf, 0);

len = gdb_read_register(cpu, libafl_qemu_mem_buf, reg);

if (len > 0) {
memcpy(val, libafl_qemu_mem_buf->data, len);
}

return len;
}

int libafl_qemu_num_regs(CPUState* cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
return cc->gdb_num_core_regs;
}

#ifndef CONFIG_USER_ONLY
hwaddr libafl_qemu_current_paging_id(CPUState* cpu)
{
CPUClass* cc = CPU_GET_CLASS(cpu);
if (cc->sysemu_ops && cc->sysemu_ops->get_paging_id) {
return cc->sysemu_ops->get_paging_id(cpu);
} else {
return 0;
}
}
#endif

void libafl_flush_jit(void)
{
CPUState *cpu;
CPU_FOREACH(cpu) {
tb_flush(cpu);
}
}

//// --- End LibAFL code ---

#ifndef CONFIG_USER_ONLY
Expand All @@ -203,7 +74,9 @@ static int cpu_common_post_load(void *opaque, int version_id)

// flushing the TBs every restore makes it really slow
// TODO handle writes to X code with specific calls to tb_invalidate_phys_addr
if (!libafl_restoring_devices) tb_flush(cpu);
if (!libafl_devices_is_restoring()) {
tb_flush(cpu);
}

//// --- End LibAFL code ---

Expand Down Expand Up @@ -462,23 +335,6 @@ void list_cpus(void)
cpu_list();
}

//// --- Begin LibAFL code ---
#if defined(CONFIG_USER_ONLY)
void libafl_breakpoint_invalidate(CPUState *cpu, target_ulong pc)
{
mmap_lock();
tb_invalidate_phys_range(pc, pc + 1);
mmap_unlock();
}
#else
void libafl_breakpoint_invalidate(CPUState *cpu, target_ulong pc)
{
// TODO invalidate only the virtual pages related to the TB
tb_flush(cpu);
}
#endif
//// --- End LibAFL code ---

/* enable or disable single step mode. EXCP_DEBUG is returned by the
CPU loop after each instruction */
void cpu_single_step(CPUState *cpu, int enabled)
Expand Down
24 changes: 0 additions & 24 deletions gdbstub/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1648,30 +1648,6 @@ static void handle_query_thread_extra(GArray *params, void *user_ctx)
gdb_put_strbuf();
}

//// --- Begin LibAFL code ---

struct libafl_custom_gdb_cmd* libafl_qemu_gdb_cmds;

void libafl_qemu_add_gdb_cmd(int (*callback)(void*, uint8_t*, size_t), void* data);
void libafl_qemu_add_gdb_cmd(int (*callback)(void*, uint8_t*, size_t), void* data)
{
struct libafl_custom_gdb_cmd* c = malloc(sizeof(struct libafl_custom_gdb_cmd));
c->callback = callback;
c->data = data;
c->next = libafl_qemu_gdb_cmds;
libafl_qemu_gdb_cmds = c;
}

void libafl_qemu_gdb_reply(const char* buf, size_t len);
void libafl_qemu_gdb_reply(const char* buf, size_t len)
{
g_autoptr(GString) hex_buf = g_string_new("O");
gdb_memtohex(hex_buf, (const uint8_t *) buf, len);
gdb_put_packet(hex_buf->str);
}

//// --- End LibAFL code ---

static void handle_query_supported(GArray *params, void *user_ctx)
{
CPUClass *cc;
Expand Down
12 changes: 0 additions & 12 deletions gdbstub/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,16 +240,4 @@ void gdb_breakpoint_remove_all(CPUState *cs);
int gdb_target_memory_rw_debug(CPUState *cs, hwaddr addr,
uint8_t *buf, int len, bool is_write);

//// --- Begin LibAFL code ---

struct libafl_custom_gdb_cmd {
int (*callback)(void*, uint8_t*, size_t);
void* data;
struct libafl_custom_gdb_cmd* next;
};

extern struct libafl_custom_gdb_cmd* libafl_qemu_gdb_cmds;

//// --- End LibAFL code ---

#endif /* GDBSTUB_INTERNALS_H */
13 changes: 5 additions & 8 deletions gdbstub/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include "trace.h"
#include "internals.h"

//// --- Begin LibAFL code ---
#include "libafl/gdb.h"
//// --- End LibAFL code ---

/* System emulation specific state */
typedef struct {
CharBackend chr;
Expand Down Expand Up @@ -531,14 +535,7 @@ void gdb_handle_query_rcmd(GArray *params, void *ctx)

//// --- Begin LibAFL code ---

struct libafl_custom_gdb_cmd** c = &libafl_qemu_gdb_cmds;
int recognized = 0;
while (*c) {
recognized |= (*c)->callback((*c)->data, gdbserver_state.mem_buf->data, gdbserver_state.mem_buf->len);
c = &(*c)->next;
}

if (recognized) {
if (libafl_qemu_gdb_exec()) {
gdb_put_packet("OK");
return;
}
Expand Down
19 changes: 7 additions & 12 deletions gdbstub/user-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
#ifdef CONFIG_LINUX
#include "linux-user/loader.h"
#include "linux-user/qemu.h"

//// --- Begin LibAFL code ---
#include "libafl/gdb.h"
//// --- End LibAFL code ---

#endif

/*
Expand Down Expand Up @@ -305,27 +310,17 @@ void gdb_handle_query_rcmd(GArray *params, void *user_ctx)
g_assert(gdbserver_state.mem_buf->len == 0);
len = len / 2;
gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);

//// --- Begin LibAFL code ---

struct libafl_custom_gdb_cmd** c = &libafl_qemu_gdb_cmds;
int recognized = 0;
while (*c) {
recognized |= (*c)->callback((*c)->data, gdbserver_state.mem_buf->data, gdbserver_state.mem_buf->len);
c = &(*c)->next;
}

if (recognized) {
if (libafl_qemu_gdb_exec()) {
gdb_put_packet("OK");
} else {
gdb_put_packet("");
}
}
#endif

//// --- End LibAFL code ---

#endif

static const char *get_filename_param(GArray *params, int i)
{
const char *hex_filename = get_param(params, i)->data;
Expand Down
Loading

0 comments on commit 7f468eb

Please sign in to comment.