linux-user/elfload.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
From: Helge Deller <deller@gmx.de>
Static built ARM binaries for Cortex-m55 may have been linked to have
their load address at address 0. When qemu-user is running as non-root
user and thus will try to mmap() a host address which is smaller than
mmap_min_addr (/proc/sys/vm/mmap_min_addr), it will fail with EPERM and
as such loading those guest programs will fail.
Avoid this EPERM failure by automatically choosing a valid starting
guest_base address which has to be higher than mmap_min_addr.
Signed-off-by: Helge Deller <deller@gmx.de>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/1890
---
linux-user/elfload.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0e757787d2..152c122a23 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1033,8 +1033,9 @@ static void pgb_dynamic(const char *image_name, uintptr_t guest_loaddr,
uintptr_t brk, ret;
PGBAddrs ga;
- /* Try the identity map first. */
- if (pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, true)) {
+ /* Try the identity map first if guest_loadaddr is above mmap_min_addr. */
+ if (guest_loaddr >= mmap_min_addr &&
+ pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, true)) {
brk = (uintptr_t)sbrk(0);
if (pgb_try_mmap_set(&ga, 0, brk)) {
guest_base = 0;
--
2.54.0
On 5/25/26 16:03, Helge Deller wrote: > From: Helge Deller <deller@gmx.de> > > Static built ARM binaries for Cortex-m55 may have been linked to have > their load address at address 0. This is a problem. We also use 0 for "unassigned" a-la ET_DYN. Perhaps ideally we'd pass around a separate flag for ET_EXEC vs ET_DYN, but ET_EXEC with 0 is not a valid binary precisely because it attempts to map at the zero page. Honestly, I think this is user error. While we support some m-profile binaries in linux-user mode which the Linux kernel does not, for the explicit benefit of the GCC testsuite, there are limits. r~
On Wed, 27 May 2026 at 16:42, Richard Henderson <richard.henderson@linaro.org> wrote: > > On 5/25/26 16:03, Helge Deller wrote: > > From: Helge Deller <deller@gmx.de> > > > > Static built ARM binaries for Cortex-m55 may have been linked to have > > their load address at address 0. > > This is a problem. We also use 0 for "unassigned" a-la ET_DYN. > > Perhaps ideally we'd pass around a separate flag for ET_EXEC vs ET_DYN, but ET_EXEC with 0 > is not a valid binary precisely because it attempts to map at the zero page. > > Honestly, I think this is user error. While we support some m-profile binaries in > linux-user mode which the Linux kernel does not, for the explicit benefit of the GCC > testsuite, there are limits. But if the user explicitly passes a guest-base address on their QEMU command line, we run the binary happily. If we refused to run the binary at all that would be one thing (and not unreasonable, as you say). But it does seem to me like a problem in our "pick a guest-base" logic that we fail to identify one that would work fine for this particular binary. thanks -- PMM
On 5/27/26 09:40, Peter Maydell wrote: > On Wed, 27 May 2026 at 16:42, Richard Henderson > <richard.henderson@linaro.org> wrote: >> >> On 5/25/26 16:03, Helge Deller wrote: >>> From: Helge Deller <deller@gmx.de> >>> >>> Static built ARM binaries for Cortex-m55 may have been linked to have >>> their load address at address 0. >> >> This is a problem. We also use 0 for "unassigned" a-la ET_DYN. >> >> Perhaps ideally we'd pass around a separate flag for ET_EXEC vs ET_DYN, but ET_EXEC with 0 >> is not a valid binary precisely because it attempts to map at the zero page. >> >> Honestly, I think this is user error. While we support some m-profile binaries in >> linux-user mode which the Linux kernel does not, for the explicit benefit of the GCC >> testsuite, there are limits. > > But if the user explicitly passes a guest-base address on their > QEMU command line, we run the binary happily. If we refused > to run the binary at all that would be one thing (and not > unreasonable, as you say). But it does seem to me like a > problem in our "pick a guest-base" logic that we fail to > identify one that would work fine for this particular binary. Then we need to do the work to track PIE separately, without overloading 0. r~
On Tue, 26 May 2026 at 00:03, Helge Deller <deller@kernel.org> wrote:
>
> From: Helge Deller <deller@gmx.de>
>
> Static built ARM binaries for Cortex-m55 may have been linked to have
> their load address at address 0. When qemu-user is running as non-root
> user and thus will try to mmap() a host address which is smaller than
> mmap_min_addr (/proc/sys/vm/mmap_min_addr), it will fail with EPERM and
> as such loading those guest programs will fail.
>
> Avoid this EPERM failure by automatically choosing a valid starting
> guest_base address which has to be higher than mmap_min_addr.
>
> Signed-off-by: Helge Deller <deller@gmx.de>
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/1890
I just put a comment in this issue, but the reason we don't
load this binary is partly because it is not a Linux binary
at all, it is a bare-metal image. So the extent to which we
can run it at all is a mix of luck and "we like to let the GCC
developers be able to run their semihosting test binaries on
qemu-user".
> ---
> linux-user/elfload.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 0e757787d2..152c122a23 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1033,8 +1033,9 @@ static void pgb_dynamic(const char *image_name, uintptr_t guest_loaddr,
> uintptr_t brk, ret;
> PGBAddrs ga;
>
> - /* Try the identity map first. */
> - if (pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, true)) {
> + /* Try the identity map first if guest_loadaddr is above mmap_min_addr. */
> + if (guest_loaddr >= mmap_min_addr &&
> + pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, true)) {
pgb_addr_set() is supposed to return false if the identity
map isn't suitable, so I feel like it would be better to
have it get the answer right rather than work around it
giving us the wrong answer in this particular case.
thanks
-- PMM
© 2016 - 2026 Red Hat, Inc.