diff options
author | Alan Modra <amodra@gmail.com> | 2016-09-01 14:56:52 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2016-09-01 15:10:07 +0930 |
commit | cd285db582fb1bd59db01e3dc29511d08999d05b (patch) | |
tree | 1bed028ad14bef4d082f8cc35c6ac8f952efa363 /bfd | |
parent | 0318424c7bd637453be8178506c18f24858ad7f6 (diff) | |
download | binutils-gdb-cd285db582fb1bd59db01e3dc29511d08999d05b.tar.gz |
Don't treat .opd section specially when ELFv2
Fixes a gdb segfault if a section named .opd is found in ELFv2 binaries.
* elf64-ppc.c (synthetic_opd): New static var.
(compare_symbols): Don't treat symbols in .opd specially for ELFv2.
(ppc64_elf_get_synthetic_symtab): Likewise. Comment.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 30 |
2 files changed, 26 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 59dfb2cb141..ddbf23ba433 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2016-09-01 Alan Modra <amodra@gmail.com> + + * elf64-ppc.c (synthetic_opd): New static var. + (compare_symbols): Don't treat symbols in .opd specially for ELFv2. + (ppc64_elf_get_synthetic_symtab): Likewise. Comment. + 2016-08-31 Alan Modra <amodra@gmail.com> * elf64-ppc.c (group_sections): Delete stub14_group_size. Instead, diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 3a9a1cb20f0..eeb68e5f848 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3085,6 +3085,7 @@ get_opd_info (asection * sec) /* Parameters for the qsort hook. */ static bfd_boolean synthetic_relocatable; +static asection *synthetic_opd; /* qsort comparison function for ppc64_elf_get_synthetic_symtab. */ @@ -3101,12 +3102,15 @@ compare_symbols (const void *ap, const void *bp) return 1; /* then .opd symbols. */ - if (strcmp (a->section->name, ".opd") == 0 - && strcmp (b->section->name, ".opd") != 0) - return -1; - if (strcmp (a->section->name, ".opd") != 0 - && strcmp (b->section->name, ".opd") == 0) - return 1; + if (synthetic_opd != NULL) + { + if (strcmp (a->section->name, ".opd") == 0 + && strcmp (b->section->name, ".opd") != 0) + return -1; + if (strcmp (a->section->name, ".opd") != 0 + && strcmp (b->section->name, ".opd") == 0) + return 1; + } /* then other code symbols. */ if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL)) @@ -3265,6 +3269,7 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, memcpy (syms, static_syms, (symcount + 1) * sizeof (*syms)); synthetic_relocatable = relocatable; + synthetic_opd = opd; qsort (syms, symcount, sizeof (*syms), compare_symbols); if (!relocatable && symcount > 1) @@ -3281,7 +3286,11 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, } i = 0; - if (strcmp (syms[i]->section->name, ".opd") == 0) + /* Note that here and in compare_symbols we can't compare opd and + sym->section directly. With separate debug info files, the + symbols will be extracted from the debug file while abfd passed + to this function is the real binary. */ + if (opd != NULL && strcmp (syms[i]->section->name, ".opd") == 0) ++i; codesecsym = i; @@ -3297,9 +3306,10 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, break; secsymend = i; - for (; i < symcount; ++i) - if (strcmp (syms[i]->section->name, ".opd") != 0) - break; + if (opd != NULL) + for (; i < symcount; ++i) + if (strcmp (syms[i]->section->name, ".opd") != 0) + break; opdsymend = i; for (; i < symcount; ++i) |