aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-09-01 14:56:52 +0930
committerAlan Modra <amodra@gmail.com>2016-09-01 15:10:07 +0930
commitcd285db582fb1bd59db01e3dc29511d08999d05b (patch)
tree1bed028ad14bef4d082f8cc35c6ac8f952efa363
parent0318424c7bd637453be8178506c18f24858ad7f6 (diff)
downloadgdb-cd285db582fb1bd59db01e3dc29511d08999d05b.zip
gdb-cd285db582fb1bd59db01e3dc29511d08999d05b.tar.gz
gdb-cd285db582fb1bd59db01e3dc29511d08999d05b.tar.bz2
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.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf64-ppc.c30
2 files changed, 26 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 59dfb2c..ddbf23b 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 3a9a1cb..eeb68e5 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)