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
@ -2201,7 +2201,8 @@ static inline void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags) { }
|
||||
#ifdef USE_ELF_CORE_DUMP
|
||||
static int elf_core_dump(int, const CPUArchState *);
|
||||
#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.
|
||||
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()) {
|
||||
load_symbols(ehdr, src->fd, load_bias);
|
||||
load_symbols(ehdr, src, 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. */
|
||||
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;
|
||||
uint64_t segsz;
|
||||
struct elf_shdr *shdr;
|
||||
g_autofree struct elf_shdr *shdr = NULL;
|
||||
char *strings = NULL;
|
||||
struct syminfo *s = NULL;
|
||||
struct elf_sym *new_syms, *syms = NULL;
|
||||
struct elf_sym *syms = NULL;
|
||||
struct elf_sym *new_syms;
|
||||
uint64_t segsz;
|
||||
|
||||
shnum = hdr->e_shnum;
|
||||
i = shnum * sizeof(struct elf_shdr);
|
||||
shdr = (struct elf_shdr *)alloca(i);
|
||||
if (pread(fd, shdr, i, hdr->e_shoff) != i) {
|
||||
shdr = imgsrc_read_alloc(hdr->e_shoff, shnum * sizeof(struct elf_shdr),
|
||||
src, NULL);
|
||||
if (shdr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3594,31 +3596,33 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||
|
||||
found:
|
||||
/* 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;
|
||||
s->disas_strtab = strings = g_try_malloc(segsz);
|
||||
if (!strings ||
|
||||
pread(fd, strings, segsz, shdr[str_idx].sh_offset) != segsz) {
|
||||
strings = g_try_malloc(segsz);
|
||||
if (!strings) {
|
||||
goto give_up;
|
||||
}
|
||||
if (!imgsrc_read(strings, shdr[str_idx].sh_offset, segsz, src, NULL)) {
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
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) {
|
||||
/* 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;
|
||||
}
|
||||
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; ) {
|
||||
bswap_sym(syms + i);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Attempt to free the storage associated with the local symbols
|
||||
that we threw away. Whether or not this has any effect on the
|
||||
memory allocation depends on the malloc implementation and how
|
||||
many symbols we managed to discard. */
|
||||
/*
|
||||
* Attempt to free the storage associated with the local symbols
|
||||
* that we threw away. Whether or not this has any effect on the
|
||||
* 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);
|
||||
if (new_syms == NULL) {
|
||||
goto give_up;
|
||||
@ -3655,20 +3661,23 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
|
||||
|
||||
qsort(syms, nsyms, sizeof(*syms), symcmp);
|
||||
|
||||
s->disas_num_syms = nsyms;
|
||||
#if ELF_CLASS == ELFCLASS32
|
||||
s->disas_symtab.elf32 = syms;
|
||||
#else
|
||||
s->disas_symtab.elf64 = syms;
|
||||
#endif
|
||||
s->lookup_symbol = lookup_symbolxx;
|
||||
s->next = syminfos;
|
||||
syminfos = s;
|
||||
{
|
||||
struct syminfo *s = g_new(struct syminfo, 1);
|
||||
|
||||
s->disas_strtab = strings;
|
||||
s->disas_num_syms = nsyms;
|
||||
#if ELF_CLASS == ELFCLASS32
|
||||
s->disas_symtab.elf32 = syms;
|
||||
#else
|
||||
s->disas_symtab.elf64 = syms;
|
||||
#endif
|
||||
s->lookup_symbol = lookup_symbolxx;
|
||||
s->next = syminfos;
|
||||
syminfos = s;
|
||||
}
|
||||
return;
|
||||
|
||||
give_up:
|
||||
g_free(s);
|
||||
give_up:
|
||||
g_free(strings);
|
||||
g_free(syms);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user