fixup! add libafl_qemu_read_user_sp_unchecked

This commit is contained in:
Alwin Berger 2025-07-23 10:20:07 +00:00
parent 49db147f92
commit cc1eb211d5

View File

@ -28,224 +28,6 @@
#include "exec/log.h" #include "exec/log.h"
#include "accel/accel-cpu-target.h" #include "accel/accel-cpu-target.h"
#include "trace/trace-root.h" #include "trace/trace-root.h"
#include "qemu/accel.h"
//// --- Begin LibAFL code ---
#ifndef CONFIG_USER_ONLY
#include "libafl/syx-snapshot/device-save.h"
#endif
//// --- End LibAFL code ---
#ifndef CONFIG_USER_ONLY
static int cpu_common_post_load(void *opaque, int version_id)
{
CPUState *cpu = opaque;
/* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
version_id is increased. */
cpu->interrupt_request &= ~0x01;
tlb_flush(cpu);
/* loadvm has just updated the content of RAM, bypassing the
* usual mechanisms that ensure we flush TBs for writes to
* memory we've translated code from. So we must flush all TBs,
* which will now be stale.
*/
//tb_flush(cpu);
//// --- Begin LibAFL code ---
// 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_devices_is_restoring()) {
tb_flush(cpu);
}
//// --- End LibAFL code ---
return 0;
}
static int cpu_common_pre_load(void *opaque)
{
CPUState *cpu = opaque;
cpu->exception_index = -1;
return 0;
}
static bool cpu_common_exception_index_needed(void *opaque)
{
CPUState *cpu = opaque;
return tcg_enabled() && cpu->exception_index != -1;
}
static const VMStateDescription vmstate_cpu_common_exception_index = {
.name = "cpu_common/exception_index",
.version_id = 1,
.minimum_version_id = 1,
.needed = cpu_common_exception_index_needed,
.fields = (const VMStateField[]) {
VMSTATE_INT32(exception_index, CPUState),
VMSTATE_END_OF_LIST()
}
};
static bool cpu_common_crash_occurred_needed(void *opaque)
{
CPUState *cpu = opaque;
return cpu->crash_occurred;
}
static const VMStateDescription vmstate_cpu_common_crash_occurred = {
.name = "cpu_common/crash_occurred",
.version_id = 1,
.minimum_version_id = 1,
.needed = cpu_common_crash_occurred_needed,
.fields = (const VMStateField[]) {
VMSTATE_BOOL(crash_occurred, CPUState),
VMSTATE_END_OF_LIST()
}
};
const VMStateDescription vmstate_cpu_common = {
.name = "cpu_common",
.version_id = 1,
.minimum_version_id = 1,
.pre_load = cpu_common_pre_load,
.post_load = cpu_common_post_load,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(halted, CPUState),
VMSTATE_UINT32(interrupt_request, CPUState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * const []) {
&vmstate_cpu_common_exception_index,
&vmstate_cpu_common_crash_occurred,
NULL
}
};
#endif
bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
{
/* cache the cpu class for the hotpath */
cpu->cc = CPU_GET_CLASS(cpu);
if (!accel_cpu_common_realize(cpu, errp)) {
return false;
}
/* Wait until cpu initialization complete before exposing cpu. */
cpu_list_add(cpu);
#ifdef CONFIG_USER_ONLY
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
qdev_get_vmsd(DEVICE(cpu))->unmigratable);
#else
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
}
if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu);
}
#endif /* CONFIG_USER_ONLY */
return true;
}
void cpu_exec_unrealizefn(CPUState *cpu)
{
#ifndef CONFIG_USER_ONLY
CPUClass *cc = CPU_GET_CLASS(cpu);
if (cc->sysemu_ops->legacy_vmsd != NULL) {
vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu);
}
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
}
#endif
cpu_list_remove(cpu);
/*
* Now that the vCPU has been removed from the RCU list, we can call
* accel_cpu_common_unrealize, which may free fields using call_rcu.
*/
accel_cpu_common_unrealize(cpu);
}
/*
* This can't go in hw/core/cpu.c because that file is compiled only
* once for both user-mode and system builds.
*/
static Property cpu_common_props[] = {
#ifdef CONFIG_USER_ONLY
/*
* Create a property for the user-only object, so users can
* adjust prctl(PR_SET_UNALIGN) from the command-line.
* Has no effect if the target does not support the feature.
*/
DEFINE_PROP_BOOL("prctl-unalign-sigbus", CPUState,
prctl_unalign_sigbus, false),
#else
/*
* Create a memory property for system CPU object, so users can
* wire up its memory. The default if no link is set up is to use
* the system address space.
*/
DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
MemoryRegion *),
#endif
DEFINE_PROP_END_OF_LIST(),
};
#ifndef CONFIG_USER_ONLY
static bool cpu_get_start_powered_off(Object *obj, Error **errp)
{
CPUState *cpu = CPU(obj);
return cpu->start_powered_off;
}
static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp)
{
CPUState *cpu = CPU(obj);
cpu->start_powered_off = value;
}
#endif
void cpu_class_init_props(DeviceClass *dc)
{
#ifndef CONFIG_USER_ONLY
ObjectClass *oc = OBJECT_CLASS(dc);
/*
* We can't use DEFINE_PROP_BOOL in the Property array for this
* property, because we want this to be settable after realize.
*/
object_class_property_add_bool(oc, "start-powered-off",
cpu_get_start_powered_off,
cpu_set_start_powered_off);
#endif
device_class_set_props(dc, cpu_common_props);
}
void cpu_exec_initfn(CPUState *cpu)
{
cpu->as = NULL;
cpu->num_ases = 0;
#ifndef CONFIG_USER_ONLY
cpu->memory = get_system_memory();
object_ref(OBJECT(cpu->memory));
#endif
}
char *cpu_model_from_type(const char *typename) char *cpu_model_from_type(const char *typename)
{ {