This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC][PATCH 3/3] libbfd: Add extended numbering support


Add extended numbering support for libbfd, which allows libbfd library
to read ELF core object file with more-than-65535 program headers.

The ELF format need comfort to the extended ELF format.

There is no change if reading ordinary ELF object file.
---
 bfd/elfcore.h |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/bfd/elfcore.h b/bfd/elfcore.h
index c51c575..eea9e0f 100644
--- a/bfd/elfcore.h
+++ b/bfd/elfcore.h
@@ -184,6 +184,63 @@ elf_core_file_p (bfd *abfd)
   if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
     goto wrong;
 
+  if (i_ehdrp->e_shoff != 0 && i_ehdrp->e_phnum == PN_XNUM)
+    {
+      Elf_External_Shdr x_shdr;
+      Elf_Internal_Shdr i_shdr;
+      bfd_signed_vma where = i_ehdrp->e_shoff;
+
+      if (where != (file_ptr) where)
+	goto wrong;
+
+      /* Seek to the section header table in the file.  */
+      if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+	goto fail;
+
+      /* Read the first section header at index 0, and convert to internal
+	 form.  */
+      if (bfd_bread (&x_shdr, sizeof (x_shdr), abfd) != sizeof (x_shdr))
+	goto fail;
+      elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
+
+      /* If the program header count is PN_XNUM(0xffff), the actual
+	 count is in the first section header.  */
+      i_ehdrp->e_phnum = i_shdr.sh_info;
+      if (i_ehdrp->e_phnum != i_shdr.sh_info
+	  || i_ehdrp->e_phnum == 0)
+	goto wrong;
+
+      /* Sanity check that we can read all of the program headers.
+	 It ought to be good enough to just read the last one.  */
+      if (i_ehdrp->e_phnum > 1)
+	{
+	  Elf_External_Phdr x_phdr;
+	  Elf_Internal_Phdr i_phdr;
+
+	  /* Check that we don't have a totally silly number of
+	     program headers.  */
+	  if (i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (x_phdr)
+	      || i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (i_phdr))
+	    goto wrong;
+
+	  where = i_ehdrp->e_phoff + (i_ehdrp->e_phnum - 1) * sizeof (x_phdr);
+	  if (where != (file_ptr) where)
+	    goto wrong;
+	  if ((bfd_size_type) where <= i_ehdrp->e_phoff)
+	    goto wrong;
+
+	  if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+	    goto fail;
+	  if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
+	    goto fail;
+
+	  /* Back to where we were.  */
+	  where = i_ehdrp->e_shoff + sizeof (x_shdr);
+	  if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+	    goto fail;
+	}
+    }
+
   /* Move to the start of the program headers.  */
   if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
     goto wrong;
-- 
1.6.5.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]