@samitouri / QOSamiQemu / commits / 58d6d6f035

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>

Richard Henderson committed May 30, 2026 at 00:36 UTC 58d6d6f035e15a4b531b71517fb42243d841c0c7
2 files changed +23 -53
bsd-user/elfload.c
+19 -18
@@ -22,6 +22,7 @@
22 #include "qemu.h"
23 #include "disas/disas.h"
24 #include "qemu/path.h"
25 +#include "user/probe-guest-base.h"
26
27 static abi_ulong target_auxents; /* Where the AUX entries are in target */
28 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,
611 abi_ulong elf_brk;
612 int error, retval;
613 char *elf_interpreter;
613 - abi_ulong baddr, elf_entry, et_dyn_addr, interp_load_addr = 0;
614 + abi_ulong elf_entry, et_dyn_addr, interp_load_addr = 0;
615 abi_ulong reloc_func_desc = 0;
616 + PGBRange range = { -1, 0 };
617
618 load_addr = 0;
619 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,
656
657 elf_brk = 0;
658
657 -
659 elf_interpreter = NULL;
659 - for (i = 0; i < elf_ex.e_phnum; i++) {
660 - if (elf_ppnt->p_type == PT_INTERP) {
660 + for (i = 0; i < elf_ex.e_phnum; i++, elf_ppnt++) {
661 + switch (elf_ppnt->p_type) {
662 + case PT_INTERP:
663 if (elf_interpreter != NULL) {
664 free(elf_phdata);
665 free(elf_interpreter);
@@ -709,8 +711,14 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
711 close(bprm->fd);
712 return retval;
713 }
714 + break;
715 +
716 + case PT_LOAD:
717 + range.lo = MIN(range.lo, elf_ppnt->p_vaddr);
718 + range.hi = MAX(range.hi,
719 + elf_ppnt->p_vaddr + elf_ppnt->p_memsz - 1);
720 + break;
721 }
713 - elf_ppnt++;
722 }
723
724 /* Some simple consistency checks for the interpreter */
@@ -740,19 +748,12 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
748 info->end_code = 0;
749 elf_entry = (abi_ulong) elf_ex.e_entry;
750
743 - /* XXX Join this with PT_INTERP search? */
744 - baddr = 0;
745 - for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
746 - if (elf_ppnt->p_type != PT_LOAD) {
747 - continue;
748 - }
749 - baddr = elf_ppnt->p_vaddr;
750 - break;
751 - }
752 -
751 et_dyn_addr = 0;
754 - if (elf_ex.e_type == ET_DYN && baddr == 0) {
755 - et_dyn_addr = ELF_ET_DYN_LOAD_ADDR;
752 + if (elf_ex.e_type == ET_DYN) {
753 + probe_guest_base(bprm->filename, NULL, NULL);
754 + et_dyn_addr = ELF_ET_DYN_LOAD_ADDR - range.lo;
755 + } else {
756 + probe_guest_base(bprm->filename, &range, NULL);
757 }
758
759 /*
@@ -766,7 +767,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
767 info->elf_flags = elf_ex.e_flags;
768
769 error = load_elf_sections(&elf_ex, elf_phdata, bprm->fd, et_dyn_addr,
769 - &load_addr);
770 + &load_addr);
771 for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
772 if (elf_ppnt->p_type != PT_LOAD) {
773 continue;
bsd-user/main.c
+4 -35
@@ -541,41 +541,10 @@ int main(int argc, char **argv)
541 }
542 }
543
544 - /*
545 - * If reserving host virtual address space, do so now.
546 - * Combined with '-B', ensure that the chosen range is free.
547 - */
548 - if (reserved_va) {
549 - void *p;
550 -
551 - if (have_guest_base) {
552 - p = mmap((void *)guest_base, reserved_va + 1, PROT_NONE,
553 - MAP_ANON | MAP_PRIVATE | MAP_FIXED | MAP_EXCL, -1, 0);
554 - } else {
555 - p = mmap(NULL, reserved_va + 1, PROT_NONE,
556 - MAP_ANON | MAP_PRIVATE, -1, 0);
557 - }
558 - if (p == MAP_FAILED) {
559 - const char *err = strerror(errno);
560 - char *sz = size_to_str(reserved_va + 1);
561 -
562 - if (have_guest_base) {
563 - error_report("Cannot allocate %s bytes at -B %p for guest "
564 - "address space: %s", sz, (void *)guest_base, err);
565 - } else {
566 - error_report("Cannot allocate %s bytes for guest "
567 - "address space: %s", sz, err);
568 - }
569 - exit(1);
570 - }
571 - guest_base = (uintptr_t)p;
572 - have_guest_base = true;
573 -
574 - /* Ensure that mmap_next_start is within range. */
575 - if (reserved_va <= mmap_next_start) {
576 - mmap_next_start = (reserved_va / 4 * 3)
577 - & TARGET_PAGE_MASK & qemu_host_page_mask;
578 - }
544 + /* Ensure that mmap_next_start is within range. */
545 + if (reserved_va && reserved_va <= mmap_next_start) {
546 + mmap_next_start = ((reserved_va / 4 * 3)
547 + & TARGET_PAGE_MASK & qemu_host_page_mask);
548 }
549
550 if (loader_exec(filename, argv + optind, target_environ, regs, info,