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