@ -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 ;
}
segsz = shdr [ sym_idx ] . sh_size ;
syms = g_try_malloc ( segsz ) ;
if ( ! syms | | pread ( fd , syms , segsz , shdr [ sym_idx ] . sh_offset ) ! = segsz ) {
if ( ! imgsrc_read ( strings , shdr [ str_idx ] . sh_offset , segsz , src , NULL ) ) {
goto give_up ;
}
segsz = shdr [ sym_idx ] . sh_size ;
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 ;
{
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 ;
s - > disas_symtab . elf32 = syms ;
# else
s - > disas_symtab . elf64 = syms ;
s - > disas_symtab . elf64 = syms ;
# endif
s - > lookup_symbol = lookup_symbolxx ;
s - > next = syminfos ;
syminfos = s ;
s - > lookup_symbol = lookup_symbolxx ;
s - > next = syminfos ;
syminfos = s ;
}
return ;
give_up :
g_free ( s ) ;
give_up :
g_free ( strings ) ;
g_free ( syms ) ;
}