Igen, a Qemu-s doksi el is magyarázza hogyan: https://www.qemu.org/docs/master/devel/tcg.html Ahogy írod, a write-protect majd page fault-os módszert használják.
A kérdés, hogy a Rosetta2 - ami saját bevallásuk szerint szigorúan ahead-of-time, nem pedig just-in-time (https://dougallj.wordpress.com/2022/11/09/why-is-rosetta-2-fast/) - mit tud tenni vele. Biztos, hogy valami kivételes fallback mechanizmusnak kell lennie erre.
Amit írsz példát (program counterhez képest relatív offset-es betöltés - ha jól olvasom az ARM assembly-t) egyáltalán nem biztos, hogy kivételes ritka dolog. Akkor játszik, ha pl 32 bites konstanst akarsz betölteni, amit az assembler nem tud immediate értékként betenni a 32 bites utasításszóba (nyilván), ezért pc relatív címzéssel valahol a .text szegmensbe rakja a hivatkozó utasítás közelébe. Ez tök gyakori dolog lehet.
Szerintem a translator előre kell hogy megoldja. A fordítás közben fenn kell tartania egy előremutató-referenciát minden generált kimenet utasításhoz, hogy mi volt az eredeti utasítás címe (ami szintén betöltve ott marad az eredeti címen a memóriában), amiből generálódott. És valószínűleg kicseréli a pc-t erre a konstansra. Valami ilyesmi. Mindenesetre mindig csodáltam azokat, akik ilyeneket tudtak implementálni, a legalább 300+ féle hasonló cornercase-t előre megtalálni és mindre kitalálni a leképzési módszert.