Wrong function reported for linker error message
authorAlan Modra <amodra@gmail.com>
Tue, 1 Sep 2015 07:58:13 +0000 (17:28 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 1 Sep 2015 08:14:33 +0000 (17:44 +0930)
OPD lookup goes awry when .opd has been shuffled to remove unused
functions.

* elf64-ppc.c (ppc64_elf_maybe_function_sym): Adjust symbol value
if .opd section has been edited.

bfd/ChangeLog
bfd/elf64-ppc.c

index e2819fe..b3ee41b 100644 (file)
@@ -1,5 +1,10 @@
 2015-09-01  Alan Modra  <amodra@gmail.com>
 
+       * elf64-ppc.c (ppc64_elf_maybe_function_sym): Adjust symbol value
+       if .opd section has been edited.
+
+2015-09-01  Alan Modra  <amodra@gmail.com>
+
        PR 18878
        * elf64-ppc.c (ARRAY_SIZE): Define.  Use throughout.
        (enum ppc_stub_type): Add ppc_stub_save_res.
index 15d5238..f179f6d 100644 (file)
@@ -6130,7 +6130,23 @@ ppc64_elf_maybe_function_sym (const asymbol *sym, asection *sec,
 
   if (strcmp (sym->section->name, ".opd") == 0)
     {
-      if (opd_entry_value (sym->section, sym->value,
+      struct _opd_sec_data *opd = get_opd_info (sym->section);
+      bfd_vma symval = sym->value;
+
+      if (opd != NULL
+         && opd->adjust != NULL
+         && elf_section_data (sym->section)->relocs != NULL)
+       {
+         /* opd_entry_value will use cached relocs that have been
+            adjusted, but with raw symbols.  That means both local
+            and global symbols need adjusting.  */
+         long adjust = opd->adjust[OPD_NDX (symval)];
+         if (adjust == -1)
+           return 0;
+         symval += adjust;
+       }
+
+      if (opd_entry_value (sym->section, symval,
                           &sec, code_off, TRUE) == (bfd_vma) -1)
        return 0;
       /* An old ABI binary with dot-syms has a size of 24 on the .opd