diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2020-10-21 10:37:44 -0700 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-10-27 10:44:02 +0000 |
commit | 8a1a5274c9395e2d92aaf6126379f58804a82aca (patch) | |
tree | 532c61e9b21ab1ecc80b739d57722b8d5ecbe0db /linux-user | |
parent | 4d9d535a8a52bf9ccc2c325b88498b35b6cc579d (diff) |
linux-user/elfload: Move PT_INTERP detection to first loop
For BTI, we need to know if the executable is static or dynamic,
which means looking for PT_INTERP earlier.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201021173749.111103-8-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/elfload.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 210592aa90..107a628a9e 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2421,8 +2421,10 @@ static void load_elf_image(const char *image_name, int image_fd, mmap_lock(); - /* Find the maximum size of the image and allocate an appropriate - amount of memory to handle that. */ + /* + * 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; info->alignment = 0; for (i = 0; i < ehdr->e_phnum; ++i) { @@ -2438,6 +2440,33 @@ static void load_elf_image(const char *image_name, int image_fd, } ++info->nsegs; info->alignment |= eppnt->p_align; + } else if (eppnt->p_type == PT_INTERP && pinterp_name) { + g_autofree char *interp_name = NULL; + + if (*pinterp_name) { + errmsg = "Multiple PT_INTERP entries"; + goto exit_errmsg; + } + interp_name = g_malloc(eppnt->p_filesz); + if (!interp_name) { + goto exit_perror; + } + + if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) { + memcpy(interp_name, bprm_buf + eppnt->p_offset, + eppnt->p_filesz); + } else { + retval = pread(image_fd, interp_name, eppnt->p_filesz, + eppnt->p_offset); + if (retval != eppnt->p_filesz) { + goto exit_perror; + } + } + if (interp_name[eppnt->p_filesz - 1] != 0) { + errmsg = "Invalid PT_INTERP entry"; + goto exit_errmsg; + } + *pinterp_name = g_steal_pointer(&interp_name); } } @@ -2590,33 +2619,6 @@ static void load_elf_image(const char *image_name, int image_fd, if (vaddr_em > info->brk) { info->brk = vaddr_em; } - } else if (eppnt->p_type == PT_INTERP && pinterp_name) { - g_autofree char *interp_name = NULL; - - if (*pinterp_name) { - errmsg = "Multiple PT_INTERP entries"; - goto exit_errmsg; - } - interp_name = g_malloc(eppnt->p_filesz); - if (!interp_name) { - goto exit_perror; - } - - if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) { - memcpy(interp_name, bprm_buf + eppnt->p_offset, - eppnt->p_filesz); - } else { - retval = pread(image_fd, interp_name, eppnt->p_filesz, - eppnt->p_offset); - if (retval != eppnt->p_filesz) { - goto exit_perror; - } - } - if (interp_name[eppnt->p_filesz - 1] != 0) { - errmsg = "Invalid PT_INTERP entry"; - goto exit_errmsg; - } - *pinterp_name = g_steal_pointer(&interp_name); #ifdef TARGET_MIPS } else if (eppnt->p_type == PT_MIPS_ABIFLAGS) { Mips_elf_abiflags_v0 abiflags; |