qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

object.c (75715B)


      1 /*
      2  * QEMU Object Model
      3  *
      4  * Copyright IBM, Corp. 2011
      5  *
      6  * Authors:
      7  *  Anthony Liguori   <aliguori@us.ibm.com>
      8  *
      9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
     10  * See the COPYING file in the top-level directory.
     11  */
     12 
     13 #include "qemu/osdep.h"
     14 #include "hw/qdev-core.h"
     15 #include "qapi/error.h"
     16 #include "qom/object.h"
     17 #include "qom/object_interfaces.h"
     18 #include "qemu/cutils.h"
     19 #include "qemu/memalign.h"
     20 #include "qapi/visitor.h"
     21 #include "qapi/string-input-visitor.h"
     22 #include "qapi/string-output-visitor.h"
     23 #include "qapi/qobject-input-visitor.h"
     24 #include "qapi/forward-visitor.h"
     25 #include "qapi/qapi-builtin-visit.h"
     26 #include "qapi/qmp/qerror.h"
     27 #include "qapi/qmp/qjson.h"
     28 #include "trace.h"
     29 
     30 /* TODO: replace QObject with a simpler visitor to avoid a dependency
     31  * of the QOM core on QObject?  */
     32 #include "qom/qom-qobject.h"
     33 #include "qapi/qmp/qbool.h"
     34 #include "qapi/qmp/qnum.h"
     35 #include "qapi/qmp/qstring.h"
     36 #include "qemu/error-report.h"
     37 
     38 #define MAX_INTERFACES 32
     39 
     40 typedef struct InterfaceImpl InterfaceImpl;
     41 typedef struct TypeImpl TypeImpl;
     42 
     43 struct InterfaceImpl
     44 {
     45     const char *typename;
     46 };
     47 
     48 struct TypeImpl
     49 {
     50     const char *name;
     51 
     52     size_t class_size;
     53 
     54     size_t instance_size;
     55     size_t instance_align;
     56 
     57     void (*class_init)(ObjectClass *klass, void *data);
     58     void (*class_base_init)(ObjectClass *klass, void *data);
     59 
     60     void *class_data;
     61 
     62     void (*instance_init)(Object *obj);
     63     void (*instance_post_init)(Object *obj);
     64     void (*instance_finalize)(Object *obj);
     65 
     66     bool abstract;
     67 
     68     const char *parent;
     69     TypeImpl *parent_type;
     70 
     71     ObjectClass *class;
     72 
     73     int num_interfaces;
     74     InterfaceImpl interfaces[MAX_INTERFACES];
     75 };
     76 
     77 static Type type_interface;
     78 
     79 static GHashTable *type_table_get(void)
     80 {
     81     static GHashTable *type_table;
     82 
     83     if (type_table == NULL) {
     84         type_table = g_hash_table_new(g_str_hash, g_str_equal);
     85     }
     86 
     87     return type_table;
     88 }
     89 
     90 static bool enumerating_types;
     91 
     92 static void type_table_add(TypeImpl *ti)
     93 {
     94     assert(!enumerating_types);
     95     g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
     96 }
     97 
     98 static TypeImpl *type_table_lookup(const char *name)
     99 {
    100     return g_hash_table_lookup(type_table_get(), name);
    101 }
    102 
    103 static TypeImpl *type_new(const TypeInfo *info)
    104 {
    105     TypeImpl *ti = g_malloc0(sizeof(*ti));
    106     int i;
    107 
    108     g_assert(info->name != NULL);
    109 
    110     if (type_table_lookup(info->name) != NULL) {
    111         fprintf(stderr, "Registering `%s' which already exists\n", info->name);
    112         abort();
    113     }
    114 
    115     ti->name = g_strdup(info->name);
    116     ti->parent = g_strdup(info->parent);
    117 
    118     ti->class_size = info->class_size;
    119     ti->instance_size = info->instance_size;
    120     ti->instance_align = info->instance_align;
    121 
    122     ti->class_init = info->class_init;
    123     ti->class_base_init = info->class_base_init;
    124     ti->class_data = info->class_data;
    125 
    126     ti->instance_init = info->instance_init;
    127     ti->instance_post_init = info->instance_post_init;
    128     ti->instance_finalize = info->instance_finalize;
    129 
    130     ti->abstract = info->abstract;
    131 
    132     for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
    133         ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
    134     }
    135     ti->num_interfaces = i;
    136 
    137     return ti;
    138 }
    139 
    140 static TypeImpl *type_register_internal(const TypeInfo *info)
    141 {
    142     TypeImpl *ti;
    143     ti = type_new(info);
    144 
    145     type_table_add(ti);
    146     return ti;
    147 }
    148 
    149 TypeImpl *type_register(const TypeInfo *info)
    150 {
    151     assert(info->parent);
    152     return type_register_internal(info);
    153 }
    154 
    155 TypeImpl *type_register_static(const TypeInfo *info)
    156 {
    157     return type_register(info);
    158 }
    159 
    160 void type_register_static_array(const TypeInfo *infos, int nr_infos)
    161 {
    162     int i;
    163 
    164     for (i = 0; i < nr_infos; i++) {
    165         type_register_static(&infos[i]);
    166     }
    167 }
    168 
    169 static TypeImpl *type_get_by_name(const char *name)
    170 {
    171     if (name == NULL) {
    172         return NULL;
    173     }
    174 
    175     return type_table_lookup(name);
    176 }
    177 
    178 static TypeImpl *type_get_parent(TypeImpl *type)
    179 {
    180     if (!type->parent_type && type->parent) {
    181         type->parent_type = type_get_by_name(type->parent);
    182         if (!type->parent_type) {
    183             fprintf(stderr, "Type '%s' is missing its parent '%s'\n",
    184                     type->name, type->parent);
    185             abort();
    186         }
    187     }
    188 
    189     return type->parent_type;
    190 }
    191 
    192 static bool type_has_parent(TypeImpl *type)
    193 {
    194     return (type->parent != NULL);
    195 }
    196 
    197 static size_t type_class_get_size(TypeImpl *ti)
    198 {
    199     if (ti->class_size) {
    200         return ti->class_size;
    201     }
    202 
    203     if (type_has_parent(ti)) {
    204         return type_class_get_size(type_get_parent(ti));
    205     }
    206 
    207     return sizeof(ObjectClass);
    208 }
    209 
    210 static size_t type_object_get_size(TypeImpl *ti)
    211 {
    212     if (ti->instance_size) {
    213         return ti->instance_size;
    214     }
    215 
    216     if (type_has_parent(ti)) {
    217         return type_object_get_size(type_get_parent(ti));
    218     }
    219 
    220     return 0;
    221 }
    222 
    223 size_t object_type_get_instance_size(const char *typename)
    224 {
    225     TypeImpl *type = type_get_by_name(typename);
    226 
    227     g_assert(type != NULL);
    228     return type_object_get_size(type);
    229 }
    230 
    231 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
    232 {
    233     assert(target_type);
    234 
    235     /* Check if target_type is a direct ancestor of type */
    236     while (type) {
    237         if (type == target_type) {
    238             return true;
    239         }
    240 
    241         type = type_get_parent(type);
    242     }
    243 
    244     return false;
    245 }
    246 
    247 static void type_initialize(TypeImpl *ti);
    248 
    249 static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type,
    250                                       TypeImpl *parent_type)
    251 {
    252     InterfaceClass *new_iface;
    253     TypeInfo info = { };
    254     TypeImpl *iface_impl;
    255 
    256     info.parent = parent_type->name;
    257     info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name);
    258     info.abstract = true;
    259 
    260     iface_impl = type_new(&info);
    261     iface_impl->parent_type = parent_type;
    262     type_initialize(iface_impl);
    263     g_free((char *)info.name);
    264 
    265     new_iface = (InterfaceClass *)iface_impl->class;
    266     new_iface->concrete_class = ti->class;
    267     new_iface->interface_type = interface_type;
    268 
    269     ti->class->interfaces = g_slist_append(ti->class->interfaces, new_iface);
    270 }
    271 
    272 static void object_property_free(gpointer data)
    273 {
    274     ObjectProperty *prop = data;
    275 
    276     if (prop->defval) {
    277         qobject_unref(prop->defval);
    278         prop->defval = NULL;
    279     }
    280     g_free(prop->name);
    281     g_free(prop->type);
    282     g_free(prop->description);
    283     g_free(prop);
    284 }
    285 
    286 static void type_initialize(TypeImpl *ti)
    287 {
    288     TypeImpl *parent;
    289 
    290     if (ti->class) {
    291         return;
    292     }
    293 
    294     ti->class_size = type_class_get_size(ti);
    295     ti->instance_size = type_object_get_size(ti);
    296     /* Any type with zero instance_size is implicitly abstract.
    297      * This means interface types are all abstract.
    298      */
    299     if (ti->instance_size == 0) {
    300         ti->abstract = true;
    301     }
    302     if (type_is_ancestor(ti, type_interface)) {
    303         assert(ti->instance_size == 0);
    304         assert(ti->abstract);
    305         assert(!ti->instance_init);
    306         assert(!ti->instance_post_init);
    307         assert(!ti->instance_finalize);
    308         assert(!ti->num_interfaces);
    309     }
    310     ti->class = g_malloc0(ti->class_size);
    311 
    312     parent = type_get_parent(ti);
    313     if (parent) {
    314         type_initialize(parent);
    315         GSList *e;
    316         int i;
    317 
    318         g_assert(parent->class_size <= ti->class_size);
    319         g_assert(parent->instance_size <= ti->instance_size);
    320         memcpy(ti->class, parent->class, parent->class_size);
    321         ti->class->interfaces = NULL;
    322 
    323         for (e = parent->class->interfaces; e; e = e->next) {
    324             InterfaceClass *iface = e->data;
    325             ObjectClass *klass = OBJECT_CLASS(iface);
    326 
    327             type_initialize_interface(ti, iface->interface_type, klass->type);
    328         }
    329 
    330         for (i = 0; i < ti->num_interfaces; i++) {
    331             TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
    332             if (!t) {
    333                 error_report("missing interface '%s' for object '%s'",
    334                              ti->interfaces[i].typename, parent->name);
    335                 abort();
    336             }
    337             for (e = ti->class->interfaces; e; e = e->next) {
    338                 TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
    339 
    340                 if (type_is_ancestor(target_type, t)) {
    341                     break;
    342                 }
    343             }
    344 
    345             if (e) {
    346                 continue;
    347             }
    348 
    349             type_initialize_interface(ti, t, t);
    350         }
    351     }
    352 
    353     ti->class->properties = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
    354                                                   object_property_free);
    355 
    356     ti->class->type = ti;
    357 
    358     while (parent) {
    359         if (parent->class_base_init) {
    360             parent->class_base_init(ti->class, ti->class_data);
    361         }
    362         parent = type_get_parent(parent);
    363     }
    364 
    365     if (ti->class_init) {
    366         ti->class_init(ti->class, ti->class_data);
    367     }
    368 }
    369 
    370 static void object_init_with_type(Object *obj, TypeImpl *ti)
    371 {
    372     if (type_has_parent(ti)) {
    373         object_init_with_type(obj, type_get_parent(ti));
    374     }
    375 
    376     if (ti->instance_init) {
    377         ti->instance_init(obj);
    378     }
    379 }
    380 
    381 static void object_post_init_with_type(Object *obj, TypeImpl *ti)
    382 {
    383     if (ti->instance_post_init) {
    384         ti->instance_post_init(obj);
    385     }
    386 
    387     if (type_has_parent(ti)) {
    388         object_post_init_with_type(obj, type_get_parent(ti));
    389     }
    390 }
    391 
    392 bool object_apply_global_props(Object *obj, const GPtrArray *props,
    393                                Error **errp)
    394 {
    395     int i;
    396 
    397     if (!props) {
    398         return true;
    399     }
    400 
    401     for (i = 0; i < props->len; i++) {
    402         GlobalProperty *p = g_ptr_array_index(props, i);
    403         Error *err = NULL;
    404 
    405         if (object_dynamic_cast(obj, p->driver) == NULL) {
    406             continue;
    407         }
    408         if (p->optional && !object_property_find(obj, p->property)) {
    409             continue;
    410         }
    411         p->used = true;
    412         if (!object_property_parse(obj, p->property, p->value, &err)) {
    413             error_prepend(&err, "can't apply global %s.%s=%s: ",
    414                           p->driver, p->property, p->value);
    415             /*
    416              * If errp != NULL, propagate error and return.
    417              * If errp == NULL, report a warning, but keep going
    418              * with the remaining globals.
    419              */
    420             if (errp) {
    421                 error_propagate(errp, err);
    422                 return false;
    423             } else {
    424                 warn_report_err(err);
    425             }
    426         }
    427     }
    428 
    429     return true;
    430 }
    431 
    432 /*
    433  * Global property defaults
    434  * Slot 0: accelerator's global property defaults
    435  * Slot 1: machine's global property defaults
    436  * Slot 2: global properties from legacy command line option
    437  * Each is a GPtrArray of of GlobalProperty.
    438  * Applied in order, later entries override earlier ones.
    439  */
    440 static GPtrArray *object_compat_props[3];
    441 
    442 /*
    443  * Retrieve @GPtrArray for global property defined with options
    444  * other than "-global".  These are generally used for syntactic
    445  * sugar and legacy command line options.
    446  */
    447 void object_register_sugar_prop(const char *driver, const char *prop,
    448                                 const char *value, bool optional)
    449 {
    450     GlobalProperty *g;
    451     if (!object_compat_props[2]) {
    452         object_compat_props[2] = g_ptr_array_new();
    453     }
    454     g = g_new0(GlobalProperty, 1);
    455     g->driver = g_strdup(driver);
    456     g->property = g_strdup(prop);
    457     g->value = g_strdup(value);
    458     g->optional = optional;
    459     g_ptr_array_add(object_compat_props[2], g);
    460 }
    461 
    462 /*
    463  * Set machine's global property defaults to @compat_props.
    464  * May be called at most once.
    465  */
    466 void object_set_machine_compat_props(GPtrArray *compat_props)
    467 {
    468     assert(!object_compat_props[1]);
    469     object_compat_props[1] = compat_props;
    470 }
    471 
    472 /*
    473  * Set accelerator's global property defaults to @compat_props.
    474  * May be called at most once.
    475  */
    476 void object_set_accelerator_compat_props(GPtrArray *compat_props)
    477 {
    478     assert(!object_compat_props[0]);
    479     object_compat_props[0] = compat_props;
    480 }
    481 
    482 void object_apply_compat_props(Object *obj)
    483 {
    484     int i;
    485 
    486     for (i = 0; i < ARRAY_SIZE(object_compat_props); i++) {
    487         object_apply_global_props(obj, object_compat_props[i],
    488                                   i == 2 ? &error_fatal : &error_abort);
    489     }
    490 }
    491 
    492 static void object_class_property_init_all(Object *obj)
    493 {
    494     ObjectPropertyIterator iter;
    495     ObjectProperty *prop;
    496 
    497     object_class_property_iter_init(&iter, object_get_class(obj));
    498     while ((prop = object_property_iter_next(&iter))) {
    499         if (prop->init) {
    500             prop->init(obj, prop);
    501         }
    502     }
    503 }
    504 
    505 static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type)
    506 {
    507     type_initialize(type);
    508 
    509     g_assert(type->instance_size >= sizeof(Object));
    510     g_assert(type->abstract == false);
    511     g_assert(size >= type->instance_size);
    512 
    513     memset(obj, 0, type->instance_size);
    514     obj->class = type->class;
    515     object_ref(obj);
    516     object_class_property_init_all(obj);
    517     obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
    518                                             NULL, object_property_free);
    519     object_init_with_type(obj, type);
    520     object_post_init_with_type(obj, type);
    521 }
    522 
    523 void object_initialize(void *data, size_t size, const char *typename)
    524 {
    525     TypeImpl *type = type_get_by_name(typename);
    526 
    527 #ifdef CONFIG_MODULES
    528     if (!type) {
    529         int rv = module_load_qom(typename, &error_fatal);
    530         if (rv > 0) {
    531             type = type_get_by_name(typename);
    532         } else {
    533             error_report("missing object type '%s'", typename);
    534             exit(1);
    535         }
    536     }
    537 #endif
    538     if (!type) {
    539         error_report("missing object type '%s'", typename);
    540         abort();
    541     }
    542 
    543     object_initialize_with_type(data, size, type);
    544 }
    545 
    546 bool object_initialize_child_with_props(Object *parentobj,
    547                                         const char *propname,
    548                                         void *childobj, size_t size,
    549                                         const char *type,
    550                                         Error **errp, ...)
    551 {
    552     va_list vargs;
    553     bool ok;
    554 
    555     va_start(vargs, errp);
    556     ok = object_initialize_child_with_propsv(parentobj, propname,
    557                                              childobj, size, type, errp,
    558                                              vargs);
    559     va_end(vargs);
    560     return ok;
    561 }
    562 
    563 bool object_initialize_child_with_propsv(Object *parentobj,
    564                                          const char *propname,
    565                                          void *childobj, size_t size,
    566                                          const char *type,
    567                                          Error **errp, va_list vargs)
    568 {
    569     bool ok = false;
    570     Object *obj;
    571     UserCreatable *uc;
    572 
    573     object_initialize(childobj, size, type);
    574     obj = OBJECT(childobj);
    575 
    576     if (!object_set_propv(obj, errp, vargs)) {
    577         goto out;
    578     }
    579 
    580     object_property_add_child(parentobj, propname, obj);
    581 
    582     uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
    583     if (uc) {
    584         if (!user_creatable_complete(uc, errp)) {
    585             object_unparent(obj);
    586             goto out;
    587         }
    588     }
    589 
    590     ok = true;
    591 
    592 out:
    593     /*
    594      * We want @obj's reference to be 1 on success, 0 on failure.
    595      * On success, it's 2: one taken by object_initialize(), and one
    596      * by object_property_add_child().
    597      * On failure in object_initialize() or earlier, it's 1.
    598      * On failure afterwards, it's also 1: object_unparent() releases
    599      * the reference taken by object_property_add_child().
    600      */
    601     object_unref(obj);
    602     return ok;
    603 }
    604 
    605 void object_initialize_child_internal(Object *parent,
    606                                       const char *propname,
    607                                       void *child, size_t size,
    608                                       const char *type)
    609 {
    610     object_initialize_child_with_props(parent, propname, child, size, type,
    611                                        &error_abort, NULL);
    612 }
    613 
    614 static inline bool object_property_is_child(ObjectProperty *prop)
    615 {
    616     return strstart(prop->type, "child<", NULL);
    617 }
    618 
    619 static void object_property_del_all(Object *obj)
    620 {
    621     g_autoptr(GHashTable) done = g_hash_table_new(NULL, NULL);
    622     ObjectProperty *prop;
    623     ObjectPropertyIterator iter;
    624     bool released;
    625 
    626     do {
    627         released = false;
    628         object_property_iter_init(&iter, obj);
    629         while ((prop = object_property_iter_next(&iter)) != NULL) {
    630             if (g_hash_table_add(done, prop)) {
    631                 if (prop->release) {
    632                     prop->release(obj, prop->name, prop->opaque);
    633                     released = true;
    634                     break;
    635                 }
    636             }
    637         }
    638     } while (released);
    639 
    640     g_hash_table_unref(obj->properties);
    641 }
    642 
    643 static void object_property_del_child(Object *obj, Object *child)
    644 {
    645     ObjectProperty *prop;
    646     GHashTableIter iter;
    647     gpointer key, value;
    648 
    649     g_hash_table_iter_init(&iter, obj->properties);
    650     while (g_hash_table_iter_next(&iter, &key, &value)) {
    651         prop = value;
    652         if (object_property_is_child(prop) && prop->opaque == child) {
    653             if (prop->release) {
    654                 prop->release(obj, prop->name, prop->opaque);
    655                 prop->release = NULL;
    656             }
    657             break;
    658         }
    659     }
    660     g_hash_table_iter_init(&iter, obj->properties);
    661     while (g_hash_table_iter_next(&iter, &key, &value)) {
    662         prop = value;
    663         if (object_property_is_child(prop) && prop->opaque == child) {
    664             g_hash_table_iter_remove(&iter);
    665             break;
    666         }
    667     }
    668 }
    669 
    670 void object_unparent(Object *obj)
    671 {
    672     if (obj->parent) {
    673         object_property_del_child(obj->parent, obj);
    674     }
    675 }
    676 
    677 static void object_deinit(Object *obj, TypeImpl *type)
    678 {
    679     if (type->instance_finalize) {
    680         type->instance_finalize(obj);
    681     }
    682 
    683     if (type_has_parent(type)) {
    684         object_deinit(obj, type_get_parent(type));
    685     }
    686 }
    687 
    688 static void object_finalize(void *data)
    689 {
    690     Object *obj = data;
    691     TypeImpl *ti = obj->class->type;
    692 
    693     object_property_del_all(obj);
    694     object_deinit(obj, ti);
    695 
    696     g_assert(obj->ref == 0);
    697     g_assert(obj->parent == NULL);
    698     if (obj->free) {
    699         obj->free(obj);
    700     }
    701 }
    702 
    703 /* Find the minimum alignment guaranteed by the system malloc. */
    704 #if __STDC_VERSION__ >= 201112L
    705 typedef max_align_t qemu_max_align_t;
    706 #else
    707 typedef union {
    708     long l;
    709     void *p;
    710     double d;
    711     long double ld;
    712 } qemu_max_align_t;
    713 #endif
    714 
    715 static Object *object_new_with_type(Type type)
    716 {
    717     Object *obj;
    718     size_t size, align;
    719     void (*obj_free)(void *);
    720 
    721     g_assert(type != NULL);
    722     type_initialize(type);
    723 
    724     size = type->instance_size;
    725     align = type->instance_align;
    726 
    727     /*
    728      * Do not use qemu_memalign unless required.  Depending on the
    729      * implementation, extra alignment implies extra overhead.
    730      */
    731     if (likely(align <= __alignof__(qemu_max_align_t))) {
    732         obj = g_malloc(size);
    733         obj_free = g_free;
    734     } else {
    735         obj = qemu_memalign(align, size);
    736         obj_free = qemu_vfree;
    737     }
    738 
    739     object_initialize_with_type(obj, size, type);
    740     obj->free = obj_free;
    741 
    742     return obj;
    743 }
    744 
    745 Object *object_new_with_class(ObjectClass *klass)
    746 {
    747     return object_new_with_type(klass->type);
    748 }
    749 
    750 Object *object_new(const char *typename)
    751 {
    752     TypeImpl *ti = type_get_by_name(typename);
    753 
    754     return object_new_with_type(ti);
    755 }
    756 
    757 
    758 Object *object_new_with_props(const char *typename,
    759                               Object *parent,
    760                               const char *id,
    761                               Error **errp,
    762                               ...)
    763 {
    764     va_list vargs;
    765     Object *obj;
    766 
    767     va_start(vargs, errp);
    768     obj = object_new_with_propv(typename, parent, id, errp, vargs);
    769     va_end(vargs);
    770 
    771     return obj;
    772 }
    773 
    774 
    775 Object *object_new_with_propv(const char *typename,
    776                               Object *parent,
    777                               const char *id,
    778                               Error **errp,
    779                               va_list vargs)
    780 {
    781     Object *obj;
    782     ObjectClass *klass;
    783     UserCreatable *uc;
    784 
    785     klass = object_class_by_name(typename);
    786     if (!klass) {
    787         error_setg(errp, "invalid object type: %s", typename);
    788         return NULL;
    789     }
    790 
    791     if (object_class_is_abstract(klass)) {
    792         error_setg(errp, "object type '%s' is abstract", typename);
    793         return NULL;
    794     }
    795     obj = object_new_with_type(klass->type);
    796 
    797     if (!object_set_propv(obj, errp, vargs)) {
    798         goto error;
    799     }
    800 
    801     if (id != NULL) {
    802         object_property_add_child(parent, id, obj);
    803     }
    804 
    805     uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
    806     if (uc) {
    807         if (!user_creatable_complete(uc, errp)) {
    808             if (id != NULL) {
    809                 object_unparent(obj);
    810             }
    811             goto error;
    812         }
    813     }
    814 
    815     object_unref(obj);
    816     return obj;
    817 
    818  error:
    819     object_unref(obj);
    820     return NULL;
    821 }
    822 
    823 
    824 bool object_set_props(Object *obj,
    825                      Error **errp,
    826                      ...)
    827 {
    828     va_list vargs;
    829     bool ret;
    830 
    831     va_start(vargs, errp);
    832     ret = object_set_propv(obj, errp, vargs);
    833     va_end(vargs);
    834 
    835     return ret;
    836 }
    837 
    838 
    839 bool object_set_propv(Object *obj,
    840                      Error **errp,
    841                      va_list vargs)
    842 {
    843     const char *propname;
    844 
    845     propname = va_arg(vargs, char *);
    846     while (propname != NULL) {
    847         const char *value = va_arg(vargs, char *);
    848 
    849         g_assert(value != NULL);
    850         if (!object_property_parse(obj, propname, value, errp)) {
    851             return false;
    852         }
    853         propname = va_arg(vargs, char *);
    854     }
    855 
    856     return true;
    857 }
    858 
    859 
    860 Object *object_dynamic_cast(Object *obj, const char *typename)
    861 {
    862     if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
    863         return obj;
    864     }
    865 
    866     return NULL;
    867 }
    868 
    869 Object *object_dynamic_cast_assert(Object *obj, const char *typename,
    870                                    const char *file, int line, const char *func)
    871 {
    872     trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
    873                                      typename, file, line, func);
    874 
    875 #ifdef CONFIG_QOM_CAST_DEBUG
    876     int i;
    877     Object *inst;
    878 
    879     for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
    880         if (qatomic_read(&obj->class->object_cast_cache[i]) == typename) {
    881             goto out;
    882         }
    883     }
    884 
    885     inst = object_dynamic_cast(obj, typename);
    886 
    887     if (!inst && obj) {
    888         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
    889                 file, line, func, obj, typename);
    890         abort();
    891     }
    892 
    893     assert(obj == inst);
    894 
    895     if (obj && obj == inst) {
    896         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
    897             qatomic_set(&obj->class->object_cast_cache[i - 1],
    898                        qatomic_read(&obj->class->object_cast_cache[i]));
    899         }
    900         qatomic_set(&obj->class->object_cast_cache[i - 1], typename);
    901     }
    902 
    903 out:
    904 #endif
    905     return obj;
    906 }
    907 
    908 ObjectClass *object_class_dynamic_cast(ObjectClass *class,
    909                                        const char *typename)
    910 {
    911     ObjectClass *ret = NULL;
    912     TypeImpl *target_type;
    913     TypeImpl *type;
    914 
    915     if (!class) {
    916         return NULL;
    917     }
    918 
    919     /* A simple fast path that can trigger a lot for leaf classes.  */
    920     type = class->type;
    921     if (type->name == typename) {
    922         return class;
    923     }
    924 
    925     target_type = type_get_by_name(typename);
    926     if (!target_type) {
    927         /* target class type unknown, so fail the cast */
    928         return NULL;
    929     }
    930 
    931     if (type->class->interfaces &&
    932             type_is_ancestor(target_type, type_interface)) {
    933         int found = 0;
    934         GSList *i;
    935 
    936         for (i = class->interfaces; i; i = i->next) {
    937             ObjectClass *target_class = i->data;
    938 
    939             if (type_is_ancestor(target_class->type, target_type)) {
    940                 ret = target_class;
    941                 found++;
    942             }
    943          }
    944 
    945         /* The match was ambiguous, don't allow a cast */
    946         if (found > 1) {
    947             ret = NULL;
    948         }
    949     } else if (type_is_ancestor(type, target_type)) {
    950         ret = class;
    951     }
    952 
    953     return ret;
    954 }
    955 
    956 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
    957                                               const char *typename,
    958                                               const char *file, int line,
    959                                               const char *func)
    960 {
    961     ObjectClass *ret;
    962 
    963     trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
    964                                            typename, file, line, func);
    965 
    966 #ifdef CONFIG_QOM_CAST_DEBUG
    967     int i;
    968 
    969     for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
    970         if (qatomic_read(&class->class_cast_cache[i]) == typename) {
    971             ret = class;
    972             goto out;
    973         }
    974     }
    975 #else
    976     if (!class || !class->interfaces) {
    977         return class;
    978     }
    979 #endif
    980 
    981     ret = object_class_dynamic_cast(class, typename);
    982     if (!ret && class) {
    983         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
    984                 file, line, func, class, typename);
    985         abort();
    986     }
    987 
    988 #ifdef CONFIG_QOM_CAST_DEBUG
    989     if (class && ret == class) {
    990         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
    991             qatomic_set(&class->class_cast_cache[i - 1],
    992                        qatomic_read(&class->class_cast_cache[i]));
    993         }
    994         qatomic_set(&class->class_cast_cache[i - 1], typename);
    995     }
    996 out:
    997 #endif
    998     return ret;
    999 }
   1000 
   1001 const char *object_get_typename(const Object *obj)
   1002 {
   1003     return obj->class->type->name;
   1004 }
   1005 
   1006 ObjectClass *object_get_class(Object *obj)
   1007 {
   1008     return obj->class;
   1009 }
   1010 
   1011 bool object_class_is_abstract(ObjectClass *klass)
   1012 {
   1013     return klass->type->abstract;
   1014 }
   1015 
   1016 const char *object_class_get_name(ObjectClass *klass)
   1017 {
   1018     return klass->type->name;
   1019 }
   1020 
   1021 ObjectClass *object_class_by_name(const char *typename)
   1022 {
   1023     TypeImpl *type = type_get_by_name(typename);
   1024 
   1025     if (!type) {
   1026         return NULL;
   1027     }
   1028 
   1029     type_initialize(type);
   1030 
   1031     return type->class;
   1032 }
   1033 
   1034 ObjectClass *module_object_class_by_name(const char *typename)
   1035 {
   1036     ObjectClass *oc;
   1037 
   1038     oc = object_class_by_name(typename);
   1039 #ifdef CONFIG_MODULES
   1040     if (!oc) {
   1041         Error *local_err = NULL;
   1042         int rv = module_load_qom(typename, &local_err);
   1043         if (rv > 0) {
   1044             oc = object_class_by_name(typename);
   1045         } else if (rv < 0) {
   1046             error_report_err(local_err);
   1047         }
   1048     }
   1049 #endif
   1050     return oc;
   1051 }
   1052 
   1053 ObjectClass *object_class_get_parent(ObjectClass *class)
   1054 {
   1055     TypeImpl *type = type_get_parent(class->type);
   1056 
   1057     if (!type) {
   1058         return NULL;
   1059     }
   1060 
   1061     type_initialize(type);
   1062 
   1063     return type->class;
   1064 }
   1065 
   1066 typedef struct OCFData
   1067 {
   1068     void (*fn)(ObjectClass *klass, void *opaque);
   1069     const char *implements_type;
   1070     bool include_abstract;
   1071     void *opaque;
   1072 } OCFData;
   1073 
   1074 static void object_class_foreach_tramp(gpointer key, gpointer value,
   1075                                        gpointer opaque)
   1076 {
   1077     OCFData *data = opaque;
   1078     TypeImpl *type = value;
   1079     ObjectClass *k;
   1080 
   1081     type_initialize(type);
   1082     k = type->class;
   1083 
   1084     if (!data->include_abstract && type->abstract) {
   1085         return;
   1086     }
   1087 
   1088     if (data->implements_type && 
   1089         !object_class_dynamic_cast(k, data->implements_type)) {
   1090         return;
   1091     }
   1092 
   1093     data->fn(k, data->opaque);
   1094 }
   1095 
   1096 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
   1097                           const char *implements_type, bool include_abstract,
   1098                           void *opaque)
   1099 {
   1100     OCFData data = { fn, implements_type, include_abstract, opaque };
   1101 
   1102     enumerating_types = true;
   1103     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
   1104     enumerating_types = false;
   1105 }
   1106 
   1107 static int do_object_child_foreach(Object *obj,
   1108                                    int (*fn)(Object *child, void *opaque),
   1109                                    void *opaque, bool recurse)
   1110 {
   1111     GHashTableIter iter;
   1112     ObjectProperty *prop;
   1113     int ret = 0;
   1114 
   1115     g_hash_table_iter_init(&iter, obj->properties);
   1116     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
   1117         if (object_property_is_child(prop)) {
   1118             Object *child = prop->opaque;
   1119 
   1120             ret = fn(child, opaque);
   1121             if (ret != 0) {
   1122                 break;
   1123             }
   1124             if (recurse) {
   1125                 ret = do_object_child_foreach(child, fn, opaque, true);
   1126                 if (ret != 0) {
   1127                     break;
   1128                 }
   1129             }
   1130         }
   1131     }
   1132     return ret;
   1133 }
   1134 
   1135 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
   1136                          void *opaque)
   1137 {
   1138     return do_object_child_foreach(obj, fn, opaque, false);
   1139 }
   1140 
   1141 int object_child_foreach_recursive(Object *obj,
   1142                                    int (*fn)(Object *child, void *opaque),
   1143                                    void *opaque)
   1144 {
   1145     return do_object_child_foreach(obj, fn, opaque, true);
   1146 }
   1147 
   1148 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
   1149 {
   1150     GSList **list = opaque;
   1151 
   1152     *list = g_slist_prepend(*list, klass);
   1153 }
   1154 
   1155 GSList *object_class_get_list(const char *implements_type,
   1156                               bool include_abstract)
   1157 {
   1158     GSList *list = NULL;
   1159 
   1160     object_class_foreach(object_class_get_list_tramp,
   1161                          implements_type, include_abstract, &list);
   1162     return list;
   1163 }
   1164 
   1165 static gint object_class_cmp(gconstpointer a, gconstpointer b)
   1166 {
   1167     return strcasecmp(object_class_get_name((ObjectClass *)a),
   1168                       object_class_get_name((ObjectClass *)b));
   1169 }
   1170 
   1171 GSList *object_class_get_list_sorted(const char *implements_type,
   1172                                      bool include_abstract)
   1173 {
   1174     return g_slist_sort(object_class_get_list(implements_type, include_abstract),
   1175                         object_class_cmp);
   1176 }
   1177 
   1178 Object *object_ref(void *objptr)
   1179 {
   1180     Object *obj = OBJECT(objptr);
   1181     uint32_t ref;
   1182 
   1183     if (!obj) {
   1184         return NULL;
   1185     }
   1186     ref = qatomic_fetch_inc(&obj->ref);
   1187     /* Assert waaay before the integer overflows */
   1188     g_assert(ref < INT_MAX);
   1189     return obj;
   1190 }
   1191 
   1192 void object_unref(void *objptr)
   1193 {
   1194     Object *obj = OBJECT(objptr);
   1195     if (!obj) {
   1196         return;
   1197     }
   1198     g_assert(obj->ref > 0);
   1199 
   1200     /* parent always holds a reference to its children */
   1201     if (qatomic_fetch_dec(&obj->ref) == 1) {
   1202         object_finalize(obj);
   1203     }
   1204 }
   1205 
   1206 ObjectProperty *
   1207 object_property_try_add(Object *obj, const char *name, const char *type,
   1208                         ObjectPropertyAccessor *get,
   1209                         ObjectPropertyAccessor *set,
   1210                         ObjectPropertyRelease *release,
   1211                         void *opaque, Error **errp)
   1212 {
   1213     ObjectProperty *prop;
   1214     size_t name_len = strlen(name);
   1215 
   1216     if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) {
   1217         int i;
   1218         ObjectProperty *ret = NULL;
   1219         char *name_no_array = g_strdup(name);
   1220 
   1221         name_no_array[name_len - 3] = '\0';
   1222         for (i = 0; i < INT16_MAX; ++i) {
   1223             char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
   1224 
   1225             ret = object_property_try_add(obj, full_name, type, get, set,
   1226                                           release, opaque, NULL);
   1227             g_free(full_name);
   1228             if (ret) {
   1229                 break;
   1230             }
   1231         }
   1232         g_free(name_no_array);
   1233         assert(ret);
   1234         return ret;
   1235     }
   1236 
   1237     if (object_property_find(obj, name) != NULL) {
   1238         error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')",
   1239                    name, object_get_typename(obj));
   1240         return NULL;
   1241     }
   1242 
   1243     prop = g_malloc0(sizeof(*prop));
   1244 
   1245     prop->name = g_strdup(name);
   1246     prop->type = g_strdup(type);
   1247 
   1248     prop->get = get;
   1249     prop->set = set;
   1250     prop->release = release;
   1251     prop->opaque = opaque;
   1252 
   1253     g_hash_table_insert(obj->properties, prop->name, prop);
   1254     return prop;
   1255 }
   1256 
   1257 ObjectProperty *
   1258 object_property_add(Object *obj, const char *name, const char *type,
   1259                     ObjectPropertyAccessor *get,
   1260                     ObjectPropertyAccessor *set,
   1261                     ObjectPropertyRelease *release,
   1262                     void *opaque)
   1263 {
   1264     return object_property_try_add(obj, name, type, get, set, release,
   1265                                    opaque, &error_abort);
   1266 }
   1267 
   1268 ObjectProperty *
   1269 object_class_property_add(ObjectClass *klass,
   1270                           const char *name,
   1271                           const char *type,
   1272                           ObjectPropertyAccessor *get,
   1273                           ObjectPropertyAccessor *set,
   1274                           ObjectPropertyRelease *release,
   1275                           void *opaque)
   1276 {
   1277     ObjectProperty *prop;
   1278 
   1279     assert(!object_class_property_find(klass, name));
   1280 
   1281     prop = g_malloc0(sizeof(*prop));
   1282 
   1283     prop->name = g_strdup(name);
   1284     prop->type = g_strdup(type);
   1285 
   1286     prop->get = get;
   1287     prop->set = set;
   1288     prop->release = release;
   1289     prop->opaque = opaque;
   1290 
   1291     g_hash_table_insert(klass->properties, prop->name, prop);
   1292 
   1293     return prop;
   1294 }
   1295 
   1296 ObjectProperty *object_property_find(Object *obj, const char *name)
   1297 {
   1298     ObjectProperty *prop;
   1299     ObjectClass *klass = object_get_class(obj);
   1300 
   1301     prop = object_class_property_find(klass, name);
   1302     if (prop) {
   1303         return prop;
   1304     }
   1305 
   1306     return g_hash_table_lookup(obj->properties, name);
   1307 }
   1308 
   1309 ObjectProperty *object_property_find_err(Object *obj, const char *name,
   1310                                          Error **errp)
   1311 {
   1312     ObjectProperty *prop = object_property_find(obj, name);
   1313     if (!prop) {
   1314         error_setg(errp, "Property '%s.%s' not found",
   1315                    object_get_typename(obj), name);
   1316     }
   1317     return prop;
   1318 }
   1319 
   1320 void object_property_iter_init(ObjectPropertyIterator *iter,
   1321                                Object *obj)
   1322 {
   1323     g_hash_table_iter_init(&iter->iter, obj->properties);
   1324     iter->nextclass = object_get_class(obj);
   1325 }
   1326 
   1327 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
   1328 {
   1329     gpointer key, val;
   1330     while (!g_hash_table_iter_next(&iter->iter, &key, &val)) {
   1331         if (!iter->nextclass) {
   1332             return NULL;
   1333         }
   1334         g_hash_table_iter_init(&iter->iter, iter->nextclass->properties);
   1335         iter->nextclass = object_class_get_parent(iter->nextclass);
   1336     }
   1337     return val;
   1338 }
   1339 
   1340 void object_class_property_iter_init(ObjectPropertyIterator *iter,
   1341                                      ObjectClass *klass)
   1342 {
   1343     g_hash_table_iter_init(&iter->iter, klass->properties);
   1344     iter->nextclass = object_class_get_parent(klass);
   1345 }
   1346 
   1347 ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name)
   1348 {
   1349     ObjectClass *parent_klass;
   1350 
   1351     parent_klass = object_class_get_parent(klass);
   1352     if (parent_klass) {
   1353         ObjectProperty *prop =
   1354             object_class_property_find(parent_klass, name);
   1355         if (prop) {
   1356             return prop;
   1357         }
   1358     }
   1359 
   1360     return g_hash_table_lookup(klass->properties, name);
   1361 }
   1362 
   1363 ObjectProperty *object_class_property_find_err(ObjectClass *klass,
   1364                                                const char *name,
   1365                                                Error **errp)
   1366 {
   1367     ObjectProperty *prop = object_class_property_find(klass, name);
   1368     if (!prop) {
   1369         error_setg(errp, "Property '.%s' not found", name);
   1370     }
   1371     return prop;
   1372 }
   1373 
   1374 
   1375 void object_property_del(Object *obj, const char *name)
   1376 {
   1377     ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
   1378 
   1379     if (prop->release) {
   1380         prop->release(obj, name, prop->opaque);
   1381     }
   1382     g_hash_table_remove(obj->properties, name);
   1383 }
   1384 
   1385 bool object_property_get(Object *obj, const char *name, Visitor *v,
   1386                          Error **errp)
   1387 {
   1388     Error *err = NULL;
   1389     ObjectProperty *prop = object_property_find_err(obj, name, errp);
   1390 
   1391     if (prop == NULL) {
   1392         return false;
   1393     }
   1394 
   1395     if (!prop->get) {
   1396         error_setg(errp, "Property '%s.%s' is not readable",
   1397                    object_get_typename(obj), name);
   1398         return false;
   1399     }
   1400     prop->get(obj, v, name, prop->opaque, &err);
   1401     error_propagate(errp, err);
   1402     return !err;
   1403 }
   1404 
   1405 bool object_property_set(Object *obj, const char *name, Visitor *v,
   1406                          Error **errp)
   1407 {
   1408     ERRP_GUARD();
   1409     ObjectProperty *prop = object_property_find_err(obj, name, errp);
   1410 
   1411     if (prop == NULL) {
   1412         return false;
   1413     }
   1414 
   1415     if (!prop->set) {
   1416         error_setg(errp, "Property '%s.%s' is not writable",
   1417                    object_get_typename(obj), name);
   1418         return false;
   1419     }
   1420     prop->set(obj, v, name, prop->opaque, errp);
   1421     return !*errp;
   1422 }
   1423 
   1424 bool object_property_set_str(Object *obj, const char *name,
   1425                              const char *value, Error **errp)
   1426 {
   1427     QString *qstr = qstring_from_str(value);
   1428     bool ok = object_property_set_qobject(obj, name, QOBJECT(qstr), errp);
   1429 
   1430     qobject_unref(qstr);
   1431     return ok;
   1432 }
   1433 
   1434 char *object_property_get_str(Object *obj, const char *name,
   1435                               Error **errp)
   1436 {
   1437     QObject *ret = object_property_get_qobject(obj, name, errp);
   1438     QString *qstring;
   1439     char *retval;
   1440 
   1441     if (!ret) {
   1442         return NULL;
   1443     }
   1444     qstring = qobject_to(QString, ret);
   1445     if (!qstring) {
   1446         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
   1447         retval = NULL;
   1448     } else {
   1449         retval = g_strdup(qstring_get_str(qstring));
   1450     }
   1451 
   1452     qobject_unref(ret);
   1453     return retval;
   1454 }
   1455 
   1456 bool object_property_set_link(Object *obj, const char *name,
   1457                               Object *value, Error **errp)
   1458 {
   1459     g_autofree char *path = NULL;
   1460 
   1461     if (value) {
   1462         path = object_get_canonical_path(value);
   1463     }
   1464     return object_property_set_str(obj, name, path ?: "", errp);
   1465 }
   1466 
   1467 Object *object_property_get_link(Object *obj, const char *name,
   1468                                  Error **errp)
   1469 {
   1470     char *str = object_property_get_str(obj, name, errp);
   1471     Object *target = NULL;
   1472 
   1473     if (str && *str) {
   1474         target = object_resolve_path(str, NULL);
   1475         if (!target) {
   1476             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
   1477                       "Device '%s' not found", str);
   1478         }
   1479     }
   1480 
   1481     g_free(str);
   1482     return target;
   1483 }
   1484 
   1485 bool object_property_set_bool(Object *obj, const char *name,
   1486                               bool value, Error **errp)
   1487 {
   1488     QBool *qbool = qbool_from_bool(value);
   1489     bool ok = object_property_set_qobject(obj, name, QOBJECT(qbool), errp);
   1490 
   1491     qobject_unref(qbool);
   1492     return ok;
   1493 }
   1494 
   1495 bool object_property_get_bool(Object *obj, const char *name,
   1496                               Error **errp)
   1497 {
   1498     QObject *ret = object_property_get_qobject(obj, name, errp);
   1499     QBool *qbool;
   1500     bool retval;
   1501 
   1502     if (!ret) {
   1503         return false;
   1504     }
   1505     qbool = qobject_to(QBool, ret);
   1506     if (!qbool) {
   1507         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
   1508         retval = false;
   1509     } else {
   1510         retval = qbool_get_bool(qbool);
   1511     }
   1512 
   1513     qobject_unref(ret);
   1514     return retval;
   1515 }
   1516 
   1517 bool object_property_set_int(Object *obj, const char *name,
   1518                              int64_t value, Error **errp)
   1519 {
   1520     QNum *qnum = qnum_from_int(value);
   1521     bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
   1522 
   1523     qobject_unref(qnum);
   1524     return ok;
   1525 }
   1526 
   1527 int64_t object_property_get_int(Object *obj, const char *name,
   1528                                 Error **errp)
   1529 {
   1530     QObject *ret = object_property_get_qobject(obj, name, errp);
   1531     QNum *qnum;
   1532     int64_t retval;
   1533 
   1534     if (!ret) {
   1535         return -1;
   1536     }
   1537 
   1538     qnum = qobject_to(QNum, ret);
   1539     if (!qnum || !qnum_get_try_int(qnum, &retval)) {
   1540         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
   1541         retval = -1;
   1542     }
   1543 
   1544     qobject_unref(ret);
   1545     return retval;
   1546 }
   1547 
   1548 static void object_property_init_defval(Object *obj, ObjectProperty *prop)
   1549 {
   1550     Visitor *v = qobject_input_visitor_new(prop->defval);
   1551 
   1552     assert(prop->set != NULL);
   1553     prop->set(obj, v, prop->name, prop->opaque, &error_abort);
   1554 
   1555     visit_free(v);
   1556 }
   1557 
   1558 static void object_property_set_default(ObjectProperty *prop, QObject *defval)
   1559 {
   1560     assert(!prop->defval);
   1561     assert(!prop->init);
   1562 
   1563     prop->defval = defval;
   1564     prop->init = object_property_init_defval;
   1565 }
   1566 
   1567 void object_property_set_default_bool(ObjectProperty *prop, bool value)
   1568 {
   1569     object_property_set_default(prop, QOBJECT(qbool_from_bool(value)));
   1570 }
   1571 
   1572 void object_property_set_default_str(ObjectProperty *prop, const char *value)
   1573 {
   1574     object_property_set_default(prop, QOBJECT(qstring_from_str(value)));
   1575 }
   1576 
   1577 void object_property_set_default_int(ObjectProperty *prop, int64_t value)
   1578 {
   1579     object_property_set_default(prop, QOBJECT(qnum_from_int(value)));
   1580 }
   1581 
   1582 void object_property_set_default_uint(ObjectProperty *prop, uint64_t value)
   1583 {
   1584     object_property_set_default(prop, QOBJECT(qnum_from_uint(value)));
   1585 }
   1586 
   1587 bool object_property_set_uint(Object *obj, const char *name,
   1588                               uint64_t value, Error **errp)
   1589 {
   1590     QNum *qnum = qnum_from_uint(value);
   1591     bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
   1592 
   1593     qobject_unref(qnum);
   1594     return ok;
   1595 }
   1596 
   1597 uint64_t object_property_get_uint(Object *obj, const char *name,
   1598                                   Error **errp)
   1599 {
   1600     QObject *ret = object_property_get_qobject(obj, name, errp);
   1601     QNum *qnum;
   1602     uint64_t retval;
   1603 
   1604     if (!ret) {
   1605         return 0;
   1606     }
   1607     qnum = qobject_to(QNum, ret);
   1608     if (!qnum || !qnum_get_try_uint(qnum, &retval)) {
   1609         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
   1610         retval = 0;
   1611     }
   1612 
   1613     qobject_unref(ret);
   1614     return retval;
   1615 }
   1616 
   1617 typedef struct EnumProperty {
   1618     const QEnumLookup *lookup;
   1619     int (*get)(Object *, Error **);
   1620     void (*set)(Object *, int, Error **);
   1621 } EnumProperty;
   1622 
   1623 int object_property_get_enum(Object *obj, const char *name,
   1624                              const char *typename, Error **errp)
   1625 {
   1626     char *str;
   1627     int ret;
   1628     ObjectProperty *prop = object_property_find_err(obj, name, errp);
   1629     EnumProperty *enumprop;
   1630 
   1631     if (prop == NULL) {
   1632         return -1;
   1633     }
   1634 
   1635     if (!g_str_equal(prop->type, typename)) {
   1636         error_setg(errp, "Property %s on %s is not '%s' enum type",
   1637                    name, object_class_get_name(
   1638                        object_get_class(obj)), typename);
   1639         return -1;
   1640     }
   1641 
   1642     enumprop = prop->opaque;
   1643 
   1644     str = object_property_get_str(obj, name, errp);
   1645     if (!str) {
   1646         return -1;
   1647     }
   1648 
   1649     ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
   1650     g_free(str);
   1651 
   1652     return ret;
   1653 }
   1654 
   1655 bool object_property_parse(Object *obj, const char *name,
   1656                            const char *string, Error **errp)
   1657 {
   1658     Visitor *v = string_input_visitor_new(string);
   1659     bool ok = object_property_set(obj, name, v, errp);
   1660 
   1661     visit_free(v);
   1662     return ok;
   1663 }
   1664 
   1665 char *object_property_print(Object *obj, const char *name, bool human,
   1666                             Error **errp)
   1667 {
   1668     Visitor *v;
   1669     char *string = NULL;
   1670 
   1671     v = string_output_visitor_new(human, &string);
   1672     if (!object_property_get(obj, name, v, errp)) {
   1673         goto out;
   1674     }
   1675 
   1676     visit_complete(v, &string);
   1677 
   1678 out:
   1679     visit_free(v);
   1680     return string;
   1681 }
   1682 
   1683 const char *object_property_get_type(Object *obj, const char *name, Error **errp)
   1684 {
   1685     ObjectProperty *prop = object_property_find_err(obj, name, errp);
   1686     if (prop == NULL) {
   1687         return NULL;
   1688     }
   1689 
   1690     return prop->type;
   1691 }
   1692 
   1693 Object *object_get_root(void)
   1694 {
   1695     static Object *root;
   1696 
   1697     if (!root) {
   1698         root = object_new("container");
   1699     }
   1700 
   1701     return root;
   1702 }
   1703 
   1704 Object *object_get_objects_root(void)
   1705 {
   1706     return container_get(object_get_root(), "/objects");
   1707 }
   1708 
   1709 Object *object_get_internal_root(void)
   1710 {
   1711     static Object *internal_root;
   1712 
   1713     if (!internal_root) {
   1714         internal_root = object_new("container");
   1715     }
   1716 
   1717     return internal_root;
   1718 }
   1719 
   1720 static void object_get_child_property(Object *obj, Visitor *v,
   1721                                       const char *name, void *opaque,
   1722                                       Error **errp)
   1723 {
   1724     Object *child = opaque;
   1725     char *path;
   1726 
   1727     path = object_get_canonical_path(child);
   1728     visit_type_str(v, name, &path, errp);
   1729     g_free(path);
   1730 }
   1731 
   1732 static Object *object_resolve_child_property(Object *parent, void *opaque,
   1733                                              const char *part)
   1734 {
   1735     return opaque;
   1736 }
   1737 
   1738 static void object_finalize_child_property(Object *obj, const char *name,
   1739                                            void *opaque)
   1740 {
   1741     Object *child = opaque;
   1742 
   1743     if (child->class->unparent) {
   1744         (child->class->unparent)(child);
   1745     }
   1746     child->parent = NULL;
   1747     object_unref(child);
   1748 }
   1749 
   1750 ObjectProperty *
   1751 object_property_try_add_child(Object *obj, const char *name,
   1752                               Object *child, Error **errp)
   1753 {
   1754     g_autofree char *type = NULL;
   1755     ObjectProperty *op;
   1756 
   1757     assert(!child->parent);
   1758 
   1759     type = g_strdup_printf("child<%s>", object_get_typename(child));
   1760 
   1761     op = object_property_try_add(obj, name, type, object_get_child_property,
   1762                                  NULL, object_finalize_child_property,
   1763                                  child, errp);
   1764     if (!op) {
   1765         return NULL;
   1766     }
   1767     op->resolve = object_resolve_child_property;
   1768     object_ref(child);
   1769     child->parent = obj;
   1770     return op;
   1771 }
   1772 
   1773 ObjectProperty *
   1774 object_property_add_child(Object *obj, const char *name,
   1775                           Object *child)
   1776 {
   1777     return object_property_try_add_child(obj, name, child, &error_abort);
   1778 }
   1779 
   1780 void object_property_allow_set_link(const Object *obj, const char *name,
   1781                                     Object *val, Error **errp)
   1782 {
   1783     /* Allow the link to be set, always */
   1784 }
   1785 
   1786 typedef struct {
   1787     union {
   1788         Object **targetp;
   1789         Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer  */
   1790         ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */
   1791     };
   1792     void (*check)(const Object *, const char *, Object *, Error **);
   1793     ObjectPropertyLinkFlags flags;
   1794 } LinkProperty;
   1795 
   1796 static Object **
   1797 object_link_get_targetp(Object *obj, LinkProperty *lprop)
   1798 {
   1799     if (lprop->flags & OBJ_PROP_LINK_DIRECT) {
   1800         return &lprop->target;
   1801     } else if (lprop->flags & OBJ_PROP_LINK_CLASS) {
   1802         return (void *)obj + lprop->offset;
   1803     } else {
   1804         return lprop->targetp;
   1805     }
   1806 }
   1807 
   1808 static void object_get_link_property(Object *obj, Visitor *v,
   1809                                      const char *name, void *opaque,
   1810                                      Error **errp)
   1811 {
   1812     LinkProperty *lprop = opaque;
   1813     Object **targetp = object_link_get_targetp(obj, lprop);
   1814     char *path;
   1815 
   1816     if (*targetp) {
   1817         path = object_get_canonical_path(*targetp);
   1818         visit_type_str(v, name, &path, errp);
   1819         g_free(path);
   1820     } else {
   1821         path = (char *)"";
   1822         visit_type_str(v, name, &path, errp);
   1823     }
   1824 }
   1825 
   1826 /*
   1827  * object_resolve_link:
   1828  *
   1829  * Lookup an object and ensure its type matches the link property type.  This
   1830  * is similar to object_resolve_path() except type verification against the
   1831  * link property is performed.
   1832  *
   1833  * Returns: The matched object or NULL on path lookup failures.
   1834  */
   1835 static Object *object_resolve_link(Object *obj, const char *name,
   1836                                    const char *path, Error **errp)
   1837 {
   1838     const char *type;
   1839     char *target_type;
   1840     bool ambiguous = false;
   1841     Object *target;
   1842 
   1843     /* Go from link<FOO> to FOO.  */
   1844     type = object_property_get_type(obj, name, NULL);
   1845     target_type = g_strndup(&type[5], strlen(type) - 6);
   1846     target = object_resolve_path_type(path, target_type, &ambiguous);
   1847 
   1848     if (ambiguous) {
   1849         error_setg(errp, "Path '%s' does not uniquely identify an object",
   1850                    path);
   1851     } else if (!target) {
   1852         target = object_resolve_path(path, &ambiguous);
   1853         if (target || ambiguous) {
   1854             error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
   1855         } else {
   1856             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
   1857                       "Device '%s' not found", path);
   1858         }
   1859         target = NULL;
   1860     }
   1861     g_free(target_type);
   1862 
   1863     return target;
   1864 }
   1865 
   1866 static void object_set_link_property(Object *obj, Visitor *v,
   1867                                      const char *name, void *opaque,
   1868                                      Error **errp)
   1869 {
   1870     Error *local_err = NULL;
   1871     LinkProperty *prop = opaque;
   1872     Object **targetp = object_link_get_targetp(obj, prop);
   1873     Object *old_target = *targetp;
   1874     Object *new_target;
   1875     char *path = NULL;
   1876 
   1877     if (!visit_type_str(v, name, &path, errp)) {
   1878         return;
   1879     }
   1880 
   1881     if (*path) {
   1882         new_target = object_resolve_link(obj, name, path, errp);
   1883         if (!new_target) {
   1884             g_free(path);
   1885             return;
   1886         }
   1887     } else {
   1888         new_target = NULL;
   1889     }
   1890 
   1891     g_free(path);
   1892 
   1893     prop->check(obj, name, new_target, &local_err);
   1894     if (local_err) {
   1895         error_propagate(errp, local_err);
   1896         return;
   1897     }
   1898 
   1899     *targetp = new_target;
   1900     if (prop->flags & OBJ_PROP_LINK_STRONG) {
   1901         object_ref(new_target);
   1902         object_unref(old_target);
   1903     }
   1904 }
   1905 
   1906 static Object *object_resolve_link_property(Object *parent, void *opaque,
   1907                                             const char *part)
   1908 {
   1909     LinkProperty *lprop = opaque;
   1910 
   1911     return *object_link_get_targetp(parent, lprop);
   1912 }
   1913 
   1914 static void object_release_link_property(Object *obj, const char *name,
   1915                                          void *opaque)
   1916 {
   1917     LinkProperty *prop = opaque;
   1918     Object **targetp = object_link_get_targetp(obj, prop);
   1919 
   1920     if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) {
   1921         object_unref(*targetp);
   1922     }
   1923     if (!(prop->flags & OBJ_PROP_LINK_CLASS)) {
   1924         g_free(prop);
   1925     }
   1926 }
   1927 
   1928 static ObjectProperty *
   1929 object_add_link_prop(Object *obj, const char *name,
   1930                      const char *type, void *ptr,
   1931                      void (*check)(const Object *, const char *,
   1932                                    Object *, Error **),
   1933                      ObjectPropertyLinkFlags flags)
   1934 {
   1935     LinkProperty *prop = g_malloc(sizeof(*prop));
   1936     g_autofree char *full_type = NULL;
   1937     ObjectProperty *op;
   1938 
   1939     if (flags & OBJ_PROP_LINK_DIRECT) {
   1940         prop->target = ptr;
   1941     } else {
   1942         prop->targetp = ptr;
   1943     }
   1944     prop->check = check;
   1945     prop->flags = flags;
   1946 
   1947     full_type = g_strdup_printf("link<%s>", type);
   1948 
   1949     op = object_property_add(obj, name, full_type,
   1950                              object_get_link_property,
   1951                              check ? object_set_link_property : NULL,
   1952                              object_release_link_property,
   1953                              prop);
   1954     op->resolve = object_resolve_link_property;
   1955     return op;
   1956 }
   1957 
   1958 ObjectProperty *
   1959 object_property_add_link(Object *obj, const char *name,
   1960                          const char *type, Object **targetp,
   1961                          void (*check)(const Object *, const char *,
   1962                                        Object *, Error **),
   1963                          ObjectPropertyLinkFlags flags)
   1964 {
   1965     return object_add_link_prop(obj, name, type, targetp, check, flags);
   1966 }
   1967 
   1968 ObjectProperty *
   1969 object_class_property_add_link(ObjectClass *oc,
   1970     const char *name,
   1971     const char *type, ptrdiff_t offset,
   1972     void (*check)(const Object *obj, const char *name,
   1973                   Object *val, Error **errp),
   1974     ObjectPropertyLinkFlags flags)
   1975 {
   1976     LinkProperty *prop = g_new0(LinkProperty, 1);
   1977     char *full_type;
   1978     ObjectProperty *op;
   1979 
   1980     prop->offset = offset;
   1981     prop->check = check;
   1982     prop->flags = flags | OBJ_PROP_LINK_CLASS;
   1983 
   1984     full_type = g_strdup_printf("link<%s>", type);
   1985 
   1986     op = object_class_property_add(oc, name, full_type,
   1987                                    object_get_link_property,
   1988                                    check ? object_set_link_property : NULL,
   1989                                    object_release_link_property,
   1990                                    prop);
   1991 
   1992     op->resolve = object_resolve_link_property;
   1993 
   1994     g_free(full_type);
   1995     return op;
   1996 }
   1997 
   1998 ObjectProperty *
   1999 object_property_add_const_link(Object *obj, const char *name,
   2000                                Object *target)
   2001 {
   2002     return object_add_link_prop(obj, name,
   2003                                 object_get_typename(target), target,
   2004                                 NULL, OBJ_PROP_LINK_DIRECT);
   2005 }
   2006 
   2007 const char *object_get_canonical_path_component(const Object *obj)
   2008 {
   2009     ObjectProperty *prop = NULL;
   2010     GHashTableIter iter;
   2011 
   2012     if (obj->parent == NULL) {
   2013         return NULL;
   2014     }
   2015 
   2016     g_hash_table_iter_init(&iter, obj->parent->properties);
   2017     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
   2018         if (!object_property_is_child(prop)) {
   2019             continue;
   2020         }
   2021 
   2022         if (prop->opaque == obj) {
   2023             return prop->name;
   2024         }
   2025     }
   2026 
   2027     /* obj had a parent but was not a child, should never happen */
   2028     g_assert_not_reached();
   2029     return NULL;
   2030 }
   2031 
   2032 char *object_get_canonical_path(const Object *obj)
   2033 {
   2034     Object *root = object_get_root();
   2035     char *newpath, *path = NULL;
   2036 
   2037     if (obj == root) {
   2038         return g_strdup("/");
   2039     }
   2040 
   2041     do {
   2042         const char *component = object_get_canonical_path_component(obj);
   2043 
   2044         if (!component) {
   2045             /* A canonical path must be complete, so discard what was
   2046              * collected so far.
   2047              */
   2048             g_free(path);
   2049             return NULL;
   2050         }
   2051 
   2052         newpath = g_strdup_printf("/%s%s", component, path ? path : "");
   2053         g_free(path);
   2054         path = newpath;
   2055         obj = obj->parent;
   2056     } while (obj != root);
   2057 
   2058     return path;
   2059 }
   2060 
   2061 Object *object_resolve_path_component(Object *parent, const char *part)
   2062 {
   2063     ObjectProperty *prop = object_property_find(parent, part);
   2064     if (prop == NULL) {
   2065         return NULL;
   2066     }
   2067 
   2068     if (prop->resolve) {
   2069         return prop->resolve(parent, prop->opaque, part);
   2070     } else {
   2071         return NULL;
   2072     }
   2073 }
   2074 
   2075 static Object *object_resolve_abs_path(Object *parent,
   2076                                           char **parts,
   2077                                           const char *typename)
   2078 {
   2079     Object *child;
   2080 
   2081     if (*parts == NULL) {
   2082         return object_dynamic_cast(parent, typename);
   2083     }
   2084 
   2085     if (strcmp(*parts, "") == 0) {
   2086         return object_resolve_abs_path(parent, parts + 1, typename);
   2087     }
   2088 
   2089     child = object_resolve_path_component(parent, *parts);
   2090     if (!child) {
   2091         return NULL;
   2092     }
   2093 
   2094     return object_resolve_abs_path(child, parts + 1, typename);
   2095 }
   2096 
   2097 static Object *object_resolve_partial_path(Object *parent,
   2098                                            char **parts,
   2099                                            const char *typename,
   2100                                            bool *ambiguous)
   2101 {
   2102     Object *obj;
   2103     GHashTableIter iter;
   2104     ObjectProperty *prop;
   2105 
   2106     obj = object_resolve_abs_path(parent, parts, typename);
   2107 
   2108     g_hash_table_iter_init(&iter, parent->properties);
   2109     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
   2110         Object *found;
   2111 
   2112         if (!object_property_is_child(prop)) {
   2113             continue;
   2114         }
   2115 
   2116         found = object_resolve_partial_path(prop->opaque, parts,
   2117                                             typename, ambiguous);
   2118         if (found) {
   2119             if (obj) {
   2120                 *ambiguous = true;
   2121                 return NULL;
   2122             }
   2123             obj = found;
   2124         }
   2125 
   2126         if (*ambiguous) {
   2127             return NULL;
   2128         }
   2129     }
   2130 
   2131     return obj;
   2132 }
   2133 
   2134 Object *object_resolve_path_type(const char *path, const char *typename,
   2135                                  bool *ambiguousp)
   2136 {
   2137     Object *obj;
   2138     char **parts;
   2139 
   2140     parts = g_strsplit(path, "/", 0);
   2141     assert(parts);
   2142 
   2143     if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
   2144         bool ambiguous = false;
   2145         obj = object_resolve_partial_path(object_get_root(), parts,
   2146                                           typename, &ambiguous);
   2147         if (ambiguousp) {
   2148             *ambiguousp = ambiguous;
   2149         }
   2150     } else {
   2151         obj = object_resolve_abs_path(object_get_root(), parts + 1, typename);
   2152     }
   2153 
   2154     g_strfreev(parts);
   2155 
   2156     return obj;
   2157 }
   2158 
   2159 Object *object_resolve_path(const char *path, bool *ambiguous)
   2160 {
   2161     return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
   2162 }
   2163 
   2164 Object *object_resolve_path_at(Object *parent, const char *path)
   2165 {
   2166     g_auto(GStrv) parts = g_strsplit(path, "/", 0);
   2167 
   2168     if (*path == '/') {
   2169         return object_resolve_abs_path(object_get_root(), parts + 1,
   2170                                        TYPE_OBJECT);
   2171     }
   2172     return object_resolve_abs_path(parent, parts, TYPE_OBJECT);
   2173 }
   2174 
   2175 typedef struct StringProperty
   2176 {
   2177     char *(*get)(Object *, Error **);
   2178     void (*set)(Object *, const char *, Error **);
   2179 } StringProperty;
   2180 
   2181 static void property_get_str(Object *obj, Visitor *v, const char *name,
   2182                              void *opaque, Error **errp)
   2183 {
   2184     StringProperty *prop = opaque;
   2185     char *value;
   2186     Error *err = NULL;
   2187 
   2188     value = prop->get(obj, &err);
   2189     if (err) {
   2190         error_propagate(errp, err);
   2191         return;
   2192     }
   2193 
   2194     visit_type_str(v, name, &value, errp);
   2195     g_free(value);
   2196 }
   2197 
   2198 static void property_set_str(Object *obj, Visitor *v, const char *name,
   2199                              void *opaque, Error **errp)
   2200 {
   2201     StringProperty *prop = opaque;
   2202     char *value;
   2203 
   2204     if (!visit_type_str(v, name, &value, errp)) {
   2205         return;
   2206     }
   2207 
   2208     prop->set(obj, value, errp);
   2209     g_free(value);
   2210 }
   2211 
   2212 static void property_release_data(Object *obj, const char *name,
   2213                                   void *opaque)
   2214 {
   2215     g_free(opaque);
   2216 }
   2217 
   2218 ObjectProperty *
   2219 object_property_add_str(Object *obj, const char *name,
   2220                         char *(*get)(Object *, Error **),
   2221                         void (*set)(Object *, const char *, Error **))
   2222 {
   2223     StringProperty *prop = g_malloc0(sizeof(*prop));
   2224 
   2225     prop->get = get;
   2226     prop->set = set;
   2227 
   2228     return object_property_add(obj, name, "string",
   2229                                get ? property_get_str : NULL,
   2230                                set ? property_set_str : NULL,
   2231                                property_release_data,
   2232                                prop);
   2233 }
   2234 
   2235 ObjectProperty *
   2236 object_class_property_add_str(ObjectClass *klass, const char *name,
   2237                                    char *(*get)(Object *, Error **),
   2238                                    void (*set)(Object *, const char *,
   2239                                                Error **))
   2240 {
   2241     StringProperty *prop = g_malloc0(sizeof(*prop));
   2242 
   2243     prop->get = get;
   2244     prop->set = set;
   2245 
   2246     return object_class_property_add(klass, name, "string",
   2247                                      get ? property_get_str : NULL,
   2248                                      set ? property_set_str : NULL,
   2249                                      NULL,
   2250                                      prop);
   2251 }
   2252 
   2253 typedef struct BoolProperty
   2254 {
   2255     bool (*get)(Object *, Error **);
   2256     void (*set)(Object *, bool, Error **);
   2257 } BoolProperty;
   2258 
   2259 static void property_get_bool(Object *obj, Visitor *v, const char *name,
   2260                               void *opaque, Error **errp)
   2261 {
   2262     BoolProperty *prop = opaque;
   2263     bool value;
   2264     Error *err = NULL;
   2265 
   2266     value = prop->get(obj, &err);
   2267     if (err) {
   2268         error_propagate(errp, err);
   2269         return;
   2270     }
   2271 
   2272     visit_type_bool(v, name, &value, errp);
   2273 }
   2274 
   2275 static void property_set_bool(Object *obj, Visitor *v, const char *name,
   2276                               void *opaque, Error **errp)
   2277 {
   2278     BoolProperty *prop = opaque;
   2279     bool value;
   2280 
   2281     if (!visit_type_bool(v, name, &value, errp)) {
   2282         return;
   2283     }
   2284 
   2285     prop->set(obj, value, errp);
   2286 }
   2287 
   2288 ObjectProperty *
   2289 object_property_add_bool(Object *obj, const char *name,
   2290                          bool (*get)(Object *, Error **),
   2291                          void (*set)(Object *, bool, Error **))
   2292 {
   2293     BoolProperty *prop = g_malloc0(sizeof(*prop));
   2294 
   2295     prop->get = get;
   2296     prop->set = set;
   2297 
   2298     return object_property_add(obj, name, "bool",
   2299                                get ? property_get_bool : NULL,
   2300                                set ? property_set_bool : NULL,
   2301                                property_release_data,
   2302                                prop);
   2303 }
   2304 
   2305 ObjectProperty *
   2306 object_class_property_add_bool(ObjectClass *klass, const char *name,
   2307                                     bool (*get)(Object *, Error **),
   2308                                     void (*set)(Object *, bool, Error **))
   2309 {
   2310     BoolProperty *prop = g_malloc0(sizeof(*prop));
   2311 
   2312     prop->get = get;
   2313     prop->set = set;
   2314 
   2315     return object_class_property_add(klass, name, "bool",
   2316                                      get ? property_get_bool : NULL,
   2317                                      set ? property_set_bool : NULL,
   2318                                      NULL,
   2319                                      prop);
   2320 }
   2321 
   2322 static void property_get_enum(Object *obj, Visitor *v, const char *name,
   2323                               void *opaque, Error **errp)
   2324 {
   2325     EnumProperty *prop = opaque;
   2326     int value;
   2327     Error *err = NULL;
   2328 
   2329     value = prop->get(obj, &err);
   2330     if (err) {
   2331         error_propagate(errp, err);
   2332         return;
   2333     }
   2334 
   2335     visit_type_enum(v, name, &value, prop->lookup, errp);
   2336 }
   2337 
   2338 static void property_set_enum(Object *obj, Visitor *v, const char *name,
   2339                               void *opaque, Error **errp)
   2340 {
   2341     EnumProperty *prop = opaque;
   2342     int value;
   2343 
   2344     if (!visit_type_enum(v, name, &value, prop->lookup, errp)) {
   2345         return;
   2346     }
   2347     prop->set(obj, value, errp);
   2348 }
   2349 
   2350 ObjectProperty *
   2351 object_property_add_enum(Object *obj, const char *name,
   2352                          const char *typename,
   2353                          const QEnumLookup *lookup,
   2354                          int (*get)(Object *, Error **),
   2355                          void (*set)(Object *, int, Error **))
   2356 {
   2357     EnumProperty *prop = g_malloc(sizeof(*prop));
   2358 
   2359     prop->lookup = lookup;
   2360     prop->get = get;
   2361     prop->set = set;
   2362 
   2363     return object_property_add(obj, name, typename,
   2364                                get ? property_get_enum : NULL,
   2365                                set ? property_set_enum : NULL,
   2366                                property_release_data,
   2367                                prop);
   2368 }
   2369 
   2370 ObjectProperty *
   2371 object_class_property_add_enum(ObjectClass *klass, const char *name,
   2372                                     const char *typename,
   2373                                     const QEnumLookup *lookup,
   2374                                     int (*get)(Object *, Error **),
   2375                                     void (*set)(Object *, int, Error **))
   2376 {
   2377     EnumProperty *prop = g_malloc(sizeof(*prop));
   2378 
   2379     prop->lookup = lookup;
   2380     prop->get = get;
   2381     prop->set = set;
   2382 
   2383     return object_class_property_add(klass, name, typename,
   2384                                      get ? property_get_enum : NULL,
   2385                                      set ? property_set_enum : NULL,
   2386                                      NULL,
   2387                                      prop);
   2388 }
   2389 
   2390 typedef struct TMProperty {
   2391     void (*get)(Object *, struct tm *, Error **);
   2392 } TMProperty;
   2393 
   2394 static void property_get_tm(Object *obj, Visitor *v, const char *name,
   2395                             void *opaque, Error **errp)
   2396 {
   2397     TMProperty *prop = opaque;
   2398     Error *err = NULL;
   2399     struct tm value;
   2400 
   2401     prop->get(obj, &value, &err);
   2402     if (err) {
   2403         error_propagate(errp, err);
   2404         return;
   2405     }
   2406 
   2407     if (!visit_start_struct(v, name, NULL, 0, errp)) {
   2408         return;
   2409     }
   2410     if (!visit_type_int32(v, "tm_year", &value.tm_year, errp)) {
   2411         goto out_end;
   2412     }
   2413     if (!visit_type_int32(v, "tm_mon", &value.tm_mon, errp)) {
   2414         goto out_end;
   2415     }
   2416     if (!visit_type_int32(v, "tm_mday", &value.tm_mday, errp)) {
   2417         goto out_end;
   2418     }
   2419     if (!visit_type_int32(v, "tm_hour", &value.tm_hour, errp)) {
   2420         goto out_end;
   2421     }
   2422     if (!visit_type_int32(v, "tm_min", &value.tm_min, errp)) {
   2423         goto out_end;
   2424     }
   2425     if (!visit_type_int32(v, "tm_sec", &value.tm_sec, errp)) {
   2426         goto out_end;
   2427     }
   2428     visit_check_struct(v, errp);
   2429 out_end:
   2430     visit_end_struct(v, NULL);
   2431 }
   2432 
   2433 ObjectProperty *
   2434 object_property_add_tm(Object *obj, const char *name,
   2435                        void (*get)(Object *, struct tm *, Error **))
   2436 {
   2437     TMProperty *prop = g_malloc0(sizeof(*prop));
   2438 
   2439     prop->get = get;
   2440 
   2441     return object_property_add(obj, name, "struct tm",
   2442                                get ? property_get_tm : NULL, NULL,
   2443                                property_release_data,
   2444                                prop);
   2445 }
   2446 
   2447 ObjectProperty *
   2448 object_class_property_add_tm(ObjectClass *klass, const char *name,
   2449                              void (*get)(Object *, struct tm *, Error **))
   2450 {
   2451     TMProperty *prop = g_malloc0(sizeof(*prop));
   2452 
   2453     prop->get = get;
   2454 
   2455     return object_class_property_add(klass, name, "struct tm",
   2456                                      get ? property_get_tm : NULL,
   2457                                      NULL, NULL, prop);
   2458 }
   2459 
   2460 static char *object_get_type(Object *obj, Error **errp)
   2461 {
   2462     return g_strdup(object_get_typename(obj));
   2463 }
   2464 
   2465 static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name,
   2466                                    void *opaque, Error **errp)
   2467 {
   2468     uint8_t value = *(uint8_t *)opaque;
   2469     visit_type_uint8(v, name, &value, errp);
   2470 }
   2471 
   2472 static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name,
   2473                                    void *opaque, Error **errp)
   2474 {
   2475     uint8_t *field = opaque;
   2476     uint8_t value;
   2477 
   2478     if (!visit_type_uint8(v, name, &value, errp)) {
   2479         return;
   2480     }
   2481 
   2482     *field = value;
   2483 }
   2484 
   2485 static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
   2486                                     void *opaque, Error **errp)
   2487 {
   2488     uint16_t value = *(uint16_t *)opaque;
   2489     visit_type_uint16(v, name, &value, errp);
   2490 }
   2491 
   2492 static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name,
   2493                                     void *opaque, Error **errp)
   2494 {
   2495     uint16_t *field = opaque;
   2496     uint16_t value;
   2497 
   2498     if (!visit_type_uint16(v, name, &value, errp)) {
   2499         return;
   2500     }
   2501 
   2502     *field = value;
   2503 }
   2504 
   2505 static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
   2506                                     void *opaque, Error **errp)
   2507 {
   2508     uint32_t value = *(uint32_t *)opaque;
   2509     visit_type_uint32(v, name, &value, errp);
   2510 }
   2511 
   2512 static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name,
   2513                                     void *opaque, Error **errp)
   2514 {
   2515     uint32_t *field = opaque;
   2516     uint32_t value;
   2517 
   2518     if (!visit_type_uint32(v, name, &value, errp)) {
   2519         return;
   2520     }
   2521 
   2522     *field = value;
   2523 }
   2524 
   2525 static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
   2526                                     void *opaque, Error **errp)
   2527 {
   2528     uint64_t value = *(uint64_t *)opaque;
   2529     visit_type_uint64(v, name, &value, errp);
   2530 }
   2531 
   2532 static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name,
   2533                                     void *opaque, Error **errp)
   2534 {
   2535     uint64_t *field = opaque;
   2536     uint64_t value;
   2537 
   2538     if (!visit_type_uint64(v, name, &value, errp)) {
   2539         return;
   2540     }
   2541 
   2542     *field = value;
   2543 }
   2544 
   2545 ObjectProperty *
   2546 object_property_add_uint8_ptr(Object *obj, const char *name,
   2547                               const uint8_t *v,
   2548                               ObjectPropertyFlags flags)
   2549 {
   2550     ObjectPropertyAccessor *getter = NULL;
   2551     ObjectPropertyAccessor *setter = NULL;
   2552 
   2553     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2554         getter = property_get_uint8_ptr;
   2555     }
   2556 
   2557     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2558         setter = property_set_uint8_ptr;
   2559     }
   2560 
   2561     return object_property_add(obj, name, "uint8",
   2562                                getter, setter, NULL, (void *)v);
   2563 }
   2564 
   2565 ObjectProperty *
   2566 object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
   2567                                     const uint8_t *v,
   2568                                     ObjectPropertyFlags flags)
   2569 {
   2570     ObjectPropertyAccessor *getter = NULL;
   2571     ObjectPropertyAccessor *setter = NULL;
   2572 
   2573     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2574         getter = property_get_uint8_ptr;
   2575     }
   2576 
   2577     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2578         setter = property_set_uint8_ptr;
   2579     }
   2580 
   2581     return object_class_property_add(klass, name, "uint8",
   2582                                      getter, setter, NULL, (void *)v);
   2583 }
   2584 
   2585 ObjectProperty *
   2586 object_property_add_uint16_ptr(Object *obj, const char *name,
   2587                                const uint16_t *v,
   2588                                ObjectPropertyFlags flags)
   2589 {
   2590     ObjectPropertyAccessor *getter = NULL;
   2591     ObjectPropertyAccessor *setter = NULL;
   2592 
   2593     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2594         getter = property_get_uint16_ptr;
   2595     }
   2596 
   2597     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2598         setter = property_set_uint16_ptr;
   2599     }
   2600 
   2601     return object_property_add(obj, name, "uint16",
   2602                                getter, setter, NULL, (void *)v);
   2603 }
   2604 
   2605 ObjectProperty *
   2606 object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
   2607                                      const uint16_t *v,
   2608                                      ObjectPropertyFlags flags)
   2609 {
   2610     ObjectPropertyAccessor *getter = NULL;
   2611     ObjectPropertyAccessor *setter = NULL;
   2612 
   2613     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2614         getter = property_get_uint16_ptr;
   2615     }
   2616 
   2617     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2618         setter = property_set_uint16_ptr;
   2619     }
   2620 
   2621     return object_class_property_add(klass, name, "uint16",
   2622                                      getter, setter, NULL, (void *)v);
   2623 }
   2624 
   2625 ObjectProperty *
   2626 object_property_add_uint32_ptr(Object *obj, const char *name,
   2627                                const uint32_t *v,
   2628                                ObjectPropertyFlags flags)
   2629 {
   2630     ObjectPropertyAccessor *getter = NULL;
   2631     ObjectPropertyAccessor *setter = NULL;
   2632 
   2633     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2634         getter = property_get_uint32_ptr;
   2635     }
   2636 
   2637     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2638         setter = property_set_uint32_ptr;
   2639     }
   2640 
   2641     return object_property_add(obj, name, "uint32",
   2642                                getter, setter, NULL, (void *)v);
   2643 }
   2644 
   2645 ObjectProperty *
   2646 object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
   2647                                      const uint32_t *v,
   2648                                      ObjectPropertyFlags flags)
   2649 {
   2650     ObjectPropertyAccessor *getter = NULL;
   2651     ObjectPropertyAccessor *setter = NULL;
   2652 
   2653     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2654         getter = property_get_uint32_ptr;
   2655     }
   2656 
   2657     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2658         setter = property_set_uint32_ptr;
   2659     }
   2660 
   2661     return object_class_property_add(klass, name, "uint32",
   2662                                      getter, setter, NULL, (void *)v);
   2663 }
   2664 
   2665 ObjectProperty *
   2666 object_property_add_uint64_ptr(Object *obj, const char *name,
   2667                                const uint64_t *v,
   2668                                ObjectPropertyFlags flags)
   2669 {
   2670     ObjectPropertyAccessor *getter = NULL;
   2671     ObjectPropertyAccessor *setter = NULL;
   2672 
   2673     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2674         getter = property_get_uint64_ptr;
   2675     }
   2676 
   2677     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2678         setter = property_set_uint64_ptr;
   2679     }
   2680 
   2681     return object_property_add(obj, name, "uint64",
   2682                                getter, setter, NULL, (void *)v);
   2683 }
   2684 
   2685 ObjectProperty *
   2686 object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
   2687                                      const uint64_t *v,
   2688                                      ObjectPropertyFlags flags)
   2689 {
   2690     ObjectPropertyAccessor *getter = NULL;
   2691     ObjectPropertyAccessor *setter = NULL;
   2692 
   2693     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
   2694         getter = property_get_uint64_ptr;
   2695     }
   2696 
   2697     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
   2698         setter = property_set_uint64_ptr;
   2699     }
   2700 
   2701     return object_class_property_add(klass, name, "uint64",
   2702                                      getter, setter, NULL, (void *)v);
   2703 }
   2704 
   2705 typedef struct {
   2706     Object *target_obj;
   2707     char *target_name;
   2708 } AliasProperty;
   2709 
   2710 static void property_get_alias(Object *obj, Visitor *v, const char *name,
   2711                                void *opaque, Error **errp)
   2712 {
   2713     AliasProperty *prop = opaque;
   2714     Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
   2715 
   2716     object_property_get(prop->target_obj, prop->target_name, alias_v, errp);
   2717     visit_free(alias_v);
   2718 }
   2719 
   2720 static void property_set_alias(Object *obj, Visitor *v, const char *name,
   2721                                void *opaque, Error **errp)
   2722 {
   2723     AliasProperty *prop = opaque;
   2724     Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
   2725 
   2726     object_property_set(prop->target_obj, prop->target_name, alias_v, errp);
   2727     visit_free(alias_v);
   2728 }
   2729 
   2730 static Object *property_resolve_alias(Object *obj, void *opaque,
   2731                                       const char *part)
   2732 {
   2733     AliasProperty *prop = opaque;
   2734 
   2735     return object_resolve_path_component(prop->target_obj, prop->target_name);
   2736 }
   2737 
   2738 static void property_release_alias(Object *obj, const char *name, void *opaque)
   2739 {
   2740     AliasProperty *prop = opaque;
   2741 
   2742     g_free(prop->target_name);
   2743     g_free(prop);
   2744 }
   2745 
   2746 ObjectProperty *
   2747 object_property_add_alias(Object *obj, const char *name,
   2748                           Object *target_obj, const char *target_name)
   2749 {
   2750     AliasProperty *prop;
   2751     ObjectProperty *op;
   2752     ObjectProperty *target_prop;
   2753     g_autofree char *prop_type = NULL;
   2754 
   2755     target_prop = object_property_find_err(target_obj, target_name,
   2756                                            &error_abort);
   2757 
   2758     if (object_property_is_child(target_prop)) {
   2759         prop_type = g_strdup_printf("link%s",
   2760                                     target_prop->type + strlen("child"));
   2761     } else {
   2762         prop_type = g_strdup(target_prop->type);
   2763     }
   2764 
   2765     prop = g_malloc(sizeof(*prop));
   2766     prop->target_obj = target_obj;
   2767     prop->target_name = g_strdup(target_name);
   2768 
   2769     op = object_property_add(obj, name, prop_type,
   2770                              property_get_alias,
   2771                              property_set_alias,
   2772                              property_release_alias,
   2773                              prop);
   2774     op->resolve = property_resolve_alias;
   2775     if (target_prop->defval) {
   2776         op->defval = qobject_ref(target_prop->defval);
   2777     }
   2778 
   2779     object_property_set_description(obj, op->name,
   2780                                     target_prop->description);
   2781     return op;
   2782 }
   2783 
   2784 void object_property_set_description(Object *obj, const char *name,
   2785                                      const char *description)
   2786 {
   2787     ObjectProperty *op;
   2788 
   2789     op = object_property_find_err(obj, name, &error_abort);
   2790     g_free(op->description);
   2791     op->description = g_strdup(description);
   2792 }
   2793 
   2794 void object_class_property_set_description(ObjectClass *klass,
   2795                                            const char *name,
   2796                                            const char *description)
   2797 {
   2798     ObjectProperty *op;
   2799 
   2800     op = g_hash_table_lookup(klass->properties, name);
   2801     g_free(op->description);
   2802     op->description = g_strdup(description);
   2803 }
   2804 
   2805 static void object_class_init(ObjectClass *klass, void *data)
   2806 {
   2807     object_class_property_add_str(klass, "type", object_get_type,
   2808                                   NULL);
   2809 }
   2810 
   2811 static void register_types(void)
   2812 {
   2813     static const TypeInfo interface_info = {
   2814         .name = TYPE_INTERFACE,
   2815         .class_size = sizeof(InterfaceClass),
   2816         .abstract = true,
   2817     };
   2818 
   2819     static const TypeInfo object_info = {
   2820         .name = TYPE_OBJECT,
   2821         .instance_size = sizeof(Object),
   2822         .class_init = object_class_init,
   2823         .abstract = true,
   2824     };
   2825 
   2826     type_interface = type_register_internal(&interface_info);
   2827     type_register_internal(&object_info);
   2828 }
   2829 
   2830 type_init(register_types)