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