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>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user