* elfcode.h (elf_swap_ehdr_out): Adjust value written for e_shnum
and e_shstrndx if out of range. (elf_object_p): Read extended values for e_shnum and e_shstrndx from the first section header. Allocate space in elf_elfsections for reserved sections and set to NULLs. (elf_write_shdrs_and_ehdr): Set overflow fields in first section header. Skip reserved sections in elf_elfsections. Remove duplicate size calculation.
This commit is contained in:
parent
2d4d1975bd
commit
5732c11485
2 changed files with 81 additions and 15 deletions
|
@ -1,3 +1,14 @@
|
|||
2001-12-11 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elfcode.h (elf_swap_ehdr_out): Adjust value written for e_shnum
|
||||
and e_shstrndx if out of range.
|
||||
(elf_object_p): Read extended values for e_shnum and e_shstrndx
|
||||
from the first section header. Allocate space in elf_elfsections
|
||||
for reserved sections and set to NULLs.
|
||||
(elf_write_shdrs_and_ehdr): Set overflow fields in first section
|
||||
header. Skip reserved sections in elf_elfsections. Remove
|
||||
duplicate size calculation.
|
||||
|
||||
2001-12-07 Geoffrey Keating <geoffk@redhat.com>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
Corinna Vinschen <vinschen@redhat.com>
|
||||
|
|
|
@ -277,6 +277,7 @@ elf_swap_ehdr_out (abfd, src, dst)
|
|||
const Elf_Internal_Ehdr *src;
|
||||
Elf_External_Ehdr *dst;
|
||||
{
|
||||
unsigned int tmp;
|
||||
int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
|
||||
memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
|
||||
/* note that all elements of dst are *arrays of unsigned char* already... */
|
||||
|
@ -294,8 +295,14 @@ elf_swap_ehdr_out (abfd, src, dst)
|
|||
H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize);
|
||||
H_PUT_16 (abfd, src->e_phnum, dst->e_phnum);
|
||||
H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize);
|
||||
H_PUT_16 (abfd, src->e_shnum, dst->e_shnum);
|
||||
H_PUT_16 (abfd, src->e_shstrndx, dst->e_shstrndx);
|
||||
tmp = src->e_shnum;
|
||||
if (tmp >= SHN_LORESERVE)
|
||||
tmp = SHN_UNDEF;
|
||||
H_PUT_16 (abfd, tmp, dst->e_shnum);
|
||||
tmp = src->e_shstrndx;
|
||||
if (tmp >= SHN_LORESERVE)
|
||||
tmp = SHN_XINDEX;
|
||||
H_PUT_16 (abfd, tmp, dst->e_shstrndx);
|
||||
}
|
||||
|
||||
/* Translate an ELF section header table entry in external format into an
|
||||
|
@ -494,6 +501,7 @@ elf_object_p (abfd)
|
|||
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
|
||||
Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
|
||||
Elf_External_Shdr x_shdr; /* Section header table entry, external form */
|
||||
Elf_Internal_Shdr i_shdr;
|
||||
Elf_Internal_Shdr *i_shdrp = NULL; /* Section header table, internal form */
|
||||
unsigned int shindex;
|
||||
char *shstrtab; /* Internal copy of section header stringtab */
|
||||
|
@ -634,27 +642,65 @@ elf_object_p (abfd)
|
|||
/* Remember the entry point specified in the ELF file header. */
|
||||
bfd_set_start_address (abfd, i_ehdrp->e_entry);
|
||||
|
||||
/* Seek to the section header table in the file. */
|
||||
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0)
|
||||
goto got_no_match;
|
||||
|
||||
/* Read the first section header at index 0, and convert to internal
|
||||
form. */
|
||||
if (bfd_bread ((PTR) & x_shdr, (bfd_size_type) sizeof x_shdr, abfd)
|
||||
!= sizeof (x_shdr))
|
||||
goto got_no_match;
|
||||
elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
|
||||
|
||||
/* If the section count is zero, the actual count is in the first
|
||||
section header. */
|
||||
if (i_ehdrp->e_shnum == SHN_UNDEF)
|
||||
i_ehdrp->e_shnum = i_shdr.sh_size;
|
||||
|
||||
/* And similarly for the string table index. */
|
||||
if (i_ehdrp->e_shstrndx == SHN_XINDEX)
|
||||
i_ehdrp->e_shstrndx = i_shdr.sh_link;
|
||||
|
||||
/* Allocate space for a copy of the section header table in
|
||||
internal form, seek to the section header table in the file,
|
||||
read it in, and convert it to internal form. */
|
||||
internal form. */
|
||||
if (i_ehdrp->e_shnum != 0)
|
||||
{
|
||||
Elf_Internal_Shdr *shdrp;
|
||||
|
||||
amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
|
||||
i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
|
||||
if (!i_shdrp)
|
||||
goto got_no_match;
|
||||
amt = sizeof (i_shdrp) * i_ehdrp->e_shnum;
|
||||
if (i_ehdrp->e_shnum > SHN_LORESERVE)
|
||||
amt += sizeof (i_shdrp) * (SHN_HIRESERVE + 1 - SHN_LORESERVE);
|
||||
elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
|
||||
if (!i_shdrp || !elf_elfsections (abfd))
|
||||
goto got_no_match;
|
||||
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0)
|
||||
if (!elf_elfsections (abfd))
|
||||
goto got_no_match;
|
||||
|
||||
memcpy (i_shdrp, &i_shdr, sizeof (*i_shdrp));
|
||||
shdrp = i_shdrp;
|
||||
shindex = 0;
|
||||
if (i_ehdrp->e_shnum > SHN_LORESERVE)
|
||||
{
|
||||
for ( ; shindex < SHN_LORESERVE; shindex++)
|
||||
elf_elfsections (abfd)[shindex] = shdrp++;
|
||||
for ( ; shindex < SHN_HIRESERVE + 1; shindex++)
|
||||
elf_elfsections (abfd)[shindex] = NULL;
|
||||
}
|
||||
for ( ; shindex < i_ehdrp->e_shnum; shindex++)
|
||||
elf_elfsections (abfd)[shindex] = shdrp++;
|
||||
}
|
||||
for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++)
|
||||
|
||||
/* Read in the rest of the section header table and convert it to
|
||||
internal form. */
|
||||
for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
|
||||
{
|
||||
if (bfd_bread ((PTR) & x_shdr, (bfd_size_type) sizeof x_shdr, abfd)
|
||||
!= sizeof (x_shdr))
|
||||
goto got_no_match;
|
||||
elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
|
||||
elf_elfsections (abfd)[shindex] = i_shdrp + shindex;
|
||||
|
||||
/* If the section is loaded, but not page aligned, clear
|
||||
D_PAGED. */
|
||||
|
@ -987,21 +1033,30 @@ elf_write_shdrs_and_ehdr (abfd)
|
|||
|| bfd_bwrite ((PTR) & x_ehdr, amt, abfd) != amt)
|
||||
return false;
|
||||
|
||||
/* Some fields in the first section header handle overflow of ehdr
|
||||
fields. */
|
||||
if (i_ehdrp->e_shnum >= SHN_LORESERVE)
|
||||
i_shdrp[0]->sh_size = i_ehdrp->e_shnum;
|
||||
if (i_ehdrp->e_shstrndx >= SHN_LORESERVE)
|
||||
i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx;
|
||||
|
||||
/* at this point we've concocted all the ELF sections... */
|
||||
amt = sizeof (*x_shdrp) * i_ehdrp->e_shnum;
|
||||
amt = i_ehdrp->e_shnum;
|
||||
amt *= sizeof (*x_shdrp);
|
||||
x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt);
|
||||
if (!x_shdrp)
|
||||
return false;
|
||||
|
||||
for (count = 0; count < i_ehdrp->e_shnum; count++)
|
||||
for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++)
|
||||
{
|
||||
#if DEBUG & 2
|
||||
elf_debug_section (count, i_shdrp[count]);
|
||||
elf_debug_section (count, *i_shdrp);
|
||||
#endif
|
||||
elf_swap_shdr_out (abfd, i_shdrp[count], x_shdrp + count);
|
||||
elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);
|
||||
|
||||
if (count == SHN_LORESERVE - 1)
|
||||
i_shdrp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
|
||||
}
|
||||
amt = i_ehdrp->e_shnum;
|
||||
amt *= sizeof (*x_shdrp);
|
||||
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
|
||||
|| bfd_bwrite ((PTR) x_shdrp, amt, abfd) != amt)
|
||||
return false;
|
||||
|
|
Loading…
Add table
Reference in a new issue