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