xref: /openbmc/qemu/qom/object.c (revision 707ded20)
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, QERR_INVALID_PARAMETER_TYPE, name, "string");
1499         retval = NULL;
1500     } else {
1501         retval = g_strdup(qstring_get_str(qstring));
1502     }
1503 
1504     qobject_unref(ret);
1505     return retval;
1506 }
1507 
1508 bool object_property_set_link(Object *obj, const char *name,
1509                               Object *value, Error **errp)
1510 {
1511     g_autofree char *path = NULL;
1512 
1513     if (value) {
1514         path = object_get_canonical_path(value);
1515     }
1516     return object_property_set_str(obj, name, path ?: "", errp);
1517 }
1518 
1519 Object *object_property_get_link(Object *obj, const char *name,
1520                                  Error **errp)
1521 {
1522     char *str = object_property_get_str(obj, name, errp);
1523     Object *target = NULL;
1524 
1525     if (str && *str) {
1526         target = object_resolve_path(str, NULL);
1527         if (!target) {
1528             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1529                       "Device '%s' not found", str);
1530         }
1531     }
1532 
1533     g_free(str);
1534     return target;
1535 }
1536 
1537 bool object_property_set_bool(Object *obj, const char *name,
1538                               bool value, Error **errp)
1539 {
1540     QBool *qbool = qbool_from_bool(value);
1541     bool ok = object_property_set_qobject(obj, name, QOBJECT(qbool), errp);
1542 
1543     qobject_unref(qbool);
1544     return ok;
1545 }
1546 
1547 bool object_property_get_bool(Object *obj, const char *name,
1548                               Error **errp)
1549 {
1550     QObject *ret = object_property_get_qobject(obj, name, errp);
1551     QBool *qbool;
1552     bool retval;
1553 
1554     if (!ret) {
1555         return false;
1556     }
1557     qbool = qobject_to(QBool, ret);
1558     if (!qbool) {
1559         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
1560         retval = false;
1561     } else {
1562         retval = qbool_get_bool(qbool);
1563     }
1564 
1565     qobject_unref(ret);
1566     return retval;
1567 }
1568 
1569 bool object_property_set_int(Object *obj, const char *name,
1570                              int64_t value, Error **errp)
1571 {
1572     QNum *qnum = qnum_from_int(value);
1573     bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
1574 
1575     qobject_unref(qnum);
1576     return ok;
1577 }
1578 
1579 int64_t object_property_get_int(Object *obj, const char *name,
1580                                 Error **errp)
1581 {
1582     QObject *ret = object_property_get_qobject(obj, name, errp);
1583     QNum *qnum;
1584     int64_t retval;
1585 
1586     if (!ret) {
1587         return -1;
1588     }
1589 
1590     qnum = qobject_to(QNum, ret);
1591     if (!qnum || !qnum_get_try_int(qnum, &retval)) {
1592         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
1593         retval = -1;
1594     }
1595 
1596     qobject_unref(ret);
1597     return retval;
1598 }
1599 
1600 static void object_property_init_defval(Object *obj, ObjectProperty *prop)
1601 {
1602     Visitor *v = qobject_input_visitor_new(prop->defval);
1603 
1604     assert(prop->set != NULL);
1605     prop->set(obj, v, prop->name, prop->opaque, &error_abort);
1606 
1607     visit_free(v);
1608 }
1609 
1610 static void object_property_set_default(ObjectProperty *prop, QObject *defval)
1611 {
1612     assert(!prop->defval);
1613     assert(!prop->init);
1614 
1615     prop->defval = defval;
1616     prop->init = object_property_init_defval;
1617 }
1618 
1619 void object_property_set_default_bool(ObjectProperty *prop, bool value)
1620 {
1621     object_property_set_default(prop, QOBJECT(qbool_from_bool(value)));
1622 }
1623 
1624 void object_property_set_default_str(ObjectProperty *prop, const char *value)
1625 {
1626     object_property_set_default(prop, QOBJECT(qstring_from_str(value)));
1627 }
1628 
1629 void object_property_set_default_list(ObjectProperty *prop)
1630 {
1631     object_property_set_default(prop, QOBJECT(qlist_new()));
1632 }
1633 
1634 void object_property_set_default_int(ObjectProperty *prop, int64_t value)
1635 {
1636     object_property_set_default(prop, QOBJECT(qnum_from_int(value)));
1637 }
1638 
1639 void object_property_set_default_uint(ObjectProperty *prop, uint64_t value)
1640 {
1641     object_property_set_default(prop, QOBJECT(qnum_from_uint(value)));
1642 }
1643 
1644 bool object_property_set_uint(Object *obj, const char *name,
1645                               uint64_t value, Error **errp)
1646 {
1647     QNum *qnum = qnum_from_uint(value);
1648     bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
1649 
1650     qobject_unref(qnum);
1651     return ok;
1652 }
1653 
1654 uint64_t object_property_get_uint(Object *obj, const char *name,
1655                                   Error **errp)
1656 {
1657     QObject *ret = object_property_get_qobject(obj, name, errp);
1658     QNum *qnum;
1659     uint64_t retval;
1660 
1661     if (!ret) {
1662         return 0;
1663     }
1664     qnum = qobject_to(QNum, ret);
1665     if (!qnum || !qnum_get_try_uint(qnum, &retval)) {
1666         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
1667         retval = 0;
1668     }
1669 
1670     qobject_unref(ret);
1671     return retval;
1672 }
1673 
1674 typedef struct EnumProperty {
1675     const QEnumLookup *lookup;
1676     int (*get)(Object *, Error **);
1677     void (*set)(Object *, int, Error **);
1678 } EnumProperty;
1679 
1680 int object_property_get_enum(Object *obj, const char *name,
1681                              const char *typename, Error **errp)
1682 {
1683     char *str;
1684     int ret;
1685     ObjectProperty *prop = object_property_find_err(obj, name, errp);
1686     EnumProperty *enumprop;
1687 
1688     if (prop == NULL) {
1689         return -1;
1690     }
1691 
1692     if (!g_str_equal(prop->type, typename)) {
1693         error_setg(errp, "Property %s on %s is not '%s' enum type",
1694                    name, object_class_get_name(
1695                        object_get_class(obj)), typename);
1696         return -1;
1697     }
1698 
1699     enumprop = prop->opaque;
1700 
1701     str = object_property_get_str(obj, name, errp);
1702     if (!str) {
1703         return -1;
1704     }
1705 
1706     ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
1707     g_free(str);
1708 
1709     return ret;
1710 }
1711 
1712 bool object_property_parse(Object *obj, const char *name,
1713                            const char *string, Error **errp)
1714 {
1715     Visitor *v = string_input_visitor_new(string);
1716     bool ok = object_property_set(obj, name, v, errp);
1717 
1718     visit_free(v);
1719     return ok;
1720 }
1721 
1722 char *object_property_print(Object *obj, const char *name, bool human,
1723                             Error **errp)
1724 {
1725     Visitor *v;
1726     char *string = NULL;
1727 
1728     v = string_output_visitor_new(human, &string);
1729     if (!object_property_get(obj, name, v, errp)) {
1730         goto out;
1731     }
1732 
1733     visit_complete(v, &string);
1734 
1735 out:
1736     visit_free(v);
1737     return string;
1738 }
1739 
1740 const char *object_property_get_type(Object *obj, const char *name, Error **errp)
1741 {
1742     ObjectProperty *prop = object_property_find_err(obj, name, errp);
1743     if (prop == NULL) {
1744         return NULL;
1745     }
1746 
1747     return prop->type;
1748 }
1749 
1750 Object *object_get_root(void)
1751 {
1752     static Object *root;
1753 
1754     if (!root) {
1755         root = object_new("container");
1756     }
1757 
1758     return root;
1759 }
1760 
1761 Object *object_get_objects_root(void)
1762 {
1763     return container_get(object_get_root(), "/objects");
1764 }
1765 
1766 Object *object_get_internal_root(void)
1767 {
1768     static Object *internal_root;
1769 
1770     if (!internal_root) {
1771         internal_root = object_new("container");
1772     }
1773 
1774     return internal_root;
1775 }
1776 
1777 static void object_get_child_property(Object *obj, Visitor *v,
1778                                       const char *name, void *opaque,
1779                                       Error **errp)
1780 {
1781     Object *child = opaque;
1782     char *path;
1783 
1784     path = object_get_canonical_path(child);
1785     visit_type_str(v, name, &path, errp);
1786     g_free(path);
1787 }
1788 
1789 static Object *object_resolve_child_property(Object *parent, void *opaque,
1790                                              const char *part)
1791 {
1792     return opaque;
1793 }
1794 
1795 static void object_finalize_child_property(Object *obj, const char *name,
1796                                            void *opaque)
1797 {
1798     Object *child = opaque;
1799 
1800     if (child->class->unparent) {
1801         (child->class->unparent)(child);
1802     }
1803     child->parent = NULL;
1804     object_unref(child);
1805 }
1806 
1807 ObjectProperty *
1808 object_property_try_add_child(Object *obj, const char *name,
1809                               Object *child, Error **errp)
1810 {
1811     g_autofree char *type = NULL;
1812     ObjectProperty *op;
1813 
1814     assert(!child->parent);
1815 
1816     type = g_strdup_printf("child<%s>", object_get_typename(child));
1817 
1818     op = object_property_try_add(obj, name, type, object_get_child_property,
1819                                  NULL, object_finalize_child_property,
1820                                  child, errp);
1821     if (!op) {
1822         return NULL;
1823     }
1824     op->resolve = object_resolve_child_property;
1825     object_ref(child);
1826     child->parent = obj;
1827     return op;
1828 }
1829 
1830 ObjectProperty *
1831 object_property_add_child(Object *obj, const char *name,
1832                           Object *child)
1833 {
1834     return object_property_try_add_child(obj, name, child, &error_abort);
1835 }
1836 
1837 void object_property_allow_set_link(const Object *obj, const char *name,
1838                                     Object *val, Error **errp)
1839 {
1840     /* Allow the link to be set, always */
1841 }
1842 
1843 typedef struct {
1844     union {
1845         Object **targetp;
1846         Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer  */
1847         ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */
1848     };
1849     void (*check)(const Object *, const char *, Object *, Error **);
1850     ObjectPropertyLinkFlags flags;
1851 } LinkProperty;
1852 
1853 static Object **
1854 object_link_get_targetp(Object *obj, LinkProperty *lprop)
1855 {
1856     if (lprop->flags & OBJ_PROP_LINK_DIRECT) {
1857         return &lprop->target;
1858     } else if (lprop->flags & OBJ_PROP_LINK_CLASS) {
1859         return (void *)obj + lprop->offset;
1860     } else {
1861         return lprop->targetp;
1862     }
1863 }
1864 
1865 static void object_get_link_property(Object *obj, Visitor *v,
1866                                      const char *name, void *opaque,
1867                                      Error **errp)
1868 {
1869     LinkProperty *lprop = opaque;
1870     Object **targetp = object_link_get_targetp(obj, lprop);
1871     char *path;
1872 
1873     if (*targetp) {
1874         path = object_get_canonical_path(*targetp);
1875         visit_type_str(v, name, &path, errp);
1876         g_free(path);
1877     } else {
1878         path = (char *)"";
1879         visit_type_str(v, name, &path, errp);
1880     }
1881 }
1882 
1883 /*
1884  * object_resolve_link:
1885  *
1886  * Lookup an object and ensure its type matches the link property type.  This
1887  * is similar to object_resolve_path() except type verification against the
1888  * link property is performed.
1889  *
1890  * Returns: The matched object or NULL on path lookup failures.
1891  */
1892 static Object *object_resolve_link(Object *obj, const char *name,
1893                                    const char *path, Error **errp)
1894 {
1895     const char *type;
1896     char *target_type;
1897     bool ambiguous = false;
1898     Object *target;
1899 
1900     /* Go from link<FOO> to FOO.  */
1901     type = object_property_get_type(obj, name, NULL);
1902     target_type = g_strndup(&type[5], strlen(type) - 6);
1903     target = object_resolve_path_type(path, target_type, &ambiguous);
1904 
1905     if (ambiguous) {
1906         error_setg(errp, "Path '%s' does not uniquely identify an object",
1907                    path);
1908     } else if (!target) {
1909         target = object_resolve_path(path, &ambiguous);
1910         if (target || ambiguous) {
1911             error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
1912         } else {
1913             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1914                       "Device '%s' not found", path);
1915         }
1916         target = NULL;
1917     }
1918     g_free(target_type);
1919 
1920     return target;
1921 }
1922 
1923 static void object_set_link_property(Object *obj, Visitor *v,
1924                                      const char *name, void *opaque,
1925                                      Error **errp)
1926 {
1927     Error *local_err = NULL;
1928     LinkProperty *prop = opaque;
1929     Object **targetp = object_link_get_targetp(obj, prop);
1930     Object *old_target = *targetp;
1931     Object *new_target;
1932     char *path = NULL;
1933 
1934     if (!visit_type_str(v, name, &path, errp)) {
1935         return;
1936     }
1937 
1938     if (*path) {
1939         new_target = object_resolve_link(obj, name, path, errp);
1940         if (!new_target) {
1941             g_free(path);
1942             return;
1943         }
1944     } else {
1945         new_target = NULL;
1946     }
1947 
1948     g_free(path);
1949 
1950     prop->check(obj, name, new_target, &local_err);
1951     if (local_err) {
1952         error_propagate(errp, local_err);
1953         return;
1954     }
1955 
1956     *targetp = new_target;
1957     if (prop->flags & OBJ_PROP_LINK_STRONG) {
1958         object_ref(new_target);
1959         object_unref(old_target);
1960     }
1961 }
1962 
1963 static Object *object_resolve_link_property(Object *parent, void *opaque,
1964                                             const char *part)
1965 {
1966     LinkProperty *lprop = opaque;
1967 
1968     return *object_link_get_targetp(parent, lprop);
1969 }
1970 
1971 static void object_release_link_property(Object *obj, const char *name,
1972                                          void *opaque)
1973 {
1974     LinkProperty *prop = opaque;
1975     Object **targetp = object_link_get_targetp(obj, prop);
1976 
1977     if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) {
1978         object_unref(*targetp);
1979     }
1980     if (!(prop->flags & OBJ_PROP_LINK_CLASS)) {
1981         g_free(prop);
1982     }
1983 }
1984 
1985 static ObjectProperty *
1986 object_add_link_prop(Object *obj, const char *name,
1987                      const char *type, void *ptr,
1988                      void (*check)(const Object *, const char *,
1989                                    Object *, Error **),
1990                      ObjectPropertyLinkFlags flags)
1991 {
1992     LinkProperty *prop = g_malloc(sizeof(*prop));
1993     g_autofree char *full_type = NULL;
1994     ObjectProperty *op;
1995 
1996     if (flags & OBJ_PROP_LINK_DIRECT) {
1997         prop->target = ptr;
1998     } else {
1999         prop->targetp = ptr;
2000     }
2001     prop->check = check;
2002     prop->flags = flags;
2003 
2004     full_type = g_strdup_printf("link<%s>", type);
2005 
2006     op = object_property_add(obj, name, full_type,
2007                              object_get_link_property,
2008                              check ? object_set_link_property : NULL,
2009                              object_release_link_property,
2010                              prop);
2011     op->resolve = object_resolve_link_property;
2012     return op;
2013 }
2014 
2015 ObjectProperty *
2016 object_property_add_link(Object *obj, const char *name,
2017                          const char *type, Object **targetp,
2018                          void (*check)(const Object *, const char *,
2019                                        Object *, Error **),
2020                          ObjectPropertyLinkFlags flags)
2021 {
2022     return object_add_link_prop(obj, name, type, targetp, check, flags);
2023 }
2024 
2025 ObjectProperty *
2026 object_class_property_add_link(ObjectClass *oc,
2027     const char *name,
2028     const char *type, ptrdiff_t offset,
2029     void (*check)(const Object *obj, const char *name,
2030                   Object *val, Error **errp),
2031     ObjectPropertyLinkFlags flags)
2032 {
2033     LinkProperty *prop = g_new0(LinkProperty, 1);
2034     char *full_type;
2035     ObjectProperty *op;
2036 
2037     prop->offset = offset;
2038     prop->check = check;
2039     prop->flags = flags | OBJ_PROP_LINK_CLASS;
2040 
2041     full_type = g_strdup_printf("link<%s>", type);
2042 
2043     op = object_class_property_add(oc, name, full_type,
2044                                    object_get_link_property,
2045                                    check ? object_set_link_property : NULL,
2046                                    object_release_link_property,
2047                                    prop);
2048 
2049     op->resolve = object_resolve_link_property;
2050 
2051     g_free(full_type);
2052     return op;
2053 }
2054 
2055 ObjectProperty *
2056 object_property_add_const_link(Object *obj, const char *name,
2057                                Object *target)
2058 {
2059     return object_add_link_prop(obj, name,
2060                                 object_get_typename(target), target,
2061                                 NULL, OBJ_PROP_LINK_DIRECT);
2062 }
2063 
2064 const char *object_get_canonical_path_component(const Object *obj)
2065 {
2066     ObjectProperty *prop = NULL;
2067     GHashTableIter iter;
2068 
2069     if (obj->parent == NULL) {
2070         return NULL;
2071     }
2072 
2073     g_hash_table_iter_init(&iter, obj->parent->properties);
2074     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
2075         if (!object_property_is_child(prop)) {
2076             continue;
2077         }
2078 
2079         if (prop->opaque == obj) {
2080             return prop->name;
2081         }
2082     }
2083 
2084     /* obj had a parent but was not a child, should never happen */
2085     g_assert_not_reached();
2086     return NULL;
2087 }
2088 
2089 char *object_get_canonical_path(const Object *obj)
2090 {
2091     Object *root = object_get_root();
2092     char *newpath, *path = NULL;
2093 
2094     if (obj == root) {
2095         return g_strdup("/");
2096     }
2097 
2098     do {
2099         const char *component = object_get_canonical_path_component(obj);
2100 
2101         if (!component) {
2102             /* A canonical path must be complete, so discard what was
2103              * collected so far.
2104              */
2105             g_free(path);
2106             return NULL;
2107         }
2108 
2109         newpath = g_strdup_printf("/%s%s", component, path ? path : "");
2110         g_free(path);
2111         path = newpath;
2112         obj = obj->parent;
2113     } while (obj != root);
2114 
2115     return path;
2116 }
2117 
2118 Object *object_resolve_path_component(Object *parent, const char *part)
2119 {
2120     ObjectProperty *prop = object_property_find(parent, part);
2121     if (prop == NULL) {
2122         return NULL;
2123     }
2124 
2125     if (prop->resolve) {
2126         return prop->resolve(parent, prop->opaque, part);
2127     } else {
2128         return NULL;
2129     }
2130 }
2131 
2132 static Object *object_resolve_abs_path(Object *parent,
2133                                           char **parts,
2134                                           const char *typename)
2135 {
2136     Object *child;
2137 
2138     if (*parts == NULL) {
2139         return object_dynamic_cast(parent, typename);
2140     }
2141 
2142     if (strcmp(*parts, "") == 0) {
2143         return object_resolve_abs_path(parent, parts + 1, typename);
2144     }
2145 
2146     child = object_resolve_path_component(parent, *parts);
2147     if (!child) {
2148         return NULL;
2149     }
2150 
2151     return object_resolve_abs_path(child, parts + 1, typename);
2152 }
2153 
2154 static Object *object_resolve_partial_path(Object *parent,
2155                                            char **parts,
2156                                            const char *typename,
2157                                            bool *ambiguous)
2158 {
2159     Object *obj;
2160     GHashTableIter iter;
2161     ObjectProperty *prop;
2162 
2163     obj = object_resolve_abs_path(parent, parts, typename);
2164 
2165     g_hash_table_iter_init(&iter, parent->properties);
2166     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
2167         Object *found;
2168 
2169         if (!object_property_is_child(prop)) {
2170             continue;
2171         }
2172 
2173         found = object_resolve_partial_path(prop->opaque, parts,
2174                                             typename, ambiguous);
2175         if (found) {
2176             if (obj) {
2177                 *ambiguous = true;
2178                 return NULL;
2179             }
2180             obj = found;
2181         }
2182 
2183         if (*ambiguous) {
2184             return NULL;
2185         }
2186     }
2187 
2188     return obj;
2189 }
2190 
2191 Object *object_resolve_path_type(const char *path, const char *typename,
2192                                  bool *ambiguousp)
2193 {
2194     Object *obj;
2195     char **parts;
2196 
2197     parts = g_strsplit(path, "/", 0);
2198     assert(parts);
2199 
2200     if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
2201         bool ambiguous = false;
2202         obj = object_resolve_partial_path(object_get_root(), parts,
2203                                           typename, &ambiguous);
2204         if (ambiguousp) {
2205             *ambiguousp = ambiguous;
2206         }
2207     } else {
2208         obj = object_resolve_abs_path(object_get_root(), parts + 1, typename);
2209     }
2210 
2211     g_strfreev(parts);
2212 
2213     return obj;
2214 }
2215 
2216 Object *object_resolve_path(const char *path, bool *ambiguous)
2217 {
2218     return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
2219 }
2220 
2221 Object *object_resolve_path_at(Object *parent, const char *path)
2222 {
2223     g_auto(GStrv) parts = g_strsplit(path, "/", 0);
2224 
2225     if (*path == '/') {
2226         return object_resolve_abs_path(object_get_root(), parts + 1,
2227                                        TYPE_OBJECT);
2228     }
2229     return object_resolve_abs_path(parent, parts, TYPE_OBJECT);
2230 }
2231 
2232 Object *object_resolve_type_unambiguous(const char *typename, Error **errp)
2233 {
2234     bool ambig;
2235     Object *o = object_resolve_path_type("", typename, &ambig);
2236 
2237     if (ambig) {
2238         error_setg(errp, "More than one object of type %s", typename);
2239         return NULL;
2240     }
2241     if (!o) {
2242         error_setg(errp, "No object found of type %s", typename);
2243         return NULL;
2244     }
2245     return o;
2246 }
2247 
2248 typedef struct StringProperty
2249 {
2250     char *(*get)(Object *, Error **);
2251     void (*set)(Object *, const char *, Error **);
2252 } StringProperty;
2253 
2254 static void property_get_str(Object *obj, Visitor *v, const char *name,
2255                              void *opaque, Error **errp)
2256 {
2257     StringProperty *prop = opaque;
2258     char *value;
2259     Error *err = NULL;
2260 
2261     value = prop->get(obj, &err);
2262     if (err) {
2263         error_propagate(errp, err);
2264         return;
2265     }
2266 
2267     visit_type_str(v, name, &value, errp);
2268     g_free(value);
2269 }
2270 
2271 static void property_set_str(Object *obj, Visitor *v, const char *name,
2272                              void *opaque, Error **errp)
2273 {
2274     StringProperty *prop = opaque;
2275     char *value;
2276 
2277     if (!visit_type_str(v, name, &value, errp)) {
2278         return;
2279     }
2280 
2281     prop->set(obj, value, errp);
2282     g_free(value);
2283 }
2284 
2285 static void property_release_data(Object *obj, const char *name,
2286                                   void *opaque)
2287 {
2288     g_free(opaque);
2289 }
2290 
2291 ObjectProperty *
2292 object_property_add_str(Object *obj, const char *name,
2293                         char *(*get)(Object *, Error **),
2294                         void (*set)(Object *, const char *, Error **))
2295 {
2296     StringProperty *prop = g_malloc0(sizeof(*prop));
2297 
2298     prop->get = get;
2299     prop->set = set;
2300 
2301     return object_property_add(obj, name, "string",
2302                                get ? property_get_str : NULL,
2303                                set ? property_set_str : NULL,
2304                                property_release_data,
2305                                prop);
2306 }
2307 
2308 ObjectProperty *
2309 object_class_property_add_str(ObjectClass *klass, const char *name,
2310                                    char *(*get)(Object *, Error **),
2311                                    void (*set)(Object *, const char *,
2312                                                Error **))
2313 {
2314     StringProperty *prop = g_malloc0(sizeof(*prop));
2315 
2316     prop->get = get;
2317     prop->set = set;
2318 
2319     return object_class_property_add(klass, name, "string",
2320                                      get ? property_get_str : NULL,
2321                                      set ? property_set_str : NULL,
2322                                      NULL,
2323                                      prop);
2324 }
2325 
2326 typedef struct BoolProperty
2327 {
2328     bool (*get)(Object *, Error **);
2329     void (*set)(Object *, bool, Error **);
2330 } BoolProperty;
2331 
2332 static void property_get_bool(Object *obj, Visitor *v, const char *name,
2333                               void *opaque, Error **errp)
2334 {
2335     BoolProperty *prop = opaque;
2336     bool value;
2337     Error *err = NULL;
2338 
2339     value = prop->get(obj, &err);
2340     if (err) {
2341         error_propagate(errp, err);
2342         return;
2343     }
2344 
2345     visit_type_bool(v, name, &value, errp);
2346 }
2347 
2348 static void property_set_bool(Object *obj, Visitor *v, const char *name,
2349                               void *opaque, Error **errp)
2350 {
2351     BoolProperty *prop = opaque;
2352     bool value;
2353 
2354     if (!visit_type_bool(v, name, &value, errp)) {
2355         return;
2356     }
2357 
2358     prop->set(obj, value, errp);
2359 }
2360 
2361 ObjectProperty *
2362 object_property_add_bool(Object *obj, const char *name,
2363                          bool (*get)(Object *, Error **),
2364                          void (*set)(Object *, bool, Error **))
2365 {
2366     BoolProperty *prop = g_malloc0(sizeof(*prop));
2367 
2368     prop->get = get;
2369     prop->set = set;
2370 
2371     return object_property_add(obj, name, "bool",
2372                                get ? property_get_bool : NULL,
2373                                set ? property_set_bool : NULL,
2374                                property_release_data,
2375                                prop);
2376 }
2377 
2378 ObjectProperty *
2379 object_class_property_add_bool(ObjectClass *klass, const char *name,
2380                                     bool (*get)(Object *, Error **),
2381                                     void (*set)(Object *, bool, Error **))
2382 {
2383     BoolProperty *prop = g_malloc0(sizeof(*prop));
2384 
2385     prop->get = get;
2386     prop->set = set;
2387 
2388     return object_class_property_add(klass, name, "bool",
2389                                      get ? property_get_bool : NULL,
2390                                      set ? property_set_bool : NULL,
2391                                      NULL,
2392                                      prop);
2393 }
2394 
2395 static void property_get_enum(Object *obj, Visitor *v, const char *name,
2396                               void *opaque, Error **errp)
2397 {
2398     EnumProperty *prop = opaque;
2399     int value;
2400     Error *err = NULL;
2401 
2402     value = prop->get(obj, &err);
2403     if (err) {
2404         error_propagate(errp, err);
2405         return;
2406     }
2407 
2408     visit_type_enum(v, name, &value, prop->lookup, errp);
2409 }
2410 
2411 static void property_set_enum(Object *obj, Visitor *v, const char *name,
2412                               void *opaque, Error **errp)
2413 {
2414     EnumProperty *prop = opaque;
2415     int value;
2416 
2417     if (!visit_type_enum(v, name, &value, prop->lookup, errp)) {
2418         return;
2419     }
2420     prop->set(obj, value, errp);
2421 }
2422 
2423 ObjectProperty *
2424 object_property_add_enum(Object *obj, const char *name,
2425                          const char *typename,
2426                          const QEnumLookup *lookup,
2427                          int (*get)(Object *, Error **),
2428                          void (*set)(Object *, int, Error **))
2429 {
2430     EnumProperty *prop = g_malloc(sizeof(*prop));
2431 
2432     prop->lookup = lookup;
2433     prop->get = get;
2434     prop->set = set;
2435 
2436     return object_property_add(obj, name, typename,
2437                                get ? property_get_enum : NULL,
2438                                set ? property_set_enum : NULL,
2439                                property_release_data,
2440                                prop);
2441 }
2442 
2443 ObjectProperty *
2444 object_class_property_add_enum(ObjectClass *klass, const char *name,
2445                                     const char *typename,
2446                                     const QEnumLookup *lookup,
2447                                     int (*get)(Object *, Error **),
2448                                     void (*set)(Object *, int, Error **))
2449 {
2450     EnumProperty *prop = g_malloc(sizeof(*prop));
2451 
2452     prop->lookup = lookup;
2453     prop->get = get;
2454     prop->set = set;
2455 
2456     return object_class_property_add(klass, name, typename,
2457                                      get ? property_get_enum : NULL,
2458                                      set ? property_set_enum : NULL,
2459                                      NULL,
2460                                      prop);
2461 }
2462 
2463 typedef struct TMProperty {
2464     void (*get)(Object *, struct tm *, Error **);
2465 } TMProperty;
2466 
2467 static void property_get_tm(Object *obj, Visitor *v, const char *name,
2468                             void *opaque, Error **errp)
2469 {
2470     TMProperty *prop = opaque;
2471     Error *err = NULL;
2472     struct tm value;
2473 
2474     prop->get(obj, &value, &err);
2475     if (err) {
2476         error_propagate(errp, err);
2477         return;
2478     }
2479 
2480     if (!visit_start_struct(v, name, NULL, 0, errp)) {
2481         return;
2482     }
2483     if (!visit_type_int32(v, "tm_year", &value.tm_year, errp)) {
2484         goto out_end;
2485     }
2486     if (!visit_type_int32(v, "tm_mon", &value.tm_mon, errp)) {
2487         goto out_end;
2488     }
2489     if (!visit_type_int32(v, "tm_mday", &value.tm_mday, errp)) {
2490         goto out_end;
2491     }
2492     if (!visit_type_int32(v, "tm_hour", &value.tm_hour, errp)) {
2493         goto out_end;
2494     }
2495     if (!visit_type_int32(v, "tm_min", &value.tm_min, errp)) {
2496         goto out_end;
2497     }
2498     if (!visit_type_int32(v, "tm_sec", &value.tm_sec, errp)) {
2499         goto out_end;
2500     }
2501     visit_check_struct(v, errp);
2502 out_end:
2503     visit_end_struct(v, NULL);
2504 }
2505 
2506 ObjectProperty *
2507 object_property_add_tm(Object *obj, const char *name,
2508                        void (*get)(Object *, struct tm *, Error **))
2509 {
2510     TMProperty *prop = g_malloc0(sizeof(*prop));
2511 
2512     prop->get = get;
2513 
2514     return object_property_add(obj, name, "struct tm",
2515                                get ? property_get_tm : NULL, NULL,
2516                                property_release_data,
2517                                prop);
2518 }
2519 
2520 ObjectProperty *
2521 object_class_property_add_tm(ObjectClass *klass, const char *name,
2522                              void (*get)(Object *, struct tm *, Error **))
2523 {
2524     TMProperty *prop = g_malloc0(sizeof(*prop));
2525 
2526     prop->get = get;
2527 
2528     return object_class_property_add(klass, name, "struct tm",
2529                                      get ? property_get_tm : NULL,
2530                                      NULL, NULL, prop);
2531 }
2532 
2533 static char *object_get_type(Object *obj, Error **errp)
2534 {
2535     return g_strdup(object_get_typename(obj));
2536 }
2537 
2538 static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name,
2539                                    void *opaque, Error **errp)
2540 {
2541     uint8_t value = *(uint8_t *)opaque;
2542     visit_type_uint8(v, name, &value, errp);
2543 }
2544 
2545 static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name,
2546                                    void *opaque, Error **errp)
2547 {
2548     uint8_t *field = opaque;
2549     uint8_t value;
2550 
2551     if (!visit_type_uint8(v, name, &value, errp)) {
2552         return;
2553     }
2554 
2555     *field = value;
2556 }
2557 
2558 static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
2559                                     void *opaque, Error **errp)
2560 {
2561     uint16_t value = *(uint16_t *)opaque;
2562     visit_type_uint16(v, name, &value, errp);
2563 }
2564 
2565 static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name,
2566                                     void *opaque, Error **errp)
2567 {
2568     uint16_t *field = opaque;
2569     uint16_t value;
2570 
2571     if (!visit_type_uint16(v, name, &value, errp)) {
2572         return;
2573     }
2574 
2575     *field = value;
2576 }
2577 
2578 static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
2579                                     void *opaque, Error **errp)
2580 {
2581     uint32_t value = *(uint32_t *)opaque;
2582     visit_type_uint32(v, name, &value, errp);
2583 }
2584 
2585 static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name,
2586                                     void *opaque, Error **errp)
2587 {
2588     uint32_t *field = opaque;
2589     uint32_t value;
2590 
2591     if (!visit_type_uint32(v, name, &value, errp)) {
2592         return;
2593     }
2594 
2595     *field = value;
2596 }
2597 
2598 static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
2599                                     void *opaque, Error **errp)
2600 {
2601     uint64_t value = *(uint64_t *)opaque;
2602     visit_type_uint64(v, name, &value, errp);
2603 }
2604 
2605 static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name,
2606                                     void *opaque, Error **errp)
2607 {
2608     uint64_t *field = opaque;
2609     uint64_t value;
2610 
2611     if (!visit_type_uint64(v, name, &value, errp)) {
2612         return;
2613     }
2614 
2615     *field = value;
2616 }
2617 
2618 ObjectProperty *
2619 object_property_add_uint8_ptr(Object *obj, const char *name,
2620                               const uint8_t *v,
2621                               ObjectPropertyFlags flags)
2622 {
2623     ObjectPropertyAccessor *getter = NULL;
2624     ObjectPropertyAccessor *setter = NULL;
2625 
2626     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2627         getter = property_get_uint8_ptr;
2628     }
2629 
2630     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2631         setter = property_set_uint8_ptr;
2632     }
2633 
2634     return object_property_add(obj, name, "uint8",
2635                                getter, setter, NULL, (void *)v);
2636 }
2637 
2638 ObjectProperty *
2639 object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
2640                                     const uint8_t *v,
2641                                     ObjectPropertyFlags flags)
2642 {
2643     ObjectPropertyAccessor *getter = NULL;
2644     ObjectPropertyAccessor *setter = NULL;
2645 
2646     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2647         getter = property_get_uint8_ptr;
2648     }
2649 
2650     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2651         setter = property_set_uint8_ptr;
2652     }
2653 
2654     return object_class_property_add(klass, name, "uint8",
2655                                      getter, setter, NULL, (void *)v);
2656 }
2657 
2658 ObjectProperty *
2659 object_property_add_uint16_ptr(Object *obj, const char *name,
2660                                const uint16_t *v,
2661                                ObjectPropertyFlags flags)
2662 {
2663     ObjectPropertyAccessor *getter = NULL;
2664     ObjectPropertyAccessor *setter = NULL;
2665 
2666     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2667         getter = property_get_uint16_ptr;
2668     }
2669 
2670     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2671         setter = property_set_uint16_ptr;
2672     }
2673 
2674     return object_property_add(obj, name, "uint16",
2675                                getter, setter, NULL, (void *)v);
2676 }
2677 
2678 ObjectProperty *
2679 object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
2680                                      const uint16_t *v,
2681                                      ObjectPropertyFlags flags)
2682 {
2683     ObjectPropertyAccessor *getter = NULL;
2684     ObjectPropertyAccessor *setter = NULL;
2685 
2686     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2687         getter = property_get_uint16_ptr;
2688     }
2689 
2690     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2691         setter = property_set_uint16_ptr;
2692     }
2693 
2694     return object_class_property_add(klass, name, "uint16",
2695                                      getter, setter, NULL, (void *)v);
2696 }
2697 
2698 ObjectProperty *
2699 object_property_add_uint32_ptr(Object *obj, const char *name,
2700                                const uint32_t *v,
2701                                ObjectPropertyFlags flags)
2702 {
2703     ObjectPropertyAccessor *getter = NULL;
2704     ObjectPropertyAccessor *setter = NULL;
2705 
2706     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2707         getter = property_get_uint32_ptr;
2708     }
2709 
2710     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2711         setter = property_set_uint32_ptr;
2712     }
2713 
2714     return object_property_add(obj, name, "uint32",
2715                                getter, setter, NULL, (void *)v);
2716 }
2717 
2718 ObjectProperty *
2719 object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
2720                                      const uint32_t *v,
2721                                      ObjectPropertyFlags flags)
2722 {
2723     ObjectPropertyAccessor *getter = NULL;
2724     ObjectPropertyAccessor *setter = NULL;
2725 
2726     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2727         getter = property_get_uint32_ptr;
2728     }
2729 
2730     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2731         setter = property_set_uint32_ptr;
2732     }
2733 
2734     return object_class_property_add(klass, name, "uint32",
2735                                      getter, setter, NULL, (void *)v);
2736 }
2737 
2738 ObjectProperty *
2739 object_property_add_uint64_ptr(Object *obj, const char *name,
2740                                const uint64_t *v,
2741                                ObjectPropertyFlags flags)
2742 {
2743     ObjectPropertyAccessor *getter = NULL;
2744     ObjectPropertyAccessor *setter = NULL;
2745 
2746     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2747         getter = property_get_uint64_ptr;
2748     }
2749 
2750     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2751         setter = property_set_uint64_ptr;
2752     }
2753 
2754     return object_property_add(obj, name, "uint64",
2755                                getter, setter, NULL, (void *)v);
2756 }
2757 
2758 ObjectProperty *
2759 object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
2760                                      const uint64_t *v,
2761                                      ObjectPropertyFlags flags)
2762 {
2763     ObjectPropertyAccessor *getter = NULL;
2764     ObjectPropertyAccessor *setter = NULL;
2765 
2766     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2767         getter = property_get_uint64_ptr;
2768     }
2769 
2770     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2771         setter = property_set_uint64_ptr;
2772     }
2773 
2774     return object_class_property_add(klass, name, "uint64",
2775                                      getter, setter, NULL, (void *)v);
2776 }
2777 
2778 typedef struct {
2779     Object *target_obj;
2780     char *target_name;
2781 } AliasProperty;
2782 
2783 static void property_get_alias(Object *obj, Visitor *v, const char *name,
2784                                void *opaque, Error **errp)
2785 {
2786     AliasProperty *prop = opaque;
2787     Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
2788 
2789     object_property_get(prop->target_obj, prop->target_name, alias_v, errp);
2790     visit_free(alias_v);
2791 }
2792 
2793 static void property_set_alias(Object *obj, Visitor *v, const char *name,
2794                                void *opaque, Error **errp)
2795 {
2796     AliasProperty *prop = opaque;
2797     Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
2798 
2799     object_property_set(prop->target_obj, prop->target_name, alias_v, errp);
2800     visit_free(alias_v);
2801 }
2802 
2803 static Object *property_resolve_alias(Object *obj, void *opaque,
2804                                       const char *part)
2805 {
2806     AliasProperty *prop = opaque;
2807 
2808     return object_resolve_path_component(prop->target_obj, prop->target_name);
2809 }
2810 
2811 static void property_release_alias(Object *obj, const char *name, void *opaque)
2812 {
2813     AliasProperty *prop = opaque;
2814 
2815     g_free(prop->target_name);
2816     g_free(prop);
2817 }
2818 
2819 ObjectProperty *
2820 object_property_add_alias(Object *obj, const char *name,
2821                           Object *target_obj, const char *target_name)
2822 {
2823     AliasProperty *prop;
2824     ObjectProperty *op;
2825     ObjectProperty *target_prop;
2826     g_autofree char *prop_type = NULL;
2827 
2828     target_prop = object_property_find_err(target_obj, target_name,
2829                                            &error_abort);
2830 
2831     if (object_property_is_child(target_prop)) {
2832         prop_type = g_strdup_printf("link%s",
2833                                     target_prop->type + strlen("child"));
2834     } else {
2835         prop_type = g_strdup(target_prop->type);
2836     }
2837 
2838     prop = g_malloc(sizeof(*prop));
2839     prop->target_obj = target_obj;
2840     prop->target_name = g_strdup(target_name);
2841 
2842     op = object_property_add(obj, name, prop_type,
2843                              property_get_alias,
2844                              property_set_alias,
2845                              property_release_alias,
2846                              prop);
2847     op->resolve = property_resolve_alias;
2848     if (target_prop->defval) {
2849         op->defval = qobject_ref(target_prop->defval);
2850     }
2851 
2852     object_property_set_description(obj, op->name,
2853                                     target_prop->description);
2854     return op;
2855 }
2856 
2857 void object_property_set_description(Object *obj, const char *name,
2858                                      const char *description)
2859 {
2860     ObjectProperty *op;
2861 
2862     op = object_property_find_err(obj, name, &error_abort);
2863     g_free(op->description);
2864     op->description = g_strdup(description);
2865 }
2866 
2867 void object_class_property_set_description(ObjectClass *klass,
2868                                            const char *name,
2869                                            const char *description)
2870 {
2871     ObjectProperty *op;
2872 
2873     op = g_hash_table_lookup(klass->properties, name);
2874     g_free(op->description);
2875     op->description = g_strdup(description);
2876 }
2877 
2878 static void object_class_init(ObjectClass *klass, void *data)
2879 {
2880     object_class_property_add_str(klass, "type", object_get_type,
2881                                   NULL);
2882 }
2883 
2884 static void register_types(void)
2885 {
2886     static const TypeInfo interface_info = {
2887         .name = TYPE_INTERFACE,
2888         .class_size = sizeof(InterfaceClass),
2889         .abstract = true,
2890     };
2891 
2892     static const TypeInfo object_info = {
2893         .name = TYPE_OBJECT,
2894         .instance_size = sizeof(Object),
2895         .class_init = object_class_init,
2896         .abstract = true,
2897     };
2898 
2899     type_interface = type_register_internal(&interface_info);
2900     type_register_internal(&object_info);
2901 }
2902 
2903 type_init(register_types)
2904