Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Second round of cleanups #83

Merged
merged 4 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading