I noticed this the other day: (qemu) info qom-tree /machine (pc-i440fx-7.2-machine) /fw_cfg (fw_cfg_io) /\x2from@etc\x2facpi\x2frsdp[0] (memory-region)b /\x2from@etc\x2facpi\x2ftables[0] (memory-region) /\x2from@etc\x2ftable-loader[0] (memory-region) /fwcfg.dma[0] (memory-region) /fwcfg[0] (memory-region) [...]
It took me a minute to realize that the "\x2" in these property names are escaped forms of '/'. I.e. the unescaped path components of the first property path are machine fw_cfg /from@etc/facpi/frsdp[0] We're embedding paths within paths. Ugh! The escaping happens in memory_region_init(): static bool memory_region_need_escape(char c) { return c == '/' || c == '[' || c == '\\' || c == ']'; } static char *memory_region_escape_name(const char *name) { const char *p; char *escaped, *q; uint8_t c; size_t bytes = 0; for (p = name; *p; p++) { bytes += memory_region_need_escape(*p) ? 4 : 1; } if (bytes == p - name) { return g_memdup(name, bytes + 1); } escaped = g_malloc(bytes + 1); for (p = name, q = escaped; *p; p++) { c = *p; if (unlikely(memory_region_need_escape(c))) { *q++ = '\\'; *q++ = 'x'; *q++ = "0123456789abcdef"[c >> 4]; c = "0123456789abcdef"[c & 15]; } *q++ = c; } *q = 0; return escaped; } static void memory_region_do_init(MemoryRegion *mr, Object *owner, const char *name, uint64_t size) { mr->size = int128_make64(size); if (size == UINT64_MAX) { mr->size = int128_2_64(); } mr->name = g_strdup(name); mr->owner = owner; mr->ram_block = NULL; if (name) { char *escaped_name = memory_region_escape_name(name); char *name_array = g_strdup_printf("%s[*]", escaped_name); if (!owner) { owner = container_get(qdev_get_machine(), "/unattached"); } object_property_add_child(owner, name_array, OBJECT(mr)); object_unref(OBJECT(mr)); g_free(name_array); g_free(escaped_name); } } void memory_region_init(MemoryRegion *mr, Object *owner, const char *name, uint64_t size) { object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION); memory_region_do_init(mr, owner, name, size); } Goes back to commit b4fefef9d52003b6d09866501275a9a57995c6b0 Author: Peter Crosthwaite <peter.crosthwa...@xilinx.com> Date: Thu Jun 5 23:15:52 2014 -0700 memory: MemoryRegion: QOMify QOMify memory regions as an Object. The former init() and destroy() routines become instance_init() and instance_finalize() resp. memory_region_init() is re-implemented to be: object_initialize() + set fields memory_region_destroy() is re-implemented to call unparent(). Signed-off-by: Peter Crosthwaite <peter.crosthwa...@xilinx.com> [Add newly-created MR as child, unparent on destruction. - Paolo] Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> No mention of the escapery. Questions: 1. Do we really want to embed slash-separated paths into slash-separated paths? 2. As far as I can tell, object.c does not guard against "funny" characters such as '/' in path components. Should it? For what it's worth, the kernel doesn't permit '/' in filenames. 3. Should the escapery live in object.c instead of memory.c?