mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-09 08:17:53 -06:00
linux-user: Use ImageSource in load_symbols
Aside from the section headers, we're unlikely to hit the ImageSource cache on guest executables. But the interface for imgsrc_read_* is better. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
3bd0238638
commit
86cf82dc9f
1 changed files with 48 additions and 39 deletions
|
@ -2201,7 +2201,8 @@ static inline void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags) { }
|
||||||
#ifdef USE_ELF_CORE_DUMP
|
#ifdef USE_ELF_CORE_DUMP
|
||||||
static int elf_core_dump(int, const CPUArchState *);
|
static int elf_core_dump(int, const CPUArchState *);
|
||||||
#endif /* USE_ELF_CORE_DUMP */
|
#endif /* USE_ELF_CORE_DUMP */
|
||||||
static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias);
|
static void load_symbols(struct elfhdr *hdr, const ImageSource *src,
|
||||||
|
abi_ulong load_bias);
|
||||||
|
|
||||||
/* Verify the portions of EHDR within E_IDENT for the target.
|
/* Verify the portions of EHDR within E_IDENT for the target.
|
||||||
This can be performed before bswapping the entire header. */
|
This can be performed before bswapping the entire header. */
|
||||||
|
@ -3473,7 +3474,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_log_enabled()) {
|
if (qemu_log_enabled()) {
|
||||||
load_symbols(ehdr, src->fd, load_bias);
|
load_symbols(ehdr, src, load_bias);
|
||||||
}
|
}
|
||||||
|
|
||||||
debuginfo_report_elf(image_name, src->fd, load_bias);
|
debuginfo_report_elf(image_name, src->fd, load_bias);
|
||||||
|
@ -3564,19 +3565,20 @@ static int symcmp(const void *s0, const void *s1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Best attempt to load symbols from this ELF object. */
|
/* Best attempt to load symbols from this ELF object. */
|
||||||
static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
static void load_symbols(struct elfhdr *hdr, const ImageSource *src,
|
||||||
|
abi_ulong load_bias)
|
||||||
{
|
{
|
||||||
int i, shnum, nsyms, sym_idx = 0, str_idx = 0;
|
int i, shnum, nsyms, sym_idx = 0, str_idx = 0;
|
||||||
uint64_t segsz;
|
g_autofree struct elf_shdr *shdr = NULL;
|
||||||
struct elf_shdr *shdr;
|
|
||||||
char *strings = NULL;
|
char *strings = NULL;
|
||||||
struct syminfo *s = NULL;
|
struct elf_sym *syms = NULL;
|
||||||
struct elf_sym *new_syms, *syms = NULL;
|
struct elf_sym *new_syms;
|
||||||
|
uint64_t segsz;
|
||||||
|
|
||||||
shnum = hdr->e_shnum;
|
shnum = hdr->e_shnum;
|
||||||
i = shnum * sizeof(struct elf_shdr);
|
shdr = imgsrc_read_alloc(hdr->e_shoff, shnum * sizeof(struct elf_shdr),
|
||||||
shdr = (struct elf_shdr *)alloca(i);
|
src, NULL);
|
||||||
if (pread(fd, shdr, i, hdr->e_shoff) != i) {
|
if (shdr == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3594,31 +3596,33 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||||
|
|
||||||
found:
|
found:
|
||||||
/* Now know where the strtab and symtab are. Snarf them. */
|
/* Now know where the strtab and symtab are. Snarf them. */
|
||||||
s = g_try_new(struct syminfo, 1);
|
|
||||||
if (!s) {
|
|
||||||
goto give_up;
|
|
||||||
}
|
|
||||||
|
|
||||||
segsz = shdr[str_idx].sh_size;
|
segsz = shdr[str_idx].sh_size;
|
||||||
s->disas_strtab = strings = g_try_malloc(segsz);
|
strings = g_try_malloc(segsz);
|
||||||
if (!strings ||
|
if (!strings) {
|
||||||
pread(fd, strings, segsz, shdr[str_idx].sh_offset) != segsz) {
|
goto give_up;
|
||||||
|
}
|
||||||
|
if (!imgsrc_read(strings, shdr[str_idx].sh_offset, segsz, src, NULL)) {
|
||||||
goto give_up;
|
goto give_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
segsz = shdr[sym_idx].sh_size;
|
segsz = shdr[sym_idx].sh_size;
|
||||||
syms = g_try_malloc(segsz);
|
|
||||||
if (!syms || pread(fd, syms, segsz, shdr[sym_idx].sh_offset) != segsz) {
|
|
||||||
goto give_up;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (segsz / sizeof(struct elf_sym) > INT_MAX) {
|
if (segsz / sizeof(struct elf_sym) > INT_MAX) {
|
||||||
/* Implausibly large symbol table: give up rather than ploughing
|
/*
|
||||||
* on with the number of symbols calculation overflowing
|
* Implausibly large symbol table: give up rather than ploughing
|
||||||
|
* on with the number of symbols calculation overflowing.
|
||||||
*/
|
*/
|
||||||
goto give_up;
|
goto give_up;
|
||||||
}
|
}
|
||||||
nsyms = segsz / sizeof(struct elf_sym);
|
nsyms = segsz / sizeof(struct elf_sym);
|
||||||
|
syms = g_try_malloc(segsz);
|
||||||
|
if (!syms) {
|
||||||
|
goto give_up;
|
||||||
|
}
|
||||||
|
if (!imgsrc_read(syms, shdr[sym_idx].sh_offset, segsz, src, NULL)) {
|
||||||
|
goto give_up;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < nsyms; ) {
|
for (i = 0; i < nsyms; ) {
|
||||||
bswap_sym(syms + i);
|
bswap_sym(syms + i);
|
||||||
/* Throw away entries which we do not need. */
|
/* Throw away entries which we do not need. */
|
||||||
|
@ -3643,10 +3647,12 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||||
goto give_up;
|
goto give_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to free the storage associated with the local symbols
|
/*
|
||||||
that we threw away. Whether or not this has any effect on the
|
* Attempt to free the storage associated with the local symbols
|
||||||
memory allocation depends on the malloc implementation and how
|
* that we threw away. Whether or not this has any effect on the
|
||||||
many symbols we managed to discard. */
|
* memory allocation depends on the malloc implementation and how
|
||||||
|
* many symbols we managed to discard.
|
||||||
|
*/
|
||||||
new_syms = g_try_renew(struct elf_sym, syms, nsyms);
|
new_syms = g_try_renew(struct elf_sym, syms, nsyms);
|
||||||
if (new_syms == NULL) {
|
if (new_syms == NULL) {
|
||||||
goto give_up;
|
goto give_up;
|
||||||
|
@ -3655,6 +3661,10 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||||
|
|
||||||
qsort(syms, nsyms, sizeof(*syms), symcmp);
|
qsort(syms, nsyms, sizeof(*syms), symcmp);
|
||||||
|
|
||||||
|
{
|
||||||
|
struct syminfo *s = g_new(struct syminfo, 1);
|
||||||
|
|
||||||
|
s->disas_strtab = strings;
|
||||||
s->disas_num_syms = nsyms;
|
s->disas_num_syms = nsyms;
|
||||||
#if ELF_CLASS == ELFCLASS32
|
#if ELF_CLASS == ELFCLASS32
|
||||||
s->disas_symtab.elf32 = syms;
|
s->disas_symtab.elf32 = syms;
|
||||||
|
@ -3664,11 +3674,10 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||||
s->lookup_symbol = lookup_symbolxx;
|
s->lookup_symbol = lookup_symbolxx;
|
||||||
s->next = syminfos;
|
s->next = syminfos;
|
||||||
syminfos = s;
|
syminfos = s;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
give_up:
|
give_up:
|
||||||
g_free(s);
|
|
||||||
g_free(strings);
|
g_free(strings);
|
||||||
g_free(syms);
|
g_free(syms);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue