forked from Imagelibrary/binutils-gdb
gprofng: Refactor readSymSec for using BFD's asymbol struct
This patch refactors a number of gprofng internal functions for using more BFD data types and functions. Stabs::readSymSec is a function which reads the symbols of an ELF file mapping them into an internal structure. To use BFD asymbols, the Elf::elf_getsym is changed from custom reading of the symbols from .symtab and .dynsym section to BFD enable functions. A new function is introduced which returns the number of either static or dynamic symbols, named Elf::elf_getSymCount. Both Elf functions are used by Stabs::readSymSec refactoring. Also, this patch removes reading symbols, SUNW_ldnsym section as it is only used by now defunct Studio compiler. However, it adds the reading of both static and dynamic symbols, previously, only either one was processed. Signed-off-by: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
This commit is contained in:
committed by
Vladimir Mezentsev
parent
91fd524499
commit
13f614be23
@@ -204,12 +204,6 @@ ElfReloc::dump_rela_debug_sec (int sec)
|
||||
if (ScnSize == 0 || EntSize == 0)
|
||||
return;
|
||||
|
||||
Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link);
|
||||
if (shdr_sym == NULL)
|
||||
return;
|
||||
Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link);
|
||||
Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link);
|
||||
char *Strtab = data_str ? (char*) data_str->d_buf : NULL;
|
||||
Elf_Internal_Rela rela;
|
||||
int n, cnt = (int) (ScnSize / EntSize);
|
||||
|
||||
@@ -233,7 +227,8 @@ ElfReloc::dump_rela_debug_sec (int sec)
|
||||
int ndx = (int) GELF_R_SYM (rela.r_info);
|
||||
Elf_Internal_Shdr *secHdr;
|
||||
Elf_Internal_Sym sym;
|
||||
elf->elf_getsym (data_sym, ndx, &sym);
|
||||
asymbol *asym;
|
||||
asym = elf->elf_getsym (ndx, &sym, false);
|
||||
Dprintf (DUMP_RELA_SEC, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"),
|
||||
n, (int) rela.r_addend,
|
||||
(long long) rela.r_offset, (long long) rela.r_info,
|
||||
@@ -243,12 +238,9 @@ ElfReloc::dump_rela_debug_sec (int sec)
|
||||
case STT_FUNC:
|
||||
case STT_OBJECT:
|
||||
case STT_NOTYPE:
|
||||
secHdr = elf->get_shdr (sym.st_shndx);
|
||||
if (secHdr)
|
||||
Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
|
||||
(long long) (sym.st_value + secHdr->sh_offset));
|
||||
if (Strtab && sym.st_name)
|
||||
Dprintf (DUMP_RELA_SEC, NTXT (" %s"), Strtab + sym.st_name);
|
||||
Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
|
||||
(long long) (bfd_asymbol_value (asym)));
|
||||
Dprintf (DUMP_RELA_SEC, NTXT (" %s"), bfd_asymbol_name (asym));
|
||||
break;
|
||||
case STT_SECTION:
|
||||
secHdr = elf->get_shdr (sym.st_shndx);
|
||||
@@ -311,10 +303,6 @@ ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
|
||||
return rlc;
|
||||
|
||||
int cnt = (int) (data->d_size / shdr->sh_entsize);
|
||||
Elf_Internal_Shdr *shdr_sym = elfp->get_shdr (shdr->sh_link);
|
||||
if (shdr_sym == NULL)
|
||||
return rlc;
|
||||
Elf_Data *data_sym = elfp->elf_getdata (shdr->sh_link);
|
||||
Vector<Sreloc *> *vp = NULL;
|
||||
|
||||
for (int n = 0; n < cnt; n++)
|
||||
@@ -331,7 +319,7 @@ ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
|
||||
}
|
||||
int ndx = (int) GELF_R_SYM (rela.r_info);
|
||||
Elf_Internal_Sym sym;
|
||||
elfp->elf_getsym (data_sym, ndx, &sym);
|
||||
elfp->elf_getsym (ndx, &sym, false);
|
||||
|
||||
srlc = new Sreloc;
|
||||
srlc->offset = rela.r_offset;
|
||||
|
||||
@@ -533,42 +533,43 @@ Elf::elf_strptr (unsigned int sec, uint64_t off)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Elf_Internal_Sym *
|
||||
Elf::elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst)
|
||||
long
|
||||
Elf::elf_getSymCount (bool is_dynamic)
|
||||
{
|
||||
if (dst == NULL || edta == NULL)
|
||||
return NULL;
|
||||
if (elf_getclass () == ELFCLASS32)
|
||||
{
|
||||
if (edta->d_size <= ndx * sizeof (Elf32_Sym))
|
||||
return NULL;
|
||||
Elf32_Sym *hdr = (Elf32_Sym*) bind (edta->d_off + ndx * sizeof (Elf32_Sym), sizeof (Elf32_Sym));
|
||||
if (hdr == NULL)
|
||||
return NULL;
|
||||
dst->st_name = decode (hdr->st_name);
|
||||
dst->st_value = decode (hdr->st_value);
|
||||
dst->st_size = decode (hdr->st_size);
|
||||
dst->st_info = ELF64_ST_INFO (ELF32_ST_BIND (decode (hdr->st_info)),
|
||||
ELF32_ST_TYPE (decode (hdr->st_info)));
|
||||
dst->st_other = decode (hdr->st_other);
|
||||
dst->st_shndx = decode (hdr->st_shndx);
|
||||
}
|
||||
if (bfd_dynsym == NULL && bfd_sym == NULL)
|
||||
get_bfd_symbols ();
|
||||
if (is_dynamic)
|
||||
return bfd_dynsymcnt;
|
||||
return bfd_symcnt;
|
||||
}
|
||||
|
||||
/* Returns an ASYMBOL on index NDX if it exists. If DST is defined,
|
||||
the internal elf symbol at intex NDX is copied into it. IS_DYNAMIC
|
||||
selects the type of the symbol. */
|
||||
|
||||
asymbol *
|
||||
Elf::elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic)
|
||||
{
|
||||
asymbol *asym;
|
||||
|
||||
if (bfd_dynsym == NULL && bfd_sym == NULL)
|
||||
get_bfd_symbols ();
|
||||
|
||||
if (is_dynamic)
|
||||
if (ndx < bfd_dynsymcnt)
|
||||
asym = bfd_dynsym[ndx];
|
||||
else
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
if (edta->d_size <= ndx * sizeof (Elf64_Sym))
|
||||
return NULL;
|
||||
Elf64_Sym *hdr = (Elf64_Sym*) bind (edta->d_off + ndx * sizeof (Elf64_Sym),
|
||||
sizeof (Elf64_Sym));
|
||||
if (hdr == NULL)
|
||||
return NULL;
|
||||
dst->st_name = decode (hdr->st_name);
|
||||
dst->st_value = decode (hdr->st_value);
|
||||
dst->st_size = decode (hdr->st_size);
|
||||
dst->st_info = decode (hdr->st_info);
|
||||
dst->st_other = decode (hdr->st_other);
|
||||
dst->st_shndx = decode (hdr->st_shndx);
|
||||
}
|
||||
return dst;
|
||||
if (ndx < bfd_symcnt)
|
||||
asym = bfd_sym[ndx];
|
||||
else
|
||||
return NULL;
|
||||
|
||||
if (dst != NULL)
|
||||
*dst = ((elf_symbol_type *) asym)->internal_elf_sym;
|
||||
|
||||
return asym;
|
||||
}
|
||||
|
||||
Elf_Internal_Rela *
|
||||
|
||||
@@ -92,7 +92,8 @@ public:
|
||||
int64_t elf_checksum ();
|
||||
uint64_t get_baseAddr();
|
||||
char *elf_strptr (unsigned int sec, uint64_t off);
|
||||
Elf_Internal_Sym *elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst);
|
||||
long elf_getSymCount (bool is_dynamic);
|
||||
asymbol *elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic);
|
||||
Elf_Internal_Rela *elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
|
||||
Elf_Internal_Rela *elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
|
||||
Elf64_Ancillary *elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst);
|
||||
|
||||
@@ -1702,43 +1702,31 @@ Stabs::check_Symtab ()
|
||||
pltSym->flags |= SYM_PLT;
|
||||
}
|
||||
}
|
||||
if (elf->symtab)
|
||||
readSymSec (elf->symtab, elf);
|
||||
else
|
||||
{
|
||||
readSymSec (elf->SUNW_ldynsym, elf);
|
||||
readSymSec (elf->dynsym, elf);
|
||||
}
|
||||
|
||||
// Read first static symbols
|
||||
readSymSec (elf, false);
|
||||
|
||||
// Read dynamic symbols
|
||||
readSymSec (elf, true);
|
||||
}
|
||||
|
||||
void
|
||||
Stabs::readSymSec (unsigned int sec, Elf *elf)
|
||||
Stabs::readSymSec (Elf *elf, bool is_dynamic)
|
||||
{
|
||||
Symbol *sitem;
|
||||
Sp_lang_code local_lcode;
|
||||
if (sec == 0)
|
||||
return;
|
||||
// Get ELF data
|
||||
Elf_Data *data = elf->elf_getdata (sec);
|
||||
if (data == NULL)
|
||||
return;
|
||||
uint64_t SymtabSize = data->d_size;
|
||||
Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
|
||||
|
||||
if ((SymtabSize == 0) || (shdr->sh_entsize == 0))
|
||||
return;
|
||||
Elf_Data *data_str = elf->elf_getdata (shdr->sh_link);
|
||||
if (data_str == NULL)
|
||||
return;
|
||||
char *Strtab = (char *) data_str->d_buf;
|
||||
unsigned int tot = elf->elf_getSymCount (is_dynamic);
|
||||
|
||||
// read func symbolic table
|
||||
for (unsigned int n = 0, tot = SymtabSize / shdr->sh_entsize; n < tot; n++)
|
||||
for (unsigned int n = 0; n < tot; n++)
|
||||
{
|
||||
Elf_Internal_Sym Sym;
|
||||
elf->elf_getsym (data, n, &Sym);
|
||||
const char *st_name = Sym.st_name < data_str->d_size ?
|
||||
(Strtab + Sym.st_name) : NTXT ("no_name");
|
||||
asymbol *asym;
|
||||
asym = elf->elf_getsym (n, &Sym, is_dynamic);
|
||||
// TBD: convert this check to an assert
|
||||
if (asym == NULL)
|
||||
break;
|
||||
const char *st_name = bfd_asymbol_name (asym);
|
||||
switch (GELF_ST_TYPE (Sym.st_info))
|
||||
{
|
||||
case STT_FUNC:
|
||||
|
||||
@@ -129,7 +129,7 @@ class Stabs {
|
||||
|
||||
// Interface with Elf Symbol Table
|
||||
void check_Symtab();
|
||||
void readSymSec(unsigned int sec, Elf *elf);
|
||||
void readSymSec (Elf *elf, bool is_dynamic);
|
||||
void get_save_addr(bool need_swap_endian);
|
||||
Symbol *map_PC_to_sym(uint64_t pc);
|
||||
Symbol *pltSym;
|
||||
|
||||
Reference in New Issue
Block a user