On 10/2/26 12:52, Rick Richard wrote:
A non-PIE qemu is loaded below 4 GiB. That includes every static
build on FreeBSD and Linux builds configured with --disable-pie.
With the identity map (guest_base 0), a non-PIE guest program can
be mapped over qemu.

Only use the identity map when qemu is loaded at 4 GiB or higher.
Non-PIE programs are normally linked below 4 GiB, and PIE programs
are loaded at or above it (ppc64 Linux loads them at exactly 4 GiB).

Signed-off-by: Rick Richard <[email protected]>
---
On FreeBSD a static qemu can't be PIE, so bsd-user is always loaded
at 0x200000. pgb_dynamic() picks guest_base 0 because the initial
image doesn't overlap qemu, but rtld later maps a non-PIE executable
at its link address on top of qemu's own text.

This isn't BSD specific, I was able to reproduce on Linux as well by
disabling PIE.

I tested the fix on Linux with static-pie and --disable-pie builds,
and on FreeBSD with aarch64, riscv64 and x86_64 guests. When qemu is
loaded high it still uses the identity map. When it's loaded low it
picks a non-zero guest_base and the guest runs normally.

I couldn't find an existing way in qemu to get its own load address,
so I used __executable_start, which both GNU ld and lld provide. If
there's a better way I'm happy to change it.

There should be no need for this at all. The probe sequence should notice conflicting addresses and adjust.

What's your failure case?


r~

Reply via email to