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)
|
if (ScnSize == 0 || EntSize == 0)
|
||||||
return;
|
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;
|
Elf_Internal_Rela rela;
|
||||||
int n, cnt = (int) (ScnSize / EntSize);
|
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);
|
int ndx = (int) GELF_R_SYM (rela.r_info);
|
||||||
Elf_Internal_Shdr *secHdr;
|
Elf_Internal_Shdr *secHdr;
|
||||||
Elf_Internal_Sym sym;
|
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|"),
|
Dprintf (DUMP_RELA_SEC, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"),
|
||||||
n, (int) rela.r_addend,
|
n, (int) rela.r_addend,
|
||||||
(long long) rela.r_offset, (long long) rela.r_info,
|
(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_FUNC:
|
||||||
case STT_OBJECT:
|
case STT_OBJECT:
|
||||||
case STT_NOTYPE:
|
case STT_NOTYPE:
|
||||||
secHdr = elf->get_shdr (sym.st_shndx);
|
Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
|
||||||
if (secHdr)
|
(long long) (bfd_asymbol_value (asym)));
|
||||||
Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
|
Dprintf (DUMP_RELA_SEC, NTXT (" %s"), bfd_asymbol_name (asym));
|
||||||
(long long) (sym.st_value + secHdr->sh_offset));
|
|
||||||
if (Strtab && sym.st_name)
|
|
||||||
Dprintf (DUMP_RELA_SEC, NTXT (" %s"), Strtab + sym.st_name);
|
|
||||||
break;
|
break;
|
||||||
case STT_SECTION:
|
case STT_SECTION:
|
||||||
secHdr = elf->get_shdr (sym.st_shndx);
|
secHdr = elf->get_shdr (sym.st_shndx);
|
||||||
@@ -311,10 +303,6 @@ ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
|
|||||||
return rlc;
|
return rlc;
|
||||||
|
|
||||||
int cnt = (int) (data->d_size / shdr->sh_entsize);
|
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;
|
Vector<Sreloc *> *vp = NULL;
|
||||||
|
|
||||||
for (int n = 0; n < cnt; n++)
|
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);
|
int ndx = (int) GELF_R_SYM (rela.r_info);
|
||||||
Elf_Internal_Sym sym;
|
Elf_Internal_Sym sym;
|
||||||
elfp->elf_getsym (data_sym, ndx, &sym);
|
elfp->elf_getsym (ndx, &sym, false);
|
||||||
|
|
||||||
srlc = new Sreloc;
|
srlc = new Sreloc;
|
||||||
srlc->offset = rela.r_offset;
|
srlc->offset = rela.r_offset;
|
||||||
|
|||||||
@@ -533,42 +533,43 @@ Elf::elf_strptr (unsigned int sec, uint64_t off)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf_Internal_Sym *
|
long
|
||||||
Elf::elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst)
|
Elf::elf_getSymCount (bool is_dynamic)
|
||||||
{
|
{
|
||||||
if (dst == NULL || edta == NULL)
|
if (bfd_dynsym == NULL && bfd_sym == NULL)
|
||||||
return NULL;
|
get_bfd_symbols ();
|
||||||
if (elf_getclass () == ELFCLASS32)
|
if (is_dynamic)
|
||||||
{
|
return bfd_dynsymcnt;
|
||||||
if (edta->d_size <= ndx * sizeof (Elf32_Sym))
|
return bfd_symcnt;
|
||||||
return NULL;
|
}
|
||||||
Elf32_Sym *hdr = (Elf32_Sym*) bind (edta->d_off + ndx * sizeof (Elf32_Sym), sizeof (Elf32_Sym));
|
|
||||||
if (hdr == NULL)
|
/* Returns an ASYMBOL on index NDX if it exists. If DST is defined,
|
||||||
return NULL;
|
the internal elf symbol at intex NDX is copied into it. IS_DYNAMIC
|
||||||
dst->st_name = decode (hdr->st_name);
|
selects the type of the symbol. */
|
||||||
dst->st_value = decode (hdr->st_value);
|
|
||||||
dst->st_size = decode (hdr->st_size);
|
asymbol *
|
||||||
dst->st_info = ELF64_ST_INFO (ELF32_ST_BIND (decode (hdr->st_info)),
|
Elf::elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic)
|
||||||
ELF32_ST_TYPE (decode (hdr->st_info)));
|
{
|
||||||
dst->st_other = decode (hdr->st_other);
|
asymbol *asym;
|
||||||
dst->st_shndx = decode (hdr->st_shndx);
|
|
||||||
}
|
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
|
else
|
||||||
{
|
if (ndx < bfd_symcnt)
|
||||||
if (edta->d_size <= ndx * sizeof (Elf64_Sym))
|
asym = bfd_sym[ndx];
|
||||||
return NULL;
|
else
|
||||||
Elf64_Sym *hdr = (Elf64_Sym*) bind (edta->d_off + ndx * sizeof (Elf64_Sym),
|
return NULL;
|
||||||
sizeof (Elf64_Sym));
|
|
||||||
if (hdr == NULL)
|
if (dst != NULL)
|
||||||
return NULL;
|
*dst = ((elf_symbol_type *) asym)->internal_elf_sym;
|
||||||
dst->st_name = decode (hdr->st_name);
|
|
||||||
dst->st_value = decode (hdr->st_value);
|
return asym;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf_Internal_Rela *
|
Elf_Internal_Rela *
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ public:
|
|||||||
int64_t elf_checksum ();
|
int64_t elf_checksum ();
|
||||||
uint64_t get_baseAddr();
|
uint64_t get_baseAddr();
|
||||||
char *elf_strptr (unsigned int sec, uint64_t off);
|
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_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);
|
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);
|
Elf64_Ancillary *elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst);
|
||||||
|
|||||||
@@ -1702,43 +1702,31 @@ Stabs::check_Symtab ()
|
|||||||
pltSym->flags |= SYM_PLT;
|
pltSym->flags |= SYM_PLT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (elf->symtab)
|
|
||||||
readSymSec (elf->symtab, elf);
|
// Read first static symbols
|
||||||
else
|
readSymSec (elf, false);
|
||||||
{
|
|
||||||
readSymSec (elf->SUNW_ldynsym, elf);
|
// Read dynamic symbols
|
||||||
readSymSec (elf->dynsym, elf);
|
readSymSec (elf, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Stabs::readSymSec (unsigned int sec, Elf *elf)
|
Stabs::readSymSec (Elf *elf, bool is_dynamic)
|
||||||
{
|
{
|
||||||
Symbol *sitem;
|
Symbol *sitem;
|
||||||
Sp_lang_code local_lcode;
|
Sp_lang_code local_lcode;
|
||||||
if (sec == 0)
|
unsigned int tot = elf->elf_getSymCount (is_dynamic);
|
||||||
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;
|
|
||||||
|
|
||||||
// read func symbolic table
|
// 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_Internal_Sym Sym;
|
||||||
elf->elf_getsym (data, n, &Sym);
|
asymbol *asym;
|
||||||
const char *st_name = Sym.st_name < data_str->d_size ?
|
asym = elf->elf_getsym (n, &Sym, is_dynamic);
|
||||||
(Strtab + Sym.st_name) : NTXT ("no_name");
|
// 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))
|
switch (GELF_ST_TYPE (Sym.st_info))
|
||||||
{
|
{
|
||||||
case STT_FUNC:
|
case STT_FUNC:
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ class Stabs {
|
|||||||
|
|
||||||
// Interface with Elf Symbol Table
|
// Interface with Elf Symbol Table
|
||||||
void check_Symtab();
|
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);
|
void get_save_addr(bool need_swap_endian);
|
||||||
Symbol *map_PC_to_sym(uint64_t pc);
|
Symbol *map_PC_to_sym(uint64_t pc);
|
||||||
Symbol *pltSym;
|
Symbol *pltSym;
|
||||||
|
|||||||
Reference in New Issue
Block a user