Commit 58d6d6f035 for qemu.org
commit 58d6d6f035e15a4b531b71517fb42243d841c0c7
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Sat May 30 00:36:09 2026 -0700
bsd-user: Use probe_guest_base
Merge the PT_LOAD loop with the PT_INTERP loop, as the XXX
comment suggests. Pass the probed range to probe_guest_base.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 3bca0cc9ed..a87a892eb8 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -22,6 +22,7 @@
#include "qemu.h"
#include "disas/disas.h"
#include "qemu/path.h"
+#include "user/probe-guest-base.h"
static abi_ulong target_auxents; /* Where the AUX entries are in target */
static size_t target_auxents_sz; /* Size of AUX entries including AT_NULL */
@@ -610,8 +611,9 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
abi_ulong elf_brk;
int error, retval;
char *elf_interpreter;
- abi_ulong baddr, elf_entry, et_dyn_addr, interp_load_addr = 0;
+ abi_ulong elf_entry, et_dyn_addr, interp_load_addr = 0;
abi_ulong reloc_func_desc = 0;
+ PGBRange range = { -1, 0 };
load_addr = 0;
elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
@@ -654,10 +656,10 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
elf_brk = 0;
-
elf_interpreter = NULL;
- for (i = 0; i < elf_ex.e_phnum; i++) {
- if (elf_ppnt->p_type == PT_INTERP) {
+ for (i = 0; i < elf_ex.e_phnum; i++, elf_ppnt++) {
+ switch (elf_ppnt->p_type) {
+ case PT_INTERP:
if (elf_interpreter != NULL) {
free(elf_phdata);
free(elf_interpreter);
@@ -709,8 +711,14 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
close(bprm->fd);
return retval;
}
+ break;
+
+ case PT_LOAD:
+ range.lo = MIN(range.lo, elf_ppnt->p_vaddr);
+ range.hi = MAX(range.hi,
+ elf_ppnt->p_vaddr + elf_ppnt->p_memsz - 1);
+ break;
}
- elf_ppnt++;
}
/* Some simple consistency checks for the interpreter */
@@ -740,19 +748,12 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
info->end_code = 0;
elf_entry = (abi_ulong) elf_ex.e_entry;
- /* XXX Join this with PT_INTERP search? */
- baddr = 0;
- for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
- if (elf_ppnt->p_type != PT_LOAD) {
- continue;
- }
- baddr = elf_ppnt->p_vaddr;
- break;
- }
-
et_dyn_addr = 0;
- if (elf_ex.e_type == ET_DYN && baddr == 0) {
- et_dyn_addr = ELF_ET_DYN_LOAD_ADDR;
+ if (elf_ex.e_type == ET_DYN) {
+ probe_guest_base(bprm->filename, NULL, NULL);
+ et_dyn_addr = ELF_ET_DYN_LOAD_ADDR - range.lo;
+ } else {
+ probe_guest_base(bprm->filename, &range, NULL);
}
/*
@@ -766,7 +767,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
info->elf_flags = elf_ex.e_flags;
error = load_elf_sections(&elf_ex, elf_phdata, bprm->fd, et_dyn_addr,
- &load_addr);
+ &load_addr);
for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
if (elf_ppnt->p_type != PT_LOAD) {
continue;
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 4f1544342e..5277b4e099 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -541,41 +541,10 @@ int main(int argc, char **argv)
}
}
- /*
- * If reserving host virtual address space, do so now.
- * Combined with '-B', ensure that the chosen range is free.
- */
- if (reserved_va) {
- void *p;
-
- if (have_guest_base) {
- p = mmap((void *)guest_base, reserved_va + 1, PROT_NONE,
- MAP_ANON | MAP_PRIVATE | MAP_FIXED | MAP_EXCL, -1, 0);
- } else {
- p = mmap(NULL, reserved_va + 1, PROT_NONE,
- MAP_ANON | MAP_PRIVATE, -1, 0);
- }
- if (p == MAP_FAILED) {
- const char *err = strerror(errno);
- char *sz = size_to_str(reserved_va + 1);
-
- if (have_guest_base) {
- error_report("Cannot allocate %s bytes at -B %p for guest "
- "address space: %s", sz, (void *)guest_base, err);
- } else {
- error_report("Cannot allocate %s bytes for guest "
- "address space: %s", sz, err);
- }
- exit(1);
- }
- guest_base = (uintptr_t)p;
- have_guest_base = true;
-
- /* Ensure that mmap_next_start is within range. */
- if (reserved_va <= mmap_next_start) {
- mmap_next_start = (reserved_va / 4 * 3)
- & TARGET_PAGE_MASK & qemu_host_page_mask;
- }
+ /* Ensure that mmap_next_start is within range. */
+ if (reserved_va && reserved_va <= mmap_next_start) {
+ mmap_next_start = ((reserved_va / 4 * 3)
+ & TARGET_PAGE_MASK & qemu_host_page_mask);
}
if (loader_exec(filename, argv + optind, target_environ, regs, info,