diff --git a/qemu/hw/core/qdev.c b/qemu/hw/core/qdev.c index b0262aaf..8fc6dbdf 100644 --- a/qemu/hw/core/qdev.c +++ b/qemu/hw/core/qdev.c @@ -30,7 +30,7 @@ #include "qapi/qmp/qerror.h" -static void bus_add_child(BusState *bus, DeviceState *child) +static void bus_add_child(struct uc_struct *uc, BusState *bus, DeviceState *child) { char name[32]; BusChild *kid = g_malloc0(sizeof(*kid)); @@ -43,7 +43,7 @@ static void bus_add_child(BusState *bus, DeviceState *child) /* This transfers ownership of kid->child to the property. */ snprintf(name, sizeof(name), "child[%d]", kid->index); - object_property_add_link(OBJECT(bus), name, + object_property_add_link(uc, OBJECT(bus), name, object_get_typename(OBJECT(child)), (Object **)&kid->child, NULL, /* read-only property */ @@ -51,11 +51,11 @@ static void bus_add_child(BusState *bus, DeviceState *child) NULL); } -void qdev_set_parent_bus(DeviceState *dev, BusState *bus) +void qdev_set_parent_bus(struct uc_struct *uc, DeviceState *dev, BusState *bus) { dev->parent_bus = bus; object_ref(OBJECT(bus)); - bus_add_child(bus, dev); + bus_add_child(uc, bus, dev); } /* Create a new device. This only initializes the device state structure diff --git a/qemu/include/hw/qdev-core.h b/qemu/include/hw/qdev-core.h index f10312e3..f6d5db7e 100644 --- a/qemu/include/hw/qdev-core.h +++ b/qemu/include/hw/qdev-core.h @@ -333,7 +333,7 @@ const char *qdev_fw_name(DeviceState *dev); Object *qdev_get_machine(struct uc_struct *); /* FIXME: make this a link<> */ -void qdev_set_parent_bus(DeviceState *dev, BusState *bus); +void qdev_set_parent_bus(struct uc_struct *uc, DeviceState *dev, BusState *bus); extern int qdev_hotplug; diff --git a/qemu/include/qom/object.h b/qemu/include/qom/object.h index 9f400f50..352f2f2f 100644 --- a/qemu/include/qom/object.h +++ b/qemu/include/qom/object.h @@ -381,6 +381,8 @@ struct ObjectClass const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE]; ObjectUnparent *unparent; + + GHashTable *properties; }; /** @@ -792,7 +794,8 @@ void object_unref(struct uc_struct *uc, Object *obj); * Returns: The #ObjectProperty; this can be used to set the @resolve * callback for child and link properties. */ -ObjectProperty *object_property_add(Object *obj, const char *name, +ObjectProperty *object_property_add(struct uc_struct *uc, Object *obj, + const char *name, const char *type, ObjectPropertyAccessor *get, ObjectPropertyAccessor *set, @@ -801,6 +804,14 @@ ObjectProperty *object_property_add(Object *obj, const char *name, void object_property_del(struct uc_struct *uc, Object *obj, const char *name, Error **errp); +ObjectProperty *object_class_property_add(struct uc_struct *uc, ObjectClass *klass, const char *name, + const char *type, + ObjectPropertyAccessor *get, + ObjectPropertyAccessor *set, + ObjectPropertyRelease *release, + void *opaque, Error **errp); + + void object_property_del_child(struct uc_struct *uc, Object *obj, Object *child, Error **errp); /** @@ -811,8 +822,10 @@ void object_property_del_child(struct uc_struct *uc, Object *obj, Object *child, * * Look up a property for an object and return its #ObjectProperty if found. */ -ObjectProperty *object_property_find(Object *obj, const char *name, - Error **errp); +ObjectProperty *object_property_find(struct uc_struct *uc, Object *obj, + const char *name, Error **errp); +ObjectProperty *object_class_property_find(struct uc_struct *uc, ObjectClass *klass, + const char *name, Error **errp); typedef struct ObjectPropertyIterator ObjectPropertyIterator; @@ -821,7 +834,7 @@ typedef struct ObjectPropertyIterator ObjectPropertyIterator; * @obj: the object * * Initializes an iterator for traversing all properties - * registered against an object instance. + * registered against an object instance, its class and all parent classes. * * It is forbidden to modify the property list while iterating, * whether removing or adding properties. @@ -861,7 +874,7 @@ void object_property_iter_free(ObjectPropertyIterator *iter); * Returns: the next property, or %NULL when all properties * have been traversed. */ -ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter); +ObjectProperty *object_property_iter_next(struct uc_struct *uc, ObjectPropertyIterator *iter); void object_unparent(struct uc_struct *uc, Object *obj); @@ -875,8 +888,8 @@ void object_unparent(struct uc_struct *uc, Object *obj); * * Reads a property from a object. */ -void object_property_get(struct uc_struct *uc, Object *obj, Visitor *v, const char *name, - Error **errp); +void object_property_get(struct uc_struct *uc, Object *obj, Visitor *v, + const char *name, Error **errp); /** * object_property_set_str: @@ -886,8 +899,9 @@ void object_property_get(struct uc_struct *uc, Object *obj, Visitor *v, const ch * * Writes a string value to a property. */ -void object_property_set_str(struct uc_struct *uc, Object *obj, const char *value, - const char *name, Error **errp); +void object_property_set_str(struct uc_struct *uc, Object *obj, + const char *value, const char *name, + Error **errp); /** * object_property_get_str: @@ -899,8 +913,8 @@ void object_property_set_str(struct uc_struct *uc, Object *obj, const char *valu * an error occurs (including when the property value is not a string). * The caller should free the string. */ -char *object_property_get_str(struct uc_struct *uc, Object *obj, const char *name, - Error **errp); +char *object_property_get_str(struct uc_struct *uc, Object *obj, + const char *name, Error **errp); /** * object_property_set_link: @@ -923,8 +937,8 @@ void object_property_set_link(struct uc_struct *uc, Object *obj, Object *value, * or NULL if an error occurs (including when the property value is not a * string or not a valid object path). */ -Object *object_property_get_link(struct uc_struct *uc, Object *obj, const char *name, - Error **errp); +Object *object_property_get_link(struct uc_struct *uc, Object *obj, + const char *name, Error **errp); /** * object_property_set_bool: @@ -946,8 +960,8 @@ void object_property_set_bool(struct uc_struct *uc, Object *obj, bool value, * Returns: the value of the property, converted to a boolean, or NULL if * an error occurs (including when the property value is not a bool). */ -bool object_property_get_bool(struct uc_struct *uc, Object *obj, const char *name, - Error **errp); +bool object_property_get_bool(struct uc_struct *uc, Object *obj, + const char *name, Error **errp); /** * object_property_set_int: @@ -969,8 +983,8 @@ void object_property_set_int(struct uc_struct *uc, Object *obj, int64_t value, * Returns: the value of the property, converted to an integer, or negative if * an error occurs (including when the property value is not an integer). */ -int64_t object_property_get_int(struct uc_struct *uc, Object *obj, const char *name, - Error **errp); +int64_t object_property_get_int(struct uc_struct *uc, Object *obj, + const char *name, Error **errp); /** * object_property_set: @@ -983,8 +997,8 @@ int64_t object_property_get_int(struct uc_struct *uc, Object *obj, const char *n * * Writes a property to a object. */ -void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, const char *name, - Error **errp); +void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, + const char *name, Error **errp); /** * object_property_parse: @@ -995,8 +1009,9 @@ void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, const ch * * Parses a string and writes the result into a property of an object. */ -void object_property_parse(struct uc_struct *uc, Object *obj, const char *string, - const char *name, Error **errp); +void object_property_parse(struct uc_struct *uc, Object *obj, + const char *string, const char *name, + Error **errp); /** * object_property_get_type: @@ -1006,8 +1021,8 @@ void object_property_parse(struct uc_struct *uc, Object *obj, const char *string * * Returns: The type name of the property. */ -const char *object_property_get_type(Object *obj, const char *name, - Error **errp); +const char *object_property_get_type(struct uc_struct *uc, Object *obj, + const char *name, Error **errp); /** * object_get_root: @@ -1055,7 +1070,8 @@ gchar *object_get_canonical_path(Object *obj); * * Returns: The matched object or NULL on path lookup failure. */ -Object *object_resolve_path(struct uc_struct *uc, const char *path, bool *ambiguous); +Object *object_resolve_path(struct uc_struct *uc, const char *path, + bool *ambiguous); /** * object_resolve_path_type: @@ -1075,7 +1091,9 @@ Object *object_resolve_path(struct uc_struct *uc, const char *path, bool *ambigu * * Returns: The matched object or NULL on path lookup failure. */ -Object *object_resolve_path_type(struct uc_struct *uc, const char *path, const char *typename, +Object *object_resolve_path_type(struct uc_struct *uc, + const char *path, + const char *typename, bool *ambiguous); /** @@ -1088,7 +1106,9 @@ Object *object_resolve_path_type(struct uc_struct *uc, const char *path, const c * * Returns: The resolved object or NULL on path lookup failure. */ -Object *object_resolve_path_component(struct uc_struct *uc, Object *parent, const gchar *part); +Object *object_resolve_path_component(struct uc_struct *uc, + Object *parent, + const gchar *part); /** * object_property_add_child: @@ -1107,8 +1127,9 @@ Object *object_resolve_path_component(struct uc_struct *uc, Object *parent, cons * canonical path. It can be retrieved using object_property_get_str(). * The child object itself can be retrieved using object_property_get_link(). */ -void object_property_add_child(Object *obj, const char *name, - Object *child, Error **errp); +void object_property_add_child(struct uc_struct *uc, Object *obj, + const char *name, Object *child, + Error **errp); typedef enum { /* Unref the link pointer when the property is deleted */ @@ -1153,7 +1174,7 @@ void object_property_allow_set_link(Object *, const char *, * @flags OBJ_PROP_LINK_UNREF_ON_RELEASE bit is set, * the reference count is decremented when the property is deleted. */ -void object_property_add_link(Object *obj, const char *name, +void object_property_add_link(struct uc_struct *uc, Object *obj, const char *name, const char *type, Object **child, void (*check)(Object *obj, const char *name, Object *val, Error **errp), @@ -1172,10 +1193,16 @@ void object_property_add_link(Object *obj, const char *name, * Add a string property using getters/setters. This function will add a * property of type 'string'. */ -void object_property_add_str(Object *obj, const char *name, +void object_property_add_str(struct uc_struct *uc, Object *obj, const char *name, char *(*get)(struct uc_struct *uc, Object *, Error **), int (*set)(struct uc_struct *uc, Object *, const char *, Error **), Error **errp); +void object_class_property_add_str(struct uc_struct *uc, ObjectClass *klass, + const char *name, + char *(*get)(struct uc_struct *uc, Object *, Error **), + int (*set)(struct uc_struct *uc, Object *, const char *, + Error **), + Error **errp); /** * object_property_add_bool: @@ -1192,6 +1219,10 @@ void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *nam bool (*get)(struct uc_struct *uc, Object *, Error **), int (*set)(struct uc_struct *uc, Object *, bool, Error **), Error **errp); +void object_class_property_add_bool(struct uc_struct *uc, ObjectClass *klass, const char *name, + bool (*get)(struct uc_struct *, Object *, Error **), + int (*set)(struct uc_struct *, Object *, bool, Error **), + Error **errp); /** * object_property_add_uint8_ptr: @@ -1203,8 +1234,12 @@ void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *nam * Add an integer property in memory. This function will add a * property of type 'uint8'. */ -void object_property_add_uint8_ptr(Object *obj, const char *name, - const uint8_t *v, Error **errp); +void object_property_add_uint8_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint8_t *v, + Error **errp); +void object_class_property_add_uint8_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint8_t *v, + Error **errp); /** * object_property_add_uint16_ptr: @@ -1216,8 +1251,12 @@ void object_property_add_uint8_ptr(Object *obj, const char *name, * Add an integer property in memory. This function will add a * property of type 'uint16'. */ -void object_property_add_uint16_ptr(Object *obj, const char *name, - const uint16_t *v, Error **errp); +void object_property_add_uint16_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint16_t *v, + Error **errp); +void object_class_property_add_uint16_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint16_t *v, + Error **errp); /** * object_property_add_uint32_ptr: @@ -1229,8 +1268,12 @@ void object_property_add_uint16_ptr(Object *obj, const char *name, * Add an integer property in memory. This function will add a * property of type 'uint32'. */ -void object_property_add_uint32_ptr(Object *obj, const char *name, - const uint32_t *v, Error **errp); +void object_property_add_uint32_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint32_t *v, + Error **errp); +void object_class_property_add_uint32_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint32_t *v, + Error **errp); /** * object_property_add_uint64_ptr: @@ -1242,8 +1285,12 @@ void object_property_add_uint32_ptr(Object *obj, const char *name, * Add an integer property in memory. This function will add a * property of type 'uint64'. */ -void object_property_add_uint64_ptr(Object *obj, const char *name, - const uint64_t *v, Error **Errp); +void object_property_add_uint64_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint64_t *v, + Error **Errp); +void object_class_property_add_uint64_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint64_t *v, + Error **Errp); /** * object_property_add_alias: @@ -1261,7 +1308,7 @@ void object_property_add_uint64_ptr(Object *obj, const char *name, * object this will be the case. For aliases to other objects the caller is * responsible for taking a reference. */ -void object_property_add_alias(Object *obj, const char *name, +void object_property_add_alias(struct uc_struct *uc, Object *obj, const char *name, Object *target_obj, const char *target_name, Error **errp); @@ -1275,8 +1322,12 @@ void object_property_add_alias(Object *obj, const char *name, * Set an object property's description. * */ -void object_property_set_description(Object *obj, const char *name, - const char *description, Error **errp); +void object_property_set_description(struct uc_struct *uc, Object *obj, + const char *name, const char *description, + Error **errp); +void object_class_property_set_description(struct uc_struct *uc, ObjectClass *klass, + const char *name, const char *description, + Error **errp); /** * object_child_foreach: diff --git a/qemu/memory.c b/qemu/memory.c index 89915130..ee9bb17a 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -877,7 +877,7 @@ void memory_region_init(struct uc_struct *uc, MemoryRegion *mr, uc->owner = owner; } - object_property_add_child(owner, name_array, OBJECT(mr), &error_abort); + object_property_add_child(uc, owner, name_array, OBJECT(mr), &error_abort); object_unref(uc, OBJECT(mr)); g_free(name_array); g_free(escaped_name); @@ -961,18 +961,18 @@ static void memory_region_initfn(struct uc_struct *uc, Object *obj, void *opaque mr->destructor = memory_region_destructor_none; QTAILQ_INIT(&mr->subregions); - op = object_property_add(OBJECT(mr), "container", + op = object_property_add(mr->uc, OBJECT(mr), "container", "link<" TYPE_MEMORY_REGION ">", memory_region_get_container, NULL, /* memory_region_set_container */ NULL, NULL, &error_abort); op->resolve = memory_region_resolve_container; - object_property_add(OBJECT(mr), "addr", "uint64", + object_property_add(mr->uc, OBJECT(mr), "addr", "uint64", memory_region_get_addr, NULL, /* memory_region_set_addr */ NULL, NULL, &error_abort); - object_property_add(OBJECT(mr), "priority", "uint32", + object_property_add(mr->uc, OBJECT(mr), "priority", "uint32", memory_region_get_priority, NULL, /* memory_region_set_priority */ NULL, NULL, &error_abort); @@ -980,7 +980,7 @@ static void memory_region_initfn(struct uc_struct *uc, Object *obj, void *opaque memory_region_get_may_overlap, NULL, /* memory_region_set_may_overlap */ &error_abort); - object_property_add(OBJECT(mr), "size", "uint64", + object_property_add(mr->uc, OBJECT(mr), "size", "uint64", memory_region_get_size, NULL, /* memory_region_set_size, */ NULL, NULL, &error_abort); diff --git a/qemu/qom/container.c b/qemu/qom/container.c index e9210268..e4de94a7 100644 --- a/qemu/qom/container.c +++ b/qemu/qom/container.c @@ -40,7 +40,7 @@ Object *container_get(struct uc_struct *uc, Object *root, const char *path) child = object_resolve_path_component(uc, obj, parts[i]); if (!child) { child = object_new(uc, "container"); - object_property_add_child(obj, parts[i], child, NULL); + object_property_add_child(uc, obj, parts[i], child, NULL); } } diff --git a/qemu/qom/object.c b/qemu/qom/object.c index 6abb8484..18075868 100644 --- a/qemu/qom/object.c +++ b/qemu/qom/object.c @@ -67,6 +67,7 @@ struct TypeImpl }; struct ObjectPropertyIterator { + ObjectClass *nextclass; GHashTableIter iter; }; @@ -241,6 +242,16 @@ static void type_initialize_interface(struct uc_struct *uc, TypeImpl *ti, TypeIm iface_impl->class); } +static void object_property_free(gpointer data) +{ + ObjectProperty *prop = data; + + g_free(prop->name); + g_free(prop->type); + g_free(prop->description); + g_free(prop); +} + static void type_initialize(struct uc_struct *uc, TypeImpl *ti) { TypeImpl *parent; @@ -263,6 +274,8 @@ static void type_initialize(struct uc_struct *uc, TypeImpl *ti) g_assert(parent->class_size <= ti->class_size); memcpy(ti->class, parent->class, parent->class_size); ti->class->interfaces = NULL; + ti->class->properties = g_hash_table_new_full( + g_str_hash, g_str_equal, g_free, object_property_free); for (e = parent->class->interfaces; e; e = e->next) { InterfaceClass *iface = e->data; @@ -287,6 +300,9 @@ static void type_initialize(struct uc_struct *uc, TypeImpl *ti) type_initialize_interface(uc, ti, t, t); } + } else { + ti->class->properties = g_hash_table_new_full( + g_str_hash, g_str_equal, g_free, object_property_free); } ti->class->type = ti; @@ -325,16 +341,6 @@ static void object_post_init_with_type(struct uc_struct *uc, Object *obj, TypeIm } } -static void object_property_free(gpointer data) -{ - ObjectProperty *prop = data; - - g_free(prop->name); - g_free(prop->type); - g_free(prop->description); - g_free(prop); -} - static void object_initialize_with_type(struct uc_struct *uc, void *data, size_t size, TypeImpl *type) { Object *obj = data; @@ -771,7 +777,8 @@ void object_unref(struct uc_struct *uc, Object *obj) } ObjectProperty * -object_property_add(Object *obj, const char *name, const char *type, +object_property_add(struct uc_struct *uc, Object *obj, + const char *name, const char *type, ObjectPropertyAccessor *get, ObjectPropertyAccessor *set, ObjectPropertyRelease *release, @@ -789,7 +796,7 @@ object_property_add(Object *obj, const char *name, const char *type, for (i = 0; ; ++i) { char *full_name = g_strdup_printf("%s[%d]", name_no_array, i); - ret = object_property_add(obj, full_name, type, get, set, + ret = object_property_add(uc, obj, full_name, type, get, set, release, opaque, NULL); g_free(full_name); if (ret) { @@ -800,10 +807,10 @@ object_property_add(Object *obj, const char *name, const char *type, return ret; } - if (g_hash_table_lookup(obj->properties, name) != NULL) { + if (object_property_find(uc, obj, name, NULL) != NULL) { error_setg(errp, "attempt to add duplicate property '%s'" - " to object (type '%s')", name, - object_get_typename(obj)); + " to object (type '%s')", name, + object_get_typename(obj)); return NULL; } @@ -821,11 +828,52 @@ object_property_add(Object *obj, const char *name, const char *type, return prop; } -ObjectProperty *object_property_find(Object *obj, const char *name, - Error **errp) +ObjectProperty * +object_class_property_add(struct uc_struct *uc, + ObjectClass *klass, + const char *name, + const char *type, + ObjectPropertyAccessor *get, + ObjectPropertyAccessor *set, + ObjectPropertyRelease *release, + void *opaque, + Error **errp) { ObjectProperty *prop; + if (object_class_property_find(uc, klass, name, NULL) != NULL) { + error_setg(errp, "attempt to add duplicate property '%s'" + " to object (type '%s')", name, + object_class_get_name(klass)); + return NULL; + } + + prop = g_malloc0(sizeof(*prop)); + + prop->name = g_strdup(name); + prop->type = g_strdup(type); + + prop->get = get; + prop->set = set; + prop->release = release; + prop->opaque = opaque; + + g_hash_table_insert(klass->properties, g_strdup(name), prop); + + return prop; +} + +ObjectProperty *object_property_find(struct uc_struct *uc, Object *obj, + const char *name, Error **errp) +{ + ObjectProperty *prop; + ObjectClass *klass = object_get_class(obj); + + prop = object_class_property_find(uc, klass, name, NULL); + if (prop) { + return prop; + } + prop = g_hash_table_lookup(obj->properties, name); if (prop) { return prop; @@ -839,6 +887,7 @@ ObjectPropertyIterator *object_property_iter_init(Object *obj) { ObjectPropertyIterator *ret = g_new0(ObjectPropertyIterator, 1); g_hash_table_iter_init(&ret->iter, obj->properties); + ret->nextclass = object_get_class(obj); return ret; } @@ -850,15 +899,40 @@ void object_property_iter_free(ObjectPropertyIterator *iter) g_free(iter); } -ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter) +ObjectProperty *object_property_iter_next(struct uc_struct *uc, ObjectPropertyIterator *iter) { gpointer key, val; - if (!g_hash_table_iter_next(&iter->iter, &key, &val)) { - return NULL; + while (!g_hash_table_iter_next(&iter->iter, &key, &val)) { + if (!iter->nextclass) { + return NULL; + } + g_hash_table_iter_init(&iter->iter, iter->nextclass->properties); + iter->nextclass = object_class_get_parent(uc, iter->nextclass); } return val; } +ObjectProperty *object_class_property_find(struct uc_struct *uc, ObjectClass *klass, + const char *name, Error **errp) +{ + ObjectProperty *prop; + ObjectClass *parent_klass; + + parent_klass = object_class_get_parent(uc, klass); + if (parent_klass) { + prop = object_class_property_find(uc, parent_klass, name, NULL); + if (prop) { + return prop; + } + } + + prop = g_hash_table_lookup(klass->properties, name); + if (!prop) { + error_setg(errp, "Property '.%s' not found", name); + } + return prop; +} + void object_property_del(struct uc_struct *uc, Object *obj, const char *name, Error **errp) { ObjectProperty *prop = g_hash_table_lookup(obj->properties, name); @@ -875,10 +949,10 @@ void object_property_del(struct uc_struct *uc, Object *obj, const char *name, Er g_hash_table_remove(obj->properties, name); } -void object_property_get(struct uc_struct *uc, Object *obj, Visitor *v, const char *name, - Error **errp) +void object_property_get(struct uc_struct *uc, Object *obj, Visitor *v, + const char *name, Error **errp) { - ObjectProperty *prop = object_property_find(obj, name, errp); + ObjectProperty *prop = object_property_find(uc, obj, name, errp); if (prop == NULL) { return; } @@ -890,10 +964,10 @@ void object_property_get(struct uc_struct *uc, Object *obj, Visitor *v, const ch } } -void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, const char *name, - Error **errp) +void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, + const char *name, Error **errp) { - ObjectProperty *prop = object_property_find(obj, name, errp); + ObjectProperty *prop = object_property_find(uc, obj, name, errp); if (prop == NULL) { return; } @@ -1038,9 +1112,10 @@ void object_property_parse(struct uc_struct *uc, Object *obj, const char *string string_input_visitor_cleanup(siv); } -const char *object_property_get_type(Object *obj, const char *name, Error **errp) +const char *object_property_get_type(struct uc_struct *uc, Object *obj, + const char *name, Error **errp) { - ObjectProperty *prop = object_property_find(obj, name, errp); + ObjectProperty *prop = object_property_find(uc, obj, name, errp); if (prop == NULL) { return NULL; } @@ -1085,8 +1160,9 @@ static void object_finalize_child_property(struct uc_struct *uc, Object *obj, co object_unref(uc, child); } -void object_property_add_child(Object *obj, const char *name, - Object *child, Error **errp) +void object_property_add_child(struct uc_struct *uc, Object *obj, + const char *name, Object *child, + Error **errp) { Error *local_err = NULL; gchar *type; @@ -1099,7 +1175,7 @@ void object_property_add_child(Object *obj, const char *name, type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); - op = object_property_add(obj, name, type, object_get_child_property, NULL, + op = object_property_add(uc, obj, name, type, object_get_child_property, NULL, object_finalize_child_property, child, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -1163,7 +1239,7 @@ static Object *object_resolve_link(struct uc_struct *uc, Object *obj, const char Object *target; /* Go from link to FOO. */ - type = object_property_get_type(obj, name, NULL); + type = object_property_get_type(uc, obj, name, NULL); target_type = g_strndup(&type[5], strlen(type) - 6); target = object_resolve_path_type(uc, path, target_type, &ambiguous); @@ -1238,7 +1314,7 @@ static void object_release_link_property(struct uc_struct *uc, Object *obj, cons g_free(prop); } -void object_property_add_link(Object *obj, const char *name, +void object_property_add_link(struct uc_struct *uc, Object *obj, const char *name, const char *type, Object **child, void (*check)(Object *, const char *, Object *, Error **), @@ -1256,7 +1332,7 @@ void object_property_add_link(Object *obj, const char *name, full_type = g_strdup_printf("link<%s>", type); - op = object_property_add(obj, name, full_type, + op = object_property_add(uc, obj, name, full_type, object_get_link_property, check ? object_set_link_property : NULL, object_release_link_property, @@ -1326,7 +1402,7 @@ gchar *object_get_canonical_path(Object *obj) Object *object_resolve_path_component(struct uc_struct *uc, Object *parent, const gchar *part) { - ObjectProperty *prop = object_property_find(parent, part, NULL); + ObjectProperty *prop = object_property_find(uc, parent, part, NULL); if (prop == NULL) { return NULL; } @@ -1480,7 +1556,7 @@ static void property_release_str(struct uc_struct *uc, Object *obj, const char * g_free(prop); } -void object_property_add_str(Object *obj, const char *name, +void object_property_add_str(struct uc_struct *uc, Object *obj, const char *name, char *(*get)(struct uc_struct *uc, Object *, Error **), int (*set)(struct uc_struct *uc, Object *, const char *, Error **), Error **errp) @@ -1491,7 +1567,7 @@ void object_property_add_str(Object *obj, const char *name, prop->get = get; prop->set = set; - object_property_add(obj, name, "string", + object_property_add(uc, obj, name, "string", get ? property_get_str : NULL, set ? property_set_str : NULL, property_release_str, @@ -1502,6 +1578,29 @@ void object_property_add_str(Object *obj, const char *name, } } +void object_class_property_add_str(struct uc_struct *uc, ObjectClass *klass, const char *name, + char *(*get)(struct uc_struct *, Object *, Error **), + int (*set)(struct uc_struct *, Object *, const char *, + Error **), + Error **errp) +{ + Error *local_err = NULL; + StringProperty *prop = g_malloc0(sizeof(*prop)); + + prop->get = get; + prop->set = set; + + object_class_property_add(uc, klass, name, "string", + get ? property_get_str : NULL, + set ? property_set_str : NULL, + property_release_str, + prop, &local_err); + if (local_err) { + error_propagate(errp, local_err); + g_free(prop); + } +} + typedef struct BoolProperty { bool (*get)(struct uc_struct *uc, Object *, Error **); @@ -1556,7 +1655,7 @@ void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *nam prop->get = get; prop->set = set; - object_property_add(obj, name, "bool", + object_property_add(uc, obj, name, "bool", get ? property_get_bool : NULL, set ? property_set_bool : NULL, property_release_bool, @@ -1567,6 +1666,29 @@ void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *nam } } +void object_class_property_add_bool(struct uc_struct *uc, ObjectClass *klass, + const char *name, + bool (*get)(struct uc_struct *, Object *, Error **), + int (*set)(struct uc_struct *, Object *, bool, Error **), + Error **errp) +{ + Error *local_err = NULL; + BoolProperty *prop = g_malloc0(sizeof(*prop)); + + prop->get = get; + prop->set = set; + + object_class_property_add(uc, klass, name, "bool", + get ? property_get_bool : NULL, + set ? property_set_bool : NULL, + property_release_bool, + prop, &local_err); + if (local_err) { + error_propagate(errp, local_err); + g_free(prop); + } +} + static char *qdev_get_type(struct uc_struct *uc, Object *obj, Error **errp) { return g_strdup(object_get_typename(obj)); @@ -1604,31 +1726,67 @@ static void property_get_uint64_ptr(struct uc_struct *uc, Object *obj, Visitor * visit_type_uint64(v, name, &value, errp); } -void object_property_add_uint8_ptr(Object *obj, const char *name, - const uint8_t *v, Error **errp) +void object_class_property_add_uint8_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint8_t *v, + Error **errp) { - object_property_add(obj, name, "uint8", property_get_uint8_ptr, + object_class_property_add(uc, klass, name, "uint8", property_get_uint8_ptr, + NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint8_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint8_t *v, + Error **errp) +{ + object_property_add(uc, obj, name, "uint8", property_get_uint8_ptr, NULL, NULL, (void *)v, errp); } -void object_property_add_uint16_ptr(Object *obj, const char *name, - const uint16_t *v, Error **errp) +void object_class_property_add_uint16_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint16_t *v, + Error **errp) { - object_property_add(obj, name, "uint16", property_get_uint16_ptr, + object_class_property_add(uc, klass, name, "uint16", property_get_uint16_ptr, + NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint16_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint16_t *v, + Error **errp) +{ + object_property_add(uc, obj, name, "uint16", property_get_uint16_ptr, NULL, NULL, (void *)v, errp); } -void object_property_add_uint32_ptr(Object *obj, const char *name, - const uint32_t *v, Error **errp) +void object_class_property_add_uint32_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint32_t *v, + Error **errp) { - object_property_add(obj, name, "uint32", property_get_uint32_ptr, + object_class_property_add(uc, klass, name, "uint32", property_get_uint32_ptr, + NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint32_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint32_t *v, + Error **errp) +{ + object_property_add(uc, obj, name, "uint32", property_get_uint32_ptr, NULL, NULL, (void *)v, errp); } -void object_property_add_uint64_ptr(Object *obj, const char *name, - const uint64_t *v, Error **errp) +void object_class_property_add_uint64_ptr(struct uc_struct *uc, ObjectClass *klass, + const char *name, const uint64_t *v, + Error **errp) { - object_property_add(obj, name, "uint64", property_get_uint64_ptr, + object_class_property_add(uc, klass, name, "uint64", property_get_uint64_ptr, + NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint64_ptr(struct uc_struct *uc, Object *obj, + const char *name, const uint64_t *v, + Error **errp) +{ + object_property_add(uc, obj, name, "uint64", property_get_uint64_ptr, NULL, NULL, (void *)v, errp); } @@ -1673,8 +1831,9 @@ static void property_release_alias(struct uc_struct *uc, Object *obj, const char g_free(prop); } -void object_property_add_alias(Object *obj, const char *name, - Object *target_obj, const char *target_name, +void object_property_add_alias(struct uc_struct *uc, Object *obj, + const char *name, Object *target_obj, + const char *target_name, Error **errp) { AliasProperty *prop; @@ -1683,7 +1842,7 @@ void object_property_add_alias(Object *obj, const char *name, gchar *prop_type; Error *local_err = NULL; - target_prop = object_property_find(target_obj, target_name, errp); + target_prop = object_property_find(uc, target_obj, target_name, errp); if (!target_prop) { return; } @@ -1699,7 +1858,7 @@ void object_property_add_alias(Object *obj, const char *name, prop->target_obj = target_obj; prop->target_name = g_strdup(target_name); - op = object_property_add(obj, name, prop_type, + op = object_property_add(uc, obj, name, prop_type, property_get_alias, property_set_alias, property_release_alias, @@ -1711,7 +1870,7 @@ void object_property_add_alias(Object *obj, const char *name, } op->resolve = property_resolve_alias; - object_property_set_description(obj, op->name, + object_property_set_description(uc, obj, op->name, target_prop->description, &error_abort); @@ -1719,12 +1878,13 @@ out: g_free(prop_type); } -void object_property_set_description(Object *obj, const char *name, - const char *description, Error **errp) +void object_property_set_description(struct uc_struct *uc, Object *obj, + const char *name, const char *description, + Error **errp) { ObjectProperty *op; - op = object_property_find(obj, name, errp); + op = object_property_find(uc, obj, name, errp); if (!op) { return; } @@ -1733,9 +1893,27 @@ void object_property_set_description(Object *obj, const char *name, op->description = g_strdup(description); } +void object_class_property_set_description(struct uc_struct *uc, + ObjectClass *klass, + const char *name, + const char *description, + Error **errp) +{ + ObjectProperty *op; + + op = g_hash_table_lookup(klass->properties, name); + if (!op) { + error_setg(errp, "Property '.%s' not found", name); + return; + } + + g_free(op->description); + op->description = g_strdup(description); +} + static void object_instance_init(struct uc_struct *uc, Object *obj, void *opaque) { - object_property_add_str(obj, "type", qdev_get_type, NULL, NULL); + object_property_add_str(uc, obj, "type", qdev_get_type, NULL, NULL); } void register_types_object(struct uc_struct *uc) diff --git a/qemu/target-i386/cpu.c b/qemu/target-i386/cpu.c index 84d72ba0..77b688e3 100644 --- a/qemu/target-i386/cpu.c +++ b/qemu/target-i386/cpu.c @@ -2851,31 +2851,31 @@ static void x86_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) cs->env_ptr = env; cpu_exec_init(cs, opaque); - object_property_add(obj, "family", "int", + object_property_add(uc, obj, "family", "int", x86_cpuid_version_get_family, x86_cpuid_version_set_family, NULL, NULL, NULL); - object_property_add(obj, "model", "int", + object_property_add(uc, obj, "model", "int", x86_cpuid_version_get_model, x86_cpuid_version_set_model, NULL, NULL, NULL); - object_property_add(obj, "stepping", "int", + object_property_add(uc, obj, "stepping", "int", x86_cpuid_version_get_stepping, x86_cpuid_version_set_stepping, NULL, NULL, NULL); - object_property_add_str(obj, "vendor", + object_property_add_str(uc, obj, "vendor", x86_cpuid_get_vendor, x86_cpuid_set_vendor, NULL); - object_property_add_str(obj, "model-id", + object_property_add_str(uc, obj, "model-id", x86_cpuid_get_model_id, x86_cpuid_set_model_id, NULL); - object_property_add(obj, "tsc-frequency", "int", + object_property_add(uc, obj, "tsc-frequency", "int", x86_cpuid_get_tsc_freq, x86_cpuid_set_tsc_freq, NULL, NULL, NULL); - object_property_add(obj, "apic-id", "int", + object_property_add(uc, obj, "apic-id", "int", x86_cpuid_get_apic_id, x86_cpuid_set_apic_id, NULL, NULL, NULL); - object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo", + object_property_add(uc, obj, "feature-words", "X86CPUFeatureWordInfo", x86_cpu_get_feature_words, NULL, NULL, (void *)env->features, NULL); - object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo", + object_property_add(uc, obj, "filtered-features", "X86CPUFeatureWordInfo", x86_cpu_get_feature_words, NULL, NULL, (void *)cpu->filtered_features, NULL); diff --git a/uc.c b/uc.c index 31a05972..6d6f4c3e 100644 --- a/uc.c +++ b/uc.c @@ -28,6 +28,7 @@ static void free_table(gpointer key, gpointer value, gpointer data) { TypeInfo *ti = (TypeInfo*) value; + g_hash_table_destroy(ti->class->properties); g_free((void *) ti->class); g_free((void *) ti->name); g_free((void *) ti->parent);