diff --git a/bindings/dotnet/Unicorn/Const/Common.fs b/bindings/dotnet/Unicorn/Const/Common.fs index 2133de54..c3c4655e 100644 --- a/bindings/dotnet/Unicorn/Const/Common.fs +++ b/bindings/dotnet/Unicorn/Const/Common.fs @@ -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 diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go index 2f80dea3..38ba0c8b 100644 --- a/bindings/go/unicorn/unicorn_const.go +++ b/bindings/go/unicorn/unicorn_const.go @@ -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 diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index 6139ecf5..2bd8eabe 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -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; diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py index 48162807..01cde40c 100644 --- a/bindings/python/unicorn/unicorn_const.py +++ b/bindings/python/unicorn/unicorn_const.py @@ -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 diff --git a/include/uc_priv.h b/include/uc_priv.h index f1f7ec2e..1493a7fd 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -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; diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index b812b473..a7a13b60 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -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; diff --git a/qemu/cpus.c b/qemu/cpus.c index e274fe5a..98ee07c1 100644 --- a/qemu/cpus.c +++ b/qemu/cpus.c @@ -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) diff --git a/qemu/hw/arm/tosa.c b/qemu/hw/arm/tosa.c index 818fe32f..fe9eaf6e 100644 --- a/qemu/hw/arm/tosa.c +++ b/qemu/hw/arm/tosa.c @@ -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) diff --git a/qemu/hw/arm/virt.c b/qemu/hw/arm/virt.c index b9156317..554e89d7 100644 --- a/qemu/hw/arm/virt.c +++ b/qemu/hw/arm/virt.c @@ -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) diff --git a/qemu/hw/core/qdev.c b/qemu/hw/core/qdev.c index e3340895..14e3ccec 100644 --- a/qemu/hw/core/qdev.c +++ b/qemu/hw/core/qdev.c @@ -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) diff --git a/qemu/hw/i386/pc.c b/qemu/hw/i386/pc.c index 5f201dbc..0721fba1 100644 --- a/qemu/hw/i386/pc.c +++ b/qemu/hw/i386/pc.c @@ -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) diff --git a/qemu/hw/i386/pc_piix.c b/qemu/hw/i386/pc_piix.c index 41f06ee3..b9759621 100644 --- a/qemu/hw/i386/pc_piix.c +++ b/qemu/hw/i386/pc_piix.c @@ -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 \ diff --git a/qemu/hw/intc/apic.c b/qemu/hw/intc/apic.c index 0cd0ab68..e58d742b 100644 --- a/qemu/hw/intc/apic.c +++ b/qemu/hw/intc/apic.c @@ -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) diff --git a/qemu/hw/intc/apic_common.c b/qemu/hw/intc/apic_common.c index d8f9cda6..c5d32e39 100644 --- a/qemu/hw/intc/apic_common.c +++ b/qemu/hw/intc/apic_common.c @@ -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) diff --git a/qemu/hw/m68k/dummy_m68k.c b/qemu/hw/m68k/dummy_m68k.c index 735e820c..5fd6ecb0 100644 --- a/qemu/hw/m68k/dummy_m68k.c +++ b/qemu/hw/m68k/dummy_m68k.c @@ -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) diff --git a/qemu/hw/mips/mips_r4k.c b/qemu/hw/mips/mips_r4k.c index 739d8029..0482567c 100644 --- a/qemu/hw/mips/mips_r4k.c +++ b/qemu/hw/mips/mips_r4k.c @@ -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) diff --git a/qemu/hw/sparc/leon3.c b/qemu/hw/sparc/leon3.c index 48c04576..07a4296c 100644 --- a/qemu/hw/sparc/leon3.c +++ b/qemu/hw/sparc/leon3.c @@ -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) diff --git a/qemu/hw/sparc64/sun4u.c b/qemu/hw/sparc64/sun4u.c index 7377a023..7e85a4a4 100644 --- a/qemu/hw/sparc64/sun4u.c +++ b/qemu/hw/sparc64/sun4u.c @@ -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) diff --git a/qemu/include/hw/boards.h b/qemu/include/hw/boards.h index b18d75ad..e0afde01 100644 --- a/qemu/include/hw/boards.h +++ b/qemu/include/hw/boards.h @@ -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; diff --git a/qemu/include/hw/i386/pc.h b/qemu/include/hw/i386/pc.h index c5478641..c149ed7a 100644 --- a/qemu/include/hw/i386/pc.h +++ b/qemu/include/hw/i386/pc.h @@ -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, diff --git a/qemu/include/hw/qdev-core.h b/qemu/include/hw/qdev-core.h index c735dfe0..bfaf773b 100644 --- a/qemu/include/hw/qdev-core.h +++ b/qemu/include/hw/qdev-core.h @@ -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); diff --git a/qemu/include/qemu/thread.h b/qemu/include/qemu/thread.h index de5956b2..2a402673 100644 --- a/qemu/include/qemu/thread.h +++ b/qemu/include/qemu/thread.h @@ -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); diff --git a/qemu/include/qom/cpu.h b/qemu/include/qom/cpu.h index 4e293c21..fb666d1e 100644 --- a/qemu/include/qom/cpu.h +++ b/qemu/include/qom/cpu.h @@ -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 */ diff --git a/qemu/include/qom/object.h b/qemu/include/qom/object.h index 8e097cf7..001e6236 100644 --- a/qemu/include/qom/object.h +++ b/qemu/include/qom/object.h @@ -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); /** diff --git a/qemu/include/sysemu/cpus.h b/qemu/include/sysemu/cpus.h index 80843a65..f22ad69d 100644 --- a/qemu/include/sysemu/cpus.h +++ b/qemu/include/sysemu/cpus.h @@ -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*); diff --git a/qemu/include/sysemu/sysemu.h b/qemu/include/sysemu/sysemu.h index 3e08b527..f2ab6e95 100644 --- a/qemu/include/sysemu/sysemu.h +++ b/qemu/include/sysemu/sysemu.h @@ -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); diff --git a/qemu/qom/cpu.c b/qemu/qom/cpu.c index c98535ca..d01d5f5c 100644 --- a/qemu/qom/cpu.c +++ b/qemu/qom/cpu.c @@ -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) diff --git a/qemu/qom/object.c b/qemu/qom/object.c index ab6b4882..aca451ba 100644 --- a/qemu/qom/object.c +++ b/qemu/qom/object.c @@ -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, diff --git a/qemu/qom/qom-qobject.c b/qemu/qom/qom-qobject.c index 9b0172ea..f1579ff2 100644 --- a/qemu/qom/qom-qobject.c +++ b/qemu/qom/qom-qobject.c @@ -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); } diff --git a/qemu/target-arm/cpu.c b/qemu/target-arm/cpu.c index d52b56d2..3373be6b 100644 --- a/qemu/target-arm/cpu.c +++ b/qemu/target-arm/cpu.c @@ -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) diff --git a/qemu/target-i386/cpu.c b/qemu/target-i386/cpu.c index 4301b946..d8b58510 100644 --- a/qemu/target-i386/cpu.c +++ b/qemu/target-i386/cpu.c @@ -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 */ diff --git a/qemu/target-m68k/cpu.c b/qemu/target-m68k/cpu.c index 140179b0..19e00067 100644 --- a/qemu/target-m68k/cpu.c +++ b/qemu/target-m68k/cpu.c @@ -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) diff --git a/qemu/target-mips/cpu.c b/qemu/target-mips/cpu.c index 2cb6e14a..00672634 100644 --- a/qemu/target-mips/cpu.c +++ b/qemu/target-mips/cpu.c @@ -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) diff --git a/qemu/target-sparc/cpu.c b/qemu/target-sparc/cpu.c index e14c4c55..c3f779b7 100644 --- a/qemu/target-sparc/cpu.c +++ b/qemu/target-sparc/cpu.c @@ -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) diff --git a/qemu/util/qemu-thread-posix.c b/qemu/util/qemu-thread-posix.c index 34632bca..26cba2da 100644 --- a/qemu/util/qemu-thread-posix.c +++ b/qemu/util/qemu-thread-posix.c @@ -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) diff --git a/qemu/util/qemu-thread-win32.c b/qemu/util/qemu-thread-win32.c index 3f7f7015..2c2cf4ad 100644 --- a/qemu/util/qemu-thread-win32.c +++ b/qemu/util/qemu-thread-win32.c @@ -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) diff --git a/qemu/vl.c b/qemu/vl.c index a65a91fa..caf6686f 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -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) diff --git a/uc.c b/uc.c index cf9e7026..7ff96368 100644 --- a/uc.c +++ b/uc.c @@ -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);