+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
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. */
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 */
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
#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)
/* 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;
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
/* 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)
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)
_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++;
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);
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);
&& (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;
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.
&& (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))
{
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;
}
outbound_shndx = NULL;
outbound_shndx_index = 0;
- symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- if (symtab_shndx_hdr->sh_name != 0)
+
+ if (elf_symtab_shndx_list (abfd))
{
- 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 = & 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);
+ 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"). */
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;
|| (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)
symtab_hdr->contents = (bfd_byte *) intsyms;
}
- if (shndx_hdr->sh_size != 0)
+ if (shndx_hdr && shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
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))
|| (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)
symtab_hdr->contents = (bfd_byte *) intsyms;
}
- if (shndx_hdr->sh_size != 0)
+ if (shndx_hdr && shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
|| (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;
symtab_hdr->contents = (bfd_byte *) intsyms;
}
- if (shndx_hdr->sh_size != 0)
+ if (shndx_hdr && shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
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;
/* 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++)
{
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)
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);
+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.
#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;
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;
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)
- {
- 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;
+ {
+ 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))
+ {
+ 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));
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)
- {
- 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;
+ {
+ 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))
+ {
+ 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));
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)
}
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);