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:
parent
bcd68f9e44
commit
6a40cf0c5c
@ -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
|
||||
|
@ -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
175
bfd/elf.c
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user