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