diff options
author | Nick Clifton <nickc@redhat.com> | 2015-09-23 17:23:58 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-09-23 17:23:58 +0100 |
commit | 6a40cf0c5c845683fdb82721813ebd5dd867cce5 (patch) | |
tree | b13bf45e4cb2ce850c1252eb9201906074ebc210 /binutils | |
parent | bcd68f9e44a70c73bde08e612a28e413570dc039 (diff) | |
download | gdb-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/ChangeLog | 10 | ||||
-rw-r--r-- | binutils/readelf.c | 104 |
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); |