* configure.in: Disable libgcj for darwin not on powerpc.
[deliverable/binutils-gdb.git] / bfd / elf64-ppc.c
index d9f04a5acff9ddcdc333e40f18efecfd130043f5..e7666507c50545c7ade633e84017bf4a25d23fc1 100644 (file)
@@ -28,7 +28,6 @@
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
-#include "elf/ppc.h"
 #include "elf/ppc64.h"
 #include "elf64-ppc.h"
 
@@ -3277,9 +3276,10 @@ ppc64_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-ppc64_elf_copy_indirect_symbol (struct elf_backend_data *bed ATTRIBUTE_UNUSED,
-                               struct elf_link_hash_entry *dir,
-                               struct elf_link_hash_entry *ind)
+ppc64_elf_copy_indirect_symbol
+  (const struct elf_backend_data *bed ATTRIBUTE_UNUSED,
+   struct elf_link_hash_entry *dir,
+   struct elf_link_hash_entry *ind)
 {
   struct ppc_link_hash_entry *edir, *eind;
   flagword mask;
@@ -6607,7 +6607,8 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
 
   /* If a code section has a function that uses the TOC then we need
      to use the right TOC (obviously).  Also, make sure that .opd gets
-     the correct TOC value.  */
+     the correct TOC value for R_PPC64_TOC relocs that don't have or
+     can't find their function symbol (shouldn't ever happen now).  */
   if (isec->has_gp_reloc || (isec->flags & SEC_CODE) == 0)
     {
       if (elf_gp (isec->owner) != 0)
@@ -7326,6 +7327,16 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 
       r_type = ELF64_R_TYPE (rel->r_info);
       r_symndx = ELF64_R_SYM (rel->r_info);
+
+      /* For old style R_PPC64_TOC relocs with a zero symbol, use the
+        symbol of the previous ADDR64 reloc.  The symbol gives us the
+        proper TOC base to use.  */
+      if (rel->r_info == ELF64_R_INFO (0, R_PPC64_TOC)
+         && rel != relocs
+         && ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_ADDR64
+         && is_opd)
+       r_symndx = ELF64_R_SYM (rel[-1].r_info);
+
       sym = NULL;
       sec = NULL;
       h = NULL;
@@ -7383,7 +7394,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
            {
              if (! ((*info->callbacks->undefined_symbol)
                     (info, h->root.root.string, input_bfd, input_section,
-                     rel->r_offset, (!info->shared
+                     rel->r_offset, (info->executable
                                      || info->no_undefined
                                      || ELF_ST_VISIBILITY (h->other)))))
                return FALSE;
@@ -7787,6 +7798,13 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                      if ((insn & 1) == 0)
                        can_plt_call = 1;
                    }
+                 else if (h != NULL
+                          && strcmp (h->root.root.string,
+                                     ".__libc_start_main") == 0)
+                   {
+                     /* Allow crt1 branch to go via a toc adjusting stub.  */
+                     can_plt_call = 1;
+                   }
                  else
                    {
                      if (strcmp (input_section->output_section->name,
This page took 0.028243 seconds and 4 git commands to generate.