* elfcode.h (elf_swap_ehdr_out): Handle e_phnum > 0xffff.

(elf_object_p): Read e_phnum extension.
	(elf_write_shdrs_and_ehdr): Write e_phnum extension.
        * elfcore.h (elf_core_file_p): Read e_phnum extension.  Sanity check
	that we can read last program header.
This commit is contained in:
Alan Modra 2010-01-19 13:50:55 +00:00
parent c75a08aa7c
commit ecd12bc14d
3 changed files with 80 additions and 3 deletions

View File

@ -1,3 +1,12 @@
2010-01-19 Daisuke Hatayama <d.hatayama@jp.fujitsu.com>
Alan Modra <amodra@gmail.com>
* elfcode.h (elf_swap_ehdr_out): Handle e_phnum > 0xffff.
(elf_object_p): Read e_phnum extension.
(elf_write_shdrs_and_ehdr): Write e_phnum extension.
* elfcore.h (elf_core_file_p): Read e_phnum extension. Sanity check
that we can read last program header.
2010-01-19 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
* elf32-arm.c (elf32_arm_howto_table_1): Correct bitsize of

View File

@ -1,6 +1,6 @@
/* ELF executable support for BFD.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
@ -279,7 +279,10 @@ elf_swap_ehdr_out (bfd *abfd,
H_PUT_32 (abfd, src->e_flags, dst->e_flags);
H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize);
H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize);
H_PUT_16 (abfd, src->e_phnum, dst->e_phnum);
tmp = src->e_phnum;
if (tmp > PN_XNUM)
tmp = PN_XNUM;
H_PUT_16 (abfd, tmp, dst->e_phnum);
H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize);
tmp = src->e_shnum;
if (tmp >= (SHN_LORESERVE & 0xffff))
@ -701,6 +704,14 @@ elf_object_p (bfd *abfd)
goto got_wrong_format_error;
}
/* And program headers. */
if (i_ehdrp->e_phnum == PN_XNUM && i_shdr.sh_info != 0)
{
i_ehdrp->e_phnum = i_shdr.sh_info;
if (i_ehdrp->e_phnum != i_shdr.sh_info)
goto got_wrong_format_error;
}
/* Sanity check that we can read all of the section headers.
It ought to be good enough to just read the last one. */
if (i_ehdrp->e_shnum != 1)
@ -1072,6 +1083,8 @@ elf_write_shdrs_and_ehdr (bfd *abfd)
/* Some fields in the first section header handle overflow of ehdr
fields. */
if (i_ehdrp->e_phnum >= PN_XNUM)
i_shdrp[0]->sh_info = i_ehdrp->e_phnum;
if (i_ehdrp->e_shnum >= (SHN_LORESERVE & 0xffff))
i_shdrp[0]->sh_size = i_ehdrp->e_shnum;
if (i_ehdrp->e_shstrndx >= (SHN_LORESERVE & 0xffff))

View File

@ -1,6 +1,6 @@
/* ELF core file support for BFD.
Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007,
2008 Free Software Foundation, Inc.
2008, 2010 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -184,6 +184,61 @@ elf_core_file_p (bfd *abfd)
if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
goto wrong;
/* If the program header count is PN_XNUM(0xffff), the actual
count is in the first section header. */
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 (i_shdr.sh_info != 0)
{
i_ehdrp->e_phnum = i_shdr.sh_info;
if (i_ehdrp->e_phnum != i_shdr.sh_info)
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;
bfd_signed_vma where;
/* 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;
}
/* Move to the start of the program headers. */
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
goto wrong;