xref: /openbmc/qemu/qom/object.c (revision 54aa3de72ea2aaa2e903e7e879a4f3dda515a00e)
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      char *retval;
1419  
1420      if (!ret) {
1421          return NULL;
1422      }
1423  
1424      retval = g_strdup(qobject_get_try_str(ret));
1425      if (!retval) {
1426          error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
1427      }
1428  
1429      qobject_unref(ret);
1430      return retval;
1431  }
1432  
1433  bool object_property_set_link(Object *obj, const char *name,
1434                                Object *value, Error **errp)
1435  {
1436      g_autofree char *path = NULL;
1437  
1438      if (value) {
1439          path = object_get_canonical_path(value);
1440      }
1441      return object_property_set_str(obj, name, path ?: "", errp);
1442  }
1443  
1444  Object *object_property_get_link(Object *obj, const char *name,
1445                                   Error **errp)
1446  {
1447      char *str = object_property_get_str(obj, name, errp);
1448      Object *target = NULL;
1449  
1450      if (str && *str) {
1451          target = object_resolve_path(str, NULL);
1452          if (!target) {
1453              error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1454                        "Device '%s' not found", str);
1455          }
1456      }
1457  
1458      g_free(str);
1459      return target;
1460  }
1461  
1462  bool object_property_set_bool(Object *obj, const char *name,
1463                                bool value, Error **errp)
1464  {
1465      QBool *qbool = qbool_from_bool(value);
1466      bool ok = object_property_set_qobject(obj, name, QOBJECT(qbool), errp);
1467  
1468      qobject_unref(qbool);
1469      return ok;
1470  }
1471  
1472  bool object_property_get_bool(Object *obj, const char *name,
1473                                Error **errp)
1474  {
1475      QObject *ret = object_property_get_qobject(obj, name, errp);
1476      QBool *qbool;
1477      bool retval;
1478  
1479      if (!ret) {
1480          return false;
1481      }
1482      qbool = qobject_to(QBool, ret);
1483      if (!qbool) {
1484          error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
1485          retval = false;
1486      } else {
1487          retval = qbool_get_bool(qbool);
1488      }
1489  
1490      qobject_unref(ret);
1491      return retval;
1492  }
1493  
1494  bool object_property_set_int(Object *obj, const char *name,
1495                               int64_t value, Error **errp)
1496  {
1497      QNum *qnum = qnum_from_int(value);
1498      bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
1499  
1500      qobject_unref(qnum);
1501      return ok;
1502  }
1503  
1504  int64_t object_property_get_int(Object *obj, const char *name,
1505                                  Error **errp)
1506  {
1507      QObject *ret = object_property_get_qobject(obj, name, errp);
1508      QNum *qnum;
1509      int64_t retval;
1510  
1511      if (!ret) {
1512          return -1;
1513      }
1514  
1515      qnum = qobject_to(QNum, ret);
1516      if (!qnum || !qnum_get_try_int(qnum, &retval)) {
1517          error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
1518          retval = -1;
1519      }
1520  
1521      qobject_unref(ret);
1522      return retval;
1523  }
1524  
1525  static void object_property_init_defval(Object *obj, ObjectProperty *prop)
1526  {
1527      Visitor *v = qobject_input_visitor_new(prop->defval);
1528  
1529      assert(prop->set != NULL);
1530      prop->set(obj, v, prop->name, prop->opaque, &error_abort);
1531  
1532      visit_free(v);
1533  }
1534  
1535  static void object_property_set_default(ObjectProperty *prop, QObject *defval)
1536  {
1537      assert(!prop->defval);
1538      assert(!prop->init);
1539  
1540      prop->defval = defval;
1541      prop->init = object_property_init_defval;
1542  }
1543  
1544  void object_property_set_default_bool(ObjectProperty *prop, bool value)
1545  {
1546      object_property_set_default(prop, QOBJECT(qbool_from_bool(value)));
1547  }
1548  
1549  void object_property_set_default_str(ObjectProperty *prop, const char *value)
1550  {
1551      object_property_set_default(prop, QOBJECT(qstring_from_str(value)));
1552  }
1553  
1554  void object_property_set_default_int(ObjectProperty *prop, int64_t value)
1555  {
1556      object_property_set_default(prop, QOBJECT(qnum_from_int(value)));
1557  }
1558  
1559  void object_property_set_default_uint(ObjectProperty *prop, uint64_t value)
1560  {
1561      object_property_set_default(prop, QOBJECT(qnum_from_uint(value)));
1562  }
1563  
1564  bool object_property_set_uint(Object *obj, const char *name,
1565                                uint64_t value, Error **errp)
1566  {
1567      QNum *qnum = qnum_from_uint(value);
1568      bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
1569  
1570      qobject_unref(qnum);
1571      return ok;
1572  }
1573  
1574  uint64_t object_property_get_uint(Object *obj, const char *name,
1575                                    Error **errp)
1576  {
1577      QObject *ret = object_property_get_qobject(obj, name, errp);
1578      QNum *qnum;
1579      uint64_t retval;
1580  
1581      if (!ret) {
1582          return 0;
1583      }
1584      qnum = qobject_to(QNum, ret);
1585      if (!qnum || !qnum_get_try_uint(qnum, &retval)) {
1586          error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
1587          retval = 0;
1588      }
1589  
1590      qobject_unref(ret);
1591      return retval;
1592  }
1593  
1594  typedef struct EnumProperty {
1595      const QEnumLookup *lookup;
1596      int (*get)(Object *, Error **);
1597      void (*set)(Object *, int, Error **);
1598  } EnumProperty;
1599  
1600  int object_property_get_enum(Object *obj, const char *name,
1601                               const char *typename, Error **errp)
1602  {
1603      char *str;
1604      int ret;
1605      ObjectProperty *prop = object_property_find_err(obj, name, errp);
1606      EnumProperty *enumprop;
1607  
1608      if (prop == NULL) {
1609          return -1;
1610      }
1611  
1612      if (!g_str_equal(prop->type, typename)) {
1613          error_setg(errp, "Property %s on %s is not '%s' enum type",
1614                     name, object_class_get_name(
1615                         object_get_class(obj)), typename);
1616          return -1;
1617      }
1618  
1619      enumprop = prop->opaque;
1620  
1621      str = object_property_get_str(obj, name, errp);
1622      if (!str) {
1623          return -1;
1624      }
1625  
1626      ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
1627      g_free(str);
1628  
1629      return ret;
1630  }
1631  
1632  bool object_property_parse(Object *obj, const char *name,
1633                             const char *string, Error **errp)
1634  {
1635      Visitor *v = string_input_visitor_new(string);
1636      bool ok = object_property_set(obj, name, v, errp);
1637  
1638      visit_free(v);
1639      return ok;
1640  }
1641  
1642  char *object_property_print(Object *obj, const char *name, bool human,
1643                              Error **errp)
1644  {
1645      Visitor *v;
1646      char *string = NULL;
1647  
1648      v = string_output_visitor_new(human, &string);
1649      if (!object_property_get(obj, name, v, errp)) {
1650          goto out;
1651      }
1652  
1653      visit_complete(v, &string);
1654  
1655  out:
1656      visit_free(v);
1657      return string;
1658  }
1659  
1660  const char *object_property_get_type(Object *obj, const char *name, Error **errp)
1661  {
1662      ObjectProperty *prop = object_property_find_err(obj, name, errp);
1663      if (prop == NULL) {
1664          return NULL;
1665      }
1666  
1667      return prop->type;
1668  }
1669  
1670  Object *object_get_root(void)
1671  {
1672      static Object *root;
1673  
1674      if (!root) {
1675          root = object_new("container");
1676      }
1677  
1678      return root;
1679  }
1680  
1681  Object *object_get_objects_root(void)
1682  {
1683      return container_get(object_get_root(), "/objects");
1684  }
1685  
1686  Object *object_get_internal_root(void)
1687  {
1688      static Object *internal_root;
1689  
1690      if (!internal_root) {
1691          internal_root = object_new("container");
1692      }
1693  
1694      return internal_root;
1695  }
1696  
1697  static void object_get_child_property(Object *obj, Visitor *v,
1698                                        const char *name, void *opaque,
1699                                        Error **errp)
1700  {
1701      Object *child = opaque;
1702      char *path;
1703  
1704      path = object_get_canonical_path(child);
1705      visit_type_str(v, name, &path, errp);
1706      g_free(path);
1707  }
1708  
1709  static Object *object_resolve_child_property(Object *parent, void *opaque,
1710                                               const char *part)
1711  {
1712      return opaque;
1713  }
1714  
1715  static void object_finalize_child_property(Object *obj, const char *name,
1716                                             void *opaque)
1717  {
1718      Object *child = opaque;
1719  
1720      if (child->class->unparent) {
1721          (child->class->unparent)(child);
1722      }
1723      child->parent = NULL;
1724      object_unref(child);
1725  }
1726  
1727  ObjectProperty *
1728  object_property_try_add_child(Object *obj, const char *name,
1729                                Object *child, Error **errp)
1730  {
1731      g_autofree char *type = NULL;
1732      ObjectProperty *op;
1733  
1734      assert(!child->parent);
1735  
1736      type = g_strdup_printf("child<%s>", object_get_typename(child));
1737  
1738      op = object_property_try_add(obj, name, type, object_get_child_property,
1739                                   NULL, object_finalize_child_property,
1740                                   child, errp);
1741      if (!op) {
1742          return NULL;
1743      }
1744      op->resolve = object_resolve_child_property;
1745      object_ref(child);
1746      child->parent = obj;
1747      return op;
1748  }
1749  
1750  ObjectProperty *
1751  object_property_add_child(Object *obj, const char *name,
1752                            Object *child)
1753  {
1754      return object_property_try_add_child(obj, name, child, &error_abort);
1755  }
1756  
1757  void object_property_allow_set_link(const Object *obj, const char *name,
1758                                      Object *val, Error **errp)
1759  {
1760      /* Allow the link to be set, always */
1761  }
1762  
1763  typedef struct {
1764      union {
1765          Object **targetp;
1766          Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer  */
1767          ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */
1768      };
1769      void (*check)(const Object *, const char *, Object *, Error **);
1770      ObjectPropertyLinkFlags flags;
1771  } LinkProperty;
1772  
1773  static Object **
1774  object_link_get_targetp(Object *obj, LinkProperty *lprop)
1775  {
1776      if (lprop->flags & OBJ_PROP_LINK_DIRECT) {
1777          return &lprop->target;
1778      } else if (lprop->flags & OBJ_PROP_LINK_CLASS) {
1779          return (void *)obj + lprop->offset;
1780      } else {
1781          return lprop->targetp;
1782      }
1783  }
1784  
1785  static void object_get_link_property(Object *obj, Visitor *v,
1786                                       const char *name, void *opaque,
1787                                       Error **errp)
1788  {
1789      LinkProperty *lprop = opaque;
1790      Object **targetp = object_link_get_targetp(obj, lprop);
1791      char *path;
1792  
1793      if (*targetp) {
1794          path = object_get_canonical_path(*targetp);
1795          visit_type_str(v, name, &path, errp);
1796          g_free(path);
1797      } else {
1798          path = (char *)"";
1799          visit_type_str(v, name, &path, errp);
1800      }
1801  }
1802  
1803  /*
1804   * object_resolve_link:
1805   *
1806   * Lookup an object and ensure its type matches the link property type.  This
1807   * is similar to object_resolve_path() except type verification against the
1808   * link property is performed.
1809   *
1810   * Returns: The matched object or NULL on path lookup failures.
1811   */
1812  static Object *object_resolve_link(Object *obj, const char *name,
1813                                     const char *path, Error **errp)
1814  {
1815      const char *type;
1816      char *target_type;
1817      bool ambiguous = false;
1818      Object *target;
1819  
1820      /* Go from link<FOO> to FOO.  */
1821      type = object_property_get_type(obj, name, NULL);
1822      target_type = g_strndup(&type[5], strlen(type) - 6);
1823      target = object_resolve_path_type(path, target_type, &ambiguous);
1824  
1825      if (ambiguous) {
1826          error_setg(errp, "Path '%s' does not uniquely identify an object",
1827                     path);
1828      } else if (!target) {
1829          target = object_resolve_path(path, &ambiguous);
1830          if (target || ambiguous) {
1831              error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
1832          } else {
1833              error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1834                        "Device '%s' not found", path);
1835          }
1836          target = NULL;
1837      }
1838      g_free(target_type);
1839  
1840      return target;
1841  }
1842  
1843  static void object_set_link_property(Object *obj, Visitor *v,
1844                                       const char *name, void *opaque,
1845                                       Error **errp)
1846  {
1847      Error *local_err = NULL;
1848      LinkProperty *prop = opaque;
1849      Object **targetp = object_link_get_targetp(obj, prop);
1850      Object *old_target = *targetp;
1851      Object *new_target;
1852      char *path = NULL;
1853  
1854      if (!visit_type_str(v, name, &path, errp)) {
1855          return;
1856      }
1857  
1858      if (*path) {
1859          new_target = object_resolve_link(obj, name, path, errp);
1860          if (!new_target) {
1861              g_free(path);
1862              return;
1863          }
1864      } else {
1865          new_target = NULL;
1866      }
1867  
1868      g_free(path);
1869  
1870      prop->check(obj, name, new_target, &local_err);
1871      if (local_err) {
1872          error_propagate(errp, local_err);
1873          return;
1874      }
1875  
1876      *targetp = new_target;
1877      if (prop->flags & OBJ_PROP_LINK_STRONG) {
1878          object_ref(new_target);
1879          object_unref(old_target);
1880      }
1881  }
1882  
1883  static Object *object_resolve_link_property(Object *parent, void *opaque,
1884                                              const char *part)
1885  {
1886      LinkProperty *lprop = opaque;
1887  
1888      return *object_link_get_targetp(parent, lprop);
1889  }
1890  
1891  static void object_release_link_property(Object *obj, const char *name,
1892                                           void *opaque)
1893  {
1894      LinkProperty *prop = opaque;
1895      Object **targetp = object_link_get_targetp(obj, prop);
1896  
1897      if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) {
1898          object_unref(*targetp);
1899      }
1900      if (!(prop->flags & OBJ_PROP_LINK_CLASS)) {
1901          g_free(prop);
1902      }
1903  }
1904  
1905  static ObjectProperty *
1906  object_add_link_prop(Object *obj, const char *name,
1907                       const char *type, void *ptr,
1908                       void (*check)(const Object *, const char *,
1909                                     Object *, Error **),
1910                       ObjectPropertyLinkFlags flags)
1911  {
1912      LinkProperty *prop = g_malloc(sizeof(*prop));
1913      g_autofree char *full_type = NULL;
1914      ObjectProperty *op;
1915  
1916      if (flags & OBJ_PROP_LINK_DIRECT) {
1917          prop->target = ptr;
1918      } else {
1919          prop->targetp = ptr;
1920      }
1921      prop->check = check;
1922      prop->flags = flags;
1923  
1924      full_type = g_strdup_printf("link<%s>", type);
1925  
1926      op = object_property_add(obj, name, full_type,
1927                               object_get_link_property,
1928                               check ? object_set_link_property : NULL,
1929                               object_release_link_property,
1930                               prop);
1931      op->resolve = object_resolve_link_property;
1932      return op;
1933  }
1934  
1935  ObjectProperty *
1936  object_property_add_link(Object *obj, const char *name,
1937                           const char *type, Object **targetp,
1938                           void (*check)(const Object *, const char *,
1939                                         Object *, Error **),
1940                           ObjectPropertyLinkFlags flags)
1941  {
1942      return object_add_link_prop(obj, name, type, targetp, check, flags);
1943  }
1944  
1945  ObjectProperty *
1946  object_class_property_add_link(ObjectClass *oc,
1947      const char *name,
1948      const char *type, ptrdiff_t offset,
1949      void (*check)(const Object *obj, const char *name,
1950                    Object *val, Error **errp),
1951      ObjectPropertyLinkFlags flags)
1952  {
1953      LinkProperty *prop = g_new0(LinkProperty, 1);
1954      char *full_type;
1955      ObjectProperty *op;
1956  
1957      prop->offset = offset;
1958      prop->check = check;
1959      prop->flags = flags | OBJ_PROP_LINK_CLASS;
1960  
1961      full_type = g_strdup_printf("link<%s>", type);
1962  
1963      op = object_class_property_add(oc, name, full_type,
1964                                     object_get_link_property,
1965                                     check ? object_set_link_property : NULL,
1966                                     object_release_link_property,
1967                                     prop);
1968  
1969      op->resolve = object_resolve_link_property;
1970  
1971      g_free(full_type);
1972      return op;
1973  }
1974  
1975  ObjectProperty *
1976  object_property_add_const_link(Object *obj, const char *name,
1977                                 Object *target)
1978  {
1979      return object_add_link_prop(obj, name,
1980                                  object_get_typename(target), target,
1981                                  NULL, OBJ_PROP_LINK_DIRECT);
1982  }
1983  
1984  const char *object_get_canonical_path_component(const Object *obj)
1985  {
1986      ObjectProperty *prop = NULL;
1987      GHashTableIter iter;
1988  
1989      if (obj->parent == NULL) {
1990          return NULL;
1991      }
1992  
1993      g_hash_table_iter_init(&iter, obj->parent->properties);
1994      while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1995          if (!object_property_is_child(prop)) {
1996              continue;
1997          }
1998  
1999          if (prop->opaque == obj) {
2000              return prop->name;
2001          }
2002      }
2003  
2004      /* obj had a parent but was not a child, should never happen */
2005      g_assert_not_reached();
2006      return NULL;
2007  }
2008  
2009  char *object_get_canonical_path(const Object *obj)
2010  {
2011      Object *root = object_get_root();
2012      char *newpath, *path = NULL;
2013  
2014      if (obj == root) {
2015          return g_strdup("/");
2016      }
2017  
2018      do {
2019          const char *component = object_get_canonical_path_component(obj);
2020  
2021          if (!component) {
2022              /* A canonical path must be complete, so discard what was
2023               * collected so far.
2024               */
2025              g_free(path);
2026              return NULL;
2027          }
2028  
2029          newpath = g_strdup_printf("/%s%s", component, path ? path : "");
2030          g_free(path);
2031          path = newpath;
2032          obj = obj->parent;
2033      } while (obj != root);
2034  
2035      return path;
2036  }
2037  
2038  Object *object_resolve_path_component(Object *parent, const char *part)
2039  {
2040      ObjectProperty *prop = object_property_find(parent, part);
2041      if (prop == NULL) {
2042          return NULL;
2043      }
2044  
2045      if (prop->resolve) {
2046          return prop->resolve(parent, prop->opaque, part);
2047      } else {
2048          return NULL;
2049      }
2050  }
2051  
2052  static Object *object_resolve_abs_path(Object *parent,
2053                                            char **parts,
2054                                            const char *typename)
2055  {
2056      Object *child;
2057  
2058      if (*parts == NULL) {
2059          return object_dynamic_cast(parent, typename);
2060      }
2061  
2062      if (strcmp(*parts, "") == 0) {
2063          return object_resolve_abs_path(parent, parts + 1, typename);
2064      }
2065  
2066      child = object_resolve_path_component(parent, *parts);
2067      if (!child) {
2068          return NULL;
2069      }
2070  
2071      return object_resolve_abs_path(child, parts + 1, typename);
2072  }
2073  
2074  static Object *object_resolve_partial_path(Object *parent,
2075                                             char **parts,
2076                                             const char *typename,
2077                                             bool *ambiguous)
2078  {
2079      Object *obj;
2080      GHashTableIter iter;
2081      ObjectProperty *prop;
2082  
2083      obj = object_resolve_abs_path(parent, parts, typename);
2084  
2085      g_hash_table_iter_init(&iter, parent->properties);
2086      while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
2087          Object *found;
2088  
2089          if (!object_property_is_child(prop)) {
2090              continue;
2091          }
2092  
2093          found = object_resolve_partial_path(prop->opaque, parts,
2094                                              typename, ambiguous);
2095          if (found) {
2096              if (obj) {
2097                  *ambiguous = true;
2098                  return NULL;
2099              }
2100              obj = found;
2101          }
2102  
2103          if (*ambiguous) {
2104              return NULL;
2105          }
2106      }
2107  
2108      return obj;
2109  }
2110  
2111  Object *object_resolve_path_type(const char *path, const char *typename,
2112                                   bool *ambiguousp)
2113  {
2114      Object *obj;
2115      char **parts;
2116  
2117      parts = g_strsplit(path, "/", 0);
2118      assert(parts);
2119  
2120      if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
2121          bool ambiguous = false;
2122          obj = object_resolve_partial_path(object_get_root(), parts,
2123                                            typename, &ambiguous);
2124          if (ambiguousp) {
2125              *ambiguousp = ambiguous;
2126          }
2127      } else {
2128          obj = object_resolve_abs_path(object_get_root(), parts + 1, typename);
2129      }
2130  
2131      g_strfreev(parts);
2132  
2133      return obj;
2134  }
2135  
2136  Object *object_resolve_path(const char *path, bool *ambiguous)
2137  {
2138      return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
2139  }
2140  
2141  typedef struct StringProperty
2142  {
2143      char *(*get)(Object *, Error **);
2144      void (*set)(Object *, const char *, Error **);
2145  } StringProperty;
2146  
2147  static void property_get_str(Object *obj, Visitor *v, const char *name,
2148                               void *opaque, Error **errp)
2149  {
2150      StringProperty *prop = opaque;
2151      char *value;
2152      Error *err = NULL;
2153  
2154      value = prop->get(obj, &err);
2155      if (err) {
2156          error_propagate(errp, err);
2157          return;
2158      }
2159  
2160      visit_type_str(v, name, &value, errp);
2161      g_free(value);
2162  }
2163  
2164  static void property_set_str(Object *obj, Visitor *v, const char *name,
2165                               void *opaque, Error **errp)
2166  {
2167      StringProperty *prop = opaque;
2168      char *value;
2169  
2170      if (!visit_type_str(v, name, &value, errp)) {
2171          return;
2172      }
2173  
2174      prop->set(obj, value, errp);
2175      g_free(value);
2176  }
2177  
2178  static void property_release_data(Object *obj, const char *name,
2179                                    void *opaque)
2180  {
2181      g_free(opaque);
2182  }
2183  
2184  ObjectProperty *
2185  object_property_add_str(Object *obj, const char *name,
2186                          char *(*get)(Object *, Error **),
2187                          void (*set)(Object *, const char *, Error **))
2188  {
2189      StringProperty *prop = g_malloc0(sizeof(*prop));
2190  
2191      prop->get = get;
2192      prop->set = set;
2193  
2194      return object_property_add(obj, name, "string",
2195                                 get ? property_get_str : NULL,
2196                                 set ? property_set_str : NULL,
2197                                 property_release_data,
2198                                 prop);
2199  }
2200  
2201  ObjectProperty *
2202  object_class_property_add_str(ObjectClass *klass, const char *name,
2203                                     char *(*get)(Object *, Error **),
2204                                     void (*set)(Object *, const char *,
2205                                                 Error **))
2206  {
2207      StringProperty *prop = g_malloc0(sizeof(*prop));
2208  
2209      prop->get = get;
2210      prop->set = set;
2211  
2212      return object_class_property_add(klass, name, "string",
2213                                       get ? property_get_str : NULL,
2214                                       set ? property_set_str : NULL,
2215                                       NULL,
2216                                       prop);
2217  }
2218  
2219  typedef struct BoolProperty
2220  {
2221      bool (*get)(Object *, Error **);
2222      void (*set)(Object *, bool, Error **);
2223  } BoolProperty;
2224  
2225  static void property_get_bool(Object *obj, Visitor *v, const char *name,
2226                                void *opaque, Error **errp)
2227  {
2228      BoolProperty *prop = opaque;
2229      bool value;
2230      Error *err = NULL;
2231  
2232      value = prop->get(obj, &err);
2233      if (err) {
2234          error_propagate(errp, err);
2235          return;
2236      }
2237  
2238      visit_type_bool(v, name, &value, errp);
2239  }
2240  
2241  static void property_set_bool(Object *obj, Visitor *v, const char *name,
2242                                void *opaque, Error **errp)
2243  {
2244      BoolProperty *prop = opaque;
2245      bool value;
2246  
2247      if (!visit_type_bool(v, name, &value, errp)) {
2248          return;
2249      }
2250  
2251      prop->set(obj, value, errp);
2252  }
2253  
2254  ObjectProperty *
2255  object_property_add_bool(Object *obj, const char *name,
2256                           bool (*get)(Object *, Error **),
2257                           void (*set)(Object *, bool, Error **))
2258  {
2259      BoolProperty *prop = g_malloc0(sizeof(*prop));
2260  
2261      prop->get = get;
2262      prop->set = set;
2263  
2264      return object_property_add(obj, name, "bool",
2265                                 get ? property_get_bool : NULL,
2266                                 set ? property_set_bool : NULL,
2267                                 property_release_data,
2268                                 prop);
2269  }
2270  
2271  ObjectProperty *
2272  object_class_property_add_bool(ObjectClass *klass, const char *name,
2273                                      bool (*get)(Object *, Error **),
2274                                      void (*set)(Object *, bool, Error **))
2275  {
2276      BoolProperty *prop = g_malloc0(sizeof(*prop));
2277  
2278      prop->get = get;
2279      prop->set = set;
2280  
2281      return object_class_property_add(klass, name, "bool",
2282                                       get ? property_get_bool : NULL,
2283                                       set ? property_set_bool : NULL,
2284                                       NULL,
2285                                       prop);
2286  }
2287  
2288  static void property_get_enum(Object *obj, Visitor *v, const char *name,
2289                                void *opaque, Error **errp)
2290  {
2291      EnumProperty *prop = opaque;
2292      int value;
2293      Error *err = NULL;
2294  
2295      value = prop->get(obj, &err);
2296      if (err) {
2297          error_propagate(errp, err);
2298          return;
2299      }
2300  
2301      visit_type_enum(v, name, &value, prop->lookup, errp);
2302  }
2303  
2304  static void property_set_enum(Object *obj, Visitor *v, const char *name,
2305                                void *opaque, Error **errp)
2306  {
2307      EnumProperty *prop = opaque;
2308      int value;
2309  
2310      if (!visit_type_enum(v, name, &value, prop->lookup, errp)) {
2311          return;
2312      }
2313      prop->set(obj, value, errp);
2314  }
2315  
2316  ObjectProperty *
2317  object_property_add_enum(Object *obj, const char *name,
2318                           const char *typename,
2319                           const QEnumLookup *lookup,
2320                           int (*get)(Object *, Error **),
2321                           void (*set)(Object *, int, Error **))
2322  {
2323      EnumProperty *prop = g_malloc(sizeof(*prop));
2324  
2325      prop->lookup = lookup;
2326      prop->get = get;
2327      prop->set = set;
2328  
2329      return object_property_add(obj, name, typename,
2330                                 get ? property_get_enum : NULL,
2331                                 set ? property_set_enum : NULL,
2332                                 property_release_data,
2333                                 prop);
2334  }
2335  
2336  ObjectProperty *
2337  object_class_property_add_enum(ObjectClass *klass, const char *name,
2338                                      const char *typename,
2339                                      const QEnumLookup *lookup,
2340                                      int (*get)(Object *, Error **),
2341                                      void (*set)(Object *, int, Error **))
2342  {
2343      EnumProperty *prop = g_malloc(sizeof(*prop));
2344  
2345      prop->lookup = lookup;
2346      prop->get = get;
2347      prop->set = set;
2348  
2349      return object_class_property_add(klass, name, typename,
2350                                       get ? property_get_enum : NULL,
2351                                       set ? property_set_enum : NULL,
2352                                       NULL,
2353                                       prop);
2354  }
2355  
2356  typedef struct TMProperty {
2357      void (*get)(Object *, struct tm *, Error **);
2358  } TMProperty;
2359  
2360  static void property_get_tm(Object *obj, Visitor *v, const char *name,
2361                              void *opaque, Error **errp)
2362  {
2363      TMProperty *prop = opaque;
2364      Error *err = NULL;
2365      struct tm value;
2366  
2367      prop->get(obj, &value, &err);
2368      if (err) {
2369          error_propagate(errp, err);
2370          return;
2371      }
2372  
2373      if (!visit_start_struct(v, name, NULL, 0, errp)) {
2374          return;
2375      }
2376      if (!visit_type_int32(v, "tm_year", &value.tm_year, errp)) {
2377          goto out_end;
2378      }
2379      if (!visit_type_int32(v, "tm_mon", &value.tm_mon, errp)) {
2380          goto out_end;
2381      }
2382      if (!visit_type_int32(v, "tm_mday", &value.tm_mday, errp)) {
2383          goto out_end;
2384      }
2385      if (!visit_type_int32(v, "tm_hour", &value.tm_hour, errp)) {
2386          goto out_end;
2387      }
2388      if (!visit_type_int32(v, "tm_min", &value.tm_min, errp)) {
2389          goto out_end;
2390      }
2391      if (!visit_type_int32(v, "tm_sec", &value.tm_sec, errp)) {
2392          goto out_end;
2393      }
2394      visit_check_struct(v, errp);
2395  out_end:
2396      visit_end_struct(v, NULL);
2397  }
2398  
2399  ObjectProperty *
2400  object_property_add_tm(Object *obj, const char *name,
2401                         void (*get)(Object *, struct tm *, Error **))
2402  {
2403      TMProperty *prop = g_malloc0(sizeof(*prop));
2404  
2405      prop->get = get;
2406  
2407      return object_property_add(obj, name, "struct tm",
2408                                 get ? property_get_tm : NULL, NULL,
2409                                 property_release_data,
2410                                 prop);
2411  }
2412  
2413  ObjectProperty *
2414  object_class_property_add_tm(ObjectClass *klass, const char *name,
2415                               void (*get)(Object *, struct tm *, Error **))
2416  {
2417      TMProperty *prop = g_malloc0(sizeof(*prop));
2418  
2419      prop->get = get;
2420  
2421      return object_class_property_add(klass, name, "struct tm",
2422                                       get ? property_get_tm : NULL,
2423                                       NULL, NULL, prop);
2424  }
2425  
2426  static char *object_get_type(Object *obj, Error **errp)
2427  {
2428      return g_strdup(object_get_typename(obj));
2429  }
2430  
2431  static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name,
2432                                     void *opaque, Error **errp)
2433  {
2434      uint8_t value = *(uint8_t *)opaque;
2435      visit_type_uint8(v, name, &value, errp);
2436  }
2437  
2438  static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name,
2439                                     void *opaque, Error **errp)
2440  {
2441      uint8_t *field = opaque;
2442      uint8_t value;
2443  
2444      if (!visit_type_uint8(v, name, &value, errp)) {
2445          return;
2446      }
2447  
2448      *field = value;
2449  }
2450  
2451  static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
2452                                      void *opaque, Error **errp)
2453  {
2454      uint16_t value = *(uint16_t *)opaque;
2455      visit_type_uint16(v, name, &value, errp);
2456  }
2457  
2458  static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name,
2459                                      void *opaque, Error **errp)
2460  {
2461      uint16_t *field = opaque;
2462      uint16_t value;
2463  
2464      if (!visit_type_uint16(v, name, &value, errp)) {
2465          return;
2466      }
2467  
2468      *field = value;
2469  }
2470  
2471  static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
2472                                      void *opaque, Error **errp)
2473  {
2474      uint32_t value = *(uint32_t *)opaque;
2475      visit_type_uint32(v, name, &value, errp);
2476  }
2477  
2478  static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name,
2479                                      void *opaque, Error **errp)
2480  {
2481      uint32_t *field = opaque;
2482      uint32_t value;
2483  
2484      if (!visit_type_uint32(v, name, &value, errp)) {
2485          return;
2486      }
2487  
2488      *field = value;
2489  }
2490  
2491  static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
2492                                      void *opaque, Error **errp)
2493  {
2494      uint64_t value = *(uint64_t *)opaque;
2495      visit_type_uint64(v, name, &value, errp);
2496  }
2497  
2498  static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name,
2499                                      void *opaque, Error **errp)
2500  {
2501      uint64_t *field = opaque;
2502      uint64_t value;
2503  
2504      if (!visit_type_uint64(v, name, &value, errp)) {
2505          return;
2506      }
2507  
2508      *field = value;
2509  }
2510  
2511  ObjectProperty *
2512  object_property_add_uint8_ptr(Object *obj, const char *name,
2513                                const uint8_t *v,
2514                                ObjectPropertyFlags flags)
2515  {
2516      ObjectPropertyAccessor *getter = NULL;
2517      ObjectPropertyAccessor *setter = NULL;
2518  
2519      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2520          getter = property_get_uint8_ptr;
2521      }
2522  
2523      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2524          setter = property_set_uint8_ptr;
2525      }
2526  
2527      return object_property_add(obj, name, "uint8",
2528                                 getter, setter, NULL, (void *)v);
2529  }
2530  
2531  ObjectProperty *
2532  object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
2533                                      const uint8_t *v,
2534                                      ObjectPropertyFlags flags)
2535  {
2536      ObjectPropertyAccessor *getter = NULL;
2537      ObjectPropertyAccessor *setter = NULL;
2538  
2539      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2540          getter = property_get_uint8_ptr;
2541      }
2542  
2543      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2544          setter = property_set_uint8_ptr;
2545      }
2546  
2547      return object_class_property_add(klass, name, "uint8",
2548                                       getter, setter, NULL, (void *)v);
2549  }
2550  
2551  ObjectProperty *
2552  object_property_add_uint16_ptr(Object *obj, const char *name,
2553                                 const uint16_t *v,
2554                                 ObjectPropertyFlags flags)
2555  {
2556      ObjectPropertyAccessor *getter = NULL;
2557      ObjectPropertyAccessor *setter = NULL;
2558  
2559      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2560          getter = property_get_uint16_ptr;
2561      }
2562  
2563      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2564          setter = property_set_uint16_ptr;
2565      }
2566  
2567      return object_property_add(obj, name, "uint16",
2568                                 getter, setter, NULL, (void *)v);
2569  }
2570  
2571  ObjectProperty *
2572  object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
2573                                       const uint16_t *v,
2574                                       ObjectPropertyFlags flags)
2575  {
2576      ObjectPropertyAccessor *getter = NULL;
2577      ObjectPropertyAccessor *setter = NULL;
2578  
2579      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2580          getter = property_get_uint16_ptr;
2581      }
2582  
2583      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2584          setter = property_set_uint16_ptr;
2585      }
2586  
2587      return object_class_property_add(klass, name, "uint16",
2588                                       getter, setter, NULL, (void *)v);
2589  }
2590  
2591  ObjectProperty *
2592  object_property_add_uint32_ptr(Object *obj, const char *name,
2593                                 const uint32_t *v,
2594                                 ObjectPropertyFlags flags)
2595  {
2596      ObjectPropertyAccessor *getter = NULL;
2597      ObjectPropertyAccessor *setter = NULL;
2598  
2599      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2600          getter = property_get_uint32_ptr;
2601      }
2602  
2603      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2604          setter = property_set_uint32_ptr;
2605      }
2606  
2607      return object_property_add(obj, name, "uint32",
2608                                 getter, setter, NULL, (void *)v);
2609  }
2610  
2611  ObjectProperty *
2612  object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
2613                                       const uint32_t *v,
2614                                       ObjectPropertyFlags flags)
2615  {
2616      ObjectPropertyAccessor *getter = NULL;
2617      ObjectPropertyAccessor *setter = NULL;
2618  
2619      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2620          getter = property_get_uint32_ptr;
2621      }
2622  
2623      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2624          setter = property_set_uint32_ptr;
2625      }
2626  
2627      return object_class_property_add(klass, name, "uint32",
2628                                       getter, setter, NULL, (void *)v);
2629  }
2630  
2631  ObjectProperty *
2632  object_property_add_uint64_ptr(Object *obj, const char *name,
2633                                 const uint64_t *v,
2634                                 ObjectPropertyFlags flags)
2635  {
2636      ObjectPropertyAccessor *getter = NULL;
2637      ObjectPropertyAccessor *setter = NULL;
2638  
2639      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2640          getter = property_get_uint64_ptr;
2641      }
2642  
2643      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2644          setter = property_set_uint64_ptr;
2645      }
2646  
2647      return object_property_add(obj, name, "uint64",
2648                                 getter, setter, NULL, (void *)v);
2649  }
2650  
2651  ObjectProperty *
2652  object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
2653                                       const uint64_t *v,
2654                                       ObjectPropertyFlags flags)
2655  {
2656      ObjectPropertyAccessor *getter = NULL;
2657      ObjectPropertyAccessor *setter = NULL;
2658  
2659      if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
2660          getter = property_get_uint64_ptr;
2661      }
2662  
2663      if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
2664          setter = property_set_uint64_ptr;
2665      }
2666  
2667      return object_class_property_add(klass, name, "uint64",
2668                                       getter, setter, NULL, (void *)v);
2669  }
2670  
2671  typedef struct {
2672      Object *target_obj;
2673      char *target_name;
2674  } AliasProperty;
2675  
2676  static void property_get_alias(Object *obj, Visitor *v, const char *name,
2677                                 void *opaque, Error **errp)
2678  {
2679      AliasProperty *prop = opaque;
2680  
2681      object_property_get(prop->target_obj, prop->target_name, v, errp);
2682  }
2683  
2684  static void property_set_alias(Object *obj, Visitor *v, const char *name,
2685                                 void *opaque, Error **errp)
2686  {
2687      AliasProperty *prop = opaque;
2688  
2689      object_property_set(prop->target_obj, prop->target_name, v, errp);
2690  }
2691  
2692  static Object *property_resolve_alias(Object *obj, void *opaque,
2693                                        const char *part)
2694  {
2695      AliasProperty *prop = opaque;
2696  
2697      return object_resolve_path_component(prop->target_obj, prop->target_name);
2698  }
2699  
2700  static void property_release_alias(Object *obj, const char *name, void *opaque)
2701  {
2702      AliasProperty *prop = opaque;
2703  
2704      g_free(prop->target_name);
2705      g_free(prop);
2706  }
2707  
2708  ObjectProperty *
2709  object_property_add_alias(Object *obj, const char *name,
2710                            Object *target_obj, const char *target_name)
2711  {
2712      AliasProperty *prop;
2713      ObjectProperty *op;
2714      ObjectProperty *target_prop;
2715      g_autofree char *prop_type = NULL;
2716  
2717      target_prop = object_property_find_err(target_obj, target_name,
2718                                             &error_abort);
2719  
2720      if (object_property_is_child(target_prop)) {
2721          prop_type = g_strdup_printf("link%s",
2722                                      target_prop->type + strlen("child"));
2723      } else {
2724          prop_type = g_strdup(target_prop->type);
2725      }
2726  
2727      prop = g_malloc(sizeof(*prop));
2728      prop->target_obj = target_obj;
2729      prop->target_name = g_strdup(target_name);
2730  
2731      op = object_property_add(obj, name, prop_type,
2732                               property_get_alias,
2733                               property_set_alias,
2734                               property_release_alias,
2735                               prop);
2736      op->resolve = property_resolve_alias;
2737      if (target_prop->defval) {
2738          op->defval = qobject_ref(target_prop->defval);
2739      }
2740  
2741      object_property_set_description(obj, op->name,
2742                                      target_prop->description);
2743      return op;
2744  }
2745  
2746  void object_property_set_description(Object *obj, const char *name,
2747                                       const char *description)
2748  {
2749      ObjectProperty *op;
2750  
2751      op = object_property_find_err(obj, name, &error_abort);
2752      g_free(op->description);
2753      op->description = g_strdup(description);
2754  }
2755  
2756  void object_class_property_set_description(ObjectClass *klass,
2757                                             const char *name,
2758                                             const char *description)
2759  {
2760      ObjectProperty *op;
2761  
2762      op = g_hash_table_lookup(klass->properties, name);
2763      g_free(op->description);
2764      op->description = g_strdup(description);
2765  }
2766  
2767  static void object_class_init(ObjectClass *klass, void *data)
2768  {
2769      object_class_property_add_str(klass, "type", object_get_type,
2770                                    NULL);
2771  }
2772  
2773  static void register_types(void)
2774  {
2775      static TypeInfo interface_info = {
2776          .name = TYPE_INTERFACE,
2777          .class_size = sizeof(InterfaceClass),
2778          .abstract = true,
2779      };
2780  
2781      static TypeInfo object_info = {
2782          .name = TYPE_OBJECT,
2783          .instance_size = sizeof(Object),
2784          .class_init = object_class_init,
2785          .abstract = true,
2786      };
2787  
2788      type_interface = type_register_internal(&interface_info);
2789      type_register_internal(&object_info);
2790  }
2791  
2792  type_init(register_types)
2793