Add support for files that contain multiple symbol index tables. Fixes PR 15835

binutils	PR binutils/15835
	* readelf.c (struct elf_section_list): New structure.
	(symtab_shndx_hdr): Replace with symtab_shndx_list.
	(get_32bit_elf_symbols): Scan for a symbol index table matching
	the symbol table in use.
	(get_64bit_elf_symbols): Likewise.
	(process_section_headers): Handle multiple symbol index sections.

bfd	* elf-bfd.h (struct elf_section_list): New structure.
	(struct elf_obj_tdata): Replace symtab_shndx_hdr with
	symtab_shndx_list.  Delete symtab_shndx_section.
	(elf_symtab_shndx): Replace macro with elf_symtab_shndx_list.
	* elf.c (bfd_elf_get_syms): If symtab index sections are present,
	scan them for the section that matches the provided symbol table.
	(bfd_section_from_shdr): Record all SHT_SYMTAB_SHNDX sections.
	(assign_section_numbers): Use the first symtab index table in the
	list.
	(_bfd_elf_compute_section_file_positions): Replace use of
	symtab_shndx_hdr with use of symtab_shndx_list.
	(find_section_in_list): New function.
	(assign_file_postions_except_relocs): Use new function.
	(_bfd_elf_copy_private_symbol_data): Likewise.
	(swap_out_syms): Handle multiple symbol table index sections.
	* elf32-m32c.c (m32c_elf_relax_section): Replace use of
	symtab_shndx_hdr with use of symtab_shndx_list.
	* elf32-rl78.c (rl78_elf_relax_section): Likewise.
	* elf32-rx.c (rx_relax_section): Likewise.
	* elf32-v850.c (v850_elf_relax_delete_bytes): Likewise.
	* elflink.c (bfd_elf_final_link): Likewise.
This commit is contained in:
Nick Clifton 2015-09-23 17:23:58 +01:00
parent bcd68f9e44
commit 6a40cf0c5c
10 changed files with 265 additions and 118 deletions

View File

@ -1,3 +1,28 @@
2015-09-23 Nick Clifton <nickc@redhat.com>
PR binutils/15835
* elf-bfd.h (struct elf_section_list): New structure.
(struct elf_obj_tdata): Replace symtab_shndx_hdr with
symtab_shndx_list. Delete symtab_shndx_section.
(elf_symtab_shndx): Replace macro with elf_symtab_shndx_list.
* elf.c (bfd_elf_get_syms): If symtab index sections are present,
scan them for the section that matches the provided symbol table.
(bfd_section_from_shdr): Record all SHT_SYMTAB_SHNDX sections.
(assign_section_numbers): Use the first symtab index table in the
list.
(_bfd_elf_compute_section_file_positions): Replace use of
symtab_shndx_hdr with use of symtab_shndx_list.
(find_section_in_list): New function.
(assign_file_postions_except_relocs): Use new function.
(_bfd_elf_copy_private_symbol_data): Likewise.
(swap_out_syms): Handle multiple symbol table index sections.
* elf32-m32c.c (m32c_elf_relax_section): Replace use of
symtab_shndx_hdr with use of symtab_shndx_list.
* elf32-rl78.c (rl78_elf_relax_section): Likewise.
* elf32-rx.c (rx_relax_section): Likewise.
* elf32-v850.c (v850_elf_relax_delete_bytes): Likewise.
* elflink.c (bfd_elf_final_link): Likewise.
2015-09-21 H.J. Lu <hongjiu.lu@intel.com>
* bfd.c (bfd_update_compression_header): Use bfd_put_32 on

View File

@ -1654,6 +1654,14 @@ enum elf_gnu_symbols
elf_gnu_symbol_all = (elf_gnu_symbol_ifunc | elf_gnu_symbol_unique)
};
typedef struct elf_section_list
{
Elf_Internal_Shdr hdr;
unsigned int ndx;
struct elf_section_list * next;
} elf_section_list;
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
@ -1670,7 +1678,7 @@ struct elf_obj_tdata
Elf_Internal_Shdr dynversym_hdr;
Elf_Internal_Shdr dynverref_hdr;
Elf_Internal_Shdr dynverdef_hdr;
Elf_Internal_Shdr symtab_shndx_hdr;
elf_section_list * symtab_shndx_list;
bfd_vma gp; /* The gp value */
unsigned int gp_size; /* The gp size */
unsigned int num_elf_sections; /* elf_sect_ptr size */
@ -1745,7 +1753,7 @@ struct elf_obj_tdata
Elf_Internal_Shdr **group_sect_ptr;
int num_group;
unsigned int symtab_section, symtab_shndx_section, dynsymtab_section;
unsigned int symtab_section, dynsymtab_section;
unsigned int dynversym_section, dynverdef_section, dynverref_section;
/* An identifier used to distinguish different target
@ -1787,7 +1795,7 @@ struct elf_obj_tdata
#define elf_stack_flags(bfd) (elf_tdata(bfd) -> o->stack_flags)
#define elf_shstrtab(bfd) (elf_tdata(bfd) -> o->strtab_ptr)
#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
#define elf_symtab_shndx(bfd) (elf_tdata(bfd) -> symtab_shndx_section)
#define elf_symtab_shndx_list(bfd) (elf_tdata(bfd) -> symtab_shndx_list)
#define elf_strtab_sec(bfd) (elf_tdata(bfd) -> o->strtab_section)
#define elf_shstrtab_sec(bfd) (elf_tdata(bfd) -> o->shstrtab_section)
#define elf_symtab_hdr(bfd) (elf_tdata(bfd) -> symtab_hdr)

175
bfd/elf.c
View File

@ -400,8 +400,28 @@ bfd_elf_get_elf_syms (bfd *ibfd,
/* Normal syms might have section extension entries. */
shndx_hdr = NULL;
if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
if (elf_symtab_shndx_list (ibfd) != NULL)
{
elf_section_list * entry;
Elf_Internal_Shdr **sections = elf_elfsections (ibfd);
/* Find an index section that is linked to this symtab section. */
for (entry = elf_symtab_shndx_list (ibfd); entry != NULL; entry = entry->next)
if (sections[entry->hdr.sh_link] == symtab_hdr)
{
shndx_hdr = & entry->hdr;
break;
};
if (shndx_hdr == NULL)
{
if (symtab_hdr == & elf_symtab_hdr (ibfd))
/* Not really accurate, but this was how the old code used to work. */
shndx_hdr = & elf_symtab_shndx_list (ibfd)->hdr;
/* Otherwise we do nothing. The assumption is that
the index table will not be needed. */
}
}
/* Read the symbols. */
alloc_ext = NULL;
@ -1843,8 +1863,8 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
goto success;
}
elf_onesymtab (abfd) = shindex;
elf_tdata (abfd)->symtab_hdr = *hdr;
elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
elf_symtab_hdr (abfd) = *hdr;
elf_elfsections (abfd)[shindex] = hdr = & elf_symtab_hdr (abfd);
abfd->flags |= HAS_SYMS;
/* Sometimes a shared object will map in the symbol table. If
@ -1862,30 +1882,39 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
/* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
can't read symbols without that section loaded as well. It
is most likely specified by the next section header. */
if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex)
{
unsigned int i, num_sec;
{
elf_section_list * entry;
unsigned int i, num_sec;
num_sec = elf_numsections (abfd);
for (i = shindex + 1; i < num_sec; i++)
for (entry = elf_symtab_shndx_list (abfd); entry != NULL; entry = entry->next)
if (entry->hdr.sh_link == shindex)
goto success;
num_sec = elf_numsections (abfd);
for (i = shindex + 1; i < num_sec; i++)
{
Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
if (hdr2->sh_type == SHT_SYMTAB_SHNDX
&& hdr2->sh_link == shindex)
break;
}
if (i == num_sec)
for (i = 1; i < shindex; i++)
{
Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
if (hdr2->sh_type == SHT_SYMTAB_SHNDX
&& hdr2->sh_link == shindex)
break;
}
if (i == num_sec)
for (i = 1; i < shindex; i++)
{
Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
if (hdr2->sh_type == SHT_SYMTAB_SHNDX
&& hdr2->sh_link == shindex)
break;
}
if (i != shindex)
ret = bfd_section_from_shdr (abfd, i);
}
goto success;
if (i != shindex)
ret = bfd_section_from_shdr (abfd, i);
/* else FIXME: we have failed to find the symbol table - should we issue an error ? */
goto success;
}
case SHT_DYNSYM: /* A dynamic symbol table. */
if (elf_dynsymtab (abfd) == shindex)
@ -1926,14 +1955,23 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
goto success;
case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections. */
if (elf_symtab_shndx (abfd) == shindex)
goto success;
{
elf_section_list * entry;
BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
elf_symtab_shndx (abfd) = shindex;
elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
goto success;
for (entry = elf_symtab_shndx_list (abfd); entry != NULL; entry = entry->next)
if (entry->ndx == shindex)
goto success;
entry = bfd_alloc (abfd, sizeof * entry);
if (entry == NULL)
goto fail;
entry->ndx = shindex;
entry->hdr = * hdr;
entry->next = elf_symtab_shndx_list (abfd);
elf_symtab_shndx_list (abfd) = entry;
elf_elfsections (abfd)[shindex] = & entry->hdr;
goto success;
}
case SHT_STRTAB: /* A string table. */
if (hdr->bfd_section != NULL)
@ -3377,11 +3415,17 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
{
elf_symtab_shndx (abfd) = section_number++;
t->symtab_shndx_hdr.sh_name
elf_section_list * entry;
BFD_ASSERT (elf_symtab_shndx_list (abfd) == NULL);
entry = bfd_zalloc (abfd, sizeof * entry);
entry->ndx = section_number++;
elf_symtab_shndx_list (abfd) = entry;
entry->hdr.sh_name
= (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
".symtab_shndx", FALSE);
if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
if (entry->hdr.sh_name == (unsigned int) -1)
return FALSE;
}
elf_strtab_sec (abfd) = section_number++;
@ -3421,8 +3465,10 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr;
if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
{
i_shdrp[elf_symtab_shndx (abfd)] = &t->symtab_shndx_hdr;
t->symtab_shndx_hdr.sh_link = elf_onesymtab (abfd);
elf_section_list * entry = elf_symtab_shndx_list (abfd);
BFD_ASSERT (entry != NULL);
i_shdrp[entry->ndx] = & entry->hdr;
entry->hdr.sh_link = elf_onesymtab (abfd);
}
i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
@ -3883,12 +3929,16 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
off = elf_next_file_pos (abfd);
hdr = &elf_tdata (abfd)->symtab_hdr;
hdr = & elf_symtab_hdr (abfd);
off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (hdr->sh_size != 0)
off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
if (elf_symtab_shndx_list (abfd) != NULL)
{
hdr = & elf_symtab_shndx_list (abfd)->hdr;
if (hdr->sh_size != 0)
off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
/* FIXME: What about other symtab_shndx sections in the list ? */
}
hdr = &elf_tdata (abfd)->strtab_hdr;
off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
@ -5286,7 +5336,8 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
&& (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
/* Compress DWARF debug sections. */
|| hdr == i_shdrpp[elf_onesymtab (abfd)]
|| hdr == i_shdrpp[elf_symtab_shndx (abfd)]
|| (elf_symtab_shndx_list (abfd) != NULL
&& hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
|| hdr == i_shdrpp[elf_strtab_sec (abfd)]
|| hdr == i_shdrpp[elf_shstrtab_sec (abfd)])
hdr->sh_offset = -1;
@ -5492,6 +5543,15 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
return TRUE;
}
static elf_section_list *
find_section_in_list (unsigned int i, elf_section_list * list)
{
for (;list != NULL; list = list->next)
if (list->ndx == i)
break;
return list;
}
/* Work out the file positions of all the sections. This is called by
_bfd_elf_compute_section_file_positions. All the section sizes and
VMAs must be known before this is called.
@ -5540,7 +5600,8 @@ assign_file_positions_except_relocs (bfd *abfd,
&& (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
/* Compress DWARF debug sections. */
|| i == elf_onesymtab (abfd)
|| i == elf_symtab_shndx (abfd)
|| (elf_symtab_shndx_list (abfd) != NULL
&& hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
|| i == elf_strtab_sec (abfd)
|| i == elf_shstrtab_sec (abfd))
{
@ -7130,7 +7191,7 @@ _bfd_elf_copy_private_symbol_data (bfd *ibfd,
shndx = MAP_STRTAB;
else if (shndx == elf_shstrtab_sec (ibfd))
shndx = MAP_SHSTRTAB;
else if (shndx == elf_symtab_shndx (ibfd))
else if (find_section_in_list (shndx, elf_symtab_shndx_list (ibfd)))
shndx = MAP_SYM_SHNDX;
osym->internal_elf_sym.st_shndx = shndx;
}
@ -7205,20 +7266,25 @@ error_return:
outbound_shndx = NULL;
outbound_shndx_index = 0;
symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (symtab_shndx_hdr->sh_name != 0)
{
amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
outbound_shndx = (bfd_byte *)
bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx));
if (outbound_shndx == NULL)
goto error_return;
symtab_shndx_hdr->contents = outbound_shndx;
symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
symtab_shndx_hdr->sh_size = amt;
symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
if (elf_symtab_shndx_list (abfd))
{
symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
if (symtab_shndx_hdr->sh_name != 0)
{
amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
outbound_shndx = (bfd_byte *)
bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx));
if (outbound_shndx == NULL)
goto error_return;
symtab_shndx_hdr->contents = outbound_shndx;
symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
symtab_shndx_hdr->sh_size = amt;
symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
}
/* FIXME: What about any other headers in the list ? */
}
/* Now generate the data (for "contents"). */
@ -7327,7 +7393,8 @@ error_return:
shndx = elf_shstrtab_sec (abfd);
break;
case MAP_SYM_SHNDX:
shndx = elf_symtab_shndx (abfd);
if (elf_symtab_shndx_list (abfd))
shndx = elf_symtab_shndx_list (abfd)->ndx;
break;
default:
shndx = SHN_ABS;

View File

@ -1473,8 +1473,11 @@ m32c_elf_relax_section
|| (sec->flags & SEC_CODE) == 0)
return TRUE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
symtab_hdr = & elf_symtab_hdr (abfd);
if (elf_symtab_shndx_list (abfd))
shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
else
shndx_hdr = NULL;
/* Get the section contents. */
if (elf_section_data (sec)->this_hdr.contents != NULL)
@ -1495,7 +1498,7 @@ m32c_elf_relax_section
symtab_hdr->contents = (bfd_byte *) intsyms;
}
if (shndx_hdr->sh_size != 0)
if (shndx_hdr && shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
@ -2043,8 +2046,16 @@ m32c_elf_relax_delete_bytes
isymend = isym + symtab_hdr->sh_info;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
shndx_hdr = & elf_tdata (abfd)->symtab_shndx_hdr;
shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
if (elf_symtab_shndx_list (abfd))
{
shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
}
else
{
shndx_hdr = NULL;
shndx_buf = NULL;
}
shndx = shndx_buf;
for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))

View File

@ -2094,8 +2094,11 @@ rl78_elf_relax_section
|| (sec->flags & SEC_CODE) == 0)
return TRUE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
symtab_hdr = & elf_symtab_hdr (abfd);
if (elf_symtab_shndx_list (abfd))
shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
else
shndx_hdr = NULL;
/* Get the section contents. */
if (elf_section_data (sec)->this_hdr.contents != NULL)
@ -2118,7 +2121,7 @@ rl78_elf_relax_section
symtab_hdr->contents = (bfd_byte *) intsyms;
}
if (shndx_hdr->sh_size != 0)
if (shndx_hdr && shndx_hdr->sh_size != 0)
{
bfd_size_type amt;

View File

@ -2009,8 +2009,11 @@ elf32_rx_relax_section (bfd * abfd,
|| (sec->flags & SEC_CODE) == 0)
return TRUE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
symtab_hdr = & elf_symtab_hdr (abfd);
if (elf_symtab_shndx_list (abfd))
shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
else
shndx_hdr = NULL;
sec_start = sec->output_section->vma + sec->output_offset;
@ -2035,7 +2038,7 @@ elf32_rx_relax_section (bfd * abfd,
symtab_hdr->contents = (bfd_byte *) intsyms;
}
if (shndx_hdr->sh_size != 0)
if (shndx_hdr && shndx_hdr->sh_size != 0)
{
bfd_size_type amt;

View File

@ -3205,7 +3205,6 @@ v850_elf_relax_delete_bytes (bfd *abfd,
Elf_Internal_Rela *irel;
Elf_Internal_Rela *irelend;
struct elf_link_hash_entry *sym_hash;
Elf_Internal_Shdr *shndx_hdr;
Elf_External_Sym_Shndx *shndx;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@ -3230,8 +3229,17 @@ v850_elf_relax_delete_bytes (bfd *abfd,
/* Adjust all the relocs. */
irel = elf_section_data (sec)->relocs;
irelend = irel + sec->reloc_count;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
if (elf_symtab_shndx_list (abfd))
{
Elf_Internal_Shdr *shndx_hdr;
shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
}
else
{
shndx = NULL;
}
for (; irel < irelend; irel++)
{

View File

@ -11032,7 +11032,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
max_sym_count = sym_count;
if (sym_count > max_sym_shndx_count
&& elf_symtab_shndx (sec->owner) != 0)
&& elf_symtab_shndx_list (sec->owner) != NULL)
max_sym_shndx_count = sym_count;
if ((sec->flags & SEC_RELOC) != 0)
@ -11562,8 +11562,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
Elf_Internal_Shdr *symstrtab_hdr;
file_ptr off = symtab_hdr->sh_offset + symtab_hdr->sh_size;
symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (symtab_shndx_hdr->sh_name != 0)
symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
if (symtab_shndx_hdr != NULL && symtab_shndx_hdr->sh_name != 0)
{
symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);

View File

@ -1,3 +1,13 @@
2015-09-23 Nick Clifton <nickc@redhat.com>
PR binutils/15835
* readelf.c (struct elf_section_list): New structure.
(symtab_shndx_hdr): Replace with symtab_shndx_list.
(get_32bit_elf_symbols): Scan for a symbol index table matching
the symbol table in use.
(get_64bit_elf_symbols): Likewise.
(process_section_headers): Handle multiple symbol index sections.
2015-09-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* readelf.c (process_dynamic_section): Handle DF_1_STUB, DF_1_PIE.

View File

@ -164,6 +164,12 @@
#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
#endif
typedef struct elf_section_list
{
Elf_Internal_Shdr * hdr;
struct elf_section_list * next;
} elf_section_list;
char * program_name = "readelf";
static unsigned long archive_file_offset;
static unsigned long archive_file_size;
@ -188,7 +194,7 @@ static Elf_Internal_Ehdr elf_header;
static Elf_Internal_Shdr * section_headers;
static Elf_Internal_Phdr * program_headers;
static Elf_Internal_Dyn * dynamic_section;
static Elf_Internal_Shdr * symtab_shndx_hdr;
static elf_section_list * symtab_shndx_list;
static int show_name;
static int do_dynamic;
static int do_syms;
@ -4984,27 +4990,30 @@ get_32bit_elf_symbols (FILE * file,
if (esyms == NULL)
goto exit_point;
shndx = NULL;
if (symtab_shndx_hdr != NULL
&& (symtab_shndx_hdr->sh_link
== (unsigned long) (section - section_headers)))
{
shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
symtab_shndx_hdr->sh_offset,
1, symtab_shndx_hdr->sh_size,
_("symbol table section indicies"));
if (shndx == NULL)
goto exit_point;
/* PR17531: file: heap-buffer-overflow */
else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
{
elf_section_list * entry;
shndx = NULL;
for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
{
error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
printable_section_name (symtab_shndx_hdr),
(unsigned long) symtab_shndx_hdr->sh_size,
(unsigned long) section->sh_size);
goto exit_point;
shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
entry->hdr->sh_offset,
1, entry->hdr->sh_size,
_("symbol table section indicies"));
if (shndx == NULL)
goto exit_point;
/* PR17531: file: heap-buffer-overflow */
else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
{
error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
printable_section_name (entry->hdr),
(unsigned long) entry->hdr->sh_size,
(unsigned long) section->sh_size);
goto exit_point;
}
}
}
}
isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
@ -5094,25 +5103,30 @@ get_64bit_elf_symbols (FILE * file,
if (!esyms)
goto exit_point;
if (symtab_shndx_hdr != NULL
&& (symtab_shndx_hdr->sh_link
== (unsigned long) (section - section_headers)))
{
shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
symtab_shndx_hdr->sh_offset,
1, symtab_shndx_hdr->sh_size,
_("symbol table section indicies"));
if (shndx == NULL)
goto exit_point;
else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
{
elf_section_list * entry;
shndx = NULL;
for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
{
error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
printable_section_name (symtab_shndx_hdr),
(unsigned long) symtab_shndx_hdr->sh_size,
(unsigned long) section->sh_size);
goto exit_point;
shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
entry->hdr->sh_offset,
1, entry->hdr->sh_size,
_("symbol table section indicies"));
if (shndx == NULL)
goto exit_point;
/* PR17531: file: heap-buffer-overflow */
else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
{
error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
printable_section_name (entry->hdr),
(unsigned long) entry->hdr->sh_size,
(unsigned long) section->sh_size);
goto exit_point;
}
}
}
}
isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
@ -5470,7 +5484,7 @@ process_section_headers (FILE * file)
dynamic_symbols = NULL;
dynamic_strings = NULL;
dynamic_syminfo = NULL;
symtab_shndx_hdr = NULL;
symtab_shndx_list = NULL;
eh_addr_size = is_32bit_elf ? 4 : 8;
switch (elf_header.e_machine)
@ -5575,12 +5589,10 @@ process_section_headers (FILE * file)
}
else if (section->sh_type == SHT_SYMTAB_SHNDX)
{
if (symtab_shndx_hdr != NULL)
{
error (_("File contains multiple symtab shndx tables\n"));
continue;
}
symtab_shndx_hdr = section;
elf_section_list * entry = xmalloc (sizeof * entry);
entry->hdr = section;
entry->next = symtab_shndx_list;
symtab_shndx_list = entry;
}
else if (section->sh_type == SHT_SYMTAB)
CHECK_ENTSIZE (section, i, Sym);