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