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

"H.J. Lu" <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
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 <[email protected]>
---
 binutils/readelf.c | 162 +++++++++++++++++----------------------------
 1 file changed, 59 insertions(+), 103 deletions(-)

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.  */
-- 
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.