[PATCH 4/5] readelf: Consolidate get_[32|64]bit_elf_symbols

"H.J. Lu" <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
Consolidate get_32bit_elf_symbols and get_64bit_elf_symbols into
get_elf_symbols.  Use BYTE_GET_SIZE to retrieve external symbol
table fields.

	PR binutils/34356
	* readelf.c (get_32bit_elf_symbols): Renamed to ...
	(get_elf_symbols): This.  Updated to support 64-bit symbol table.
	(get_64bit_elf_symbols): Removed.

Signed-off-by: H.J. Lu <[email protected]>
---
 binutils/readelf.c | 167 +++++++--------------------------------------
 1 file changed, 26 insertions(+), 141 deletions(-)

diff --git a/binutils/readelf.c b/binutils/readelf.c
index 21a237b52a7..fe87467a032 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -8021,12 +8021,12 @@ get_section_headers (Filedata *filedata, bool probe)
 }
 
 static Elf_Internal_Sym *
-get_32bit_elf_symbols (Filedata *filedata,
-		       Elf_Internal_Shdr *section,
-		       uint64_t *num_syms_return)
+get_elf_symbols (Filedata *filedata,
+		 Elf_Internal_Shdr *section,
+		 uint64_t *num_syms_return)
 {
   uint64_t number = 0;
-  Elf32_External_Sym * esyms = NULL;
+  void * esyms = NULL, * ptr;
   Elf_External_Sym_Shndx * shndx = NULL;
   Elf_Internal_Sym * isyms = NULL;
   Elf_Internal_Sym * psym;
@@ -8059,7 +8059,13 @@ get_32bit_elf_symbols (Filedata *filedata,
 
   number = section->sh_size / section->sh_entsize;
 
-  if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
+  unsigned int sizeof_External_Sym;
+  if (is_32bit_elf)
+    sizeof_External_Sym = sizeof (Elf32_External_Sym);
+  else
+    sizeof_External_Sym = sizeof (Elf64_External_Sym);
+
+  if (number * sizeof_External_Sym > section->sh_size + 1)
     {
       error (_("Size (%#" PRIx64 ") of section %s "
 	       "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
@@ -8069,8 +8075,8 @@ get_32bit_elf_symbols (Filedata *filedata,
       goto exit_point;
     }
 
-  esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
-                                           section->sh_size, _("symbols"));
+  esyms = get_data (NULL, filedata, section->sh_offset, 1,
+		    section->sh_size, _("symbols"));
   if (esyms == NULL)
     goto exit_point;
 
@@ -8112,138 +8118,28 @@ get_32bit_elf_symbols (Filedata *filedata,
       goto exit_point;
     }
 
+  ptr = esyms;
   for (j = 0, psym = isyms; j < number; j++, psym++)
     {
-      psym->st_name  = BYTE_GET (esyms[j].st_name);
-      psym->st_value = BYTE_GET (esyms[j].st_value);
-      psym->st_size  = BYTE_GET (esyms[j].st_size);
-      psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
-      if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
-	psym->st_shndx
-	  = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
-      else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
-	psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
-      psym->st_info  = BYTE_GET (esyms[j].st_info);
-      psym->st_other = BYTE_GET (esyms[j].st_other);
-    }
-
- exit_point:
-  free (shndx);
-  free (esyms);
-
-  if (num_syms_return != NULL)
-    * num_syms_return = isyms == NULL ? 0 : number;
-
-  return isyms;
-}
-
-static Elf_Internal_Sym *
-get_64bit_elf_symbols (Filedata *filedata,
-		       Elf_Internal_Shdr *section,
-		       uint64_t *num_syms_return)
-{
-  uint64_t number = 0;
-  Elf64_External_Sym * esyms = NULL;
-  Elf_External_Sym_Shndx * shndx = NULL;
-  Elf_Internal_Sym * isyms = NULL;
-  Elf_Internal_Sym * psym;
-  unsigned int j;
-  elf_section_list * entry;
-
-  if (section->sh_size == 0)
-    {
-      if (num_syms_return != NULL)
-	* num_syms_return = 0;
-      return NULL;
-    }
-
-  /* Run some sanity checks first.  */
-  if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
-    {
-      error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
-	     printable_section_name (filedata, section),
-	     section->sh_entsize);
-      goto exit_point;
-    }
-
-  if (section->sh_size > filedata->file_size)
-    {
-      error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
-	     printable_section_name (filedata, section),
-	     section->sh_size);
-      goto exit_point;
-    }
-
-  number = section->sh_size / section->sh_entsize;
-
-  if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
-    {
-      error (_("Size (%#" PRIx64 ") of section %s "
-	       "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
-	     section->sh_size,
-	     printable_section_name (filedata, section),
-	     section->sh_entsize);
-      goto exit_point;
-    }
-
-  esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
-                                           section->sh_size, _("symbols"));
-  if (!esyms)
-    goto exit_point;
-
-  shndx = NULL;
-  for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
-    {
-      if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
-	continue;
-
-      if (shndx != NULL)
+      BYTE_GET_SIZE (psym->st_name, ptr, 4);
+      if (is_32bit_elf)
 	{
-	  error (_("Multiple symbol table index sections associated with the same symbol section\n"));
-	  free (shndx);
+	  BYTE_GET_SIZE (psym->st_value, ptr, 4);
+	  BYTE_GET_SIZE (psym->st_size, ptr, 4);
 	}
-
-      shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
-						   entry->hdr->sh_offset,
-						   1, entry->hdr->sh_size,
-						   _("symbol table section indices"));
-      if (shndx == NULL)
-	goto exit_point;
-
-      /* PR17531: file: heap-buffer-overflow */
-      if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
-	{
-	  error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
-		 printable_section_name (filedata, entry->hdr),
-		 entry->hdr->sh_size,
-		 section->sh_size);
-	  goto exit_point;
-	}
-    }
-
-  isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
-
-  if (isyms == NULL)
-    {
-      error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
-      goto exit_point;
-    }
-
-  for (j = 0, psym = isyms; j < number; j++, psym++)
-    {
-      psym->st_name  = BYTE_GET (esyms[j].st_name);
-      psym->st_info  = BYTE_GET (esyms[j].st_info);
-      psym->st_other = BYTE_GET (esyms[j].st_other);
-      psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
-
+      BYTE_GET_SIZE (psym->st_info, ptr, 1);
+      BYTE_GET_SIZE (psym->st_other, ptr, 1);
+      BYTE_GET_SIZE (psym->st_shndx, ptr, 2);
       if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
 	psym->st_shndx
 	  = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
       else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
 	psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
-
-      psym->st_value = BYTE_GET (esyms[j].st_value);
-      psym->st_size  = BYTE_GET (esyms[j].st_size);
+      if (!is_32bit_elf)
+	{
+	  BYTE_GET_SIZE (psym->st_value, ptr, 8);
+	  BYTE_GET_SIZE (psym->st_size, ptr, 8);
+	}
     }
 
  exit_point:
@@ -8256,17 +8152,6 @@ get_64bit_elf_symbols (Filedata *filedata,
   return isyms;
 }
 
-static Elf_Internal_Sym *
-get_elf_symbols (Filedata *filedata,
-		 Elf_Internal_Shdr *section,
-		 uint64_t *num_syms_return)
-{
-  if (is_32bit_elf)
-    return get_32bit_elf_symbols (filedata, section, num_syms_return);
-  else
-    return get_64bit_elf_symbols (filedata, section, num_syms_return);
-}
-
 static const char *
 get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
 {
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.