* Ugly QOM property names: paths within paths
@ 2022-11-14 9:24 Markus Armbruster
0 siblings, 0 replies; only message in thread
From: Markus Armbruster @ 2022-11-14 9:24 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Crosthwaite, Paolo Bonzini, Daniel P. Berrangé,
Eduardo Habkost
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.crosthwaite@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.crosthwaite@xilinx.com>
[Add newly-created MR as child, unparent on destruction. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@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?
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-11-15 0:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-14 9:24 Ugly QOM property names: paths within paths Markus Armbruster
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.