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,