This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[RFC][PATCH 3/3] libbfd: Add extended numbering support
- From: Daisuke HATAYAMA <d dot hatayama at jp dot fujitsu dot com>
- To: binutils at sourceware dot org
- Date: Fri, 15 Jan 2010 11:47:49 +0900 (JST)
- Subject: [RFC][PATCH 3/3] libbfd: Add extended numbering support
- References: <20100115.114307.193710254.d.hatayama@jp.fujitsu.com>
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