[3/5] readelf: Consolidate get_[32|64]bit_program_headers

Message ID 20260709124052.680684-4-hjl.tools@gmail.com
State New
Headers
Series readelf.c: Consolidating get_[32|64]bit_XXX into get_XXX |

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-arm success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed

Commit Message

H.J. Lu July 9, 2026, 12:40 p.m. UTC
  Consolidate get_32bit_program_headers and get_64bit_program_headers into
get_program_headers.  Use BYTE_GET_SIZE to retrieve external ELF program
header fields.

	PR binutils/34356
	* readelf.c (get_32bit_program_headers): Moved to ...
	(get_program_headers): This.  Use BYTE_GET_SIZE to retrieve
	external ELF program header fields.
	(get_64bit_program_headers): Removed.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 binutils/readelf.c | 162 +++++++++++++++++----------------------------
 1 file changed, 59 insertions(+), 103 deletions(-)
  

Patch

diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1e3caeec252..21a237b52a7 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -7361,100 +7361,6 @@  process_file_header (Filedata * filedata)
   return true;
 }
 
-/* Read in the program headers from FILEDATA and store them in PHEADERS.
-   Returns TRUE upon success, FALSE otherwise.  Loads 32-bit headers.  */
-
-static bool
-get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
-{
-  Elf32_External_Phdr * phdrs;
-  Elf32_External_Phdr * external;
-  Elf_Internal_Phdr *   internal;
-  unsigned int i;
-  unsigned int size = filedata->file_header.e_phentsize;
-  unsigned int num  = filedata->file_header.e_phnum;
-
-  /* PR binutils/17531: Cope with unexpected section header sizes.  */
-  if (size == 0 || num == 0)
-    return false;
-  if (size < sizeof * phdrs)
-    {
-      error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
-      return false;
-    }
-  if (size > sizeof * phdrs)
-    warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
-
-  phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
-                                            size, num, _("program headers"));
-  if (phdrs == NULL)
-    return false;
-
-  for (i = 0, internal = pheaders, external = phdrs;
-       i < filedata->file_header.e_phnum;
-       i++, internal++, external++)
-    {
-      internal->p_type   = BYTE_GET (external->p_type);
-      internal->p_offset = BYTE_GET (external->p_offset);
-      internal->p_vaddr  = BYTE_GET (external->p_vaddr);
-      internal->p_paddr  = BYTE_GET (external->p_paddr);
-      internal->p_filesz = BYTE_GET (external->p_filesz);
-      internal->p_memsz  = BYTE_GET (external->p_memsz);
-      internal->p_flags  = BYTE_GET (external->p_flags);
-      internal->p_align  = BYTE_GET (external->p_align);
-    }
-
-  free (phdrs);
-  return true;
-}
-
-/* Read in the program headers from FILEDATA and store them in PHEADERS.
-   Returns TRUE upon success, FALSE otherwise.  Loads 64-bit headers.  */
-
-static bool
-get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
-{
-  Elf64_External_Phdr * phdrs;
-  Elf64_External_Phdr * external;
-  Elf_Internal_Phdr *   internal;
-  unsigned int i;
-  unsigned int size = filedata->file_header.e_phentsize;
-  unsigned int num  = filedata->file_header.e_phnum;
-
-  /* PR binutils/17531: Cope with unexpected section header sizes.  */
-  if (size == 0 || num == 0)
-    return false;
-  if (size < sizeof * phdrs)
-    {
-      error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
-      return false;
-    }
-  if (size > sizeof * phdrs)
-    warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
-
-  phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
-                                            size, num, _("program headers"));
-  if (!phdrs)
-    return false;
-
-  for (i = 0, internal = pheaders, external = phdrs;
-       i < filedata->file_header.e_phnum;
-       i++, internal++, external++)
-    {
-      internal->p_type   = BYTE_GET (external->p_type);
-      internal->p_flags  = BYTE_GET (external->p_flags);
-      internal->p_offset = BYTE_GET (external->p_offset);
-      internal->p_vaddr  = BYTE_GET (external->p_vaddr);
-      internal->p_paddr  = BYTE_GET (external->p_paddr);
-      internal->p_filesz = BYTE_GET (external->p_filesz);
-      internal->p_memsz  = BYTE_GET (external->p_memsz);
-      internal->p_align  = BYTE_GET (external->p_align);
-    }
-
-  free (phdrs);
-  return true;
-}
-
 /* Returns TRUE if the program headers were read into `program_headers'.  */
 
 static bool
@@ -7466,10 +7372,22 @@  get_program_headers (Filedata * filedata)
   if (filedata->program_headers != NULL)
     return true;
 
+  unsigned int elf_class_size;
+  unsigned int sizeof_External_Phdr;
+  if (is_32bit_elf)
+    {
+      elf_class_size = 4;
+      sizeof_External_Phdr = sizeof (Elf32_External_Phdr);
+    }
+  else
+    {
+      elf_class_size = 8;
+      sizeof_External_Phdr = sizeof (Elf64_External_Phdr);
+    }
+
   /* Be kind to memory checkers by looking for
      e_phnum values which we know must be invalid.  */
-  if (filedata->file_header.e_phnum
-      * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
+  if (filedata->file_header.e_phnum * sizeof_External_Phdr
       >= filedata->file_size)
     {
       error (_("Too many program headers - %#x - the file is not that big\n"),
@@ -7486,16 +7404,54 @@  get_program_headers (Filedata * filedata)
       return false;
     }
 
-  if (is_32bit_elf
-      ? get_32bit_program_headers (filedata, phdrs)
-      : get_64bit_program_headers (filedata, phdrs))
+  unsigned int i;
+  unsigned int size = filedata->file_header.e_phentsize;
+  unsigned int num  = filedata->file_header.e_phnum;
+  void *e_phdrs, *external;
+  Elf_Internal_Phdr *internal;
+
+  /* PR binutils/17531: Cope with unexpected section header sizes.  */
+  if (size == 0 || num == 0)
+    {
+      free (phdrs);
+      return false;
+    }
+
+  if (size != sizeof_External_Phdr)
+    warn (_("The e_phentsize field (%u) in the ELF header isn't the "
+	    "same as the size of an ELF program header (%u)\n"),
+	  size, sizeof_External_Phdr);
+
+  e_phdrs = get_data (NULL, filedata, filedata->file_header.e_phoff,
+		      size, num, _("program headers"));
+  if (e_phdrs == NULL)
     {
-      filedata->program_headers = phdrs;
-      return true;
+      free (phdrs);
+      return false;
     }
 
-  free (phdrs);
-  return false;
+  external = e_phdrs;
+  for (i = 0, internal = phdrs;
+       i < filedata->file_header.e_phnum;
+       i++, internal++)
+    {
+      BYTE_GET_SIZE (internal->p_type, external, 4);
+      if (!is_32bit_elf)
+	BYTE_GET_SIZE (internal->p_flags, external, 4);
+      BYTE_GET_SIZE (internal->p_offset, external, elf_class_size);
+      BYTE_GET_SIZE (internal->p_vaddr, external, elf_class_size);
+      BYTE_GET_SIZE (internal->p_paddr, external, elf_class_size);
+      BYTE_GET_SIZE (internal->p_filesz, external, elf_class_size);
+      BYTE_GET_SIZE (internal->p_memsz, external, elf_class_size);
+      if (is_32bit_elf)
+	BYTE_GET_SIZE (internal->p_flags, external, 4);
+      BYTE_GET_SIZE (internal->p_align, external, elf_class_size);
+    }
+
+  free (e_phdrs);
+
+  filedata->program_headers = phdrs;
+  return true;
 }
 
 /* Print program header info and locate dynamic section.  */