Running out of time for today, so I'm sending what I have, with real
review to follow.
First, let me describe what's wrong in my own words, because that's how
I understand stuff.
Reproducer (hidden behind the link to the bug tracker):
$ qemu-system-x86_64 \
-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.fd","node-name":"pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"pflash0-format","read-only":true,"driver":"raw","file":"pflash0-storage"}' \
-machine pc,pflash0=pflash0-format
The -machine gets (keyval-)parsed into a QDict, which is then processed
by object_set_properties_from_qdict() with the (keyval) QObject input
visitor. Makes sense.
object_set_properties_from_qdict() performs a virtual struct visit
guided by the QDict's keys. It calls object_property_set() for each
key.
For "pflash0", this calls object_property_set(obj, "pflash0", v, &err).
Since "pflash0" is a QOM alias property, this in turn calls
object_property_set(prop->target_obj, "drive0", v, &err), where prop is
the alias property, and prop->target_obj is the "cfi.pflash01" device.
Since "drive" is a drive property, this calls set_drive(), which calls
visit_type_str(v, "drive", &str, errp). Fails, because the QDict
wrapped in visitor @v does not have a "drive" member, it has a "pflash0"
member.
Next, the solution. I get the idea of a wrapper visitor which gives you
"pflash0" when you ask for "drive", but oh boy do I wish we could fix
the bug with a lot less code.