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);