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