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