aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-09-23 17:23:58 +0100
committerNick Clifton <nickc@redhat.com>2015-09-23 17:23:58 +0100
commit6a40cf0c5c845683fdb82721813ebd5dd867cce5 (patch)
treeb13bf45e4cb2ce850c1252eb9201906074ebc210 /binutils
parentbcd68f9e44a70c73bde08e612a28e413570dc039 (diff)
downloadgdb-6a40cf0c5c845683fdb82721813ebd5dd867cce5.zip
gdb-6a40cf0c5c845683fdb82721813ebd5dd867cce5.tar.gz
gdb-6a40cf0c5c845683fdb82721813ebd5dd867cce5.tar.bz2
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.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog10
-rw-r--r--binutils/readelf.c104
2 files changed, 68 insertions, 46 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 13f2166..be987ec 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 4d19e6f..bbf5b02 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -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)
- {
- 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));
@@ -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)
- {
- 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));
@@ -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);