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