MIPS/opcodes: Reformat `-M' disassembler option's help text
[deliverable/binutils-gdb.git] / bfd / elf64-ppc.c
index d6acc1f38026309e62bac872365fc89a0e522f5f..b3975f8584451b756927d9b61b279a781b4825d8 100644 (file)
@@ -75,6 +75,7 @@ static bfd_vma opd_entry_value
 #define elf_backend_can_gc_sections 1
 #define elf_backend_can_refcount 1
 #define elf_backend_rela_normal 1
+#define elf_backend_dtrel_excludes_plt 1
 #define elf_backend_default_execstack 0
 
 #define bfd_elf64_mkobject                   ppc64_elf_mkobject
@@ -86,6 +87,7 @@ static bfd_vma opd_entry_value
 #define bfd_elf64_bfd_link_hash_table_create  ppc64_elf_link_hash_table_create
 #define bfd_elf64_get_synthetic_symtab       ppc64_elf_get_synthetic_symtab
 #define bfd_elf64_bfd_link_just_syms         ppc64_elf_link_just_syms
+#define bfd_elf64_bfd_gc_sections            ppc64_elf_gc_sections
 
 #define elf_backend_object_p                 ppc64_elf_object_p
 #define elf_backend_grok_prstatus            ppc64_elf_grok_prstatus
@@ -117,6 +119,7 @@ static bfd_vma opd_entry_value
 #define elf_backend_link_output_symbol_hook   ppc64_elf_output_symbol_hook
 #define elf_backend_special_sections         ppc64_elf_special_sections
 #define elf_backend_merge_symbol_attribute    ppc64_elf_merge_symbol_attribute
+#define elf_backend_merge_symbol             ppc64_elf_merge_symbol
 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
@@ -2490,8 +2493,9 @@ ppc64_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
   type = ELF64_R_TYPE (dst->r_info);
   if (type >= ARRAY_SIZE (ppc64_elf_howto_table))
     {
-      (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
-                            abfd, (int) type);
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%B: invalid relocation type %d"),
+                         abfd, (int) type);
       type = R_PPC64_NONE;
     }
   cache_ptr->howto = ppc64_elf_howto_table[type];
@@ -3976,9 +3980,6 @@ struct ppc_link_hash_entry
      should be set for all globals defined in any opd/toc section.  */
   unsigned int adjust_done:1;
 
-  /* Set if we twiddled this symbol to weak at some stage.  */
-  unsigned int was_undefined:1;
-
   /* Set if this is an out-of-line register save/restore function,
      with non-standard calling convention.  */
   unsigned int save_res:1;
@@ -4085,8 +4086,8 @@ struct ppc_link_hash_table
   /* Set on error.  */
   unsigned int stub_error:1;
 
-  /* Temp used by ppc64_elf_before_check_relocs.  */
-  unsigned int twiddled_syms:1;
+  /* Whether func_desc_adjust needs to be run over symbols.  */
+  unsigned int need_func_desc_adj:1;
 
   /* Incremented every time we size stubs.  */
   unsigned int stub_iteration;
@@ -4588,6 +4589,7 @@ ppc_add_stub (const char *stub_name,
                                     TRUE, FALSE);
   if (stub_entry == NULL)
     {
+      /* xgettext:c-format */
       info->callbacks->einfo (_("%P: %B: cannot create stub entry %s\n"),
                              section->owner, stub_name);
       return NULL;
@@ -4737,19 +4739,22 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
   if (eind->oh != NULL)
     edir->oh = ppc_follow_link (eind->oh);
 
-  /* If called to transfer flags for a weakdef during processing
-     of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF.
-     We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
-  if (!(ELIMINATE_COPY_RELOCS
-       && eind->elf.root.type != bfd_link_hash_indirect
-       && edir->elf.dynamic_adjusted))
-    edir->elf.non_got_ref |= eind->elf.non_got_ref;
+  if (edir->elf.versioned != versioned_hidden)
+    {
+      /* If called to transfer flags for a weakdef during processing
+        of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF.
+        We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
+      if (!(ELIMINATE_COPY_RELOCS
+           && eind->elf.root.type != bfd_link_hash_indirect
+           && edir->elf.dynamic_adjusted))
+       edir->elf.non_got_ref |= eind->elf.non_got_ref;
 
-  edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
-  edir->elf.ref_regular |= eind->elf.ref_regular;
-  edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
-  edir->elf.needs_plt |= eind->elf.needs_plt;
-  edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
+      edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
+      edir->elf.ref_regular |= eind->elf.ref_regular;
+      edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
+      edir->elf.needs_plt |= eind->elf.needs_plt;
+      edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
+    }
 
   /* If we were called to copy over info for a weak sym, don't copy
      dyn_relocs, plt/got info, or dynindx.  We used to copy dyn_relocs
@@ -4892,32 +4897,29 @@ lookup_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
       fh->oh = fdh;
     }
 
-  return ppc_follow_link (fdh);
+  fdh = ppc_follow_link (fdh);
+  fdh->is_func_descriptor = 1;
+  fdh->oh = fh;
+  return fdh;
 }
 
-/* Make a fake function descriptor sym for the code sym FH.  */
+/* Make a fake function descriptor sym for the undefined code sym FH.  */
 
 static struct ppc_link_hash_entry *
 make_fdh (struct bfd_link_info *info,
          struct ppc_link_hash_entry *fh)
 {
-  bfd *abfd;
-  asymbol *newsym;
-  struct bfd_link_hash_entry *bh;
+  bfd *abfd = fh->elf.root.u.undef.abfd;
+  struct bfd_link_hash_entry *bh = NULL;
   struct ppc_link_hash_entry *fdh;
-
-  abfd = fh->elf.root.u.undef.abfd;
-  newsym = bfd_make_empty_symbol (abfd);
-  newsym->name = fh->elf.root.root.string + 1;
-  newsym->section = bfd_und_section_ptr;
-  newsym->value = 0;
-  newsym->flags = BSF_WEAK;
-
-  bh = NULL;
-  if (!_bfd_generic_link_add_one_symbol (info, abfd, newsym->name,
-                                        newsym->flags, newsym->section,
-                                        newsym->value, NULL, FALSE, FALSE,
-                                        &bh))
+  flagword flags = (fh->elf.root.type == bfd_link_hash_undefweak
+                   ? BSF_WEAK
+                   : BSF_GLOBAL);
+
+  if (!_bfd_generic_link_add_one_symbol (info, abfd,
+                                        fh->elf.root.root.string + 1,
+                                        flags, bfd_und_section_ptr, 0,
+                                        NULL, FALSE, FALSE, &bh))
     return NULL;
 
   fdh = (struct ppc_link_hash_entry *) bh;
@@ -5006,6 +5008,22 @@ ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
                | ELF_ST_VISIBILITY (h->other));
 }
 
+/* Hook called on merging a symbol.  We use this to clear "fake" since
+   we now have a real symbol.  */
+
+static bfd_boolean
+ppc64_elf_merge_symbol (struct elf_link_hash_entry *h,
+                       const Elf_Internal_Sym *isym ATTRIBUTE_UNUSED,
+                       asection **psec ATTRIBUTE_UNUSED,
+                       bfd_boolean newdef ATTRIBUTE_UNUSED,
+                       bfd_boolean olddef ATTRIBUTE_UNUSED,
+                       bfd *oldbfd ATTRIBUTE_UNUSED,
+                       const asection *oldsec ATTRIBUTE_UNUSED)
+{
+  ((struct ppc_link_hash_entry *) h)->fake = 0;
+  return TRUE;
+}
+
 /* This function makes an old ABI object reference to ".bar" cause the
    inclusion of a new ABI object archive that defines "bar".
    NAME is a symbol defined in an archive.  Return a symbol in the hash
@@ -5024,8 +5042,7 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
   if (h != NULL
       /* Don't return this sym if it is a fake function descriptor
         created by add_symbol_adjust.  */
-      && !(h->root.type == bfd_link_hash_undefweak
-          && ((struct ppc_link_hash_entry *) h)->fake))
+      && !((struct ppc_link_hash_entry *) h)->fake)
     return h;
 
   if (name[0] == '.')
@@ -5057,12 +5074,12 @@ add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
   struct ppc_link_hash_table *htab;
   struct ppc_link_hash_entry *fdh;
 
-  if (eh->elf.root.type == bfd_link_hash_indirect)
-    return TRUE;
-
   if (eh->elf.root.type == bfd_link_hash_warning)
     eh = (struct ppc_link_hash_entry *) eh->elf.root.u.i.link;
 
+  if (eh->elf.root.type == bfd_link_hash_indirect)
+    return TRUE;
+
   if (eh->elf.root.root.string[0] != '.')
     abort ();
 
@@ -5071,38 +5088,49 @@ add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
     return FALSE;
 
   fdh = lookup_fdh (eh, htab);
-  if (fdh == NULL)
-    {
-      if (!bfd_link_relocatable (info)
-         && (eh->elf.root.type == bfd_link_hash_undefined
-             || eh->elf.root.type == bfd_link_hash_undefweak)
-         && eh->elf.ref_regular)
-       {
-         /* Make an undefweak function descriptor sym, which is enough to
-            pull in an --as-needed shared lib, but won't cause link
-            errors.  Archives are handled elsewhere.  */
-         fdh = make_fdh (info, eh);
-         if (fdh == NULL)
-           return FALSE;
-         fdh->elf.ref_regular = 1;
-       }
+  if (fdh == NULL
+      && !bfd_link_relocatable (info)
+      && (eh->elf.root.type == bfd_link_hash_undefined
+         || eh->elf.root.type == bfd_link_hash_undefweak)
+      && eh->elf.ref_regular)
+    {
+      /* Make an undefined function descriptor sym, in order to
+        pull in an --as-needed shared lib.  Archives are handled
+        elsewhere.  */
+      fdh = make_fdh (info, eh);
+      if (fdh == NULL)
+       return FALSE;
     }
-  else
+
+  if (fdh != NULL)
     {
       unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
       unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
+
+      /* Make both descriptor and entry symbol have the most
+        constraining visibility of either symbol.  */
       if (entry_vis < descr_vis)
        fdh->elf.other += entry_vis - descr_vis;
       else if (entry_vis > descr_vis)
        eh->elf.other += descr_vis - entry_vis;
 
-      if ((fdh->elf.root.type == bfd_link_hash_defined
-          || fdh->elf.root.type == bfd_link_hash_defweak)
-         && eh->elf.root.type == bfd_link_hash_undefined)
-       {
-         eh->elf.root.type = bfd_link_hash_undefweak;
-         eh->was_undefined = 1;
-         htab->twiddled_syms = 1;
+      /* Propagate reference flags from entry symbol to function
+        descriptor symbol.  */
+      fdh->elf.root.non_ir_ref |= eh->elf.root.non_ir_ref;
+      fdh->elf.ref_regular |= eh->elf.ref_regular;
+      fdh->elf.ref_regular_nonweak |= eh->elf.ref_regular_nonweak;
+
+      if (!fdh->elf.forced_local
+         && fdh->elf.dynindx == -1
+         && fdh->elf.versioned != versioned_hidden
+         && (bfd_link_dll (info)
+             || fdh->elf.def_dynamic
+             || fdh->elf.ref_dynamic)
+         && (eh->elf.ref_regular
+             || eh->elf.def_regular))
+       {
+         if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
+           return FALSE;
        }
     }
 
@@ -5125,6 +5153,7 @@ ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
        set_abiversion (ibfd, 1);
       else if (abiversion (ibfd) >= 2)
        {
+         /* xgettext:c-format */
          info->callbacks->einfo (_("%P: %B .opd not allowed in ABI"
                                    " version %d\n"),
                                  ibfd, abiversion (ibfd));
@@ -5183,26 +5212,14 @@ ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
       else if (htab->elf.hgot == NULL
               && strcmp (eh->elf.root.root.string, ".TOC.") == 0)
        htab->elf.hgot = &eh->elf;
-      else if (!add_symbol_adjust (eh, info))
-       return FALSE;
-      p = &eh->u.next_dot_sym;
-    }
-
-  /* Clear the list for non-ppc64 input files.  */
-  p = &htab->dot_syms;
-  while ((eh = *p) != NULL)
-    {
-      *p = NULL;
+      else if (abiversion (ibfd) <= 1)
+       {
+         htab->need_func_desc_adj = 1;
+         if (!add_symbol_adjust (eh, info))
+           return FALSE;
+       }
       p = &eh->u.next_dot_sym;
     }
-
-  /* We need to fix the undefs list for any syms we have twiddled to
-     undefweak.  */
-  if (htab->twiddled_syms)
-    {
-      bfd_link_repair_undef_list (&htab->elf.root);
-      htab->twiddled_syms = 0;
-    }
   return TRUE;
 }
 
@@ -5395,12 +5412,17 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        h = NULL;
       else
        {
+         struct ppc_link_hash_entry *eh;
+
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
          h = elf_follow_link (h);
+         eh = (struct ppc_link_hash_entry *) h;
 
          /* PR15323, ref flags aren't set for references in the same
             object.  */
          h->root.non_ir_ref = 1;
+         if (eh->is_func && eh->oh != NULL)
+           eh->oh->elf.root.non_ir_ref = 1;
 
          if (h == htab->elf.hgot)
            sec->has_toc_reloc = 1;
@@ -5471,7 +5493,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
          tls_type = TLS_TLS | TLS_DTPREL;
        dogottls:
          sec->has_tls_reloc = 1;
-         /* Fall thru */
+         /* Fall through */
 
        case R_PPC64_GOT16:
        case R_PPC64_GOT16_DS:
@@ -5559,6 +5581,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
              /* It does not make sense to have a procedure linkage
                 table entry for a non-ifunc local symbol.  */
              info->callbacks->einfo
+               /* xgettext:c-format */
                (_("%P: %H: %s reloc against local symbol\n"),
                 abfd, sec, rel->r_offset,
                 ppc64_elf_howto_table[r_type]->name);
@@ -5606,6 +5629,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
            {
              if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
                ppc_howto_init ();
+             /* xgettext:c-format */
              info->callbacks->einfo (_("%P: %H: %s reloc unsupported "
                                        "in shared libraries and PIEs.\n"),
                                      abfd, sec, rel->r_offset,
@@ -5619,6 +5643,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_TOC16_DS:
          htab->do_multi_toc = 1;
          ppc64_elf_tdata (abfd)->has_small_toc_reloc = 1;
+         /* Fall through.  */
        case R_PPC64_TOC16_LO:
        case R_PPC64_TOC16_HI:
        case R_PPC64_TOC16_HA:
@@ -5807,14 +5832,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
              && ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC)
            {
              if (h != NULL)
-               {
-                 if (h->root.root.string[0] == '.'
-                     && h->root.root.string[1] != 0
-                     && lookup_fdh ((struct ppc_link_hash_entry *) h, htab))
-                   ;
-                 else
-                   ((struct ppc_link_hash_entry *) h)->is_func = 1;
-               }
+               ((struct ppc_link_hash_entry *) h)->is_func = 1;
              else
                {
                  asection *s;
@@ -5998,8 +6016,9 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
    object file when linking.  */
 
 static bfd_boolean
-ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+ppc64_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   unsigned long iflags, oflags;
 
   if ((ibfd->flags & BFD_LINKER_CREATED) != 0)
@@ -6008,7 +6027,7 @@ ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   if (!is_ppc64_elf (ibfd) || !is_ppc64_elf (obfd))
     return TRUE;
 
-  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+  if (!_bfd_generic_verify_endian_match (ibfd, info))
     return FALSE;
 
   iflags = elf_elfheader (ibfd)->e_flags;
@@ -6016,24 +6035,26 @@ ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
   if (iflags & ~EF_PPC64_ABI)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
+       /* xgettext:c-format */
        (_("%B uses unknown e_flags 0x%lx"), ibfd, iflags);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
   else if (iflags != oflags && iflags != 0)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
+       /* xgettext:c-format */
        (_("%B: ABI version %ld is not compatible with ABI version %ld output"),
         ibfd, iflags, oflags);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
 
-  _bfd_elf_ppc_merge_fp_attributes (ibfd, obfd);
+  _bfd_elf_ppc_merge_fp_attributes (ibfd, info);
 
   /* Merge Tag_compatibility attributes and any common GNU ones.  */
-  _bfd_elf_merge_object_attributes (ibfd, obfd);
+  _bfd_elf_merge_object_attributes (ibfd, info);
 
   return TRUE;
 }
@@ -6048,7 +6069,6 @@ ppc64_elf_print_private_bfd_data (bfd *abfd, void *ptr)
     {
       FILE *file = ptr;
 
-      /* xgettext:c-format */
       fprintf (file, _("private flags = 0x%lx:"),
               elf_elfheader (abfd)->e_flags);
 
@@ -6339,6 +6359,23 @@ defined_func_desc (struct ppc_link_hash_entry *fh)
   return NULL;
 }
 
+static bfd_boolean func_desc_adjust (struct elf_link_hash_entry *, void *);
+
+/* Garbage collect sections, after first dealing with dot-symbols.  */
+
+static bfd_boolean
+ppc64_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
+{
+  struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+  if (htab != NULL && htab->need_func_desc_adj)
+    {
+      elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
+      htab->need_func_desc_adj = 0;
+    }
+  return bfd_elf_gc_sections (abfd, info);
+}
+
 /* Mark all our entry sym sections, both opd and code section.  */
 
 static void
@@ -6473,7 +6510,15 @@ ppc64_elf_gc_mark_hook (asection *sec,
              eh = (struct ppc_link_hash_entry *) h;
              fdh = defined_func_desc (eh);
              if (fdh != NULL)
-               eh = fdh;
+               {
+                 /* -mcall-aixdesc code references the dot-symbol on
+                    a call reloc.  Mark the function descriptor too
+                    against garbage collection.  */
+                 fdh->elf.mark = 1;
+                 if (fdh->elf.u.weakdef != NULL)
+                   fdh->elf.u.weakdef->mark = 1;
+                 eh = fdh;
+               }
 
              /* Function descriptor syms cause the associated
                 function code sym section to be marked.  */
@@ -6952,7 +6997,6 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
 {
   struct bfd_link_info *info;
   struct ppc_link_hash_table *htab;
-  struct plt_entry *ent;
   struct ppc_link_hash_entry *fh;
   struct ppc_link_hash_entry *fdh;
   bfd_boolean force_local;
@@ -6961,18 +7005,29 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
   if (fh->elf.root.type == bfd_link_hash_indirect)
     return TRUE;
 
+  if (!fh->is_func)
+    return TRUE;
+
+  if (fh->elf.root.root.string[0] != '.'
+      || fh->elf.root.root.string[1] == '\0')
+    return TRUE;
+
   info = inf;
   htab = ppc_hash_table (info);
   if (htab == NULL)
     return FALSE;
 
+  /* Find the corresponding function descriptor symbol.  */
+  fdh = lookup_fdh (fh, htab);
+
   /* Resolve undefined references to dot-symbols as the value
      in the function descriptor, if we have one in a regular object.
      This is to satisfy cases like ".quad .foo".  Calls to functions
      in dynamic objects are handled elsewhere.  */
-  if (fh->elf.root.type == bfd_link_hash_undefweak
-      && fh->was_undefined
-      && (fdh = defined_func_desc (fh)) != NULL
+  if ((fh->elf.root.type == bfd_link_hash_undefined
+       || fh->elf.root.type == bfd_link_hash_undefweak)
+      && (fdh->elf.root.type == bfd_link_hash_defined
+         || fdh->elf.root.type == bfd_link_hash_defweak)
       && get_opd_info (fdh->elf.root.u.def.section) != NULL
       && opd_entry_value (fdh->elf.root.u.def.section,
                          fdh->elf.root.u.def.value,
@@ -6985,23 +7040,18 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
       fh->elf.def_dynamic = fdh->elf.def_dynamic;
     }
 
-  /* If this is a function code symbol, transfer dynamic linking
-     information to the function descriptor symbol.  */
-  if (!fh->is_func)
-    return TRUE;
-
-  for (ent = fh->elf.plt.plist; ent != NULL; ent = ent->next)
-    if (ent->plt.refcount > 0)
-      break;
-  if (ent == NULL
-      || fh->elf.root.root.string[0] != '.'
-      || fh->elf.root.root.string[1] == '\0')
-    return TRUE;
+  if (!fh->elf.dynamic)
+    {
+      struct plt_entry *ent;
 
-  /* Find the corresponding function descriptor symbol.  Create it
-     as undefined if necessary.  */
+      for (ent = fh->elf.plt.plist; ent != NULL; ent = ent->next)
+       if (ent->plt.refcount > 0)
+         break;
+      if (ent == NULL)
+       return TRUE;
+    }
 
-  fdh = lookup_fdh (fh, htab);
+  /* Create a descriptor as undefined if necessary.  */
   if (fdh == NULL
       && !bfd_link_executable (info)
       && (fh->elf.root.type == bfd_link_hash_undefined
@@ -7012,51 +7062,30 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
        return FALSE;
     }
 
-  /* Fake function descriptors are made undefweak.  If the function
-     code symbol is strong undefined, make the fake sym the same.
-     If the function code symbol is defined, then force the fake
-     descriptor local;  We can't support overriding of symbols in a
-     shared library on a fake descriptor.  */
-
+  /* We can't support overriding of symbols on a fake descriptor.  */
   if (fdh != NULL
       && fdh->fake
-      && fdh->elf.root.type == bfd_link_hash_undefweak)
-    {
-      if (fh->elf.root.type == bfd_link_hash_undefined)
-       {
-         fdh->elf.root.type = bfd_link_hash_undefined;
-         bfd_link_add_undef (&htab->elf.root, &fdh->elf.root);
-       }
-      else if (fh->elf.root.type == bfd_link_hash_defined
-              || fh->elf.root.type == bfd_link_hash_defweak)
-       {
-         _bfd_elf_link_hash_hide_symbol (info, &fdh->elf, TRUE);
-       }
-    }
+      && (fh->elf.root.type == bfd_link_hash_defined
+         || fh->elf.root.type == bfd_link_hash_defweak))
+    _bfd_elf_link_hash_hide_symbol (info, &fdh->elf, TRUE);
 
-  if (fdh != NULL
-      && !fdh->elf.forced_local
-      && (!bfd_link_executable (info)
-         || fdh->elf.def_dynamic
-         || fdh->elf.ref_dynamic
-         || (fdh->elf.root.type == bfd_link_hash_undefweak
-             && ELF_ST_VISIBILITY (fdh->elf.other) == STV_DEFAULT)))
-    {
-      if (fdh->elf.dynindx == -1)
-       if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
-         return FALSE;
+  /* Transfer dynamic linking information to the function descriptor.  */
+  if (fdh != NULL)
+    {
       fdh->elf.ref_regular |= fh->elf.ref_regular;
       fdh->elf.ref_dynamic |= fh->elf.ref_dynamic;
       fdh->elf.ref_regular_nonweak |= fh->elf.ref_regular_nonweak;
       fdh->elf.non_got_ref |= fh->elf.non_got_ref;
-      if (ELF_ST_VISIBILITY (fh->elf.other) == STV_DEFAULT)
-       {
-         move_plt_plist (fh, fdh);
-         fdh->elf.needs_plt = 1;
-       }
-      fdh->is_func_descriptor = 1;
-      fdh->oh = fh;
-      fh->oh = fdh;
+      fdh->elf.dynamic |= fh->elf.dynamic;
+      fdh->elf.needs_plt |= (fh->elf.needs_plt
+                            || fh->elf.type == STT_FUNC
+                            || fh->elf.type == STT_GNU_IFUNC);
+      move_plt_plist (fh, fdh);
+
+      if (!fdh->elf.forced_local
+         && fh->elf.dynindx != -1)
+       if (!bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
+         return FALSE;
     }
 
   /* Now that the info is on the function descriptor, clear the
@@ -7141,7 +7170,11 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
                               | STV_HIDDEN);
     }
 
-  elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
+  if (htab->need_func_desc_adj)
+    {
+      elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
+      htab->need_func_desc_adj = 0;
+    }
 
   return TRUE;
 }
@@ -7388,7 +7421,7 @@ ppc64_elf_hide_symbol (struct bfd_link_info *info,
       if (fh == NULL)
        {
          const char *p, *q;
-         struct ppc_link_hash_table *htab;
+         struct elf_link_hash_table *htab = elf_hash_table (info);
          char save;
 
          /* We aren't supposed to use alloca in BFD because on
@@ -7403,12 +7436,8 @@ ppc64_elf_hide_symbol (struct bfd_link_info *info,
          p = eh->elf.root.root.string - 1;
          save = *p;
          *(char *) p = '.';
-         htab = ppc_hash_table (info);
-         if (htab == NULL)
-           return;
-
          fh = (struct ppc_link_hash_entry *)
-           elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
+           elf_link_hash_lookup (htab, p, FALSE, FALSE, FALSE);
          *(char *) p = save;
 
          /* Unfortunately, if it so happens that the string we were
@@ -7422,7 +7451,7 @@ ppc64_elf_hide_symbol (struct bfd_link_info *info,
                --q, --p;
              if (q < eh->elf.root.root.string && *p == '.')
                fh = (struct ppc_link_hash_entry *)
-                 elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
+                 elf_link_hash_lookup (htab, p, FALSE, FALSE, FALSE);
            }
          if (fh != NULL)
            {
@@ -7599,7 +7628,7 @@ tocsave_find (struct ppc_link_hash_table *htab,
     return NULL;
   if (ent.sec == NULL || ent.sec->output_section == NULL)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
        (_("%B: undefined symbol on R_PPC64_TOCSAVE relocation"));
       return NULL;
     }
@@ -7829,6 +7858,7 @@ dec_dynrel_count (bfd_vma r_info,
        }
     }
 
+  /* xgettext:c-format */
   info->callbacks->einfo (_("%P: dynreloc miscount for %B, section %A\n"),
                          sec->owner, sec);
   bfd_set_error (bfd_error_bad_value);
@@ -7917,7 +7947,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
                 something silly in .opd with the assembler.  No .opd
                 optimization for them!  */
            broken_opd:
-             (*_bfd_error_handler)
+             _bfd_error_handler
                (_("%B: .opd is not a regular array of opd entries"), ibfd);
              broken = TRUE;
              break;
@@ -7926,7 +7956,8 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
          if ((r_type = ELF64_R_TYPE (rel->r_info)) != R_PPC64_ADDR64
              || (r_type = ELF64_R_TYPE ((rel + 1)->r_info)) != R_PPC64_TOC)
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: unexpected reloc type %u in .opd section"),
                 ibfd, r_type);
              broken = TRUE;
@@ -7947,7 +7978,8 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
                sym_name = bfd_elf_sym_name (ibfd, symtab_hdr, sym,
                                             sym_sec);
 
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: undefined sym `%s' in .opd section"),
                 ibfd, sym_name);
              broken = TRUE;
@@ -8089,11 +8121,14 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
              if (h != NULL
                  && h->root.root.string[0] == '.')
                {
-                 fdh = lookup_fdh ((struct ppc_link_hash_entry *) h, htab);
-                 if (fdh != NULL
-                     && fdh->elf.root.type != bfd_link_hash_defined
-                     && fdh->elf.root.type != bfd_link_hash_defweak)
-                   fdh = NULL;
+                 fdh = ((struct ppc_link_hash_entry *) h)->oh;
+                 if (fdh != NULL)
+                   {
+                     fdh = ppc_follow_link (fdh);
+                     if (fdh->elf.root.type != bfd_link_hash_defined
+                         && fdh->elf.root.type != bfd_link_hash_defweak)
+                       fdh = NULL;
+                   }
                }
 
              skip = (sym_sec->owner != ibfd
@@ -8524,7 +8559,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
                    case R_PPC64_GOT_TLSLD16_LO:
                      expecting_tls_get_addr = 1;
                      found_tls_get_addr_arg = 1;
-                     /* Fall thru */
+                     /* Fall through.  */
 
                    case R_PPC64_GOT_TLSLD16_HI:
                    case R_PPC64_GOT_TLSLD16_HA:
@@ -8544,7 +8579,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
                    case R_PPC64_GOT_TLSGD16_LO:
                      expecting_tls_get_addr = 1;
                      found_tls_get_addr_arg = 1;
-                     /* Fall thru */
+                     /* Fall through. */
 
                    case R_PPC64_GOT_TLSGD16_HI:
                    case R_PPC64_GOT_TLSGD16_HA:
@@ -8575,7 +8610,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
                    case R_PPC64_TLSGD:
                    case R_PPC64_TLSLD:
                      found_tls_get_addr_arg = 1;
-                     /* Fall thru */
+                     /* Fall through.  */
 
                    case R_PPC64_TLS:
                    case R_PPC64_TOC16:
@@ -8707,6 +8742,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
                         could just mark this symbol to exclude it
                         from tls optimization but it's safer to skip
                         the entire optimization.  */
+                     /* xgettext:c-format */
                      info->callbacks->minfo (_("%H arg lost __tls_get_addr, "
                                                "TLS optimization disabled\n"),
                                              ibfd, sec, rel->r_offset);
@@ -8851,7 +8887,7 @@ adjust_toc_syms (struct elf_link_hash_entry *h, void *inf)
 
       if ((toc_inf->skip[i] & (ref_from_discarded | can_optimize)) != 0)
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
            (_("%s defined on removed toc entry"), eh->elf.root.root.string);
          do
            ++i;
@@ -8868,12 +8904,14 @@ adjust_toc_syms (struct elf_link_hash_entry *h, void *inf)
   return TRUE;
 }
 
-/* Return TRUE iff INSN is one we expect on a _LO variety toc/got reloc.  */
+/* Return TRUE iff INSN with a relocation of R_TYPE is one we expect
+   on a _LO variety toc/got reloc.  */
 
 static bfd_boolean
-ok_lo_toc_insn (unsigned int insn)
+ok_lo_toc_insn (unsigned int insn, enum elf_ppc64_reloc_type r_type)
 {
-  return ((insn & (0x3f << 26)) == 14u << 26 /* addi */
+  return ((insn & (0x3f << 26)) == 12u << 26 /* addic */
+         || (insn & (0x3f << 26)) == 14u << 26 /* addi */
          || (insn & (0x3f << 26)) == 32u << 26 /* lwz */
          || (insn & (0x3f << 26)) == 34u << 26 /* lbz */
          || (insn & (0x3f << 26)) == 36u << 26 /* stw */
@@ -8887,11 +8925,20 @@ ok_lo_toc_insn (unsigned int insn)
          || (insn & (0x3f << 26)) == 50u << 26 /* lfd */
          || (insn & (0x3f << 26)) == 52u << 26 /* stfs */
          || (insn & (0x3f << 26)) == 54u << 26 /* stfd */
-         || ((insn & (0x3f << 26)) == 58u << 26 /* lwa,ld,lmd */
-             && (insn & 3) != 1)
-         || ((insn & (0x3f << 26)) == 62u << 26 /* std, stmd */
-             && ((insn & 3) == 0 || (insn & 3) == 3))
-         || (insn & (0x3f << 26)) == 12u << 26 /* addic */);
+         || (insn & (0x3f << 26)) == 56u << 26 /* lq,lfq */
+         || ((insn & (0x3f << 26)) == 57u << 26 /* lxsd,lxssp,lfdp */
+             /* Exclude lfqu by testing reloc.  If relocs are ever
+                defined for the reduced D field in psq_lu then those
+                will need testing too.  */
+             && r_type != R_PPC64_TOC16_LO && r_type != R_PPC64_GOT16_LO)
+         || ((insn & (0x3f << 26)) == 58u << 26 /* ld,lwa */
+             && (insn & 1) == 0)
+         || (insn & (0x3f << 26)) == 60u << 26 /* stfq */
+         || ((insn & (0x3f << 26)) == 61u << 26 /* lxv,stx{v,sd,ssp},stfdp */
+             /* Exclude stfqu.  psq_stu as above for psq_lu.  */
+             && r_type != R_PPC64_TOC16_LO && r_type != R_PPC64_GOT16_LO)
+         || ((insn & (0x3f << 26)) == 62u << 26 /* std,stq */
+             && (insn & 1) == 0));
 }
 
 /* Examine all relocs referencing .toc sections in order to remove
@@ -9196,7 +9243,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
                        }
                      insn = bfd_get_32 (ibfd, buf);
                      if (insn_check == check_lo
-                         ? !ok_lo_toc_insn (insn)
+                         ? !ok_lo_toc_insn (insn, r_type)
                          : ((insn & ((0x3f << 26) | 0x1f << 16))
                             != ((15u << 26) | (2 << 16)) /* addis rt,2,imm */))
                        {
@@ -9205,6 +9252,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
                          ppc64_elf_tdata (ibfd)->unexpected_toc_insn = 1;
                          sprintf (str, "%#08x", insn);
                          info->callbacks->einfo
+                           /* xgettext:c-format */
                            (_("%P: %H: toc optimization is not supported for"
                               " %s instruction.\n"),
                             ibfd, sec, rel->r_offset & ~3, str);
@@ -9268,7 +9316,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
                            }
                          if ((opc & (0x3f << 2)) == (58u << 2))
                            break;
-                         /* Fall thru */
+                         /* Fall through.  */
 
                        default:
                          /* Wrong sort of reloc, or not a ld.  We may
@@ -9433,6 +9481,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
                          if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
                            ppc_howto_init ();
                          info->callbacks->einfo
+                           /* xgettext:c-format */
                            (_("%P: %H: %s references "
                               "optimized away TOC entry\n"),
                             ibfd, sec, rel->r_offset,
@@ -9475,7 +9524,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
                  if ((skip[i] & (ref_from_discarded | can_optimize)) != 0)
                    {
                      if (local_toc_syms)
-                       (*_bfd_error_handler)
+                       _bfd_error_handler
                          (_("%s defined on removed toc entry"),
                           bfd_elf_sym_name (ibfd, symtab_hdr, sym, NULL));
                      do
@@ -11074,10 +11123,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 
          /* If the old-ABI "dot-symbol" is undefined make it weak so
             we don't get a link error from RELOC_FOR_GLOBAL_SYMBOL.  */
-         if (fh->elf.root.type == bfd_link_hash_undefined)
+         if (fh->elf.root.type == bfd_link_hash_undefined
+             && (stub_entry->h->elf.root.type == bfd_link_hash_defined
+                 || stub_entry->h->elf.root.type == bfd_link_hash_defweak))
            fh->elf.root.type = bfd_link_hash_undefweak;
-         /* Stop undo_symbol_twiddle changing it back to undefined.  */
-         fh->was_undefined = 0;
        }
 
       /* Now build the stub.  */
@@ -11122,6 +11171,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
        {
          info->callbacks->einfo
+           /* xgettext:c-format */
            (_("%P: linkage table error against `%T'\n"),
             stub_entry->h != NULL
             ? stub_entry->h->elf.root.root.string
@@ -12104,8 +12154,9 @@ group_sections (struct bfd_link_info *info,
 
          big_sec = total > group_size;
          if (big_sec && !suppress_size_errors)
-           (*_bfd_error_handler) (_("%B section %A exceeds stub group size"),
-                                    tail->owner, tail);
+           /* xgettext:c-format */
+           _bfd_error_handler (_("%B section %A exceeds stub group size"),
+                               tail->owner, tail);
          curr_toc = htab->sec_info[tail->id].toc_off;
 
          while ((prev = htab->sec_info[curr->id].u.list) != NULL
@@ -12404,8 +12455,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
                         use the func descriptor sym instead if it is
                         defined.  */
                      if (hash->elf.root.root.string[0] == '.'
-                         && (fdh = lookup_fdh (hash, htab)) != NULL)
+                         && hash->oh != NULL)
                        {
+                         fdh = ppc_follow_link (hash->oh);
                          if (fdh->elf.root.type == bfd_link_hash_defined
                              || fdh->elf.root.type == bfd_link_hash_defweak)
                            {
@@ -12600,7 +12652,10 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
          {
-           stub_sec->rawsize = stub_sec->size;
+           if (htab->stub_iteration <= STUB_SHRINK_ITER
+               || stub_sec->rawsize < stub_sec->size)
+             /* Past STUB_SHRINK_ITER, rawsize is the max size seen.  */
+             stub_sec->rawsize = stub_sec->size;
            stub_sec->size = 0;
            stub_sec->reloc_count = 0;
            stub_sec->flags &= ~SEC_RELOC;
@@ -13231,33 +13286,6 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
   return TRUE;
 }
 
-/* This function undoes the changes made by add_symbol_adjust.  */
-
-static bfd_boolean
-undo_symbol_twiddle (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
-{
-  struct ppc_link_hash_entry *eh;
-
-  if (h->root.type == bfd_link_hash_indirect)
-    return TRUE;
-
-  eh = (struct ppc_link_hash_entry *) h;
-  if (eh->elf.root.type != bfd_link_hash_undefweak || !eh->was_undefined)
-    return TRUE;
-
-  eh->elf.root.type = bfd_link_hash_undefined;
-  return TRUE;
-}
-
-void
-ppc64_elf_restore_symbols (struct bfd_link_info *info)
-{
-  struct ppc_link_hash_table *htab = ppc_hash_table (info);
-
-  if (htab != NULL)
-    elf_link_hash_traverse (&htab->elf, undo_symbol_twiddle, info);
-}
-
 /* What to do when ld finds relocations against symbols defined in
    discarded sections.  */
 
@@ -13329,7 +13357,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
   bfd_boolean is_opd;
   /* Assume 'at' branch hints.  */
   bfd_boolean is_isa_v2 = TRUE;
-  bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
+  bfd_vma d_offset = (bfd_big_endian (input_bfd) ? 2 : 0);
 
   /* Initialize howto table if needed.  */
   if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
@@ -13558,7 +13586,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          else
            info->callbacks->einfo
              (!IS_PPC64_TLS_RELOC (r_type)
+              /* xgettext:c-format */
               ? _("%P: %H: %s used with TLS symbol `%T'\n")
+              /* xgettext:c-format */
               : _("%P: %H: %s used with non-TLS symbol `%T'\n"),
               input_bfd, input_section, rel->r_offset,
               ppc64_elf_howto_table[r_type]->name,
@@ -13584,11 +13614,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          break;
 
        case R_PPC64_LO_DS_OPT:
-         insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
+         insn = bfd_get_32 (input_bfd, contents + rel->r_offset - d_offset);
          if ((insn & (0x3f << 26)) != 58u << 26)
            abort ();
          insn += (14u << 26) - (58u << 26);
-         bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset);
+         bfd_put_32 (input_bfd, insn, contents + rel->r_offset - d_offset);
          r_type = R_PPC64_TOC16_LO;
          rel->r_info = ELF64_R_INFO (r_symndx, r_type);
          break;
@@ -13643,7 +13673,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              && (tls_mask & TLS_TPREL) == 0)
            {
              rel->r_offset -= d_offset;
-             bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
+             bfd_put_32 (input_bfd, NOP, contents + rel->r_offset);
              r_type = R_PPC64_NONE;
              rel->r_info = ELF64_R_INFO (r_symndx, r_type);
            }
@@ -13655,11 +13685,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              && (tls_mask & TLS_TPREL) == 0)
            {
            toctprel:
-             insn = bfd_get_32 (output_bfd,
+             insn = bfd_get_32 (input_bfd,
                                 contents + rel->r_offset - d_offset);
              insn &= 31 << 21;
              insn |= 0x3c0d0000;       /* addis 0,13,0 */
-             bfd_put_32 (output_bfd, insn,
+             bfd_put_32 (input_bfd, insn,
                          contents + rel->r_offset - d_offset);
              r_type = R_PPC64_TPREL16_HA;
              if (toc_symndx != 0)
@@ -13679,11 +13709,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          if (tls_mask != 0
              && (tls_mask & TLS_TPREL) == 0)
            {
-             insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
+             insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
              insn = _bfd_elf_ppc_at_tls_transform (insn, 13);
              if (insn == 0)
                abort ();
-             bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+             bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
              /* Was PPC64_TLS which sits on insn boundary, now
                 PPC64_TPREL16_LO which is at low-order half-word.  */
              rel->r_offset += d_offset;
@@ -13719,7 +13749,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              else
                {
                  rel->r_offset -= d_offset;
-                 bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
+                 bfd_put_32 (input_bfd, NOP, contents + rel->r_offset);
                  r_type = R_PPC64_NONE;
                }
              rel->r_info = ELF64_R_INFO (r_symndx, r_type);
@@ -13757,7 +13787,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                 need to keep the destination reg.  It may be
                 something other than the usual r3, and moved to r3
                 before the call by intervening code.  */
-             insn1 = bfd_get_32 (output_bfd,
+             insn1 = bfd_get_32 (input_bfd,
                                  contents + rel->r_offset - d_offset);
              if ((tls_mask & tls_gd) != 0)
                {
@@ -13813,20 +13843,20 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                      rel[1].r_addend = rel->r_addend;
                    }
                }
-             bfd_put_32 (output_bfd, insn1,
+             bfd_put_32 (input_bfd, insn1,
                          contents + rel->r_offset - d_offset);
              if (offset != (bfd_vma) -1)
                {
-                 insn3 = bfd_get_32 (output_bfd,
+                 insn3 = bfd_get_32 (input_bfd,
                                      contents + offset + 4);
                  if (insn3 == NOP
                      || insn3 == CROR_151515 || insn3 == CROR_313131)
                    {
                      rel[1].r_offset += 4;
-                     bfd_put_32 (output_bfd, insn2, contents + offset + 4);
+                     bfd_put_32 (input_bfd, insn2, contents + offset + 4);
                      insn2 = NOP;
                    }
-                 bfd_put_32 (output_bfd, insn2, contents + offset);
+                 bfd_put_32 (input_bfd, insn2, contents + offset);
                }
              if ((tls_mask & tls_gd) == 0
                  && (tls_gd == 0 || toc_symndx != 0))
@@ -13866,16 +13896,16 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              /* Zap the reloc on the _tls_get_addr call too.  */
              BFD_ASSERT (offset == rel[1].r_offset);
              rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
-             insn3 = bfd_get_32 (output_bfd,
+             insn3 = bfd_get_32 (input_bfd,
                                  contents + offset + 4);
              if (insn3 == NOP
                  || insn3 == CROR_151515 || insn3 == CROR_313131)
                {
                  rel->r_offset += 4;
-                 bfd_put_32 (output_bfd, insn2, contents + offset + 4);
+                 bfd_put_32 (input_bfd, insn2, contents + offset + 4);
                  insn2 = NOP;
                }
-             bfd_put_32 (output_bfd, insn2, contents + offset);
+             bfd_put_32 (input_bfd, insn2, contents + offset);
              if ((tls_mask & TLS_TPRELGD) == 0 && toc_symndx != 0)
                goto again;
            }
@@ -13909,16 +13939,16 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              BFD_ASSERT (offset == rel[1].r_offset);
              rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
              insn2 = 0x38630000;       /* addi 3,3,0 */
-             insn3 = bfd_get_32 (output_bfd,
+             insn3 = bfd_get_32 (input_bfd,
                                  contents + offset + 4);
              if (insn3 == NOP
                  || insn3 == CROR_151515 || insn3 == CROR_313131)
                {
                  rel->r_offset += 4;
-                 bfd_put_32 (output_bfd, insn2, contents + offset + 4);
+                 bfd_put_32 (input_bfd, insn2, contents + offset + 4);
                  insn2 = NOP;
                }
-             bfd_put_32 (output_bfd, insn2, contents + offset);
+             bfd_put_32 (input_bfd, insn2, contents + offset);
              goto again;
            }
          break;
@@ -13973,10 +14003,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              if ((insn1 & ~0xfffc) == LD_R2_0R12
                  && insn2 == ADD_R2_R2_R12)
                {
-                 bfd_put_32 (output_bfd,
+                 bfd_put_32 (input_bfd,
                              LIS_R2 + PPC_HA (relocation),
                              contents + rel->r_offset);
-                 bfd_put_32 (output_bfd,
+                 bfd_put_32 (input_bfd,
                              ADDI_R2_R2 + PPC_LO (relocation),
                              contents + rel->r_offset + 4);
                }
@@ -13995,10 +14025,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                  if ((insn1 & ~0xfffc) == LD_R2_0R12
                      && insn2 == ADD_R2_R2_R12)
                    {
-                     bfd_put_32 (output_bfd,
+                     bfd_put_32 (input_bfd,
                                  ADDIS_R2_R12 + PPC_HA (relocation),
                                  contents + rel->r_offset);
-                     bfd_put_32 (output_bfd,
+                     bfd_put_32 (input_bfd,
                                  ADDI_R2_R2 + PPC_LO (relocation),
                                  contents + rel->r_offset + 4);
                    }
@@ -14027,8 +14057,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
            {
              unsigned int insn1, insn2;
              bfd_vma offset = rel->r_offset - d_offset;
-             insn1 = bfd_get_32 (output_bfd, contents + offset);
-             insn2 = bfd_get_32 (output_bfd, contents + offset + 4);
+             insn1 = bfd_get_32 (input_bfd, contents + offset);
+             insn2 = bfd_get_32 (input_bfd, contents + offset + 4);
              if ((insn1 & 0xffff0000) == ADDIS_R2_R12
                  && (insn2 & 0xffff0000) == ADDI_R2_R2)
                {
@@ -14037,7 +14067,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                  rel->r_addend -= d_offset;
                  rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_ADDR16_LO);
                  rel[1].r_addend -= d_offset + 4;
-                 bfd_put_32 (output_bfd, LIS_R2, contents + offset);
+                 bfd_put_32 (input_bfd, LIS_R2, contents + offset);
                }
            }
          break;
@@ -14073,18 +14103,18 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        case R_PPC64_ADDR14_BRTAKEN:
        case R_PPC64_REL14_BRTAKEN:
          insn = 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field.  */
-         /* Fall thru.  */
+         /* Fall through.  */
 
          /* Branch not taken prediction relocations.  */
        case R_PPC64_ADDR14_BRNTAKEN:
        case R_PPC64_REL14_BRNTAKEN:
-         insn |= bfd_get_32 (output_bfd,
+         insn |= bfd_get_32 (input_bfd,
                              contents + rel->r_offset) & ~(0x01 << 21);
-         /* Fall thru.  */
+         /* Fall through.  */
 
        case R_PPC64_REL14:
          max_br_offset = 1 << 15;
-         /* Fall thru.  */
+         /* Fall through.  */
 
        case R_PPC64_REL24:
          /* Calls to functions with a different TOC, such as calls to
@@ -14188,11 +14218,13 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                  if (stub_entry->stub_type == ppc_stub_plt_call
                      || stub_entry->stub_type == ppc_stub_plt_call_r2save)
                    info->callbacks->einfo
+                     /* xgettext:c-format */
                      (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
                         "recompile with -fPIC\n"),
                       input_bfd, input_section, rel->r_offset, sym_name);
                  else
                    info->callbacks->einfo
+                     /* xgettext:c-format */
                      (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
                         "(-mcmodel=small toc adjust stub)\n"),
                       input_bfd, input_section, rel->r_offset, sym_name);
@@ -14295,7 +14327,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                    insn ^= 0x01 << 21;
                }
 
-             bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+             bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
            }
 
          /* NOP out calls to undefined weak functions.
@@ -14308,7 +14340,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                   && relocation == 0
                   && addend == 0)
            {
-             bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
+             bfd_put_32 (input_bfd, NOP, contents + rel->r_offset);
              goto copy_reloc;
            }
          break;
@@ -14320,6 +14352,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        {
        default:
          info->callbacks->einfo
+           /* xgettext:c-format */
            (_("%P: %B: unknown relocation type %d for `%T'\n"),
             input_bfd, (int) r_type, sym_name);
 
@@ -14680,10 +14713,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                 defined before using them.  */
              bfd_byte *p = contents + rel->r_offset - d_offset;
 
-             insn = bfd_get_32 (output_bfd, p);
+             insn = bfd_get_32 (input_bfd, p);
              insn = _bfd_elf_ppc_at_tprel_transform (insn, 13);
              if (insn != 0)
-               bfd_put_32 (output_bfd, insn, p);
+               bfd_put_32 (input_bfd, insn, p);
              break;
            }
          if (htab->elf.tls_sec != NULL)
@@ -14730,7 +14763,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        case R_PPC64_DTPREL64:
          if (htab->elf.tls_sec != NULL)
            addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
-         /* Fall thru */
+         /* Fall through.  */
 
          /* Relocations that may need to be propagated if this is a
             dynamic object.  */
@@ -14862,6 +14895,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                          : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
                        {
                          info->callbacks->einfo
+                           /* xgettext:c-format */
                            (_("%P: %H: %s for indirect "
                               "function `%T' unsupported\n"),
                             input_bfd, input_section, rel->r_offset,
@@ -14969,6 +15003,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          /* These ones haven't been implemented yet.  */
 
          info->callbacks->einfo
+           /* xgettext:c-format */
            (_("%P: %B: %s is not supported for `%T'\n"),
             input_bfd,
             ppc64_elf_howto_table[r_type]->name, sym_name);
@@ -15073,7 +15108,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
             alone (it will be set to zero elsewhere in the link).  */
          if (sec == NULL)
            break;
-         /* Fall thru */
+         /* Fall through.  */
 
        case R_PPC64_GOT16_HA:
        case R_PPC64_PLTGOT16_HA:
@@ -15123,6 +15158,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
            {
              relocation ^= relocation & mask;
              info->callbacks->einfo
+               /* xgettext:c-format */
                (_("%P: %H: error: %s not a multiple of %u\n"),
                 input_bfd, input_section, rel->r_offset,
                 howto->name,
@@ -15144,6 +15180,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                                      rel->r_offset) != (bfd_vma) -1)
        {
          info->callbacks->einfo
+           /* xgettext:c-format */
            (_("%P: %H: unresolvable %s against `%T'\n"),
             input_bfd, input_section, rel->r_offset,
             howto->name,
@@ -15240,6 +15277,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          else
            {
              info->callbacks->einfo
+               /* xgettext:c-format */
                (_("%P: %H: %s against `%T': error %d\n"),
                 input_bfd, input_section, rel->r_offset,
                 reloc_name, sym_name, (int) r);
@@ -15538,27 +15576,6 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
            case DT_PLTRELSZ:
              dyn.d_un.d_val = htab->elf.srelplt->size;
              break;
-
-           case DT_RELASZ:
-             /* Don't count procedure linkage table relocs in the
-                overall reloc count.  */
-             s = htab->elf.srelplt;
-             if (s == NULL)
-               continue;
-             dyn.d_un.d_val -= s->size;
-             break;
-
-           case DT_RELA:
-             /* We may not be using the standard ELF linker script.
-                If .rela.plt is the first .rela section, we adjust
-                DT_RELA to not include it.  */
-             s = htab->elf.srelplt;
-             if (s == NULL)
-               continue;
-             if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
-               continue;
-             dyn.d_un.d_ptr += s->size;
-             break;
            }
 
          bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
This page took 0.045201 seconds and 4 git commands to generate.