handle some errors properly so avoid exit() during initialization. this fixes issue #237

This commit is contained in:
Nguyen Anh Quynh 2015-11-12 01:43:41 +08:00
parent 116d96692d
commit 2f297bdd3a
38 changed files with 203 additions and 125 deletions

View File

@ -58,6 +58,7 @@ module Common =
let UC_ERR_WRITE_UNALIGNED = 17
let UC_ERR_FETCH_UNALIGNED = 18
let UC_ERR_HOOK_EXIST = 19
let UC_ERR_RESOURCE = 20
let UC_MEM_READ = 16
let UC_MEM_WRITE = 17
let UC_MEM_FETCH = 18

View File

@ -53,6 +53,7 @@ const (
ERR_WRITE_UNALIGNED = 17
ERR_FETCH_UNALIGNED = 18
ERR_HOOK_EXIST = 19
ERR_RESOURCE = 20
MEM_READ = 16
MEM_WRITE = 17
MEM_FETCH = 18

View File

@ -55,6 +55,7 @@ public interface UnicornConst {
public static final int UC_ERR_WRITE_UNALIGNED = 17;
public static final int UC_ERR_FETCH_UNALIGNED = 18;
public static final int UC_ERR_HOOK_EXIST = 19;
public static final int UC_ERR_RESOURCE = 20;
public static final int UC_MEM_READ = 16;
public static final int UC_MEM_WRITE = 17;
public static final int UC_MEM_FETCH = 18;

View File

@ -51,6 +51,7 @@ UC_ERR_READ_UNALIGNED = 16
UC_ERR_WRITE_UNALIGNED = 17
UC_ERR_FETCH_UNALIGNED = 18
UC_ERR_HOOK_EXIST = 19
UC_ERR_RESOURCE = 20
UC_MEM_READ = 16
UC_MEM_WRITE = 17
UC_MEM_FETCH = 18

View File

@ -36,6 +36,7 @@ typedef bool (*uc_read_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf, int l
typedef void (*uc_args_void_t)(void*);
typedef void (*uc_args_uc_t)(struct uc_struct*);
typedef int (*uc_args_int_uc_t)(struct uc_struct*);
typedef bool (*uc_args_tcg_enable_t)(struct uc_struct*);
@ -91,7 +92,8 @@ struct uc_struct {
uc_args_uc_u64_t set_pc; // set PC for tracecode
uc_args_int_t stop_interrupt; // check if the interrupt should stop emulation
uc_args_uc_t init_arch, pause_all_vcpus, vm_start, cpu_exec_init_all;
uc_args_uc_t init_arch, pause_all_vcpus, cpu_exec_init_all;
uc_args_int_uc_t vm_start;
uc_args_tcg_enable_t tcg_enabled;
uc_args_uc_long_t tcg_exec_init;
uc_args_uc_ram_size_t memory_map;

View File

@ -125,6 +125,7 @@ typedef enum uc_err {
UC_ERR_WRITE_UNALIGNED, // Unaligned write
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
UC_ERR_HOOK_EXIST, // hook for this event already existed
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
} uc_err;

View File

@ -37,16 +37,19 @@ static bool cpu_can_run(CPUState *cpu);
static void cpu_handle_guest_debug(CPUState *cpu);
static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env);
static bool tcg_exec_all(struct uc_struct* uc);
static void qemu_tcg_init_vcpu(CPUState *cpu);
static int qemu_tcg_init_vcpu(CPUState *cpu);
static void *qemu_tcg_cpu_thread_fn(void *arg);
void vm_start(struct uc_struct* uc)
int vm_start(struct uc_struct* uc)
{
resume_all_vcpus(uc);
if (resume_all_vcpus(uc)) {
return -1;
}
//sleep(3);
// kick off TCG thread
qemu_mutex_unlock_iothread(uc);
return 0;
}
bool cpu_is_stopped(CPUState *cpu)
@ -78,7 +81,7 @@ void pause_all_vcpus(struct uc_struct *uc)
}
void resume_all_vcpus(struct uc_struct *uc)
int resume_all_vcpus(struct uc_struct *uc)
{
CPUState *cpu;
@ -93,7 +96,8 @@ void resume_all_vcpus(struct uc_struct *uc)
CPU_FOREACH(cpu) {
cpu->created = true;
cpu->halted = 0;
qemu_init_vcpu(cpu);
if (qemu_init_vcpu(cpu))
return -1;
}
qemu_mutex_lock_iothread(uc);
}
@ -103,18 +107,21 @@ void resume_all_vcpus(struct uc_struct *uc)
CPU_FOREACH(cpu) {
cpu_resume(cpu);
}
return 0;
}
void qemu_init_vcpu(CPUState *cpu)
int qemu_init_vcpu(CPUState *cpu)
{
cpu->nr_cores = smp_cores;
cpu->nr_threads = smp_threads;
cpu->stopped = true;
cpu->uc->tcg_cpu_thread = NULL;
if (tcg_enabled(cpu->uc)) {
qemu_tcg_init_vcpu(cpu);
}
if (tcg_enabled(cpu->uc))
return qemu_tcg_init_vcpu(cpu);
return 0;
}
@ -133,7 +140,6 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
qemu_cond_signal(&uc->qemu_cpu_cond);
/* wait for initial kick-off after machine start */
while (QTAILQ_FIRST(&uc->cpus)->stopped) {
qemu_cond_wait(uc->tcg_halt_cond, &uc->qemu_global_mutex);
@ -170,7 +176,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* For temporary buffers for forming a name */
#define VCPU_THREAD_NAME_SIZE 16
static void qemu_tcg_init_vcpu(CPUState *cpu)
static int qemu_tcg_init_vcpu(CPUState *cpu)
{
struct uc_struct *uc = cpu->uc;
char thread_name[VCPU_THREAD_NAME_SIZE];
@ -185,8 +191,9 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
uc->tcg_halt_cond = cpu->halt_cond;
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
cpu->cpu_index);
qemu_thread_create(uc, cpu->thread, thread_name, qemu_tcg_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE);
if (qemu_thread_create(uc, cpu->thread, thread_name, qemu_tcg_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE))
return -1;
#ifdef _WIN32
cpu->hThread = qemu_thread_get_handle(cpu->thread);
#endif
@ -198,6 +205,8 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
cpu->thread = uc->tcg_cpu_thread;
cpu->halt_cond = uc->tcg_halt_cond;
}
return 0;
}
static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env)

View File

@ -17,10 +17,12 @@
#include "exec/address-spaces.h"
static void tosa_init(struct uc_struct *uc, MachineState *machine)
static int tosa_init(struct uc_struct *uc, MachineState *machine)
{
//cpu_arm_init(uc, "pxa255");
cpu_arm_init(uc, "cortex-a15"); // FIXME
return 0;
}
void tosa_machine_init(struct uc_struct *uc)

View File

@ -36,7 +36,7 @@
#include "exec/address-spaces.h"
static void machvirt_init(struct uc_struct *uc, MachineState *machine)
static int machvirt_init(struct uc_struct *uc, MachineState *machine)
{
const char *cpu_model = machine->cpu_model;
int n;
@ -51,12 +51,14 @@ static void machvirt_init(struct uc_struct *uc, MachineState *machine)
if (!oc) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
return -1;
}
cpuobj = object_new(uc, object_class_get_name(oc));
object_property_set_bool(uc, cpuobj, true, "realized", NULL);
}
return 0;
}
void machvirt_machine_init(struct uc_struct *uc)

View File

@ -155,7 +155,7 @@ static bool device_get_realized(struct uc_struct *uc, Object *obj, Error **errp)
return dev->realized;
}
static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, Error **errp)
static int device_set_realized(struct uc_struct *uc, Object *obj, bool value, Error **errp)
{
DeviceState *dev = DEVICE(uc, obj);
DeviceClass *dc = DEVICE_GET_CLASS(uc, dev);
@ -164,7 +164,7 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
if (dev->hotplugged && !dc->hotpluggable) {
error_set(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
return;
return -1;
}
if (value && !dev->realized) {
@ -181,7 +181,8 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
#endif
if (dc->realize) {
dc->realize(uc, dev, &local_err);
if (dc->realize(uc, dev, &local_err))
return -1;
}
if (local_err != NULL) {
@ -222,7 +223,7 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
}
dev->realized = value;
return;
return 0;
child_realize_fail:
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
@ -237,7 +238,7 @@ post_realize_fail:
fail:
error_propagate(errp, local_err);
return;
return -1;
}
static void device_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View File

@ -104,7 +104,7 @@ static X86CPU *pc_new_cpu(struct uc_struct *uc, const char *cpu_model, int64_t a
}
object_property_set_int(uc, OBJECT(cpu), apic_id, "apic-id", &local_err);
object_property_set_bool(uc, OBJECT(cpu), true, "realized", &local_err);
object_property_set_bool(uc, OBJECT(cpu), true, "realized", &local_err); // qq
if (local_err) {
error_propagate(errp, local_err);
@ -114,7 +114,7 @@ static X86CPU *pc_new_cpu(struct uc_struct *uc, const char *cpu_model, int64_t a
return cpu;
}
void pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
int pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
{
int i;
Error *error = NULL;
@ -129,13 +129,15 @@ void pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
}
for (i = 0; i < smp_cpus; i++) {
uc->cpu = pc_new_cpu(uc, cpu_model, x86_cpu_apic_id_from_index(i), &error);
uc->cpu = pc_new_cpu(uc, cpu_model, x86_cpu_apic_id_from_index(i), &error); // qq
if (error) {
//error_report("%s", error_get_pretty(error));
error_free(error);
exit(1);
return -1;
}
}
return 0;
}
static void pc_machine_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View File

@ -36,14 +36,14 @@
#define GIGABYTE_ALIGN true
/* PC hardware initialisation */
static void pc_init1(struct uc_struct *uc, MachineState *machine)
static int pc_init1(struct uc_struct *uc, MachineState *machine)
{
pc_cpus_init(uc, machine->cpu_model);
return pc_cpus_init(uc, machine->cpu_model);
}
static void pc_init_pci(struct uc_struct *uc, MachineState *machine)
static int pc_init_pci(struct uc_struct *uc, MachineState *machine)
{
pc_init1(uc, machine);
return pc_init1(uc, machine);
}
#define PC_I440FX_MACHINE_OPTIONS \

View File

@ -186,8 +186,9 @@ static void apic_post_load(APICCommonState *s)
}
}
static void apic_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int apic_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
return 0;
}
static void apic_class_init(struct uc_struct *uc, ObjectClass *klass, void *data)

View File

@ -196,7 +196,7 @@ static void apic_reset_common(struct uc_struct *uc, DeviceState *dev)
}
}
static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
APICCommonState *s = APIC_COMMON(uc, dev);
APICCommonClass *info;
@ -204,7 +204,7 @@ static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **
if (uc->apic_no >= MAX_APICS) {
error_setg(errp, "%s initialization failed.",
object_get_typename(OBJECT(dev)));
return;
return -1;
}
s->idx = uc->apic_no++;
@ -225,6 +225,8 @@ static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **
if (uc->apic_report_tpr_access && info->enable_tpr_reporting) {
info->enable_tpr_reporting(s, true);
}
return 0;
}
static void apic_common_class_init(struct uc_struct *uc, ObjectClass *klass, void *data)

View File

@ -16,7 +16,7 @@
/* Board init. */
static void dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
static int dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
{
const char *cpu_model = machine->cpu_model;
CPUM68KState *env;
@ -27,12 +27,14 @@ static void dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
env = cpu_init(uc, cpu_model);
if (!env) {
fprintf(stderr, "Unable to find m68k CPU definition\n");
exit(1);
return -1;
}
/* Initialize CPU registers. */
env->vbr = 0;
env->pc = 0;
return 0;
}
void dummy_m68k_machine_init(struct uc_struct *uc)

View File

@ -20,7 +20,7 @@
#include "exec/address-spaces.h"
static void mips_r4k_init(struct uc_struct *uc, MachineState *machine)
static int mips_r4k_init(struct uc_struct *uc, MachineState *machine)
{
const char *cpu_model = machine->cpu_model;
MIPSCPU *cpu;
@ -38,8 +38,10 @@ static void mips_r4k_init(struct uc_struct *uc, MachineState *machine)
cpu = cpu_mips_init(uc, cpu_model);
if (cpu == NULL) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
return -1;
}
return 0;
}
void mips_machine_init(struct uc_struct *uc)

View File

@ -33,7 +33,7 @@
#include "exec/address-spaces.h"
static void leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
static int leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
{
const char *cpu_model = machine->cpu_model;
SPARCCPU *cpu;
@ -46,10 +46,12 @@ static void leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
cpu = cpu_sparc_init(uc, cpu_model);
if (cpu == NULL) {
fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
exit(1);
return -1;
}
cpu_sparc_set_id(&cpu->env, 0);
return 0;
}
void leon3_machine_init(struct uc_struct *uc)

View File

@ -30,7 +30,7 @@
/* Sun4u hardware initialisation */
static void sun4u_init(struct uc_struct *uc, MachineState *machine)
static int sun4u_init(struct uc_struct *uc, MachineState *machine)
{
const char *cpu_model = machine->cpu_model;
SPARCCPU *cpu;
@ -41,8 +41,10 @@ static void sun4u_init(struct uc_struct *uc, MachineState *machine)
cpu = cpu_sparc_init(uc, cpu_model);
if (cpu == NULL) {
fprintf(stderr, "Unable to find Sparc CPU definition\n");
exit(1);
return -1;
}
return 0;
}
void sun4u_machine_init(struct uc_struct *uc)

View File

@ -9,7 +9,7 @@
#include "qom/object.h"
#include "uc_priv.h"
typedef void QEMUMachineInitFunc(struct uc_struct *uc, MachineState *ms);
typedef int QEMUMachineInitFunc(struct uc_struct *uc, MachineState *ms);
typedef void QEMUMachineResetFunc(void);
@ -54,7 +54,7 @@ struct MachineClass {
const char *family; /* NULL iff @name identifies a standalone machtype */
const char *name;
void (*init)(struct uc_struct *uc, MachineState *state);
int (*init)(struct uc_struct *uc, MachineState *state);
void (*reset)(void);
int max_cpus;

View File

@ -34,7 +34,7 @@ typedef struct PCMachineClass PCMachineClass;
#define PC_MACHINE_CLASS(klass) \
OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
void pc_cpus_init(struct uc_struct *uc, const char *cpu_model);
int pc_cpus_init(struct uc_struct *uc, const char *cpu_model);
FWCfgState *pc_memory_init(MachineState *machine,
MemoryRegion *system_memory,

View File

@ -32,7 +32,7 @@ typedef enum DeviceCategory {
typedef int (*qdev_initfn)(DeviceState *dev);
typedef int (*qdev_event)(DeviceState *dev);
typedef void (*qdev_resetfn)(DeviceState *dev);
typedef void (*DeviceRealize)(struct uc_struct *uc, DeviceState *dev, Error **errp);
typedef int (*DeviceRealize)(struct uc_struct *uc, DeviceState *dev, Error **errp);
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
typedef void (*BusRealize)(BusState *bus, Error **errp);
typedef void (*BusUnrealize)(BusState *bus, Error **errp);

View File

@ -53,7 +53,8 @@ void qemu_event_wait(QemuEvent *ev);
void qemu_event_destroy(QemuEvent *ev);
struct uc_struct;
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
// return -1 on error, 0 on success
int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
void *(*start_routine)(void *),
void *arg, int mode);
void *qemu_thread_join(QemuThread *thread);

View File

@ -582,7 +582,7 @@ void cpu_resume(CPUState *cpu);
*
* Initializes a vCPU.
*/
void qemu_init_vcpu(CPUState *cpu);
int qemu_init_vcpu(CPUState *cpu);
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */

View File

@ -304,6 +304,11 @@ typedef void (ObjectPropertyAccessor)(struct uc_struct *uc, Object *obj,
void *opaque,
const char *name,
Error **errp);
typedef int (ObjectPropertySetAccessor)(struct uc_struct *uc, Object *obj,
struct Visitor *v,
void *opaque,
const char *name,
Error **errp);
/**
* ObjectPropertyResolve:
@ -342,7 +347,7 @@ typedef struct ObjectProperty
gchar *type;
gchar *description;
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
ObjectPropertySetAccessor *set;
ObjectPropertyResolve *resolve;
ObjectPropertyRelease *release;
void *opaque;
@ -799,7 +804,7 @@ void object_unref(struct uc_struct *uc, Object *obj);
ObjectProperty *object_property_add(Object *obj, const char *name,
const char *type,
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertySetAccessor *set,
ObjectPropertyRelease *release,
void *opaque, Error **errp);
@ -1168,7 +1173,7 @@ void object_property_add_link(Object *obj, const char *name,
*/
void object_property_add_str(Object *obj, const char *name,
char *(*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, const char *, Error **),
int (*set)(struct uc_struct *uc, Object *, const char *, Error **),
Error **errp);
/**
@ -1184,7 +1189,7 @@ void object_property_add_str(Object *obj, const char *name,
*/
void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name,
bool (*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, bool, Error **),
int (*set)(struct uc_struct *uc, Object *, bool, Error **),
Error **errp);
/**

View File

@ -5,7 +5,7 @@ struct uc_struct;
/* cpus.c */
void qemu_init_cpu_loop(struct uc_struct*);
void resume_all_vcpus(struct uc_struct*);
int resume_all_vcpus(struct uc_struct*);
void pause_all_vcpus(struct uc_struct*);
void cpu_stop_current(struct uc_struct*);

View File

@ -17,7 +17,7 @@ typedef struct vm_change_state_entry VMChangeStateEntry;
#define VMRESET_SILENT false
#define VMRESET_REPORT true
void vm_start(struct uc_struct*);
int vm_start(struct uc_struct*);
void qemu_system_reset_request(struct uc_struct*);
void qemu_system_shutdown_request(void);

View File

@ -216,13 +216,15 @@ static void cpu_common_parse_features(CPUState *cpu, char *features,
}
}
static void cpu_common_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int cpu_common_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
CPUState *cpu = CPU(dev);
if (dev->hotplugged) {
cpu_resume(cpu);
}
return 0;
}
static void cpu_common_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View File

@ -716,7 +716,7 @@ void object_unref(struct uc_struct *uc, Object *obj)
ObjectProperty *
object_property_add(Object *obj, const char *name, const char *type,
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertySetAccessor *set,
ObjectPropertyRelease *release,
void *opaque, Error **errp)
{
@ -826,7 +826,8 @@ void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, const ch
if (!prop->set) {
error_set(errp, QERR_PERMISSION_DENIED);
} else {
prop->set(uc, obj, v, prop->opaque, name, errp);
if (prop->set(uc, obj, v, prop->opaque, name, errp))
error_set(errp, QERR_UNDEFINED_ERROR);
}
}
@ -1169,7 +1170,7 @@ static Object *object_resolve_link(struct uc_struct *uc, Object *obj, const char
return target;
}
static void object_set_link_property(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int object_set_link_property(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
Error *local_err = NULL;
@ -1188,18 +1189,20 @@ static void object_set_link_property(struct uc_struct *uc, Object *obj, Visitor
g_free(path);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
prop->check(obj, name, new_target, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
object_ref(new_target);
*child = new_target;
object_unref(uc, old_target);
return 0;
}
static Object *object_resolve_link_property(struct uc_struct *uc, Object *parent, void *opaque, const gchar *part)
@ -1410,7 +1413,7 @@ Object *object_resolve_path(struct uc_struct *uc, const char *path, bool *ambigu
typedef struct StringProperty
{
char *(*get)(struct uc_struct *uc, Object *, Error **);
void (*set)(struct uc_struct *uc, Object *, const char *, Error **);
int (*set)(struct uc_struct *uc, Object *, const char *, Error **);
} StringProperty;
static void property_get_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1426,7 +1429,7 @@ static void property_get_str(struct uc_struct *uc, Object *obj, Visitor *v, void
}
}
static void property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
StringProperty *prop = opaque;
@ -1436,11 +1439,13 @@ static void property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void
visit_type_str(v, &value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
prop->set(uc, obj, value, errp);
g_free(value);
return 0;
}
static void property_release_str(struct uc_struct *uc, Object *obj, const char *name,
@ -1452,7 +1457,7 @@ static void property_release_str(struct uc_struct *uc, Object *obj, const char *
void object_property_add_str(Object *obj, const char *name,
char *(*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, const char *, Error **),
int (*set)(struct uc_struct *uc, Object *, const char *, Error **),
Error **errp)
{
Error *local_err = NULL;
@ -1475,7 +1480,7 @@ void object_property_add_str(Object *obj, const char *name,
typedef struct BoolProperty
{
bool (*get)(struct uc_struct *uc, Object *, Error **);
void (*set)(struct uc_struct *uc, Object *, bool, Error **);
int (*set)(struct uc_struct *uc, Object *, bool, Error **);
} BoolProperty;
static void property_get_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1488,7 +1493,7 @@ static void property_get_bool(struct uc_struct *uc, Object *obj, Visitor *v, voi
visit_type_bool(v, &value, name, errp);
}
static void property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
BoolProperty *prop = opaque;
@ -1498,10 +1503,10 @@ static void property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, voi
visit_type_bool(v, &value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
prop->set(uc, obj, value, errp);
return prop->set(uc, obj, value, errp);
}
static void property_release_bool(struct uc_struct *uc, Object *obj, const char *name,
@ -1513,7 +1518,7 @@ static void property_release_bool(struct uc_struct *uc, Object *obj, const char
void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name,
bool (*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, bool, Error **),
int (*set)(struct uc_struct *uc, Object *, bool, Error **),
Error **errp)
{
Error *local_err = NULL;
@ -1611,12 +1616,14 @@ static void property_get_alias(struct uc_struct *uc, Object *obj, struct Visitor
object_property_get(uc, prop->target_obj, v, prop->target_name, errp);
}
static void property_set_alias(struct uc_struct *uc, Object *obj, struct Visitor *v, void *opaque,
static int property_set_alias(struct uc_struct *uc, Object *obj, struct Visitor *v, void *opaque,
const char *name, Error **errp)
{
AliasProperty *prop = opaque;
object_property_set(uc, prop->target_obj, v, prop->target_name, errp);
return 0;
}
static Object *property_resolve_alias(struct uc_struct *uc, Object *obj, void *opaque,

View File

@ -21,7 +21,7 @@ void object_property_set_qobject(struct uc_struct *uc, Object *obj, QObject *val
{
QmpInputVisitor *mi;
mi = qmp_input_visitor_new(value);
object_property_set(uc, obj, qmp_input_get_visitor(mi), name, errp);
object_property_set(uc, obj, qmp_input_get_visitor(mi), name, errp); // qq
qmp_input_visitor_cleanup(mi);
}

View File

@ -329,7 +329,7 @@ static void arm_cpu_finalizefn(struct uc_struct *uc, Object *obj, void *opaque)
g_hash_table_destroy(cpu->cp_regs);
}
static void arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
ARMCPU *cpu = ARM_CPU(uc, dev);
@ -399,6 +399,8 @@ static void arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
cpu_reset(cs);
acc->parent_realize(uc, dev, errp);
return 0;
}
static ObjectClass *arm_cpu_class_by_name(struct uc_struct *uc, const char *cpu_model)

View File

@ -1162,7 +1162,7 @@ static void x86_cpuid_version_get_family(struct uc_struct *uc, Object *obj, Visi
visit_type_int(v, &value, name, errp);
}
static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
@ -1175,12 +1175,12 @@ static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visi
visit_type_int(v, &value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max);
return;
return -1;
}
env->cpuid_version &= ~0xff00f00;
@ -1189,6 +1189,8 @@ static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visi
} else {
env->cpuid_version |= value << 8;
}
return 0;
}
static void x86_cpuid_version_get_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1203,7 +1205,7 @@ static void x86_cpuid_version_get_model(struct uc_struct *uc, Object *obj, Visit
visit_type_int(v, &value, name, errp);
}
static void x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
@ -1216,16 +1218,18 @@ static void x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visit
visit_type_int(v, &value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max);
return;
return -1;
}
env->cpuid_version &= ~0xf00f0;
env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
return 0;
}
static void x86_cpuid_version_get_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
@ -1240,7 +1244,7 @@ static void x86_cpuid_version_get_stepping(struct uc_struct *uc, Object *obj, Vi
visit_type_int(v, &value, name, errp);
}
static void x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
static int x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
void *opaque, const char *name,
Error **errp)
{
@ -1254,16 +1258,18 @@ static void x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Vi
visit_type_int(v, &value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max);
return;
return -1;
}
env->cpuid_version &= ~0xf;
env->cpuid_version |= value & 0xf;
return 0;
}
static void x86_cpuid_get_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1274,12 +1280,14 @@ static void x86_cpuid_get_level(struct uc_struct *uc, Object *obj, Visitor *v, v
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
}
static void x86_cpuid_set_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int x86_cpuid_set_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
return 0;
}
static void x86_cpuid_get_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1290,12 +1298,14 @@ static void x86_cpuid_get_xlevel(struct uc_struct *uc, Object *obj, Visitor *v,
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
}
static void x86_cpuid_set_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int x86_cpuid_set_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
return 0;
}
static char *x86_cpuid_get_vendor(struct uc_struct *uc, Object *obj, Error **errp)
@ -1310,7 +1320,7 @@ static char *x86_cpuid_get_vendor(struct uc_struct *uc, Object *obj, Error **err
return value;
}
static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *value,
static int x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *value,
Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
@ -1320,7 +1330,7 @@ static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *
if (strlen(value) != CPUID_VENDOR_SZ) {
error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
"vendor", value);
return;
return -1;
}
env->cpuid_vendor1 = 0;
@ -1331,6 +1341,8 @@ static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *
env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
}
return 0;
}
static char *x86_cpuid_get_model_id(struct uc_struct *uc, Object *obj, Error **errp)
@ -1348,7 +1360,7 @@ static char *x86_cpuid_get_model_id(struct uc_struct *uc, Object *obj, Error **e
return value;
}
static void x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char *model_id,
static int x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char *model_id,
Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
@ -1368,6 +1380,8 @@ static void x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char
}
env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
}
return 0;
}
static void x86_cpuid_get_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1380,7 +1394,7 @@ static void x86_cpuid_get_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v
visit_type_int(v, &value, name, errp);
}
static void x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
@ -1392,15 +1406,17 @@ static void x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v
visit_type_int(v, &value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return -1;
}
if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max);
return;
return -1;
}
cpu->env.tsc_khz = value / 1000;
return 0;
}
static void x86_cpuid_get_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1412,7 +1428,7 @@ static void x86_cpuid_get_apic_id(struct uc_struct *uc, Object *obj, Visitor *v,
visit_type_int(v, &value, name, errp);
}
static void x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
static int x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
X86CPU *cpu = X86_CPU(uc, obj);
@ -1425,26 +1441,28 @@ static void x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v,
if (dev->realized) {
error_setg(errp, "Attempt to set property '%s' on '%s' after "
"it was realized", name, object_get_typename(obj));
return;
return -1;
}
visit_type_int(v, &value, name, &error);
if (error) {
error_propagate(errp, error);
return;
return -1;
}
if (value < min || value > max) {
error_setg(errp, "Property %s.%s doesn't take value %" PRId64
" (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
object_get_typename(obj), name, value, min, max);
return;
return -1;
}
if ((value != cpu->env.cpuid_apic_id) && cpu_exists(uc, value)) {
error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
return;
return -1;
}
cpu->env.cpuid_apic_id = value;
return 0;
}
/* Generic getter for "feature-words" and "filtered-features" properties */
@ -2249,7 +2267,7 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
(env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
(env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
X86CPU *cpu = X86_CPU(uc, dev);
@ -2270,7 +2288,6 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
& CPUID_EXT2_AMD_ALIASES);
}
if (x86_cpu_filter_features(cpu) && cpu->enforce_cpuid) {
error_setg(&local_err,
"TCG doesn't support requested features");
@ -2289,7 +2306,8 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
#endif
mce_init(cpu);
qemu_init_vcpu(cs);
if (qemu_init_vcpu(cs))
return -1;
x86_cpu_apic_realize(cpu, &local_err);
if (local_err != NULL) {
@ -2301,8 +2319,10 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
out:
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
return -1;
}
return 0;
}
/* Enables contiguous-apic-ID mode, for compatibility */

View File

@ -146,7 +146,7 @@ static const M68kCPUInfo m68k_cpus[] = {
{ .name = "any", .instance_init = any_cpu_initfn },
};
static void m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(uc, dev);
@ -155,6 +155,8 @@ static void m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **e
qemu_init_vcpu(cs);
mcc->parent_realize(cs->uc, dev, errp);
return 0;
}
static void m68k_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View File

@ -92,7 +92,7 @@ static void mips_cpu_reset(CPUState *s)
cpu_state_reset(env);
}
static void mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(uc, dev);
@ -101,6 +101,8 @@ static void mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **e
qemu_init_vcpu(cs);
mcc->parent_realize(uc, dev, errp);
return 0;
}
static void mips_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View File

@ -783,7 +783,7 @@ static bool sparc_cpu_has_work(CPUState *cs)
cpu_interrupts_enabled(env);
}
static void sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
static int sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(uc, dev);
#if defined(CONFIG_USER_ONLY)
@ -798,6 +798,8 @@ static void sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **
qemu_init_vcpu(CPU(dev));
scc->parent_realize(uc, dev, errp);
return 0;
}
static void sparc_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View File

@ -29,8 +29,8 @@
static void error_exit(int err, const char *msg)
{
fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
abort();
// fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
// abort();
}
void qemu_mutex_init(QemuMutex *mutex)
@ -389,7 +389,7 @@ void qemu_event_wait(QemuEvent *ev)
}
}
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
void *(*start_routine)(void*),
void *arg, int mode)
{
@ -397,20 +397,16 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
int err;
pthread_attr_t attr;
#if 0
static int count = 0;
count++;
printf(">>> create thread %u\n", count);
#endif
err = pthread_attr_init(&attr);
if (err) {
error_exit(err, __func__);
return -1;
}
if (mode == QEMU_THREAD_DETACHED) {
err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (err) {
error_exit(err, __func__);
return -1;
}
}
@ -418,12 +414,16 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
sigfillset(&set);
pthread_sigmask(SIG_SETMASK, &set, &oldset);
err = pthread_create(&thread->thread, &attr, start_routine, arg);
if (err)
if (err) {
error_exit(err, __func__);
return -1;
}
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
pthread_attr_destroy(&attr);
return 0;
}
void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread)

View File

@ -27,7 +27,7 @@ static void error_exit(int err, const char *msg)
NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
LocalFree(pstr);
abort();
//abort();
}
void qemu_mutex_init(QemuMutex *mutex)
@ -326,7 +326,7 @@ void *qemu_thread_join(QemuThread *thread)
return ret;
}
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
void *(*start_routine)(void *),
void *arg, int mode)
{
@ -350,9 +350,13 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
data, 0, &thread->tid);
if (!hThread) {
error_exit(GetLastError(), __func__);
return -1;
}
CloseHandle(hThread);
thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data;
return 0;
}
void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread)

View File

@ -94,8 +94,6 @@ int machine_initialize(struct uc_struct *uc)
MachineClass *machine_class;
MachineState *current_machine;
//printf(">>> starting machine initialize\n");
module_call_init(uc, MODULE_INIT_QOM);
register_types_object(uc);
machine_register_types(uc);
@ -115,11 +113,8 @@ int machine_initialize(struct uc_struct *uc)
return -2;
}
// printf("222\n");
current_machine = MACHINE(uc, object_new(uc, object_class_get_name(
OBJECT_CLASS(machine_class))));
//object_property_add_child(object_get_root(), "machine",
// OBJECT(current_machine), &error_abort);
current_machine->uc = uc;
uc->cpu_exec_init_all(uc);
@ -129,14 +124,10 @@ int machine_initialize(struct uc_struct *uc)
qemu_init_cpu_loop(uc);
qemu_mutex_lock_iothread(uc);
//cpu_ticks_init();
// printf("333\n");
current_machine->cpu_model = NULL;
machine_class->init(uc, current_machine);
//printf(">>> ending machine initialize\n");
return 0;
return machine_class->init(uc, current_machine);
}
void qemu_system_reset_request(struct uc_struct* uc)

10
uc.c
View File

@ -97,6 +97,8 @@ const char *uc_strerror(uc_err code)
return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)";
case UC_ERR_HOOK_EXIST:
return "Hook for this type event already exists (UC_ERR_HOOK_EXIST)";
case UC_ERR_RESOURCE:
return "Insufficient resource (UC_ERR_RESOURCE)";
}
}
@ -235,7 +237,8 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
return UC_ERR_ARCH;
}
machine_initialize(uc);
if (machine_initialize(uc))
return UC_ERR_RESOURCE;
*result = uc;
@ -502,7 +505,10 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
uc->addr_end = until;
uc->vm_start(uc);
if (uc->vm_start(uc)) {
return UC_ERR_RESOURCE;
}
if (timeout)
enable_emu_timer(uc, timeout * 1000); // microseconds -> nanoseconds
uc->pause_all_vcpus(uc);