xref: /qemu/qom/object.c (revision fb5c28e1955537228fe59a901e6cf6258da682d5)
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/qjson.h"
27 #include "trace.h"
28 
29 /* TODO: replace QObject with a simpler visitor to avoid a dependency
30  * of the QOM core on QObject?  */
31 #include "qom/qom-qobject.h"
32 #include "qapi/qmp/qbool.h"
33 #include "qapi/qmp/qlist.h"
34 #include "qapi/qmp/qnum.h"
35 #include "qapi/qmp/qstring.h"
36 #include "qemu/error-report.h"
37 
38 #define MAX_INTERFACES 32
39 
40 typedef struct InterfaceImpl InterfaceImpl;
41 typedef struct TypeImpl TypeImpl;
42 
43 struct InterfaceImpl
44 {
45     const char *typename;
46 };
47 
48 struct TypeImpl
49 {
50     const char *name;
51 
52     size_t class_size;
53 
54     size_t instance_size;
55     size_t instance_align;
56 
57     void (*class_init)(ObjectClass *klass, void *data);
58     void (*class_base_init)(ObjectClass *klass, void *data);
59 
60     void *class_data;
61 
62     void (*instance_init)(Object *obj);
63     void (*instance_post_init)(Object *obj);
64     void (*instance_finalize)(Object *obj);
65 
66     bool abstract;
67 
68     const char *parent;
69     TypeImpl *parent_type;
70 
71     ObjectClass *class;
72 
73     int num_interfaces;
74     InterfaceImpl interfaces[MAX_INTERFACES];
75 };
76 
77 static Type type_interface;
78 
79 static GHashTable *type_table_get(void)
80 {
81     static GHashTable *type_table;
82 
83     if (type_table == NULL) {
84         type_table = g_hash_table_new(g_str_hash, g_str_equal);
85     }
86 
87     return type_table;
88 }
89 
90 static bool enumerating_types;
91 
92 static void type_table_add(TypeImpl *ti)
93 {
94     assert(!enumerating_types);
95     g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
96 }
97 
98 static TypeImpl *type_table_lookup(const char *name)
99 {
100     return g_hash_table_lookup(type_table_get(), name);
101 }
102 
103 static TypeImpl *type_new(const TypeInfo *info)
104 {
105     TypeImpl *ti = g_malloc0(sizeof(*ti));
106     int i;
107 
108     g_assert(info->name != NULL);
109 
110     if (type_table_lookup(info->name) != NULL) {
111         fprintf(stderr, "Registering `%s' which already exists\n", info->name);
112         abort();
113     }
114 
115     ti->name = g_strdup(info->name);
116     ti->parent = g_strdup(info->parent);
117 
118     ti->class_size = info->class_size;
119     ti->instance_size = info->instance_size;
120     ti->instance_align = info->instance_align;
121 
122     ti->class_init = info->class_init;
123     ti->class_base_init = info->class_base_init;
124     ti->class_data = info->class_data;
125 
126     ti->instance_init = info->instance_init;
127     ti->instance_post_init = info->instance_post_init;
128     ti->instance_finalize = info->instance_finalize;
129 
130     ti->abstract = info->abstract;
131 
132     for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
133         ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
134     }
135     ti->num_interfaces = i;
136 
137     return ti;
138 }
139 
140 static bool type_name_is_valid(const char *name)
141 {
142     const int slen = strlen(name);
143     int plen;
144 
145     g_assert(slen > 1);
146 
147     /*
148      * Ideally, the name should start with a letter - however, we've got
149      * too many names starting with a digit already, so allow digits here,
150      * too (except '0' which is not used yet)
151      */
152     if (!g_ascii_isalnum(name[0]) || name[0] == '0') {
153         return false;
154     }
155 
156     plen = strspn(name, "abcdefghijklmnopqrstuvwxyz"
157                         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
158                         "0123456789-_.");
159 
160     return plen == slen;
161 }
162 
163 static TypeImpl *type_register_internal(const TypeInfo *info)
164 {
165     TypeImpl *ti;
166 
167     if (!type_name_is_valid(info->name)) {
168         fprintf(stderr, "Registering '%s' with illegal type name\n", info->name);
169         abort();
170     }
171 
172     ti = type_new(info);
173 
174     type_table_add(ti);
175     return ti;
176 }
177 
178 TypeImpl *type_register_static(const TypeInfo *info)
179 {
180     assert(info->parent);
181     return type_register_internal(info);
182 }
183 
184 void type_register_static_array(const TypeInfo *infos, int nr_infos)
185 {
186     int i;
187 
188     for (i = 0; i < nr_infos; i++) {
189         type_register_static(&infos[i]);
190     }
191 }
192 
193 static TypeImpl *type_get_by_name_noload(const char *name)
194 {
195     if (name == NULL) {
196         return NULL;
197     }
198 
199     return type_table_lookup(name);
200 }
201 
202 static TypeImpl *type_get_or_load_by_name(const char *name, Error **errp)
203 {
204     TypeImpl *type = type_get_by_name_noload(name);
205 
206 #ifdef CONFIG_MODULES
207     if (!type) {
208         int rv = module_load_qom(name, errp);
209         if (rv > 0) {
210             type = type_get_by_name_noload(name);
211         } else {
212             error_prepend(errp, "could not load a module for type '%s'", name);
213             return NULL;
214         }
215     }
216 #endif
217     if (!type) {
218         error_setg(errp, "unknown type '%s'", name);
219     }
220 
221     return type;
222 }
223 
224 static TypeImpl *type_get_parent(TypeImpl *type)
225 {
226     if (!type->parent_type && type->parent) {
227         type->parent_type = type_get_by_name_noload(type->parent);
228         if (!type->parent_type) {
229             fprintf(stderr, "Type '%s' is missing its parent '%s'\n",
230                     type->name, type->parent);
231             abort();
232         }
233     }
234 
235     return type->parent_type;
236 }
237 
238 static bool type_has_parent(TypeImpl *type)
239 {
240     return (type->parent != NULL);
241 }
242 
243 static size_t type_class_get_size(TypeImpl *ti)
244 {
245     if (ti->class_size) {
246         return ti->class_size;
247     }
248 
249     if (type_has_parent(ti)) {
250         return type_class_get_size(type_get_parent(ti));
251     }
252 
253     return sizeof(ObjectClass);
254 }
255 
256 static size_t type_object_get_size(TypeImpl *ti)
257 {
258     if (ti->instance_size) {
259         return ti->instance_size;
260     }
261 
262     if (type_has_parent(ti)) {
263         return type_object_get_size(type_get_parent(ti));
264     }
265 
266     return 0;
267 }
268 
269 static size_t type_object_get_align(TypeImpl *ti)
270 {
271     if (ti->instance_align) {
272         return ti->instance_align;
273     }
274 
275     if (type_has_parent(ti)) {
276         return type_object_get_align(type_get_parent(ti));
277     }
278 
279     return 0;
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_noload(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_or_load_by_name(typename, &error_fatal);
578 
579     object_initialize_with_type(data, size, type);
580 }
581 
582 bool object_initialize_child_with_props(Object *parentobj,
583                                         const char *propname,
584                                         void *childobj, size_t size,
585                                         const char *type,
586                                         Error **errp, ...)
587 {
588     va_list vargs;
589     bool ok;
590 
591     va_start(vargs, errp);
592     ok = object_initialize_child_with_propsv(parentobj, propname,
593                                              childobj, size, type, errp,
594                                              vargs);
595     va_end(vargs);
596     return ok;
597 }
598 
599 bool object_initialize_child_with_propsv(Object *parentobj,
600                                          const char *propname,
601                                          void *childobj, size_t size,
602                                          const char *type,
603                                          Error **errp, va_list vargs)
604 {
605     bool ok = false;
606     Object *obj;
607     UserCreatable *uc;
608 
609     object_initialize(childobj, size, type);
610     obj = OBJECT(childobj);
611 
612     if (!object_set_propv(obj, errp, vargs)) {
613         goto out;
614     }
615 
616     object_property_add_child(parentobj, propname, obj);
617 
618     uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
619     if (uc) {
620         if (!user_creatable_complete(uc, errp)) {
621             object_unparent(obj);
622             goto out;
623         }
624     }
625 
626     ok = true;
627 
628 out:
629     /*
630      * We want @obj's reference to be 1 on success, 0 on failure.
631      * On success, it's 2: one taken by object_initialize(), and one
632      * by object_property_add_child().
633      * On failure in object_initialize() or earlier, it's 1.
634      * On failure afterwards, it's also 1: object_unparent() releases
635      * the reference taken by object_property_add_child().
636      */
637     object_unref(obj);
638     return ok;
639 }
640 
641 void object_initialize_child_internal(Object *parent,
642                                       const char *propname,
643                                       void *child, size_t size,
644                                       const char *type)
645 {
646     object_initialize_child_with_props(parent, propname, child, size, type,
647                                        &error_abort, NULL);
648 }
649 
650 static inline bool object_property_is_child(ObjectProperty *prop)
651 {
652     return strstart(prop->type, "child<", NULL);
653 }
654 
655 static void object_property_del_all(Object *obj)
656 {
657     g_autoptr(GHashTable) done = g_hash_table_new(NULL, NULL);
658     ObjectProperty *prop;
659     ObjectPropertyIterator iter;
660     bool released;
661 
662     do {
663         released = false;
664         object_property_iter_init(&iter, obj);
665         while ((prop = object_property_iter_next(&iter)) != NULL) {
666             if (g_hash_table_add(done, prop)) {
667                 if (prop->release) {
668                     prop->release(obj, prop->name, prop->opaque);
669                     released = true;
670                     break;
671                 }
672             }
673         }
674     } while (released);
675 
676     g_hash_table_unref(obj->properties);
677 }
678 
679 static void object_property_del_child(Object *obj, Object *child)
680 {
681     ObjectProperty *prop;
682     GHashTableIter iter;
683     gpointer key, value;
684 
685     g_hash_table_iter_init(&iter, obj->properties);
686     while (g_hash_table_iter_next(&iter, &key, &value)) {
687         prop = value;
688         if (object_property_is_child(prop) && prop->opaque == child) {
689             if (prop->release) {
690                 prop->release(obj, prop->name, prop->opaque);
691                 prop->release = NULL;
692             }
693             break;
694         }
695     }
696     g_hash_table_iter_init(&iter, obj->properties);
697     while (g_hash_table_iter_next(&iter, &key, &value)) {
698         prop = value;
699         if (object_property_is_child(prop) && prop->opaque == child) {
700             g_hash_table_iter_remove(&iter);
701             break;
702         }
703     }
704 }
705 
706 void object_unparent(Object *obj)
707 {
708     if (obj->parent) {
709         object_property_del_child(obj->parent, obj);
710     }
711 }
712 
713 static void object_deinit(Object *obj, TypeImpl *type)
714 {
715     if (type->instance_finalize) {
716         type->instance_finalize(obj);
717     }
718 
719     if (type_has_parent(type)) {
720         object_deinit(obj, type_get_parent(type));
721     }
722 }
723 
724 static void object_finalize(void *data)
725 {
726     Object *obj = data;
727     TypeImpl *ti = obj->class->type;
728 
729     object_property_del_all(obj);
730     object_deinit(obj, ti);
731 
732     g_assert(obj->ref == 0);
733     g_assert(obj->parent == NULL);
734     if (obj->free) {
735         obj->free(obj);
736     }
737 }
738 
739 /* Find the minimum alignment guaranteed by the system malloc. */
740 #if __STDC_VERSION__ >= 201112L
741 typedef max_align_t qemu_max_align_t;
742 #else
743 typedef union {
744     long l;
745     void *p;
746     double d;
747     long double ld;
748 } qemu_max_align_t;
749 #endif
750 
751 static Object *object_new_with_type(Type type)
752 {
753     Object *obj;
754     size_t size, align;
755     void (*obj_free)(void *);
756 
757     g_assert(type != NULL);
758     type_initialize(type);
759 
760     size = type->instance_size;
761     align = type->instance_align;
762 
763     /*
764      * Do not use qemu_memalign unless required.  Depending on the
765      * implementation, extra alignment implies extra overhead.
766      */
767     if (likely(align <= __alignof__(qemu_max_align_t))) {
768         obj = g_malloc(size);
769         obj_free = g_free;
770     } else {
771         obj = qemu_memalign(align, size);
772         obj_free = qemu_vfree;
773     }
774 
775     object_initialize_with_type(obj, size, type);
776     obj->free = obj_free;
777 
778     return obj;
779 }
780 
781 Object *object_new_with_class(ObjectClass *klass)
782 {
783     return object_new_with_type(klass->type);
784 }
785 
786 Object *object_new(const char *typename)
787 {
788     TypeImpl *ti = type_get_or_load_by_name(typename, &error_fatal);
789 
790     return object_new_with_type(ti);
791 }
792 
793 
794 Object *object_new_with_props(const char *typename,
795                               Object *parent,
796                               const char *id,
797                               Error **errp,
798                               ...)
799 {
800     va_list vargs;
801     Object *obj;
802 
803     va_start(vargs, errp);
804     obj = object_new_with_propv(typename, parent, id, errp, vargs);
805     va_end(vargs);
806 
807     return obj;
808 }
809 
810 
811 Object *object_new_with_propv(const char *typename,
812                               Object *parent,
813                               const char *id,
814                               Error **errp,
815                               va_list vargs)
816 {
817     Object *obj;
818     ObjectClass *klass;
819     UserCreatable *uc;
820 
821     klass = object_class_by_name(typename);
822     if (!klass) {
823         error_setg(errp, "invalid object type: %s", typename);
824         return NULL;
825     }
826 
827     if (object_class_is_abstract(klass)) {
828         error_setg(errp, "object type '%s' is abstract", typename);
829         return NULL;
830     }
831     obj = object_new_with_type(klass->type);
832 
833     if (!object_set_propv(obj, errp, vargs)) {
834         goto error;
835     }
836 
837     if (id != NULL) {
838         object_property_add_child(parent, id, obj);
839     }
840 
841     uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
842     if (uc) {
843         if (!user_creatable_complete(uc, errp)) {
844             if (id != NULL) {
845                 object_unparent(obj);
846             }
847             goto error;
848         }
849     }
850 
851     object_unref(obj);
852     return obj;
853 
854  error:
855     object_unref(obj);
856     return NULL;
857 }
858 
859 
860 bool object_set_props(Object *obj,
861                      Error **errp,
862                      ...)
863 {
864     va_list vargs;
865     bool ret;
866 
867     va_start(vargs, errp);
868     ret = object_set_propv(obj, errp, vargs);
869     va_end(vargs);
870 
871     return ret;
872 }
873 
874 
875 bool object_set_propv(Object *obj,
876                      Error **errp,
877                      va_list vargs)
878 {
879     const char *propname;
880 
881     propname = va_arg(vargs, char *);
882     while (propname != NULL) {
883         const char *value = va_arg(vargs, char *);
884 
885         g_assert(value != NULL);
886         if (!object_property_parse(obj, propname, value, errp)) {
887             return false;
888         }
889         propname = va_arg(vargs, char *);
890     }
891 
892     return true;
893 }
894 
895 
896 Object *object_dynamic_cast(Object *obj, const char *typename)
897 {
898     if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
899         return obj;
900     }
901 
902     return NULL;
903 }
904 
905 Object *object_dynamic_cast_assert(Object *obj, const char *typename,
906                                    const char *file, int line, const char *func)
907 {
908     trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
909                                      typename, file, line, func);
910 
911 #ifdef CONFIG_QOM_CAST_DEBUG
912     int i;
913     Object *inst;
914 
915     for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
916         if (qatomic_read(&obj->class->object_cast_cache[i]) == typename) {
917             goto out;
918         }
919     }
920 
921     inst = object_dynamic_cast(obj, typename);
922 
923     if (!inst && obj) {
924         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
925                 file, line, func, obj, typename);
926         abort();
927     }
928 
929     assert(obj == inst);
930 
931     if (obj && obj == inst) {
932         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
933             qatomic_set(&obj->class->object_cast_cache[i - 1],
934                        qatomic_read(&obj->class->object_cast_cache[i]));
935         }
936         qatomic_set(&obj->class->object_cast_cache[i - 1], typename);
937     }
938 
939 out:
940 #endif
941     return obj;
942 }
943 
944 ObjectClass *object_class_dynamic_cast(ObjectClass *class,
945                                        const char *typename)
946 {
947     ObjectClass *ret = NULL;
948     TypeImpl *target_type;
949     TypeImpl *type;
950 
951     if (!class) {
952         return NULL;
953     }
954 
955     /* A simple fast path that can trigger a lot for leaf classes.  */
956     type = class->type;
957     if (type->name == typename) {
958         return class;
959     }
960 
961     target_type = type_get_by_name_noload(typename);
962     if (!target_type) {
963         /* target class type unknown, so fail the cast */
964         return NULL;
965     }
966 
967     if (type->class->interfaces &&
968             type_is_ancestor(target_type, type_interface)) {
969         int found = 0;
970         GSList *i;
971 
972         for (i = class->interfaces; i; i = i->next) {
973             ObjectClass *target_class = i->data;
974 
975             if (type_is_ancestor(target_class->type, target_type)) {
976                 ret = target_class;
977                 found++;
978             }
979          }
980 
981         /* The match was ambiguous, don't allow a cast */
982         if (found > 1) {
983             ret = NULL;
984         }
985     } else if (type_is_ancestor(type, target_type)) {
986         ret = class;
987     }
988 
989     return ret;
990 }
991 
992 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
993                                               const char *typename,
994                                               const char *file, int line,
995                                               const char *func)
996 {
997     ObjectClass *ret;
998 
999     trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
1000                                            typename, file, line, func);
1001 
1002 #ifdef CONFIG_QOM_CAST_DEBUG
1003     int i;
1004 
1005     for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
1006         if (qatomic_read(&class->class_cast_cache[i]) == typename) {
1007             ret = class;
1008             goto out;
1009         }
1010     }
1011 #else
1012     if (!class || !class->interfaces) {
1013         return class;
1014     }
1015 #endif
1016 
1017     ret = object_class_dynamic_cast(class, typename);
1018     if (!ret && class) {
1019         fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
1020                 file, line, func, class, typename);
1021         abort();
1022     }
1023 
1024 #ifdef CONFIG_QOM_CAST_DEBUG
1025     if (class && ret == class) {
1026         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
1027             qatomic_set(&class->class_cast_cache[i - 1],
1028                        qatomic_read(&class->class_cast_cache[i]));
1029         }
1030         qatomic_set(&class->class_cast_cache[i - 1], typename);
1031     }
1032 out:
1033 #endif
1034     return ret;
1035 }
1036 
1037 const char *object_get_typename(const Object *obj)
1038 {
1039     return obj->class->type->name;
1040 }
1041 
1042 ObjectClass *object_get_class(Object *obj)
1043 {
1044     return obj->class;
1045 }
1046 
1047 bool object_class_is_abstract(ObjectClass *klass)
1048 {
1049     return klass->type->abstract;
1050 }
1051 
1052 const char *object_class_get_name(ObjectClass *klass)
1053 {
1054     return klass->type->name;
1055 }
1056 
1057 ObjectClass *object_class_by_name(const char *typename)
1058 {
1059     TypeImpl *type = type_get_by_name_noload(typename);
1060 
1061     if (!type) {
1062         return NULL;
1063     }
1064 
1065     type_initialize(type);
1066 
1067     return type->class;
1068 }
1069 
1070 ObjectClass *module_object_class_by_name(const char *typename)
1071 {
1072     TypeImpl *type = type_get_or_load_by_name(typename, NULL);
1073 
1074     if (!type) {
1075         return NULL;
1076     }
1077 
1078     type_initialize(type);
1079 
1080     return type->class;
1081 }
1082 
1083 ObjectClass *object_class_get_parent(ObjectClass *class)
1084 {
1085     TypeImpl *type = type_get_parent(class->type);
1086 
1087     if (!type) {
1088         return NULL;
1089     }
1090 
1091     type_initialize(type);
1092 
1093     return type->class;
1094 }
1095 
1096 typedef struct OCFData
1097 {
1098     void (*fn)(ObjectClass *klass, void *opaque);
1099     const char *implements_type;
1100     bool include_abstract;
1101     void *opaque;
1102 } OCFData;
1103 
1104 static void object_class_foreach_tramp(gpointer key, gpointer value,
1105                                        gpointer opaque)
1106 {
1107     OCFData *data = opaque;
1108     TypeImpl *type = value;
1109     ObjectClass *k;
1110 
1111     type_initialize(type);
1112     k = type->class;
1113 
1114     if (!data->include_abstract && type->abstract) {
1115         return;
1116     }
1117 
1118     if (data->implements_type &&
1119         !object_class_dynamic_cast(k, data->implements_type)) {
1120         return;
1121     }
1122 
1123     data->fn(k, data->opaque);
1124 }
1125 
1126 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
1127                           const char *implements_type, bool include_abstract,
1128                           void *opaque)
1129 {
1130     OCFData data = { fn, implements_type, include_abstract, opaque };
1131 
1132     enumerating_types = true;
1133     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
1134     enumerating_types = false;
1135 }
1136 
1137 static int do_object_child_foreach(Object *obj,
1138                                    int (*fn)(Object *child, void *opaque),
1139                                    void *opaque, bool recurse)
1140 {
1141     GHashTableIter iter;
1142     ObjectProperty *prop;
1143     int ret = 0;
1144 
1145     g_hash_table_iter_init(&iter, obj->properties);
1146     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1147         if (object_property_is_child(prop)) {
1148             Object *child = prop->opaque;
1149 
1150             ret = fn(child, opaque);
1151             if (ret != 0) {
1152                 break;
1153             }
1154             if (recurse) {
1155                 ret = do_object_child_foreach(child, fn, opaque, true);
1156                 if (ret != 0) {
1157                     break;
1158                 }
1159             }
1160         }
1161     }
1162     return ret;
1163 }
1164 
1165 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
1166                          void *opaque)
1167 {
1168     return do_object_child_foreach(obj, fn, opaque, false);
1169 }
1170 
1171 int object_child_foreach_recursive(Object *obj,
1172                                    int (*fn)(Object *child, void *opaque),
1173                                    void *opaque)
1174 {
1175     return do_object_child_foreach(obj, fn, opaque, true);
1176 }
1177 
1178 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
1179 {
1180     GSList **list = opaque;
1181 
1182     *list = g_slist_prepend(*list, klass);
1183 }
1184 
1185 GSList *object_class_get_list(const char *implements_type,
1186                               bool include_abstract)
1187 {
1188     GSList *list = NULL;
1189 
1190     object_class_foreach(object_class_get_list_tramp,
1191                          implements_type, include_abstract, &list);
1192     return list;
1193 }
1194 
1195 static gint object_class_cmp(gconstpointer a, gconstpointer b)
1196 {
1197     return strcasecmp(object_class_get_name((ObjectClass *)a),
1198                       object_class_get_name((ObjectClass *)b));
1199 }
1200 
1201 GSList *object_class_get_list_sorted(const char *implements_type,
1202                                      bool include_abstract)
1203 {
1204     return g_slist_sort(object_class_get_list(implements_type, include_abstract),
1205                         object_class_cmp);
1206 }
1207 
1208 Object *object_ref(void *objptr)
1209 {
1210     Object *obj = OBJECT(objptr);
1211     uint32_t ref;
1212 
1213     if (!obj) {
1214         return NULL;
1215     }
1216     ref = qatomic_fetch_inc(&obj->ref);
1217     /* Assert waaay before the integer overflows */
1218     g_assert(ref < INT_MAX);
1219     return obj;
1220 }
1221 
1222 void object_unref(void *objptr)
1223 {
1224     Object *obj = OBJECT(objptr);
1225     if (!obj) {
1226         return;
1227     }
1228     g_assert(obj->ref > 0);
1229 
1230     /* parent always holds a reference to its children */
1231     if (qatomic_fetch_dec(&obj->ref) == 1) {
1232         object_finalize(obj);
1233     }
1234 }
1235 
1236 ObjectProperty *
1237 object_property_try_add(Object *obj, const char *name, const char *type,
1238                         ObjectPropertyAccessor *get,
1239                         ObjectPropertyAccessor *set,
1240                         ObjectPropertyRelease *release,
1241                         void *opaque, Error **errp)
1242 {
1243     ObjectProperty *prop;
1244     size_t name_len = strlen(name);
1245 
1246     if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) {
1247         int i;
1248         ObjectProperty *ret = NULL;
1249         char *name_no_array = g_strdup(name);
1250 
1251         name_no_array[name_len - 3] = '\0';
1252         for (i = 0; i < INT16_MAX; ++i) {
1253             char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
1254 
1255             ret = object_property_try_add(obj, full_name, type, get, set,
1256                                           release, opaque, NULL);
1257             g_free(full_name);
1258             if (ret) {
1259                 break;
1260             }
1261         }
1262         g_free(name_no_array);
1263         assert(ret);
1264         return ret;
1265     }
1266 
1267     if (object_property_find(obj, name) != NULL) {
1268         error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')",
1269                    name, object_get_typename(obj));
1270         return NULL;
1271     }
1272 
1273     prop = g_malloc0(sizeof(*prop));
1274 
1275     prop->name = g_strdup(name);
1276     prop->type = g_strdup(type);
1277 
1278     prop->get = get;
1279     prop->set = set;
1280     prop->release = release;
1281     prop->opaque = opaque;
1282 
1283     g_hash_table_insert(obj->properties, prop->name, prop);
1284     return prop;
1285 }
1286 
1287 ObjectProperty *
1288 object_property_add(Object *obj, const char *name, const char *type,
1289                     ObjectPropertyAccessor *get,
1290                     ObjectPropertyAccessor *set,
1291                     ObjectPropertyRelease *release,
1292                     void *opaque)
1293 {
1294     return object_property_try_add(obj, name, type, get, set, release,
1295                                    opaque, &error_abort);
1296 }
1297 
1298 ObjectProperty *
1299 object_class_property_add(ObjectClass *klass,
1300                           const char *name,
1301                           const char *type,
1302                           ObjectPropertyAccessor *get,
1303                           ObjectPropertyAccessor *set,
1304                           ObjectPropertyRelease *release,
1305                           void *opaque)
1306 {
1307     ObjectProperty *prop;
1308 
1309     assert(!object_class_property_find(klass, name));
1310 
1311     prop = g_malloc0(sizeof(*prop));
1312 
1313     prop->name = g_strdup(name);
1314     prop->type = g_strdup(type);
1315 
1316     prop->get = get;
1317     prop->set = set;
1318     prop->release = release;
1319     prop->opaque = opaque;
1320 
1321     g_hash_table_insert(klass->properties, prop->name, prop);
1322 
1323     return prop;
1324 }
1325 
1326 ObjectProperty *object_property_find(Object *obj, const char *name)
1327 {
1328     ObjectProperty *prop;
1329     ObjectClass *klass = object_get_class(obj);
1330 
1331     prop = object_class_property_find(klass, name);
1332     if (prop) {
1333         return prop;
1334     }
1335 
1336     return g_hash_table_lookup(obj->properties, name);
1337 }
1338 
1339 ObjectProperty *object_property_find_err(Object *obj, const char *name,
1340                                          Error **errp)
1341 {
1342     ObjectProperty *prop = object_property_find(obj, name);
1343     if (!prop) {
1344         error_setg(errp, "Property '%s.%s' not found",
1345                    object_get_typename(obj), name);
1346     }
1347     return prop;
1348 }
1349 
1350 void object_property_iter_init(ObjectPropertyIterator *iter,
1351                                Object *obj)
1352 {
1353     g_hash_table_iter_init(&iter->iter, obj->properties);
1354     iter->nextclass = object_get_class(obj);
1355 }
1356 
1357 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
1358 {
1359     gpointer key, val;
1360     while (!g_hash_table_iter_next(&iter->iter, &key, &val)) {
1361         if (!iter->nextclass) {
1362             return NULL;
1363         }
1364         g_hash_table_iter_init(&iter->iter, iter->nextclass->properties);
1365         iter->nextclass = object_class_get_parent(iter->nextclass);
1366     }
1367     return val;
1368 }
1369 
1370 void object_class_property_iter_init(ObjectPropertyIterator *iter,
1371                                      ObjectClass *klass)
1372 {
1373     g_hash_table_iter_init(&iter->iter, klass->properties);
1374     iter->nextclass = object_class_get_parent(klass);
1375 }
1376 
1377 ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name)
1378 {
1379     ObjectClass *parent_klass;
1380 
1381     parent_klass = object_class_get_parent(klass);
1382     if (parent_klass) {
1383         ObjectProperty *prop =
1384             object_class_property_find(parent_klass, name);
1385         if (prop) {
1386             return prop;
1387         }
1388     }
1389 
1390     return g_hash_table_lookup(klass->properties, name);
1391 }
1392 
1393 ObjectProperty *object_class_property_find_err(ObjectClass *klass,
1394                                                const char *name,
1395                                                Error **errp)
1396 {
1397     ObjectProperty *prop = object_class_property_find(klass, name);
1398     if (!prop) {
1399         error_setg(errp, "Property '.%s' not found", name);
1400     }
1401     return prop;
1402 }
1403 
1404 
1405 void object_property_del(Object *obj, const char *name)
1406 {
1407     ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
1408 
1409     if (prop->release) {
1410         prop->release(obj, name, prop->opaque);
1411     }
1412     g_hash_table_remove(obj->properties, name);
1413 }
1414 
1415 bool object_property_get(Object *obj, const char *name, Visitor *v,
1416                          Error **errp)
1417 {
1418     Error *err = NULL;
1419     ObjectProperty *prop = object_property_find_err(obj, name, errp);
1420 
1421     if (prop == NULL) {
1422         return false;
1423     }
1424 
1425     if (!prop->get) {
1426         error_setg(errp, "Property '%s.%s' is not readable",
1427                    object_get_typename(obj), name);
1428         return false;
1429     }
1430     prop->get(obj, v, name, prop->opaque, &err);
1431     error_propagate(errp, err);
1432     return !err;
1433 }
1434 
1435 bool object_property_set(Object *obj, const char *name, Visitor *v,
1436                          Error **errp)
1437 {
1438     ERRP_GUARD();
1439     ObjectProperty *prop = object_property_find_err(obj, name, errp);
1440 
1441     if (prop == NULL) {
1442         return false;
1443     }
1444 
1445     if (!prop->set) {
1446         error_setg(errp, "Property '%s.%s' is not writable",
1447                    object_get_typename(obj), name);
1448         return false;
1449     }
1450     prop->set(obj, v, name, prop->opaque, errp);
1451     return !*errp;
1452 }
1453 
1454 bool object_property_set_str(Object *obj, const char *name,
1455                              const char *value, Error **errp)
1456 {
1457     QString *qstr = qstring_from_str(value);
1458     bool ok = object_property_set_qobject(obj, name, QOBJECT(qstr), errp);
1459 
1460     qobject_unref(qstr);
1461     return ok;
1462 }
1463 
1464 char *object_property_get_str(Object *obj, const char *name,
1465                               Error **errp)
1466 {
1467     QObject *ret = object_property_get_qobject(obj, name, errp);
1468     QString *qstring;
1469     char *retval;
1470 
1471     if (!ret) {
1472         return NULL;
1473     }
1474     qstring = qobject_to(QString, ret);
1475     if (!qstring) {
1476         error_setg(errp, "Invalid parameter type for '%s', expected: string",
1477                    name);
1478         retval = NULL;
1479     } else {
1480         retval = g_strdup(qstring_get_str(qstring));
1481     }
1482 
1483     qobject_unref(ret);
1484     return retval;
1485 }
1486 
1487 bool object_property_set_link(Object *obj, const char *name,
1488                               Object *value, Error **errp)
1489 {
1490     g_autofree char *path = NULL;
1491 
1492     if (value) {
1493         path = object_get_canonical_path(value);
1494     }
1495     return object_property_set_str(obj, name, path ?: "", errp);
1496 }
1497 
1498 Object *object_property_get_link(Object *obj, const char *name,
1499                                  Error **errp)
1500 {
1501     char *str = object_property_get_str(obj, name, errp);
1502     Object *target = NULL;
1503 
1504     if (str && *str) {
1505         target = object_resolve_path(str, NULL);
1506         if (!target) {
1507             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1508                       "Device '%s' not found", str);
1509         }
1510     }
1511 
1512     g_free(str);
1513     return target;
1514 }
1515 
1516 bool object_property_set_bool(Object *obj, const char *name,
1517                               bool value, Error **errp)
1518 {
1519     QBool *qbool = qbool_from_bool(value);
1520     bool ok = object_property_set_qobject(obj, name, QOBJECT(qbool), errp);
1521 
1522     qobject_unref(qbool);
1523     return ok;
1524 }
1525 
1526 bool object_property_get_bool(Object *obj, const char *name,
1527                               Error **errp)
1528 {
1529     QObject *ret = object_property_get_qobject(obj, name, errp);
1530     QBool *qbool;
1531     bool retval;
1532 
1533     if (!ret) {
1534         return false;
1535     }
1536     qbool = qobject_to(QBool, ret);
1537     if (!qbool) {
1538         error_setg(errp, "Invalid parameter type for '%s', expected: boolean",
1539                    name);
1540         retval = false;
1541     } else {
1542         retval = qbool_get_bool(qbool);
1543     }
1544 
1545     qobject_unref(ret);
1546     return retval;
1547 }
1548 
1549 bool object_property_set_int(Object *obj, const char *name,
1550                              int64_t value, Error **errp)
1551 {
1552     QNum *qnum = qnum_from_int(value);
1553     bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
1554 
1555     qobject_unref(qnum);
1556     return ok;
1557 }
1558 
1559 int64_t object_property_get_int(Object *obj, const char *name,
1560                                 Error **errp)
1561 {
1562     QObject *ret = object_property_get_qobject(obj, name, errp);
1563     QNum *qnum;
1564     int64_t retval;
1565 
1566     if (!ret) {
1567         return -1;
1568     }
1569 
1570     qnum = qobject_to(QNum, ret);
1571     if (!qnum || !qnum_get_try_int(qnum, &retval)) {
1572         error_setg(errp, "Invalid parameter type for '%s', expected: int",
1573                    name);
1574         retval = -1;
1575     }
1576 
1577     qobject_unref(ret);
1578     return retval;
1579 }
1580 
1581 static void object_property_init_defval(Object *obj, ObjectProperty *prop)
1582 {
1583     Visitor *v = qobject_input_visitor_new(prop->defval);
1584 
1585     assert(prop->set != NULL);
1586     prop->set(obj, v, prop->name, prop->opaque, &error_abort);
1587 
1588     visit_free(v);
1589 }
1590 
1591 static void object_property_set_default(ObjectProperty *prop, QObject *defval)
1592 {
1593     assert(!prop->defval);
1594     assert(!prop->init);
1595 
1596     prop->defval = defval;
1597     prop->init = object_property_init_defval;
1598 }
1599 
1600 void object_property_set_default_bool(ObjectProperty *prop, bool value)
1601 {
1602     object_property_set_default(prop, QOBJECT(qbool_from_bool(value)));
1603 }
1604 
1605 void object_property_set_default_str(ObjectProperty *prop, const char *value)
1606 {
1607     object_property_set_default(prop, QOBJECT(qstring_from_str(value)));
1608 }
1609 
1610 void object_property_set_default_list(ObjectProperty *prop)
1611 {
1612     object_property_set_default(prop, QOBJECT(qlist_new()));
1613 }
1614 
1615 void object_property_set_default_int(ObjectProperty *prop, int64_t value)
1616 {
1617     object_property_set_default(prop, QOBJECT(qnum_from_int(value)));
1618 }
1619 
1620 void object_property_set_default_uint(ObjectProperty *prop, uint64_t value)
1621 {
1622     object_property_set_default(prop, QOBJECT(qnum_from_uint(value)));
1623 }
1624 
1625 bool object_property_set_uint(Object *obj, const char *name,
1626                               uint64_t value, Error **errp)
1627 {
1628     QNum *qnum = qnum_from_uint(value);
1629     bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
1630 
1631     qobject_unref(qnum);
1632     return ok;
1633 }
1634 
1635 uint64_t object_property_get_uint(Object *obj, const char *name,
1636                                   Error **errp)
1637 {
1638     QObject *ret = object_property_get_qobject(obj, name, errp);
1639     QNum *qnum;
1640     uint64_t retval;
1641 
1642     if (!ret) {
1643         return 0;
1644     }
1645     qnum = qobject_to(QNum, ret);
1646     if (!qnum || !qnum_get_try_uint(qnum, &retval)) {
1647         error_setg(errp, "Invalid parameter type for '%s', expected: uint",
1648                    name);
1649         retval = 0;
1650     }
1651 
1652     qobject_unref(ret);
1653     return retval;
1654 }
1655 
1656 typedef struct EnumProperty {
1657     const QEnumLookup *lookup;
1658     int (*get)(Object *, Error **);
1659     void (*set)(Object *, int, Error **);
1660 } EnumProperty;
1661 
1662 int object_property_get_enum(Object *obj, const char *name,
1663                              const char *typename, Error **errp)
1664 {
1665     char *str;
1666     int ret;
1667     ObjectProperty *prop = object_property_find_err(obj, name, errp);
1668     EnumProperty *enumprop;
1669 
1670     if (prop == NULL) {
1671         return -1;
1672     }
1673 
1674     if (!g_str_equal(prop->type, typename)) {
1675         error_setg(errp, "Property %s on %s is not '%s' enum type",
1676                    name, object_class_get_name(
1677                        object_get_class(obj)), typename);
1678         return -1;
1679     }
1680 
1681     enumprop = prop->opaque;
1682 
1683     str = object_property_get_str(obj, name, errp);
1684     if (!str) {
1685         return -1;
1686     }
1687 
1688     ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
1689     g_free(str);
1690 
1691     return ret;
1692 }
1693 
1694 bool object_property_parse(Object *obj, const char *name,
1695                            const char *string, Error **errp)
1696 {
1697     Visitor *v = string_input_visitor_new(string);
1698     bool ok = object_property_set(obj, name, v, errp);
1699 
1700     visit_free(v);
1701     return ok;
1702 }
1703 
1704 char *object_property_print(Object *obj, const char *name, bool human,
1705                             Error **errp)
1706 {
1707     Visitor *v;
1708     char *string = NULL;
1709 
1710     v = string_output_visitor_new(human, &string);
1711     if (!object_property_get(obj, name, v, errp)) {
1712         goto out;
1713     }
1714 
1715     visit_complete(v, &string);
1716 
1717 out:
1718     visit_free(v);
1719     return string;
1720 }
1721 
1722 const char *object_property_get_type(Object *obj, const char *name, Error **errp)
1723 {
1724     ObjectProperty *prop = object_property_find_err(obj, name, errp);
1725     if (prop == NULL) {
1726         return NULL;
1727     }
1728 
1729     return prop->type;
1730 }
1731 
1732 static const char *const root_containers[] = {
1733     "chardevs",
1734     "objects",
1735     "backend"
1736 };
1737 
1738 static Object *object_root_initialize(void)
1739 {
1740     Object *root = object_new(TYPE_CONTAINER);
1741     int i;
1742 
1743     /*
1744      * Create all QEMU system containers.  "machine" and its sub-containers
1745      * are only created when machine initializes (qemu_create_machine()).
1746      */
1747     for (i = 0; i < ARRAY_SIZE(root_containers); i++) {
1748         object_property_add_new_container(root, root_containers[i]);
1749     }
1750 
1751     return root;
1752 }
1753 
1754 Object *object_get_root(void)
1755 {
1756     static Object *root;
1757 
1758     if (!root) {
1759         root = object_root_initialize();
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(TYPE_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, "Invalid parameter type for '%s', expected: %s",
1916                              name, target_type);
1917         } else {
1918             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1919                       "Device '%s' not found", path);
1920         }
1921         target = NULL;
1922     }
1923     g_free(target_type);
1924 
1925     return target;
1926 }
1927 
1928 static void object_set_link_property(Object *obj, Visitor *v,
1929                                      const char *name, void *opaque,
1930                                      Error **errp)
1931 {
1932     Error *local_err = NULL;
1933     LinkProperty *prop = opaque;
1934     Object **targetp = object_link_get_targetp(obj, prop);
1935     Object *old_target = *targetp;
1936     Object *new_target;
1937     char *path = NULL;
1938 
1939     if (!visit_type_str(v, name, &path, errp)) {
1940         return;
1941     }
1942 
1943     if (*path) {
1944         new_target = object_resolve_link(obj, name, path, errp);
1945         if (!new_target) {
1946             g_free(path);
1947             return;
1948         }
1949     } else {
1950         new_target = NULL;
1951     }
1952 
1953     g_free(path);
1954 
1955     prop->check(obj, name, new_target, &local_err);
1956     if (local_err) {
1957         error_propagate(errp, local_err);
1958         return;
1959     }
1960 
1961     *targetp = new_target;
1962     if (prop->flags & OBJ_PROP_LINK_STRONG) {
1963         object_ref(new_target);
1964         object_unref(old_target);
1965     }
1966 }
1967 
1968 static Object *object_resolve_link_property(Object *parent, void *opaque,
1969                                             const char *part)
1970 {
1971     LinkProperty *lprop = opaque;
1972 
1973     return *object_link_get_targetp(parent, lprop);
1974 }
1975 
1976 static void object_release_link_property(Object *obj, const char *name,
1977                                          void *opaque)
1978 {
1979     LinkProperty *prop = opaque;
1980     Object **targetp = object_link_get_targetp(obj, prop);
1981 
1982     if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) {
1983         object_unref(*targetp);
1984     }
1985     if (!(prop->flags & OBJ_PROP_LINK_CLASS)) {
1986         g_free(prop);
1987     }
1988 }
1989 
1990 static ObjectProperty *
1991 object_add_link_prop(Object *obj, const char *name,
1992                      const char *type, void *ptr,
1993                      void (*check)(const Object *, const char *,
1994                                    Object *, Error **),
1995                      ObjectPropertyLinkFlags flags)
1996 {
1997     LinkProperty *prop = g_malloc(sizeof(*prop));
1998     g_autofree char *full_type = NULL;
1999     ObjectProperty *op;
2000 
2001     if (flags & OBJ_PROP_LINK_DIRECT) {
2002         prop->target = ptr;
2003     } else {
2004         prop->targetp = ptr;
2005     }
2006     prop->check = check;
2007     prop->flags = flags;
2008 
2009     full_type = g_strdup_printf("link<%s>", type);
2010 
2011     op = object_property_add(obj, name, full_type,
2012                              object_get_link_property,
2013                              check ? object_set_link_property : NULL,
2014                              object_release_link_property,
2015                              prop);
2016     op->resolve = object_resolve_link_property;
2017     return op;
2018 }
2019 
2020 ObjectProperty *
2021 object_property_add_link(Object *obj, const char *name,
2022                          const char *type, Object **targetp,
2023                          void (*check)(const Object *, const char *,
2024                                        Object *, Error **),
2025                          ObjectPropertyLinkFlags flags)
2026 {
2027     return object_add_link_prop(obj, name, type, targetp, check, flags);
2028 }
2029 
2030 ObjectProperty *
2031 object_class_property_add_link(ObjectClass *oc,
2032     const char *name,
2033     const char *type, ptrdiff_t offset,
2034     void (*check)(const Object *obj, const char *name,
2035                   Object *val, Error **errp),
2036     ObjectPropertyLinkFlags flags)
2037 {
2038     LinkProperty *prop = g_new0(LinkProperty, 1);
2039     char *full_type;
2040     ObjectProperty *op;
2041 
2042     prop->offset = offset;
2043     prop->check = check;
2044     prop->flags = flags | OBJ_PROP_LINK_CLASS;
2045 
2046     full_type = g_strdup_printf("link<%s>", type);
2047 
2048     op = object_class_property_add(oc, name, full_type,
2049                                    object_get_link_property,
2050                                    check ? object_set_link_property : NULL,
2051                                    object_release_link_property,
2052                                    prop);
2053 
2054     op->resolve = object_resolve_link_property;
2055 
2056     g_free(full_type);
2057     return op;
2058 }
2059 
2060 ObjectProperty *
2061 object_property_add_const_link(Object *obj, const char *name,
2062                                Object *target)
2063 {
2064     return object_add_link_prop(obj, name,
2065                                 object_get_typename(target), target,
2066                                 NULL, OBJ_PROP_LINK_DIRECT);
2067 }
2068 
2069 const char *object_get_canonical_path_component(const Object *obj)
2070 {
2071     ObjectProperty *prop = NULL;
2072     GHashTableIter iter;
2073 
2074     if (obj->parent == NULL) {
2075         return NULL;
2076     }
2077 
2078     g_hash_table_iter_init(&iter, obj->parent->properties);
2079     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
2080         if (!object_property_is_child(prop)) {
2081             continue;
2082         }
2083 
2084         if (prop->opaque == obj) {
2085             return prop->name;
2086         }
2087     }
2088 
2089     /* obj had a parent but was not a child, should never happen */
2090     g_assert_not_reached();
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 *ambiguous)
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 ambig = false;
2206         obj = object_resolve_partial_path(object_get_root(), parts,
2207                                           typename, &ambig);
2208         if (ambiguous) {
2209             *ambiguous = ambig;
2210         }
2211     } else {
2212         obj = object_resolve_abs_path(object_get_root(), parts + 1, typename);
2213         if (ambiguous) {
2214             *ambiguous = false;
2215         }
2216     }
2217 
2218     g_strfreev(parts);
2219 
2220     return obj;
2221 }
2222 
2223 Object *object_resolve_path(const char *path, bool *ambiguous)
2224 {
2225     return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
2226 }
2227 
2228 Object *object_resolve_path_at(Object *parent, const char *path)
2229 {
2230     g_auto(GStrv) parts = g_strsplit(path, "/", 0);
2231 
2232     if (*path == '/') {
2233         return object_resolve_abs_path(object_get_root(), parts + 1,
2234                                        TYPE_OBJECT);
2235     }
2236     return object_resolve_abs_path(parent, parts, TYPE_OBJECT);
2237 }
2238 
2239 Object *object_resolve_type_unambiguous(const char *typename, Error **errp)
2240 {
2241     bool ambig = false;
2242     Object *o = object_resolve_path_type("", typename, &ambig);
2243 
2244     if (ambig) {
2245         error_setg(errp, "More than one object of type %s", typename);
2246         return NULL;
2247     }
2248     if (!o) {
2249         error_setg(errp, "No object found of type %s", typename);
2250         return NULL;
2251     }
2252     return o;
2253 }
2254 
2255 typedef struct StringProperty
2256 {
2257     char *(*get)(Object *, Error **);
2258     void (*set)(Object *, const char *, Error **);
2259 } StringProperty;
2260 
2261 static void property_get_str(Object *obj, Visitor *v, const char *name,
2262                              void *opaque, Error **errp)
2263 {
2264     StringProperty *prop = opaque;
2265     char *value;
2266     Error *err = NULL;
2267 
2268     value = prop->get(obj, &err);
2269     if (err) {
2270         error_propagate(errp, err);
2271         return;
2272     }
2273 
2274     visit_type_str(v, name, &value, errp);
2275     g_free(value);
2276 }
2277 
2278 static void property_set_str(Object *obj, Visitor *v, const char *name,
2279                              void *opaque, Error **errp)
2280 {
2281     StringProperty *prop = opaque;
2282     char *value;
2283 
2284     if (!visit_type_str(v, name, &value, errp)) {
2285         return;
2286     }
2287 
2288     prop->set(obj, value, errp);
2289     g_free(value);
2290 }
2291 
2292 static void property_release_data(Object *obj, const char *name,
2293                                   void *opaque)
2294 {
2295     g_free(opaque);
2296 }
2297 
2298 ObjectProperty *
2299 object_property_add_str(Object *obj, const char *name,
2300                         char *(*get)(Object *, Error **),
2301                         void (*set)(Object *, const char *, Error **))
2302 {
2303     StringProperty *prop = g_malloc0(sizeof(*prop));
2304 
2305     prop->get = get;
2306     prop->set = set;
2307 
2308     return object_property_add(obj, name, "string",
2309                                get ? property_get_str : NULL,
2310                                set ? property_set_str : NULL,
2311                                property_release_data,
2312                                prop);
2313 }
2314 
2315 ObjectProperty *
2316 object_class_property_add_str(ObjectClass *klass, const char *name,
2317                                    char *(*get)(Object *, Error **),
2318                                    void (*set)(Object *, const char *,
2319                                                Error **))
2320 {
2321     StringProperty *prop = g_malloc0(sizeof(*prop));
2322 
2323     prop->get = get;
2324     prop->set = set;
2325 
2326     return object_class_property_add(klass, name, "string",
2327                                      get ? property_get_str : NULL,
2328                                      set ? property_set_str : NULL,
2329                                      NULL,
2330                                      prop);
2331 }
2332 
2333 typedef struct BoolProperty
2334 {
2335     bool (*get)(Object *, Error **);
2336     void (*set)(Object *, bool, Error **);
2337 } BoolProperty;
2338 
2339 static void property_get_bool(Object *obj, Visitor *v, const char *name,
2340                               void *opaque, Error **errp)
2341 {
2342     BoolProperty *prop = opaque;
2343     bool value;
2344     Error *err = NULL;
2345 
2346     value = prop->get(obj, &err);
2347     if (err) {
2348         error_propagate(errp, err);
2349         return;
2350     }
2351 
2352     visit_type_bool(v, name, &value, errp);
2353 }
2354 
2355 static void property_set_bool(Object *obj, Visitor *v, const char *name,
2356                               void *opaque, Error **errp)
2357 {
2358     BoolProperty *prop = opaque;
2359     bool value;
2360 
2361     if (!visit_type_bool(v, name, &value, errp)) {
2362         return;
2363     }
2364 
2365     prop->set(obj, value, errp);
2366 }
2367 
2368 ObjectProperty *
2369 object_property_add_bool(Object *obj, const char *name,
2370                          bool (*get)(Object *, Error **),
2371                          void (*set)(Object *, bool, Error **))
2372 {
2373     BoolProperty *prop = g_malloc0(sizeof(*prop));
2374 
2375     prop->get = get;
2376     prop->set = set;
2377 
2378     return object_property_add(obj, name, "bool",
2379                                get ? property_get_bool : NULL,
2380                                set ? property_set_bool : NULL,
2381                                property_release_data,
2382                                prop);
2383 }
2384 
2385 ObjectProperty *
2386 object_class_property_add_bool(ObjectClass *klass, const char *name,
2387                                     bool (*get)(Object *, Error **),
2388                                     void (*set)(Object *, bool, Error **))
2389 {
2390     BoolProperty *prop = g_malloc0(sizeof(*prop));
2391 
2392     prop->get = get;
2393     prop->set = set;
2394 
2395     return object_class_property_add(klass, name, "bool",
2396                                      get ? property_get_bool : NULL,
2397                                      set ? property_set_bool : NULL,
2398                                      NULL,
2399                                      prop);
2400 }
2401 
2402 static void property_get_enum(Object *obj, Visitor *v, const char *name,
2403                               void *opaque, Error **errp)
2404 {
2405     EnumProperty *prop = opaque;
2406     int value;
2407     Error *err = NULL;
2408 
2409     value = prop->get(obj, &err);
2410     if (err) {
2411         error_propagate(errp, err);
2412         return;
2413     }
2414 
2415     visit_type_enum(v, name, &value, prop->lookup, errp);
2416 }
2417 
2418 static void property_set_enum(Object *obj, Visitor *v, const char *name,
2419                               void *opaque, Error **errp)
2420 {
2421     EnumProperty *prop = opaque;
2422     int value;
2423 
2424     if (!visit_type_enum(v, name, &value, prop->lookup, errp)) {
2425         return;
2426     }
2427     prop->set(obj, value, errp);
2428 }
2429 
2430 ObjectProperty *
2431 object_property_add_enum(Object *obj, const char *name,
2432                          const char *typename,
2433                          const QEnumLookup *lookup,
2434                          int (*get)(Object *, Error **),
2435                          void (*set)(Object *, int, Error **))
2436 {
2437     EnumProperty *prop = g_malloc(sizeof(*prop));
2438 
2439     prop->lookup = lookup;
2440     prop->get = get;
2441     prop->set = set;
2442 
2443     return object_property_add(obj, name, typename,
2444                                get ? property_get_enum : NULL,
2445                                set ? property_set_enum : NULL,
2446                                property_release_data,
2447                                prop);
2448 }
2449 
2450 ObjectProperty *
2451 object_class_property_add_enum(ObjectClass *klass, const char *name,
2452                                     const char *typename,
2453                                     const QEnumLookup *lookup,
2454                                     int (*get)(Object *, Error **),
2455                                     void (*set)(Object *, int, Error **))
2456 {
2457     EnumProperty *prop = g_malloc(sizeof(*prop));
2458 
2459     prop->lookup = lookup;
2460     prop->get = get;
2461     prop->set = set;
2462 
2463     return object_class_property_add(klass, name, typename,
2464                                      get ? property_get_enum : NULL,
2465                                      set ? property_set_enum : NULL,
2466                                      NULL,
2467                                      prop);
2468 }
2469 
2470 typedef struct TMProperty {
2471     void (*get)(Object *, struct tm *, Error **);
2472 } TMProperty;
2473 
2474 static void property_get_tm(Object *obj, Visitor *v, const char *name,
2475                             void *opaque, Error **errp)
2476 {
2477     TMProperty *prop = opaque;
2478     Error *err = NULL;
2479     struct tm value;
2480 
2481     prop->get(obj, &value, &err);
2482     if (err) {
2483         error_propagate(errp, err);
2484         return;
2485     }
2486 
2487     if (!visit_start_struct(v, name, NULL, 0, errp)) {
2488         return;
2489     }
2490     if (!visit_type_int32(v, "tm_year", &value.tm_year, errp)) {
2491         goto out_end;
2492     }
2493     if (!visit_type_int32(v, "tm_mon", &value.tm_mon, errp)) {
2494         goto out_end;
2495     }
2496     if (!visit_type_int32(v, "tm_mday", &value.tm_mday, errp)) {
2497         goto out_end;
2498     }
2499     if (!visit_type_int32(v, "tm_hour", &value.tm_hour, errp)) {
2500         goto out_end;
2501     }
2502     if (!visit_type_int32(v, "tm_min", &value.tm_min, errp)) {
2503         goto out_end;
2504     }
2505     if (!visit_type_int32(v, "tm_sec", &value.tm_sec, errp)) {
2506         goto out_end;
2507     }
2508     visit_check_struct(v, errp);
2509 out_end:
2510     visit_end_struct(v, NULL);
2511 }
2512 
2513 ObjectProperty *
2514 object_property_add_tm(Object *obj, const char *name,
2515                        void (*get)(Object *, struct tm *, Error **))
2516 {
2517     TMProperty *prop = g_malloc0(sizeof(*prop));
2518 
2519     prop->get = get;
2520 
2521     return object_property_add(obj, name, "struct tm",
2522                                get ? property_get_tm : NULL, NULL,
2523                                property_release_data,
2524                                prop);
2525 }
2526 
2527 ObjectProperty *
2528 object_class_property_add_tm(ObjectClass *klass, const char *name,
2529                              void (*get)(Object *, struct tm *, Error **))
2530 {
2531     TMProperty *prop = g_malloc0(sizeof(*prop));
2532 
2533     prop->get = get;
2534 
2535     return object_class_property_add(klass, name, "struct tm",
2536                                      get ? property_get_tm : NULL,
2537                                      NULL, NULL, prop);
2538 }
2539 
2540 static char *object_get_type(Object *obj, Error **errp)
2541 {
2542     return g_strdup(object_get_typename(obj));
2543 }
2544 
2545 static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name,
2546                                    void *opaque, Error **errp)
2547 {
2548     uint8_t value = *(uint8_t *)opaque;
2549     visit_type_uint8(v, name, &value, errp);
2550 }
2551 
2552 static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name,
2553                                    void *opaque, Error **errp)
2554 {
2555     uint8_t *field = opaque;
2556     uint8_t value;
2557 
2558     if (!visit_type_uint8(v, name, &value, errp)) {
2559         return;
2560     }
2561 
2562     *field = value;
2563 }
2564 
2565 static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
2566                                     void *opaque, Error **errp)
2567 {
2568     uint16_t value = *(uint16_t *)opaque;
2569     visit_type_uint16(v, name, &value, errp);
2570 }
2571 
2572 static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name,
2573                                     void *opaque, Error **errp)
2574 {
2575     uint16_t *field = opaque;
2576     uint16_t value;
2577 
2578     if (!visit_type_uint16(v, name, &value, errp)) {
2579         return;
2580     }
2581 
2582     *field = value;
2583 }
2584 
2585 static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
2586                                     void *opaque, Error **errp)
2587 {
2588     uint32_t value = *(uint32_t *)opaque;
2589     visit_type_uint32(v, name, &value, errp);
2590 }
2591 
2592 static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name,
2593                                     void *opaque, Error **errp)
2594 {
2595     uint32_t *field = opaque;
2596     uint32_t value;
2597 
2598     if (!visit_type_uint32(v, name, &value, errp)) {
2599         return;
2600     }
2601 
2602     *field = value;
2603 }
2604 
2605 static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
2606                                     void *opaque, Error **errp)
2607 {
2608     uint64_t value = *(uint64_t *)opaque;
2609     visit_type_uint64(v, name, &value, errp);
2610 }
2611 
2612 static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name,
2613                                     void *opaque, Error **errp)
2614 {
2615     uint64_t *field = opaque;
2616     uint64_t value;
2617 
2618     if (!visit_type_uint64(v, name, &value, errp)) {
2619         return;
2620     }
2621 
2622     *field = value;
2623 }
2624 
2625 ObjectProperty *
2626 object_property_add_uint8_ptr(Object *obj, const char *name,
2627                               const uint8_t *v,
2628                               ObjectPropertyFlags flags)
2629 {
2630     ObjectPropertyAccessor *getter = NULL;
2631     ObjectPropertyAccessor *setter = NULL;
2632 
2633     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2634         getter = property_get_uint8_ptr;
2635     }
2636 
2637     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2638         setter = property_set_uint8_ptr;
2639     }
2640 
2641     return object_property_add(obj, name, "uint8",
2642                                getter, setter, NULL, (void *)v);
2643 }
2644 
2645 ObjectProperty *
2646 object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
2647                                     const uint8_t *v,
2648                                     ObjectPropertyFlags flags)
2649 {
2650     ObjectPropertyAccessor *getter = NULL;
2651     ObjectPropertyAccessor *setter = NULL;
2652 
2653     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2654         getter = property_get_uint8_ptr;
2655     }
2656 
2657     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2658         setter = property_set_uint8_ptr;
2659     }
2660 
2661     return object_class_property_add(klass, name, "uint8",
2662                                      getter, setter, NULL, (void *)v);
2663 }
2664 
2665 ObjectProperty *
2666 object_property_add_uint16_ptr(Object *obj, const char *name,
2667                                const uint16_t *v,
2668                                ObjectPropertyFlags flags)
2669 {
2670     ObjectPropertyAccessor *getter = NULL;
2671     ObjectPropertyAccessor *setter = NULL;
2672 
2673     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2674         getter = property_get_uint16_ptr;
2675     }
2676 
2677     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2678         setter = property_set_uint16_ptr;
2679     }
2680 
2681     return object_property_add(obj, name, "uint16",
2682                                getter, setter, NULL, (void *)v);
2683 }
2684 
2685 ObjectProperty *
2686 object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
2687                                      const uint16_t *v,
2688                                      ObjectPropertyFlags flags)
2689 {
2690     ObjectPropertyAccessor *getter = NULL;
2691     ObjectPropertyAccessor *setter = NULL;
2692 
2693     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2694         getter = property_get_uint16_ptr;
2695     }
2696 
2697     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2698         setter = property_set_uint16_ptr;
2699     }
2700 
2701     return object_class_property_add(klass, name, "uint16",
2702                                      getter, setter, NULL, (void *)v);
2703 }
2704 
2705 ObjectProperty *
2706 object_property_add_uint32_ptr(Object *obj, const char *name,
2707                                const uint32_t *v,
2708                                ObjectPropertyFlags flags)
2709 {
2710     ObjectPropertyAccessor *getter = NULL;
2711     ObjectPropertyAccessor *setter = NULL;
2712 
2713     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2714         getter = property_get_uint32_ptr;
2715     }
2716 
2717     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2718         setter = property_set_uint32_ptr;
2719     }
2720 
2721     return object_property_add(obj, name, "uint32",
2722                                getter, setter, NULL, (void *)v);
2723 }
2724 
2725 ObjectProperty *
2726 object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
2727                                      const uint32_t *v,
2728                                      ObjectPropertyFlags flags)
2729 {
2730     ObjectPropertyAccessor *getter = NULL;
2731     ObjectPropertyAccessor *setter = NULL;
2732 
2733     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2734         getter = property_get_uint32_ptr;
2735     }
2736 
2737     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2738         setter = property_set_uint32_ptr;
2739     }
2740 
2741     return object_class_property_add(klass, name, "uint32",
2742                                      getter, setter, NULL, (void *)v);
2743 }
2744 
2745 ObjectProperty *
2746 object_property_add_uint64_ptr(Object *obj, const char *name,
2747                                const uint64_t *v,
2748                                ObjectPropertyFlags flags)
2749 {
2750     ObjectPropertyAccessor *getter = NULL;
2751     ObjectPropertyAccessor *setter = NULL;
2752 
2753     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2754         getter = property_get_uint64_ptr;
2755     }
2756 
2757     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2758         setter = property_set_uint64_ptr;
2759     }
2760 
2761     return object_property_add(obj, name, "uint64",
2762                                getter, setter, NULL, (void *)v);
2763 }
2764 
2765 ObjectProperty *
2766 object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
2767                                      const uint64_t *v,
2768                                      ObjectPropertyFlags flags)
2769 {
2770     ObjectPropertyAccessor *getter = NULL;
2771     ObjectPropertyAccessor *setter = NULL;
2772 
2773     if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2774         getter = property_get_uint64_ptr;
2775     }
2776 
2777     if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2778         setter = property_set_uint64_ptr;
2779     }
2780 
2781     return object_class_property_add(klass, name, "uint64",
2782                                      getter, setter, NULL, (void *)v);
2783 }
2784 
2785 typedef struct {
2786     Object *target_obj;
2787     char *target_name;
2788 } AliasProperty;
2789 
2790 static void property_get_alias(Object *obj, Visitor *v, const char *name,
2791                                void *opaque, Error **errp)
2792 {
2793     AliasProperty *prop = opaque;
2794     Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
2795 
2796     object_property_get(prop->target_obj, prop->target_name, alias_v, errp);
2797     visit_free(alias_v);
2798 }
2799 
2800 static void property_set_alias(Object *obj, Visitor *v, const char *name,
2801                                void *opaque, Error **errp)
2802 {
2803     AliasProperty *prop = opaque;
2804     Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
2805 
2806     object_property_set(prop->target_obj, prop->target_name, alias_v, errp);
2807     visit_free(alias_v);
2808 }
2809 
2810 static Object *property_resolve_alias(Object *obj, void *opaque,
2811                                       const char *part)
2812 {
2813     AliasProperty *prop = opaque;
2814 
2815     return object_resolve_path_component(prop->target_obj, prop->target_name);
2816 }
2817 
2818 static void property_release_alias(Object *obj, const char *name, void *opaque)
2819 {
2820     AliasProperty *prop = opaque;
2821 
2822     g_free(prop->target_name);
2823     g_free(prop);
2824 }
2825 
2826 ObjectProperty *
2827 object_property_add_alias(Object *obj, const char *name,
2828                           Object *target_obj, const char *target_name)
2829 {
2830     AliasProperty *prop;
2831     ObjectProperty *op;
2832     ObjectProperty *target_prop;
2833     g_autofree char *prop_type = NULL;
2834 
2835     target_prop = object_property_find_err(target_obj, target_name,
2836                                            &error_abort);
2837 
2838     if (object_property_is_child(target_prop)) {
2839         prop_type = g_strdup_printf("link%s",
2840                                     target_prop->type + strlen("child"));
2841     } else {
2842         prop_type = g_strdup(target_prop->type);
2843     }
2844 
2845     prop = g_malloc(sizeof(*prop));
2846     prop->target_obj = target_obj;
2847     prop->target_name = g_strdup(target_name);
2848 
2849     op = object_property_add(obj, name, prop_type,
2850                              property_get_alias,
2851                              property_set_alias,
2852                              property_release_alias,
2853                              prop);
2854     op->resolve = property_resolve_alias;
2855     if (target_prop->defval) {
2856         op->defval = qobject_ref(target_prop->defval);
2857     }
2858 
2859     object_property_set_description(obj, op->name,
2860                                     target_prop->description);
2861     return op;
2862 }
2863 
2864 void object_property_set_description(Object *obj, const char *name,
2865                                      const char *description)
2866 {
2867     ObjectProperty *op;
2868 
2869     op = object_property_find_err(obj, name, &error_abort);
2870     g_free(op->description);
2871     op->description = g_strdup(description);
2872 }
2873 
2874 void object_class_property_set_description(ObjectClass *klass,
2875                                            const char *name,
2876                                            const char *description)
2877 {
2878     ObjectProperty *op;
2879 
2880     op = g_hash_table_lookup(klass->properties, name);
2881     g_free(op->description);
2882     op->description = g_strdup(description);
2883 }
2884 
2885 static void object_class_init(ObjectClass *klass, void *data)
2886 {
2887     object_class_property_add_str(klass, "type", object_get_type,
2888                                   NULL);
2889 }
2890 
2891 static void register_types(void)
2892 {
2893     static const TypeInfo interface_info = {
2894         .name = TYPE_INTERFACE,
2895         .class_size = sizeof(InterfaceClass),
2896         .abstract = true,
2897     };
2898 
2899     static const TypeInfo object_info = {
2900         .name = TYPE_OBJECT,
2901         .instance_size = sizeof(Object),
2902         .class_init = object_class_init,
2903         .abstract = true,
2904     };
2905 
2906     type_interface = type_register_internal(&interface_info);
2907     type_register_internal(&object_info);
2908 }
2909 
2910 type_init(register_types)
2911