linux-user: Use PGBRange in load_elf_image
Collect into range instead of loaddr+hiaddr. Reviewed-by: Warner Losh <imp@bsdimp.com> Reviewed-by: Helge Deller <deller@gmx.de> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
@@ -1278,7 +1278,8 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
char **pinterp_name)
|
||||
{
|
||||
g_autofree struct elf_phdr *phdr = NULL;
|
||||
abi_ulong load_addr, load_bias, loaddr, hiaddr, error, align;
|
||||
PGBRange range = { -1, 0 };
|
||||
abi_ulong load_addr, load_bias, error, align;
|
||||
size_t reserve_size, align_size;
|
||||
int i, prot_exec;
|
||||
Error *err = NULL;
|
||||
@@ -1318,19 +1319,18 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
* Find the maximum size of the image and allocate an appropriate
|
||||
* amount of memory to handle that. Locate the interpreter, if any.
|
||||
*/
|
||||
loaddr = -1, hiaddr = 0;
|
||||
align = 0;
|
||||
info->exec_stack = EXSTACK_DEFAULT;
|
||||
for (i = 0; i < ehdr->e_phnum; ++i) {
|
||||
struct elf_phdr *eppnt = phdr + i;
|
||||
if (eppnt->p_type == PT_LOAD) {
|
||||
abi_ulong a = eppnt->p_vaddr & TARGET_PAGE_MASK;
|
||||
if (a < loaddr) {
|
||||
loaddr = a;
|
||||
if (a < range.lo) {
|
||||
range.lo = a;
|
||||
}
|
||||
a = eppnt->p_vaddr + eppnt->p_memsz - 1;
|
||||
if (a > hiaddr) {
|
||||
hiaddr = a;
|
||||
if (a > range.hi) {
|
||||
range.hi = a;
|
||||
}
|
||||
++info->nsegs;
|
||||
align |= eppnt->p_align;
|
||||
@@ -1361,7 +1361,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
}
|
||||
}
|
||||
|
||||
load_addr = loaddr;
|
||||
load_addr = range.lo;
|
||||
|
||||
align = pow2ceil(align);
|
||||
|
||||
@@ -1371,13 +1371,13 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
* Make sure that the low address does not conflict with
|
||||
* MMAP_MIN_ADDR or the QEMU application itself.
|
||||
*/
|
||||
probe_guest_base(image_name, loaddr, hiaddr);
|
||||
probe_guest_base(image_name, range.lo, range.hi);
|
||||
} else {
|
||||
/*
|
||||
* The binary is dynamic, but we still need to
|
||||
* select guest_base. In this case we pass a size.
|
||||
*/
|
||||
probe_guest_base(image_name, 0, hiaddr - loaddr);
|
||||
probe_guest_base(image_name, 0, range.hi - range.lo);
|
||||
|
||||
/*
|
||||
* Avoid collision with the loader by providing a different
|
||||
@@ -1414,7 +1414,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
* In both cases, we will overwrite pages in this range with mappings
|
||||
* from the executable.
|
||||
*/
|
||||
reserve_size = (size_t)hiaddr - loaddr + 1;
|
||||
reserve_size = range.hi - range.lo + 1;
|
||||
align_size = reserve_size;
|
||||
|
||||
if (ehdr->e_type != ET_EXEC && align > qemu_real_host_page_size()) {
|
||||
@@ -1443,7 +1443,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
load_addr = align_addr;
|
||||
}
|
||||
|
||||
load_bias = load_addr - loaddr;
|
||||
load_bias = load_addr - range.lo;
|
||||
|
||||
if (elf_is_fdpic(ehdr)) {
|
||||
struct elf32_fdpic_loadseg *loadsegs = info->loadsegs =
|
||||
@@ -1480,7 +1480,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
info->start_data = -1;
|
||||
info->end_data = 0;
|
||||
/* Usual start for brk is after all sections of the main executable. */
|
||||
info->brk = TARGET_PAGE_ALIGN(hiaddr + load_bias);
|
||||
info->brk = TARGET_PAGE_ALIGN(range.hi + load_bias);
|
||||
info->elf_flags = ehdr->e_flags;
|
||||
#ifdef TARGET_MIPS
|
||||
info->use_k0_tls = (ehdr->e_flags & EF_MIPS_MACH) == EF_MIPS_MACH_OCTEON;
|
||||
|
||||
Reference in New Issue
Block a user