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

H.J. Lu hjl.tools@gmail.com
Thu Jul 9 12:40:51 GMT 2026


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 <hjl.tools@gmail.com>
---
 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



More information about the Binutils mailing list