[2/3] gprofng: Refactor readSymSec for using BFD's asymbol struct

Message ID 20250402091530.10597-2-claudiu.zissulescu-ianculescu@oracle.com
State New
Headers
Series [1/3] gprofng: Remove check_Relocs() function |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Claudiu Zissulescu-Ianculescu April 2, 2025, 9:15 a.m. UTC
  From: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>

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>
---
 gprofng/src/DwarfLib.cc | 24 ++++----------
 gprofng/src/Elf.cc      | 69 +++++++++++++++++++++--------------------
 gprofng/src/Elf.h       |  3 +-
 gprofng/src/Stabs.cc    | 42 +++++++++----------------
 gprofng/src/Stabs.h     |  2 +-
 5 files changed, 59 insertions(+), 81 deletions(-)
  

Patch

diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc
index 9b40401138b..d399c3356cf 100644
--- a/gprofng/src/DwarfLib.cc
+++ b/gprofng/src/DwarfLib.cc
@@ -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;
diff --git a/gprofng/src/Elf.cc b/gprofng/src/Elf.cc
index b9da2403bef..f0fd1215a04 100644
--- a/gprofng/src/Elf.cc
+++ b/gprofng/src/Elf.cc
@@ -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 *
diff --git a/gprofng/src/Elf.h b/gprofng/src/Elf.h
index 7c32dfe10b1..b324c394d16 100644
--- a/gprofng/src/Elf.h
+++ b/gprofng/src/Elf.h
@@ -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);
diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc
index 908dcc4b7b4..2f64810b25f 100644
--- a/gprofng/src/Stabs.cc
+++ b/gprofng/src/Stabs.cc
@@ -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:
diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h
index 88c2b8d64a5..a6a572d938c 100644
--- a/gprofng/src/Stabs.h
+++ b/gprofng/src/Stabs.h
@@ -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;