cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

object.c (74821B)


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