* elf-bfd.h (_bfd_elf_create_linker_section) Don't declare.
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index 6fdfebe795f9d20196e0decf7f60a17ab18d791d..f2b987c19ed723786fc69ce9d0ca3caa1eea34f9 100644 (file)
@@ -16,8 +16,9 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 /* This file is based on a preliminary PowerPC ELF ABI.  The
    information may not match the final PowerPC ELF ABI.  It includes
 
 /* RELA relocations are used here.  */
 
-static struct bfd_hash_entry *ppc_elf_link_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
-          const char *string));
-static struct bfd_link_hash_table *ppc_elf_link_hash_table_create
-  PARAMS ((bfd *abfd));
-static void ppc_elf_copy_indirect_symbol
-  PARAMS ((struct elf_backend_data *bed, struct elf_link_hash_entry *dir,
-          struct elf_link_hash_entry *ind));
-static reloc_howto_type *ppc_elf_reloc_type_lookup
-  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-static void ppc_elf_info_to_howto
-  PARAMS ((bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst));
-static void ppc_elf_howto_init
-  PARAMS ((void));
-static int ppc_elf_sort_rela
-  PARAMS ((const PTR, const PTR));
-static bfd_boolean ppc_elf_relax_section
-  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
 static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc_elf_unhandled_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static bfd_boolean ppc_elf_object_p
-  PARAMS ((bfd *));
-static bfd_boolean ppc_elf_set_private_flags
-  PARAMS ((bfd *, flagword));
-static bfd_boolean ppc_elf_merge_private_bfd_data
-  PARAMS ((bfd *, bfd *));
-static int ppc_elf_additional_program_headers
-  PARAMS ((bfd *));
-static bfd_boolean ppc_elf_modify_segment_map
-  PARAMS ((bfd *));
-static bfd_boolean ppc_elf_create_got
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean ppc_elf_create_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean ppc_elf_section_from_shdr
-  PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
-static bfd_boolean ppc_elf_fake_sections
-  PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
-static elf_linker_section_t *ppc_elf_create_linker_section
-  PARAMS ((bfd *abfd, struct bfd_link_info *info,
-          enum elf_linker_section_enum));
-static bfd_boolean update_local_sym_info
-  PARAMS ((bfd *, Elf_Internal_Shdr *, unsigned long, int));
-static void bad_shared_reloc
-  PARAMS ((bfd *, enum elf_ppc_reloc_type));
-static bfd_boolean ppc_elf_check_relocs
-  PARAMS ((bfd *, struct bfd_link_info *, asection *,
-          const Elf_Internal_Rela *));
-static asection *ppc_elf_gc_mark_hook
-  PARAMS ((asection *sec, struct bfd_link_info *info, Elf_Internal_Rela *rel,
-          struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
-static bfd_boolean ppc_elf_gc_sweep_hook
-  PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
-          const Elf_Internal_Rela *relocs));
-static bfd_boolean ppc_elf_adjust_dynamic_symbol
-  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static bfd_boolean allocate_dynrelocs
-  PARAMS ((struct elf_link_hash_entry *, PTR));
-static bfd_boolean readonly_dynrelocs
-  PARAMS ((struct elf_link_hash_entry *, PTR));
-static bfd_boolean ppc_elf_size_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean ppc_elf_relocate_section
-  PARAMS ((bfd *, struct bfd_link_info *info, bfd *, asection *, bfd_byte *,
-          Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
-          asection **));
-static bfd_boolean ppc_elf_add_symbol_hook
-  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
-          const char **, flagword *, asection **, bfd_vma *));
-static bfd_boolean ppc_elf_finish_dynamic_symbol
-  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
-          Elf_Internal_Sym *));
-static bfd_boolean ppc_elf_finish_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static enum elf_reloc_type_class ppc_elf_reloc_type_class
-  PARAMS ((const Elf_Internal_Rela *));
-static bfd_boolean ppc_elf_grok_prstatus
-  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-static bfd_boolean ppc_elf_grok_psinfo
-  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 
 /* Branch prediction bit for branch taken relocs.  */
 #define BRANCH_PREDICT_BIT 0x200000
@@ -146,23 +69,6 @@ static bfd_boolean ppc_elf_grok_psinfo
 #define TP_OFFSET      0x7000
 #define DTP_OFFSET     0x8000
 
-/* Will references to this symbol always reference the symbol
-   in this object?  */
-#define SYMBOL_REFERENCES_LOCAL(INFO, H)                               \
-  ((! INFO->shared                                                     \
-    || INFO->symbolic                                                  \
-    || H->dynindx == -1                                                        \
-    || ELF_ST_VISIBILITY (H->other) == STV_INTERNAL                    \
-    || ELF_ST_VISIBILITY (H->other) == STV_HIDDEN)                     \
-   && (H->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
-
-/* Will _calls_ to this symbol always call the version in this object?  */
-#define SYMBOL_CALLS_LOCAL(INFO, H)                            \
-  ((! INFO->shared                                                     \
-    || INFO->symbolic                                                  \
-    || H->dynindx == -1                                                        \
-    || ELF_ST_VISIBILITY (H->other) != STV_DEFAULT)                    \
-   && (H->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
 \f
 /* The PPC linker needs to keep track of the number of relocs that it
    decides to copy as dynamic relocs in check_relocs for each symbol.
@@ -194,7 +100,7 @@ struct ppc_elf_link_hash_entry
   struct ppc_elf_dyn_relocs *dyn_relocs;
 
   /* Contexts in which symbol is used in the GOT (or TOC).
-     TLS_GD .. TLS_EXPLICIT bits are or'd into the mask as the
+     TLS_GD .. TLS_TLS bits are or'd into the mask as the
      corresponding relocs are encountered during check_relocs.
      tls_optimize clears TLS_GD .. TLS_TPREL when optimizing to
      indicate the corresponding GOT entry type is not needed.  */
@@ -251,10 +157,9 @@ struct ppc_elf_link_hash_table
 /* Create an entry in a PPC ELF linker hash table.  */
 
 static struct bfd_hash_entry *
-ppc_elf_link_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+ppc_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+                          struct bfd_hash_table *table,
+                          const char *string)
 {
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
@@ -280,13 +185,11 @@ ppc_elf_link_hash_newfunc (entry, table, string)
 /* Create a PPC ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
-ppc_elf_link_hash_table_create (abfd)
-     bfd *abfd;
+ppc_elf_link_hash_table_create (bfd *abfd)
 {
   struct ppc_elf_link_hash_table *ret;
 
-  ret = ((struct ppc_elf_link_hash_table *)
-        bfd_malloc (sizeof (struct ppc_elf_link_hash_table)));
+  ret = bfd_malloc (sizeof (struct ppc_elf_link_hash_table));
   if (ret == NULL)
     return NULL;
 
@@ -315,12 +218,18 @@ ppc_elf_link_hash_table_create (abfd)
   return &ret->elf.root;
 }
 
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+   copying dynamic variables from a shared lib into an app's dynbss
+   section, and instead use a dynamic relocation to point into the
+   shared lib.  */
+#define ELIMINATE_COPY_RELOCS 1
+
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-ppc_elf_copy_indirect_symbol (bed, dir, ind)
-     struct elf_backend_data *bed;
-     struct elf_link_hash_entry *dir, *ind;
+ppc_elf_copy_indirect_symbol (struct elf_backend_data *bed,
+                             struct elf_link_hash_entry *dir,
+                             struct elf_link_hash_entry *ind)
 {
   struct ppc_elf_link_hash_entry *edir, *eind;
 
@@ -363,10 +272,21 @@ ppc_elf_copy_indirect_symbol (bed, dir, ind)
 
   edir->tls_mask |= eind->tls_mask;
 
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  if (ELIMINATE_COPY_RELOCS
+      && ind->root.type != bfd_link_hash_indirect
+      && (dir->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
+    /* If called to transfer flags for a weakdef during processing
+       of elf_adjust_dynamic_symbol, don't copy ELF_LINK_NON_GOT_REF.
+       We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
+    dir->elf_link_hash_flags |=
+      (ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
+                                  | ELF_LINK_HASH_REF_REGULAR
+                                  | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+  else
+    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
 \f
-static reloc_howto_type *ppc_elf_howto_table[(int) R_PPC_max];
+static reloc_howto_type *ppc_elf_howto_table[R_PPC_max];
 
 static reloc_howto_type ppc_elf_howto_raw[] = {
   /* This reloc does nothing.  */
@@ -1605,14 +1525,18 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
 
 static void
-ppc_elf_howto_init ()
+ppc_elf_howto_init (void)
 {
   unsigned int i, type;
 
-  for (i = 0; i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); i++)
+  for (i = 0;
+       i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
+       i++)
     {
       type = ppc_elf_howto_raw[i].type;
-      BFD_ASSERT (type < sizeof (ppc_elf_howto_table) / sizeof (ppc_elf_howto_table[0]));
+      if (type >= (sizeof (ppc_elf_howto_table)
+                  / sizeof (ppc_elf_howto_table[0])))
+       abort ();
       ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
     }
 }
@@ -1626,7 +1550,8 @@ ppc_elf_howto_init ()
    2/ The branch is predicted as not taken.
    3/ The branch is taken.
    4/ The branch is located in the last 5 words of a page.
-      (The EOP limit is 5 by default but may be specified as any value from 1-10.)
+      (The EOP limit is 5 by default but may be specified as any value
+      from 1-10.)
 
    Our software solution is to detect these problematic branches in a
    linker pass and modify them as follows:
@@ -1641,23 +1566,20 @@ ppc_elf_howto_init ()
 /* Sort sections by address.  */
 
 static int
-ppc_elf_sort_rela (arg1, arg2)
-     const PTR arg1;
-     const PTR arg2;
+ppc_elf_sort_rela (const void *arg1, const void *arg2)
 {
-  const Elf_Internal_Rela **rela1 = (const Elf_Internal_Rela**) arg1;
-  const Elf_Internal_Rela **rela2 = (const Elf_Internal_Rela**) arg2;
+  const Elf_Internal_Rela * const *rela1 = arg1;
+  const Elf_Internal_Rela * const *rela2 = arg2;
 
   /* Sort by offset.  */
   return ((*rela1)->r_offset - (*rela2)->r_offset);
 }
 
 static bfd_boolean
-ppc_elf_relax_section (abfd, isec, link_info, again)
-     bfd *abfd;
-     asection *isec;
-     struct bfd_link_info *link_info;
-     bfd_boolean *again;
+ppc_elf_relax_section (bfd *abfd,
+                      asection *isec,
+                      struct bfd_link_info *link_info,
+                      bfd_boolean *again)
 {
 #define PAGESIZE 0x1000
 
@@ -1689,7 +1611,7 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
       else
        {
          /* Go get them off disk.  */
-         contents = (bfd_byte *) bfd_malloc (isec->_raw_size);
+         contents = bfd_malloc (isec->_raw_size);
          if (contents == NULL)
            goto error_return;
          free_contents = contents;
@@ -1708,9 +1630,8 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
 
          /* Get a copy of the native relocations.  */
          internal_relocs
-           = _bfd_elf32_link_read_relocs (abfd, isec, (PTR) NULL,
-                                          (Elf_Internal_Rela *) NULL,
-                                          link_info->keep_memory);
+           = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL,
+                                        link_info->keep_memory);
          if (internal_relocs == NULL)
            goto error_return;
          if (! link_info->keep_memory)
@@ -1719,15 +1640,15 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
          /* Setup a faster access method for the reloc info we need.  */
          amt = isec->reloc_count;
          amt *= sizeof (Elf_Internal_Rela*);
-         rela_comb = (Elf_Internal_Rela**) bfd_malloc (amt);
+         rela_comb = bfd_malloc (amt);
          if (rela_comb == NULL)
            goto error_return;
          for (n = 0; n < isec->reloc_count; ++n)
            {
-             long r_type;
+             enum elf_ppc_reloc_type r_type;
 
              r_type = ELF32_R_TYPE (internal_relocs[n].r_info);
-             if (r_type < 0 || r_type >= (int) R_PPC_max)
+             if (r_type >= R_PPC_max)
                goto error_return;
 
              /* Prologue constants are sometimes present in the ".text"
@@ -1855,7 +1776,7 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
 #undef BO4
              if (modified)
                {
-                 bfd_put_32 (abfd, (bfd_vma) insn, contents + isec_offset);
+                 bfd_put_32 (abfd, insn, contents + isec_offset);
                  section_modified = TRUE;
                }
            }
@@ -1904,20 +1825,19 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
 }
 \f
 static reloc_howto_type *
-ppc_elf_reloc_type_lookup (abfd, code)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     bfd_reloc_code_real_type code;
+ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                          bfd_reloc_code_real_type code)
 {
   enum elf_ppc_reloc_type r;
 
+  /* Initialize howto table if not already done.  */
   if (!ppc_elf_howto_table[R_PPC_ADDR32])
-    /* Initialize howto table if needed.  */
     ppc_elf_howto_init ();
 
-  switch ((int) code)
+  switch (code)
     {
     default:
-      return (reloc_howto_type *) NULL;
+      return NULL;
 
     case BFD_RELOC_NONE:               r = R_PPC_NONE;                 break;
     case BFD_RELOC_32:                 r = R_PPC_ADDR32;               break;
@@ -2002,19 +1922,18 @@ ppc_elf_reloc_type_lookup (abfd, code)
     case BFD_RELOC_VTABLE_ENTRY:       r = R_PPC_GNU_VTENTRY;          break;
     }
 
-  return ppc_elf_howto_table[(int) r];
+  return ppc_elf_howto_table[r];
 };
 
 /* Set the howto pointer for a PowerPC ELF reloc.  */
 
 static void
-ppc_elf_info_to_howto (abfd, cache_ptr, dst)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *cache_ptr;
-     Elf_Internal_Rela *dst;
+ppc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+                      arelent *cache_ptr,
+                      Elf_Internal_Rela *dst)
 {
+  /* Initialize howto table if not already done.  */
   if (!ppc_elf_howto_table[R_PPC_ADDR32])
-    /* Initialize howto table if needed.  */
     ppc_elf_howto_init ();
 
   BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
@@ -2024,15 +1943,13 @@ ppc_elf_info_to_howto (abfd, cache_ptr, dst)
 /* Handle the R_PPC_ADDR16_HA reloc.  */
 
 static bfd_reloc_status_type
-ppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section,
-                        output_bfd, error_message)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *reloc_entry;
-     asymbol *symbol;
-     PTR data ATTRIBUTE_UNUSED;
-     asection *input_section;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+ppc_elf_addr16_ha_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+                        arelent *reloc_entry,
+                        asymbol *symbol,
+                        void *data ATTRIBUTE_UNUSED,
+                        asection *input_section,
+                        bfd *output_bfd,
+                        char **error_message ATTRIBUTE_UNUSED)
 {
   bfd_vma relocation;
 
@@ -2060,15 +1977,13 @@ ppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section,
 }
 
 static bfd_reloc_status_type
-ppc_elf_unhandled_reloc (abfd, reloc_entry, symbol, data,
-                        input_section, output_bfd, error_message)
-     bfd *abfd;
-     arelent *reloc_entry;
-     asymbol *symbol;
-     PTR data;
-     asection *input_section;
-     bfd *output_bfd;
-     char **error_message;
+ppc_elf_unhandled_reloc (bfd *abfd,
+                        arelent *reloc_entry,
+                        asymbol *symbol,
+                        void *data,
+                        asection *input_section,
+                        bfd *output_bfd,
+                        char **error_message)
 {
   /* If this is a relocatable link (output_bfd test tells us), just
      call the generic function.  Any adjustment will be done at final
@@ -2080,7 +1995,7 @@ ppc_elf_unhandled_reloc (abfd, reloc_entry, symbol, data,
   if (error_message != NULL)
     {
       static char buf[60];
-      sprintf (buf, "generic linker can't handle %s",
+      sprintf (buf, _("generic linker can't handle %s"),
               reloc_entry->howto->name);
       *error_message = buf;
     }
@@ -2091,8 +2006,7 @@ ppc_elf_unhandled_reloc (abfd, reloc_entry, symbol, data,
    default is 64 bit.  */
 
 static bfd_boolean
-ppc_elf_object_p (abfd)
-     bfd *abfd;
+ppc_elf_object_p (bfd *abfd)
 {
   if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 64)
     {
@@ -2111,9 +2025,7 @@ ppc_elf_object_p (abfd)
 /* Function to set whether a module needs the -mrelocatable bit set.  */
 
 static bfd_boolean
-ppc_elf_set_private_flags (abfd, flags)
-     bfd *abfd;
-     flagword flags;
+ppc_elf_set_private_flags (bfd *abfd, flagword flags)
 {
   BFD_ASSERT (!elf_flags_init (abfd)
              || elf_elfheader (abfd)->e_flags == flags);
@@ -2127,9 +2039,7 @@ ppc_elf_set_private_flags (abfd, flags)
    object file when linking.  */
 
 static bfd_boolean
-ppc_elf_merge_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   flagword old_flags;
   flagword new_flags;
@@ -2167,7 +2077,8 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd)
        {
          error = TRUE;
          (*_bfd_error_handler)
-           (_("%s: compiled with -mrelocatable and linked with modules compiled normally"),
+           (_("%s: compiled with -mrelocatable and linked with "
+              "modules compiled normally"),
             bfd_archive_filename (ibfd));
        }
       else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
@@ -2175,7 +2086,8 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd)
        {
          error = TRUE;
          (*_bfd_error_handler)
-           (_("%s: compiled normally and linked with modules compiled with -mrelocatable"),
+           (_("%s: compiled normally and linked with "
+              "modules compiled with -mrelocatable"),
             bfd_archive_filename (ibfd));
        }
 
@@ -2202,7 +2114,8 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd)
        {
          error = TRUE;
          (*_bfd_error_handler)
-           (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+           (_("%s: uses different e_flags (0x%lx) fields "
+              "than previous modules (0x%lx)"),
             bfd_archive_filename (ibfd), (long) new_flags, (long) old_flags);
        }
 
@@ -2220,10 +2133,7 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd)
    is called when elfcode.h finds a section with an unknown type.  */
 
 static bfd_boolean
-ppc_elf_section_from_shdr (abfd, hdr, name)
-     bfd *abfd;
-     Elf_Internal_Shdr *hdr;
-     const char *name;
+ppc_elf_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, const char *name)
 {
   asection *newsect;
   flagword flags;
@@ -2246,10 +2156,9 @@ ppc_elf_section_from_shdr (abfd, hdr, name)
 /* Set up any other section flags and such that may be necessary.  */
 
 static bfd_boolean
-ppc_elf_fake_sections (abfd, shdr, asect)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     Elf_Internal_Shdr *shdr;
-     asection *asect;
+ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+                      Elf_Internal_Shdr *shdr,
+                      asection *asect)
 {
   if ((asect->flags & SEC_EXCLUDE) != 0)
     shdr->sh_flags |= SHF_EXCLUDE;
@@ -2260,12 +2169,365 @@ ppc_elf_fake_sections (abfd, shdr, asect)
   return TRUE;
 }
 \f
+/* Create a special linker section, or return a pointer to a linker
+   section already created */
+
+static elf_linker_section_t *
+elf_create_linker_section (bfd *abfd,
+                          struct bfd_link_info *info,
+                          enum elf_linker_section_enum which,
+                          elf_linker_section_t *defaults)
+{
+  bfd *dynobj = elf_hash_table (info)->dynobj;
+  elf_linker_section_t *lsect;
+
+  /* Record the first bfd section that needs the special section */
+  if (!dynobj)
+    dynobj = elf_hash_table (info)->dynobj = abfd;
+
+  /* If this is the first time, create the section */
+  lsect = elf_linker_section (dynobj, which);
+  if (!lsect)
+    {
+      asection *s;
+      bfd_size_type amt = sizeof (elf_linker_section_t);
+
+      lsect = bfd_alloc (dynobj, amt);
+
+      *lsect = *defaults;
+      elf_linker_section (dynobj, which) = lsect;
+      lsect->which = which;
+      lsect->hole_written_p = FALSE;
+
+      /* See if the sections already exist */
+      lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
+      if (!s || (s->flags & defaults->flags) != defaults->flags)
+       {
+         lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);
+
+         if (s == NULL)
+           return NULL;
+
+         bfd_set_section_flags (dynobj, s, defaults->flags);
+         bfd_set_section_alignment (dynobj, s, lsect->alignment);
+       }
+      else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)
+       bfd_set_section_alignment (dynobj, s, lsect->alignment);
+
+      s->_raw_size = align_power (s->_raw_size, lsect->alignment);
+
+      /* Is there a hole we have to provide?  If so check whether the
+        segment is too big already */
+      if (lsect->hole_size)
+       {
+         lsect->hole_offset = s->_raw_size;
+         s->_raw_size += lsect->hole_size;
+         if (lsect->hole_offset > lsect->max_hole_offset)
+           {
+             (*_bfd_error_handler)
+               (_("%s: Section %s is too large to add hole of %ld bytes"),
+                bfd_get_filename (abfd),
+                lsect->name,
+                (long) lsect->hole_size);
+
+             bfd_set_error (bfd_error_bad_value);
+             return NULL;
+           }
+       }
+
+#ifdef DEBUG
+      fprintf (stderr, "Creating section %s, current size = %ld\n",
+              lsect->name, (long) s->_raw_size);
+#endif
+
+      if (lsect->sym_name)
+       {
+         struct elf_link_hash_entry *h;
+         struct bfd_link_hash_entry *bh;
+
+#ifdef DEBUG
+         fprintf (stderr, "Adding %s to section %s\n",
+                  lsect->sym_name,
+                  lsect->name);
+#endif
+         bh = bfd_link_hash_lookup (info->hash, lsect->sym_name,
+                                    FALSE, FALSE, FALSE);
+
+         if ((bh == NULL || bh->type == bfd_link_hash_undefined)
+             && !(_bfd_generic_link_add_one_symbol
+                  (info, abfd, lsect->sym_name, BSF_GLOBAL, s,
+                   (lsect->hole_size
+                    ? s->_raw_size - lsect->hole_size + lsect->sym_offset
+                    : lsect->sym_offset),
+                   NULL, FALSE,
+                   get_elf_backend_data (abfd)->collect, &bh)))
+           return NULL;
+         h = (struct elf_link_hash_entry *) bh;
+
+         if ((defaults->which != LINKER_SECTION_SDATA)
+             && (defaults->which != LINKER_SECTION_SDATA2))
+           h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
+
+         h->type = STT_OBJECT;
+         lsect->sym_hash = h;
+
+         if (info->shared
+             && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+           return NULL;
+       }
+    }
+
+  return lsect;
+}
+\f
+/* Find a linker generated pointer with a given addend and type.  */
+
+static elf_linker_section_pointers_t *
+elf_find_pointer_linker_section
+  (elf_linker_section_pointers_t *linker_pointers,
+   bfd_vma addend,
+   elf_linker_section_enum_t which)
+{
+  for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
+    if (which == linker_pointers->which && addend == linker_pointers->addend)
+      return linker_pointers;
+
+  return NULL;
+}
+\f
+/* Allocate a pointer to live in a linker created section.  */
+
+static bfd_boolean
+elf_create_pointer_linker_section (bfd *abfd,
+                                  struct bfd_link_info *info,
+                                  elf_linker_section_t *lsect,
+                                  struct elf_link_hash_entry *h,
+                                  const Elf_Internal_Rela *rel)
+{
+  elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL;
+  elf_linker_section_pointers_t *linker_section_ptr;
+  unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
+  bfd_size_type amt;
+
+  BFD_ASSERT (lsect != NULL);
+
+  /* Is this a global symbol?  */
+  if (h != NULL)
+    {
+      /* Has this symbol already been allocated?  If so, our work is done.  */
+      if (elf_find_pointer_linker_section (h->linker_section_pointer,
+                                          rel->r_addend,
+                                          lsect->which))
+       return TRUE;
+
+      ptr_linker_section_ptr = &h->linker_section_pointer;
+      /* Make sure this symbol is output as a dynamic symbol.  */
+      if (h->dynindx == -1)
+       {
+         if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+           return FALSE;
+       }
+
+      if (lsect->rel_section)
+       lsect->rel_section->_raw_size += sizeof (Elf32_External_Rela);
+    }
+  else
+    {
+      /* Allocation of a pointer to a local symbol.  */
+      elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd);
+
+      /* Allocate a table to hold the local symbols if first time.  */
+      if (!ptr)
+       {
+         unsigned int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
+         register unsigned int i;
+
+         amt = num_symbols;
+         amt *= sizeof (elf_linker_section_pointers_t *);
+         ptr = bfd_alloc (abfd, amt);
+
+         if (!ptr)
+           return FALSE;
+
+         elf_local_ptr_offsets (abfd) = ptr;
+         for (i = 0; i < num_symbols; i++)
+           ptr[i] = NULL;
+       }
+
+      /* Has this symbol already been allocated?  If so, our work is done.  */
+      if (elf_find_pointer_linker_section (ptr[r_symndx],
+                                          rel->r_addend,
+                                          lsect->which))
+       return TRUE;
+
+      ptr_linker_section_ptr = &ptr[r_symndx];
+
+      if (info->shared)
+       {
+         /* If we are generating a shared object, we need to
+            output a R_<xxx>_RELATIVE reloc so that the
+            dynamic linker can adjust this GOT entry.  */
+         BFD_ASSERT (lsect->rel_section != NULL);
+         lsect->rel_section->_raw_size += sizeof (Elf32_External_Rela);
+       }
+    }
+
+  /* Allocate space for a pointer in the linker section, and allocate
+     a new pointer record from internal memory.  */
+  BFD_ASSERT (ptr_linker_section_ptr != NULL);
+  amt = sizeof (elf_linker_section_pointers_t);
+  linker_section_ptr = bfd_alloc (abfd, amt);
+
+  if (!linker_section_ptr)
+    return FALSE;
+
+  linker_section_ptr->next = *ptr_linker_section_ptr;
+  linker_section_ptr->addend = rel->r_addend;
+  linker_section_ptr->which = lsect->which;
+  linker_section_ptr->written_address_p = FALSE;
+  *ptr_linker_section_ptr = linker_section_ptr;
+
+  linker_section_ptr->offset = lsect->section->_raw_size;
+  lsect->section->_raw_size += 4;
+
+#ifdef DEBUG
+  fprintf (stderr,
+          "Create pointer in linker section %s, offset = %ld, section size = %ld\n",
+          lsect->name, (long) linker_section_ptr->offset,
+          (long) lsect->section->_raw_size);
+#endif
+
+  return TRUE;
+}
+\f
+#define bfd_put_ptr(BFD, VAL, ADDR) bfd_put_32 (BFD, VAL, ADDR)
+
+/* Fill in the address for a pointer generated in a linker section.  */
+
+static bfd_vma
+elf_finish_pointer_linker_section (bfd *output_bfd,
+                                  bfd *input_bfd,
+                                  struct bfd_link_info *info,
+                                  elf_linker_section_t *lsect,
+                                  struct elf_link_hash_entry *h,
+                                  bfd_vma relocation,
+                                  const Elf_Internal_Rela *rel,
+                                  int relative_reloc)
+{
+  elf_linker_section_pointers_t *linker_section_ptr;
+
+  BFD_ASSERT (lsect != NULL);
+
+  if (h != NULL)
+    {
+      /* Handle global symbol.  */
+      linker_section_ptr
+       = elf_find_pointer_linker_section (h->linker_section_pointer,
+                                          rel->r_addend,
+                                          lsect->which);
+
+      BFD_ASSERT (linker_section_ptr != NULL);
+
+      if (! elf_hash_table (info)->dynamic_sections_created
+         || (info->shared
+             && info->symbolic
+             && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+       {
+         /* This is actually a static link, or it is a
+            -Bsymbolic link and the symbol is defined
+            locally.  We must initialize this entry in the
+            global section.
+
+            When doing a dynamic link, we create a .rela.<xxx>
+            relocation entry to initialize the value.  This
+            is done in the finish_dynamic_symbol routine.  */
+         if (!linker_section_ptr->written_address_p)
+           {
+             linker_section_ptr->written_address_p = TRUE;
+             bfd_put_ptr (output_bfd,
+                          relocation + linker_section_ptr->addend,
+                          (lsect->section->contents
+                           + linker_section_ptr->offset));
+           }
+       }
+    }
+  else
+    {
+      /* Handle local symbol.  */
+      unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
+      BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
+      BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL);
+      linker_section_ptr = (elf_find_pointer_linker_section
+                           (elf_local_ptr_offsets (input_bfd)[r_symndx],
+                            rel->r_addend,
+                            lsect->which));
+
+      BFD_ASSERT (linker_section_ptr != NULL);
+
+      /* Write out pointer if it hasn't been rewritten out before.  */
+      if (!linker_section_ptr->written_address_p)
+       {
+         linker_section_ptr->written_address_p = TRUE;
+         bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
+                      lsect->section->contents + linker_section_ptr->offset);
+
+         if (info->shared)
+           {
+             asection *srel = lsect->rel_section;
+             Elf_Internal_Rela outrel[MAX_INT_RELS_PER_EXT_REL];
+             bfd_byte *erel;
+             struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+             unsigned int i;
+
+             /* We need to generate a relative reloc for the dynamic
+                linker.  */
+             if (!srel)
+               {
+                 srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
+                                                 lsect->rel_name);
+                 lsect->rel_section = srel;
+               }
+
+             BFD_ASSERT (srel != NULL);
+
+             for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
+               {
+                 outrel[i].r_offset = (lsect->section->output_section->vma
+                                       + lsect->section->output_offset
+                                       + linker_section_ptr->offset);
+                 outrel[i].r_info = 0;
+                 outrel[i].r_addend = 0;
+               }
+             outrel[0].r_info = ELF32_R_INFO (0, relative_reloc);
+             erel = lsect->section->contents;
+             erel += (elf_section_data (lsect->section)->rel_count++
+                      * sizeof (Elf32_External_Rela));
+             bfd_elf32_swap_reloca_out (output_bfd, outrel, erel);
+           }
+       }
+    }
+
+  relocation = (lsect->section->output_offset
+               + linker_section_ptr->offset
+               - lsect->hole_offset
+               - lsect->sym_offset);
+
+#ifdef DEBUG
+  fprintf (stderr,
+          "Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
+          lsect->name, (long) relocation, (long) relocation);
+#endif
+
+  /* Subtract out the addend, because it will get added back in by the normal
+     processing.  */
+  return relocation - linker_section_ptr->addend;
+}
+\f
 /* Create a special linker section */
 static elf_linker_section_t *
-ppc_elf_create_linker_section (abfd, info, which)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     enum elf_linker_section_enum which;
+ppc_elf_create_linker_section (bfd *abfd,
+                              struct bfd_link_info *info,
+                              enum elf_linker_section_enum which)
 {
   bfd *dynobj = elf_hash_table (info)->dynobj;
   elf_linker_section_t *lsect;
@@ -2305,7 +2567,7 @@ ppc_elf_create_linker_section (abfd, info, which)
                                 (int) which);
 
          bfd_set_error (bfd_error_bad_value);
-         return (elf_linker_section_t *) 0;
+         return NULL;
 
        case LINKER_SECTION_SDATA:      /* .sdata/.sbss section */
          defaults.name           = ".sdata";
@@ -2325,7 +2587,7 @@ ppc_elf_create_linker_section (abfd, info, which)
          break;
        }
 
-      lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
+      lsect = elf_create_linker_section (abfd, info, which, &defaults);
     }
 
   return lsect;
@@ -2335,8 +2597,7 @@ ppc_elf_create_linker_section (abfd, info, which)
    need to bump up the number of section headers.  */
 
 static int
-ppc_elf_additional_program_headers (abfd)
-     bfd *abfd;
+ppc_elf_additional_program_headers (bfd *abfd)
 {
   asection *s;
   int ret;
@@ -2361,8 +2622,7 @@ ppc_elf_additional_program_headers (abfd)
 /* Modify the segment map if needed.  */
 
 static bfd_boolean
-ppc_elf_modify_segment_map (abfd)
-     bfd *abfd ATTRIBUTE_UNUSED;
+ppc_elf_modify_segment_map (bfd *abfd ATTRIBUTE_UNUSED)
 {
   return TRUE;
 }
@@ -2370,9 +2630,7 @@ ppc_elf_modify_segment_map (abfd)
 /* The powerpc .got has a blrl instruction in it.  Mark it executable.  */
 
 static bfd_boolean
-ppc_elf_create_got (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+ppc_elf_create_got (bfd *abfd, struct bfd_link_info *info)
 {
   struct ppc_elf_link_hash_table *htab;
   asection *s;
@@ -2408,15 +2666,16 @@ ppc_elf_create_got (abfd, info)
    to create .dynbss and .rela.bss).  */
 
 static bfd_boolean
-ppc_elf_create_dynamic_sections (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   struct ppc_elf_link_hash_table *htab;
   asection *s;
   flagword flags;
 
-  if (!ppc_elf_create_got (abfd, info))
+  htab = ppc_elf_hash_table (info);
+
+  if (htab->got == NULL
+      && !ppc_elf_create_got (abfd, info))
     return FALSE;
 
   if (!_bfd_elf_create_dynamic_sections (abfd, info))
@@ -2425,7 +2684,6 @@ ppc_elf_create_dynamic_sections (abfd, info)
   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
           | SEC_LINKER_CREATED);
 
-  htab = ppc_elf_hash_table (info);
   htab->dynbss = bfd_get_section_by_name (abfd, ".dynbss");
   htab->dynsbss = s = bfd_make_section (abfd, ".dynsbss");
   if (s == NULL
@@ -2451,12 +2709,6 @@ ppc_elf_create_dynamic_sections (abfd, info)
   return bfd_set_section_flags (abfd, s, flags);
 }
 
-/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
-   copying dynamic variables from a shared lib into an app's dynbss
-   section, and instead use a dynamic relocation to point into the
-   shared lib.  */
-#define ELIMINATE_COPY_RELOCS 1
-
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2464,9 +2716,8 @@ ppc_elf_create_dynamic_sections (abfd, info)
    understand.  */
 
 static bfd_boolean
-ppc_elf_adjust_dynamic_symbol (info, h)
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
+ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+                              struct elf_link_hash_entry *h)
 {
   struct ppc_elf_link_hash_table *htab;
   asection *s;
@@ -2495,19 +2746,21 @@ ppc_elf_adjust_dynamic_symbol (info, h)
     {
       /* Clear procedure linkage table information for any symbol that
         won't need a .plt entry.  */
-      if (! htab->elf.dynamic_sections_created
-         || SYMBOL_CALLS_LOCAL (info, h)
-         || h->plt.refcount <= 0)
+      if (h->plt.refcount <= 0
+         || SYMBOL_CALLS_LOCAL (info, h)
+         || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+             && h->root.type == bfd_link_hash_undefweak))
        {
          /* A PLT entry is not required/allowed when:
 
-         1. We are not using ld.so; because then the PLT entry
-         can't be set up, so we can't use one.
+            1. We are not using ld.so; because then the PLT entry
+            can't be set up, so we can't use one.  In this case,
+            ppc_elf_adjust_dynamic_symbol won't even be called.
 
-         2. We know for certain that a call to this symbol
-         will go to this object.
+            2. GC has rendered the entry unused.
 
-         3. GC has rendered the entry unused.  */
+            3. We know for certain that a call to this symbol
+            will go to this object, or will remain undefined.  */
          h->plt.offset = (bfd_vma) -1;
          h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
        }
@@ -2653,11 +2906,9 @@ ppc_elf_adjust_dynamic_symbol (info, h)
 /* Allocate space in associated reloc sections for dynamic relocs.  */
 
 static bfd_boolean
-allocate_dynrelocs (h, inf)
-     struct elf_link_hash_entry *h;
-     PTR inf;
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 {
-  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  struct bfd_link_info *info = inf;
   struct ppc_elf_link_hash_entry *eh;
   struct ppc_elf_link_hash_table *htab;
   struct ppc_elf_dyn_relocs *p;
@@ -2717,7 +2968,7 @@ allocate_dynrelocs (h, inf)
             for two entries is allocated.  */
          s->_raw_size += PLT_ENTRY_SIZE;
          if ((s->_raw_size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
-             >= PLT_NUM_SINGLE_ENTRIES)
+             > PLT_NUM_SINGLE_ENTRIES)
            s->_raw_size += PLT_ENTRY_SIZE;
 
          /* We also need to make an entry in the .rela.plt section.  */
@@ -2768,8 +3019,10 @@ allocate_dynrelocs (h, inf)
          else
            htab->got->_raw_size += 4;
          dyn = htab->elf.dynamic_sections_created;
-         if (info->shared
-             || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
+         if ((info->shared
+              || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
+             && (ELF_ST_VISIBILITY (eh->elf.other) == STV_DEFAULT
+                 || eh->elf.root.type != bfd_link_hash_undefweak))
            {
              /* All the entries we allocated need relocs.  */
              htab->relgot->_raw_size
@@ -2792,11 +3045,16 @@ allocate_dynrelocs (h, inf)
      defined in regular objects.  For the normal shared case, discard
      space for relocs that have become local due to symbol visibility
      changes.  */
+
   if (info->shared)
     {
-      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
-         && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
-             || info->symbolic))
+      /* Relocs that use pc_count are those that appear on a call insn,
+        or certain REL relocs (see MUST_BE_DYN_RELOC) that can be
+        generated via assembly.  We want calls to protected symbols to
+        resolve directly to the function rather than going via the plt.
+        If people want function pointer comparisons to work as expected
+        then they should avoid writing weird assembly.  */
+      if (SYMBOL_CALLS_LOCAL (info, h))
        {
          struct ppc_elf_dyn_relocs **pp;
 
@@ -2810,6 +3068,12 @@ allocate_dynrelocs (h, inf)
                pp = &p->next;
            }
        }
+
+      /* Also discard relocs on undefined weak syms with non-default
+        visibility.  */
+      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+         && h->root.type == bfd_link_hash_undefweak)
+       eh->dyn_relocs = NULL;
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
@@ -2854,9 +3118,7 @@ allocate_dynrelocs (h, inf)
 /* Find any dynamic relocs that apply to read-only sections.  */
 
 static bfd_boolean
-readonly_dynrelocs (h, info)
-     struct elf_link_hash_entry *h;
-     PTR info;
+readonly_dynrelocs (struct elf_link_hash_entry *h, void *info)
 {
   struct ppc_elf_dyn_relocs *p;
 
@@ -2886,9 +3148,8 @@ readonly_dynrelocs (h, info)
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
-ppc_elf_size_dynamic_sections (output_bfd, info)
-     bfd *output_bfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info;
+ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+                              struct bfd_link_info *info)
 {
   struct ppc_elf_link_hash_table *htab;
   asection *s;
@@ -2905,7 +3166,7 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (! info->shared)
+      if (info->executable)
        {
          s = bfd_get_section_by_name (htab->elf.dynobj, ".interp");
          BFD_ASSERT (s != NULL);
@@ -3072,7 +3333,7 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
        }
 
       /* Allocate memory for the section contents.  */
-      s->contents = (bfd_byte *) bfd_zalloc (htab->elf.dynobj, s->_raw_size);
+      s->contents = bfd_zalloc (htab->elf.dynobj, s->_raw_size);
       if (s->contents == NULL)
        return FALSE;
     }
@@ -3085,9 +3346,9 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
         the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */
 #define add_dynamic_entry(TAG, VAL) \
-  bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+  bfd_elf32_add_dynamic_entry (info, (TAG), (VAL))
 
-      if (!info->shared)
+      if (info->executable)
        {
          if (!add_dynamic_entry (DT_DEBUG, 0))
            return FALSE;
@@ -3114,7 +3375,7 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
         need a DT_TEXTREL entry.  */
       if ((info->flags & DF_TEXTREL) == 0)
        elf_link_hash_traverse (elf_hash_table (info), readonly_dynrelocs,
-                               (PTR) info);
+                               info);
 
       if ((info->flags & DF_TEXTREL) != 0)
        {
@@ -3128,11 +3389,10 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
 }
 \f
 static bfd_boolean
-update_local_sym_info (abfd, symtab_hdr, r_symndx, tls_type)
-     bfd *abfd;
-     Elf_Internal_Shdr *symtab_hdr;
-     unsigned long r_symndx;
-     int tls_type;
+update_local_sym_info (bfd *abfd,
+                      Elf_Internal_Shdr *symtab_hdr,
+                      unsigned long r_symndx,
+                      int tls_type)
 {
   bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
   char *local_got_tls_masks;
@@ -3142,7 +3402,7 @@ update_local_sym_info (abfd, symtab_hdr, r_symndx, tls_type)
       bfd_size_type size = symtab_hdr->sh_info;
 
       size *= sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks);
-      local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size);
+      local_got_refcounts = bfd_zalloc (abfd, size);
       if (local_got_refcounts == NULL)
        return FALSE;
       elf_local_got_refcounts (abfd) = local_got_refcounts;
@@ -3155,14 +3415,12 @@ update_local_sym_info (abfd, symtab_hdr, r_symndx, tls_type)
 }
 
 static void
-bad_shared_reloc (abfd, r_type)
-     bfd *abfd;
-     enum elf_ppc_reloc_type r_type;
+bad_shared_reloc (bfd *abfd, enum elf_ppc_reloc_type r_type)
 {
   (*_bfd_error_handler)
     (_("%s: relocation %s cannot be used when making a shared object"),
      bfd_archive_filename (abfd),
-     ppc_elf_howto_table[(int) r_type]->name);
+     ppc_elf_howto_table[r_type]->name);
   bfd_set_error (bfd_error_bad_value);
 }
 
@@ -3171,11 +3429,10 @@ bad_shared_reloc (abfd, r_type)
    table.  */
 
 static bfd_boolean
-ppc_elf_check_relocs (abfd, info, sec, relocs)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *sec;
-     const Elf_Internal_Rela *relocs;
+ppc_elf_check_relocs (bfd *abfd,
+                     struct bfd_link_info *info,
+                     asection *sec,
+                     const Elf_Internal_Rela *relocs)
 {
   struct ppc_elf_link_hash_table *htab;
   Elf_Internal_Shdr *symtab_hdr;
@@ -3184,7 +3441,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
   const Elf_Internal_Rela *rel_end;
   asection *sreloc;
 
-  if (info->relocateable)
+  if (info->relocatable)
     return TRUE;
 
 #ifdef DEBUG
@@ -3193,9 +3450,12 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
           bfd_archive_filename (abfd));
 #endif
 
+  /* Initialize howto table if not already done.  */
+  if (!ppc_elf_howto_table[R_PPC_ADDR32])
+    ppc_elf_howto_init ();
+
   /* Create the linker generated sections all the time so that the
      special symbols are created.  */
-
   htab = ppc_elf_hash_table (info);
   if (htab->sdata == NULL)
     {
@@ -3249,7 +3509,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
            }
        }
 
-      r_type = (enum elf_ppc_reloc_type) ELF32_R_TYPE (rel->r_info);
+      r_type = ELF32_R_TYPE (rel->r_info);
       switch (r_type)
        {
        case R_PPC_GOT_TLSLD16:
@@ -3316,8 +3576,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
              bad_shared_reloc (abfd, r_type);
              return FALSE;
            }
-         if (!bfd_elf32_create_pointer_linker_section (abfd, info,
-                                                       htab->sdata, h, rel))
+         if (!elf_create_pointer_linker_section (abfd, info,
+                                                 htab->sdata, h, rel))
            return FALSE;
          break;
 
@@ -3328,8 +3588,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
              bad_shared_reloc (abfd, r_type);
              return FALSE;
            }
-         if (!bfd_elf32_create_pointer_linker_section (abfd, info,
-                                                       htab->sdata2, h, rel))
+         if (!elf_create_pointer_linker_section (abfd, info,
+                                                 htab->sdata2, h, rel))
            return FALSE;
          break;
 
@@ -3368,6 +3628,12 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
            {
              /* It does not make sense to have a procedure linkage
                 table entry for a local symbol.  */
+             (*_bfd_error_handler) (_("%s(%s+0x%lx): %s reloc against "
+                                      "local symbol"),
+                                    bfd_archive_filename (abfd),
+                                    sec->name,
+                                    (long) rel->r_offset,
+                                    ppc_elf_howto_table[r_type]->name);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -3525,7 +3791,9 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
              struct ppc_elf_dyn_relocs **head;
 
 #ifdef DEBUG
-             fprintf (stderr, "ppc_elf_check_relocs need to create relocation for %s\n",
+             fprintf (stderr,
+                      "ppc_elf_check_relocs needs to "
+                      "create relocation for %s\n",
                       (h && h->root.root.string
                        ? h->root.root.string : "<unknown>"));
 #endif
@@ -3589,8 +3857,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
              p = *head;
              if (p == NULL || p->sec != sec)
                {
-                 p = ((struct ppc_elf_dyn_relocs *)
-                      bfd_alloc (htab->elf.dynobj, sizeof *p));
+                 p = bfd_alloc (htab->elf.dynobj, sizeof *p);
                  if (p == NULL)
                    return FALSE;
                  p->next = *head;
@@ -3616,12 +3883,11 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
    relocation.  */
 
 static asection *
-ppc_elf_gc_mark_hook (sec, info, rel, h, sym)
-     asection *sec;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     Elf_Internal_Rela *rel;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+ppc_elf_gc_mark_hook (asection *sec,
+                     struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                     Elf_Internal_Rela *rel,
+                     struct elf_link_hash_entry *h,
+                     Elf_Internal_Sym *sym)
 {
   if (h != NULL)
     {
@@ -3656,11 +3922,10 @@ ppc_elf_gc_mark_hook (sec, info, rel, h, sym)
    section being removed.  */
 
 static bfd_boolean
-ppc_elf_gc_sweep_hook (abfd, info, sec, relocs)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *sec;
-     const Elf_Internal_Rela *relocs;
+ppc_elf_gc_sweep_hook (bfd *abfd,
+                      struct bfd_link_info *info,
+                      asection *sec,
+                      const Elf_Internal_Rela *relocs)
 {
   struct ppc_elf_link_hash_table *htab;
   Elf_Internal_Shdr *symtab_hdr;
@@ -3700,7 +3965,7 @@ ppc_elf_gc_sweep_hook (abfd, info, sec, relocs)
              }
        }
 
-      r_type = (enum elf_ppc_reloc_type) ELF32_R_TYPE (rel->r_info);
+      r_type = ELF32_R_TYPE (rel->r_info);
       switch (r_type)
        {
        case R_PPC_GOT_TLSLD16:
@@ -3781,9 +4046,7 @@ ppc_elf_gc_sweep_hook (abfd, info, sec, relocs)
 /* Set htab->tls_sec and htab->tls_get_addr.  */
 
 bfd_boolean
-ppc_elf_tls_setup (obfd, info)
-     bfd *obfd;
-     struct bfd_link_info *info;
+ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
 {
   asection *tls;
   struct ppc_elf_link_hash_table *htab;
@@ -3805,15 +4068,14 @@ ppc_elf_tls_setup (obfd, info)
    opportunities.  */
 
 bfd_boolean
-ppc_elf_tls_optimize (obfd, info)
-     bfd *obfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info;
+ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
+                     struct bfd_link_info *info)
 {
   bfd *ibfd;
   asection *sec;
   struct ppc_elf_link_hash_table *htab;
 
-  if (info->relocateable || info->shared)
+  if (info->relocatable || info->shared)
     return TRUE;
 
   htab = ppc_elf_hash_table (info);
@@ -3829,9 +4091,8 @@ ppc_elf_tls_optimize (obfd, info)
            int expecting_tls_get_addr;
 
            /* Read the relocations.  */
-           relstart = _bfd_elf32_link_read_relocs (ibfd, sec, (PTR) NULL,
-                                                   (Elf_Internal_Rela *) NULL,
-                                                   info->keep_memory);
+           relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
+                                                 info->keep_memory);
            if (relstart == NULL)
              return FALSE;
 
@@ -3863,7 +4124,7 @@ ppc_elf_tls_optimize (obfd, info)
                    || !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC))
                  is_local = TRUE;
 
-               r_type = (enum elf_ppc_reloc_type) ELF32_R_TYPE (rel->r_info);
+               r_type = ELF32_R_TYPE (rel->r_info);
                switch (r_type)
                  {
                  case R_PPC_GOT_TLSLD16:
@@ -4000,17 +4261,16 @@ ppc_elf_tls_optimize (obfd, info)
    file.  We use it to put .comm items in .sbss, and not .bss.  */
 
 static bfd_boolean
-ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     const Elf_Internal_Sym *sym;
-     const char **namep ATTRIBUTE_UNUSED;
-     flagword *flagsp ATTRIBUTE_UNUSED;
-     asection **secp;
-     bfd_vma *valp;
+ppc_elf_add_symbol_hook (bfd *abfd,
+                        struct bfd_link_info *info,
+                        const Elf_Internal_Sym *sym,
+                        const char **namep ATTRIBUTE_UNUSED,
+                        flagword *flagsp ATTRIBUTE_UNUSED,
+                        asection **secp,
+                        bfd_vma *valp)
 {
   if (sym->st_shndx == SHN_COMMON
-      && !info->relocateable
+      && !info->relocatable
       && sym->st_size <= elf_gp_size (abfd)
       && info->hash->creator->flavour == bfd_target_elf_flavour)
     {
@@ -4028,17 +4288,16 @@ ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
             will move the symbols to the appropriate output section
             when it defines common symbols.  */
          amt = sizeof (asection);
-         sdata->bss_section = (asection *) bfd_zalloc (abfd, amt);
+         sdata->bss_section = bfd_zalloc (abfd, amt);
          if (sdata->bss_section == NULL)
            return FALSE;
          sdata->bss_section->name = sdata->bss_name;
          sdata->bss_section->flags = SEC_IS_COMMON;
          sdata->bss_section->output_section = sdata->bss_section;
          amt = sizeof (asymbol);
-         sdata->bss_section->symbol = (asymbol *) bfd_zalloc (abfd, amt);
+         sdata->bss_section->symbol = bfd_zalloc (abfd, amt);
          amt = sizeof (asymbol *);
-         sdata->bss_section->symbol_ptr_ptr =
-           (asymbol **) bfd_zalloc (abfd, amt);
+         sdata->bss_section->symbol_ptr_ptr = bfd_zalloc (abfd, amt);
          if (sdata->bss_section->symbol == NULL
              || sdata->bss_section->symbol_ptr_ptr == NULL)
            return FALSE;
@@ -4059,11 +4318,10 @@ ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
    dynamic sections here.  */
 
 static bfd_boolean
-ppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
+                              struct bfd_link_info *info,
+                              struct elf_link_hash_entry *h,
+                              Elf_Internal_Sym *sym)
 {
   struct ppc_elf_link_hash_table *htab;
 
@@ -4168,9 +4426,8 @@ ppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
 /* Finish up the dynamic sections.  */
 
 static bfd_boolean
-ppc_elf_finish_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
+ppc_elf_finish_dynamic_sections (bfd *output_bfd,
+                                struct bfd_link_info *info)
 {
   asection *sdyn;
   struct ppc_elf_link_hash_table *htab;
@@ -4226,10 +4483,10 @@ ppc_elf_finish_dynamic_sections (output_bfd, info)
   if (htab->got)
     {
       unsigned char *contents = htab->got->contents;
-      bfd_put_32 (output_bfd, (bfd_vma) 0x4e800021 /* blrl */, contents);
+      bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, contents);
 
       if (sdyn == NULL)
-       bfd_put_32 (output_bfd, (bfd_vma) 0, contents + 4);
+       bfd_put_32 (output_bfd, 0, contents + 4);
       else
        bfd_put_32 (output_bfd,
                    sdyn->output_section->vma + sdyn->output_offset,
@@ -4250,7 +4507,7 @@ ppc_elf_finish_dynamic_sections (output_bfd, info)
 
    This function is responsible for adjust the section contents as
    necessary, and (if using Rela relocs and generating a
-   relocateable output file) adjusting the reloc addend as
+   relocatable output file) adjusting the reloc addend as
    necessary.
 
    This function does not have to worry about setting the reloc
@@ -4264,23 +4521,21 @@ ppc_elf_finish_dynamic_sections (output_bfd, info)
    The global hash table entry for the global symbols can be found
    via elf_sym_hashes (input_bfd).
 
-   When generating relocateable output, this function must handle
+   When generating relocatable output, this function must handle
    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
    going to be the section symbol corresponding to the output
    section, which means that the addend must be adjusted
    accordingly.  */
 
 static bfd_boolean
-ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
-                         contents, relocs, local_syms, local_sections)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     bfd *input_bfd;
-     asection *input_section;
-     bfd_byte *contents;
-     Elf_Internal_Rela *relocs;
-     Elf_Internal_Sym *local_syms;
-     asection **local_sections;
+ppc_elf_relocate_section (bfd *output_bfd,
+                         struct bfd_link_info *info,
+                         bfd *input_bfd,
+                         asection *input_section,
+                         bfd_byte *contents,
+                         Elf_Internal_Rela *relocs,
+                         Elf_Internal_Sym *local_syms,
+                         asection **local_sections)
 {
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
@@ -4294,18 +4549,19 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
   bfd_boolean ret = TRUE;
 
 #ifdef DEBUG
-  fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
+  fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, "
+          "%ld relocations%s\n",
           bfd_archive_filename (input_bfd),
           bfd_section_name(input_bfd, input_section),
           (long) input_section->reloc_count,
-          (info->relocateable) ? " (relocatable)" : "");
+          (info->relocatable) ? " (relocatable)" : "");
 #endif
 
-  if (info->relocateable)
+  if (info->relocatable)
     return TRUE;
 
+  /* Initialize howto table if not already done.  */
   if (!ppc_elf_howto_table[R_PPC_ADDR32])
-    /* Initialize howto table if needed.  */
     ppc_elf_howto_init ();
 
   htab = ppc_elf_hash_table (info);
@@ -4331,10 +4587,10 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       bfd_boolean warned;
       unsigned int tls_type, tls_mask, tls_gd;
 
-      r_type = (enum elf_ppc_reloc_type)ELF32_R_TYPE (rel->r_info);
-      sym = (Elf_Internal_Sym *) 0;
-      sec = (asection *) 0;
-      h = (struct elf_link_hash_entry *) 0;
+      r_type = ELF32_R_TYPE (rel->r_info);
+      sym = NULL;
+      sec = NULL;
+      h = NULL;
       unresolved_reloc = FALSE;
       warned = FALSE;
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -4527,8 +4783,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
                  /* The next instruction should be a call to
                     __tls_get_addr.  Peek at the reloc to be sure.  */
-                 r_type2
-                   = (enum elf_ppc_reloc_type) ELF32_R_TYPE (rel[1].r_info);
+                 r_type2 = ELF32_R_TYPE (rel[1].r_info);
                  r_symndx2 = ELF32_R_SYM (rel[1].r_info);
                  if (r_symndx2 < symtab_hdr->sh_info
                      || (r_type2 != R_PPC_REL14
@@ -4627,8 +4882,8 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       addend = rel->r_addend;
       tls_type = 0;
       howto = NULL;
-      if ((unsigned) r_type < (unsigned) R_PPC_max)
-       howto = ppc_elf_howto_table[(int) r_type];
+      if (r_type < R_PPC_max)
+       howto = ppc_elf_howto_table[r_type];
       switch (r_type)
        {
        default:
@@ -4772,7 +5027,10 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                      }
 
                    /* Generate relocs for the dynamic linker.  */
-                   if (info->shared || indx != 0)
+                   if ((info->shared || indx != 0)
+                       && (h == NULL
+                           || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                           || h->root.type != bfd_link_hash_undefweak))
                      {
                        outrel.r_offset = (htab->got->output_section->vma
                                           + htab->got->output_offset
@@ -4974,12 +5232,12 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          /* Fall thru.  */
 
          if ((info->shared
+              && (h == NULL
+                  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                  || h->root.type != bfd_link_hash_undefweak)
               && (MUST_BE_DYN_RELOC (r_type)
                   || (h != NULL
-                      && h->dynindx != -1
-                      && (!info->symbolic
-                          || (h->elf_link_hash_flags
-                              & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+                      && !SYMBOL_CALLS_LOCAL (info, h))))
              || (ELIMINATE_COPY_RELOCS
                  && !info->shared
                  && (input_section->flags & SEC_ALLOC) != 0
@@ -4992,7 +5250,8 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              int skip;
 
 #ifdef DEBUG
-             fprintf (stderr, "ppc_elf_relocate_section need to create relocation for %s\n",
+             fprintf (stderr, "ppc_elf_relocate_section needs to "
+                      "create relocation for %s\n",
                       (h && h->root.root.string
                        ? h->root.root.string : "<unknown>"));
 #endif
@@ -5071,11 +5330,9 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                          BFD_ASSERT (indx > 0);
 #ifdef DEBUG
                          if (indx <= 0)
-                           {
-                             printf ("indx=%d section=%s flags=%08x name=%s\n",
-                                     indx, osec->name, osec->flags,
-                                     h->root.root.string);
-                           }
+                           printf ("indx=%d section=%s flags=%08x name=%s\n",
+                                   indx, osec->name, osec->flags,
+                                   h->root.root.string);
 #endif
                        }
 
@@ -5107,20 +5364,18 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_PPC_EMB_SDAI16:
          BFD_ASSERT (htab->sdata != NULL);
          relocation
-           = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd,
-                                                      info, htab->sdata, h,
-                                                      relocation, rel,
-                                                      R_PPC_RELATIVE);
+           = elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
+                                                htab->sdata, h, relocation,
+                                                rel, R_PPC_RELATIVE);
          break;
 
          /* Indirect .sdata2 relocation.  */
        case R_PPC_EMB_SDA2I16:
          BFD_ASSERT (htab->sdata2 != NULL);
          relocation
-           = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd,
-                                                      info, htab->sdata2, h,
-                                                      relocation, rel,
-                                                      R_PPC_RELATIVE);
+           = elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
+                                                htab->sdata2, h, relocation,
+                                                rel, R_PPC_RELATIVE);
          break;
 
          /* Handle the TOC16 reloc.  We want to use the offset within the .got
@@ -5128,7 +5383,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
             an embedded ELF object, for which the .got section acts like the
             AIX .toc section.  */
        case R_PPC_TOC16:                       /* phony GOT16 relocations */
-         BFD_ASSERT (sec != (asection *) 0);
+         BFD_ASSERT (sec != NULL);
          BFD_ASSERT (bfd_is_und_section (sec)
                      || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
                      || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0)
@@ -5162,18 +5417,20 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            const char *name;
            const struct elf_link_hash_entry *sh;
 
-           BFD_ASSERT (sec != (asection *) 0);
+           BFD_ASSERT (sec != NULL);
            name = bfd_get_section_name (abfd, sec->output_section);
            if (! ((strncmp (name, ".sdata", 6) == 0
                    && (name[6] == 0 || name[6] == '.'))
                   || (strncmp (name, ".sbss", 5) == 0
                       && (name[5] == 0 || name[5] == '.'))))
              {
-               (*_bfd_error_handler) (_("%s: the target (%s) of a %s relocation is in the wrong output section (%s)"),
-                                      bfd_archive_filename (input_bfd),
-                                      sym_name,
-                                      howto->name,
-                                      name);
+               (*_bfd_error_handler)
+                 (_("%s: the target (%s) of a %s relocation is "
+                    "in the wrong output section (%s)"),
+                  bfd_archive_filename (input_bfd),
+                  sym_name,
+                  howto->name,
+                  name);
              }
            sh = htab->sdata->sym_hash;
            addend -= (sh->root.u.def.value
@@ -5188,16 +5445,18 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            const char *name;
            const struct elf_link_hash_entry *sh;
 
-           BFD_ASSERT (sec != (asection *) 0);
+           BFD_ASSERT (sec != NULL);
            name = bfd_get_section_name (abfd, sec->output_section);
            if (! (strncmp (name, ".sdata2", 7) == 0
                   || strncmp (name, ".sbss2", 6) == 0))
              {
-               (*_bfd_error_handler) (_("%s: the target (%s) of a %s relocation is in the wrong output section (%s)"),
-                                      bfd_archive_filename (input_bfd),
-                                      sym_name,
-                                      howto->name,
-                                      name);
+               (*_bfd_error_handler)
+                 (_("%s: the target (%s) of a %s relocation is "
+                    "in the wrong output section (%s)"),
+                  bfd_archive_filename (input_bfd),
+                  sym_name,
+                  howto->name,
+                  name);
 
                bfd_set_error (bfd_error_bad_value);
                ret = FALSE;
@@ -5218,7 +5477,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            const struct elf_link_hash_entry *sh;
            int reg;
 
-           BFD_ASSERT (sec != (asection *) 0);
+           BFD_ASSERT (sec != NULL);
            name = bfd_get_section_name (abfd, sec->output_section);
            if (((strncmp (name, ".sdata", 6) == 0
                  && (name[6] == 0 || name[6] == '.'))
@@ -5250,11 +5509,13 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
            else
              {
-               (*_bfd_error_handler) (_("%s: the target (%s) of a %s relocation is in the wrong output section (%s)"),
-                                      bfd_archive_filename (input_bfd),
-                                      sym_name,
-                                      howto->name,
-                                      name);
+               (*_bfd_error_handler)
+                 (_("%s: the target (%s) of a %s relocation is "
+                    "in the wrong output section (%s)"),
+                  bfd_archive_filename (input_bfd),
+                  sym_name,
+                  howto->name,
+                  name);
 
                bfd_set_error (bfd_error_bad_value);
                ret = FALSE;
@@ -5275,7 +5536,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_PPC_SECTOFF_LO:
        case R_PPC_SECTOFF_HI:
        case R_PPC_SECTOFF_HA:
-         BFD_ASSERT (sec != (asection *) 0);
+         BFD_ASSERT (sec != NULL);
          addend -= sec->output_section->vma;
          break;
 
@@ -5344,7 +5605,8 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        }
 
 #ifdef DEBUG
-      fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n",
+      fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, "
+              "offset = %ld, addend = %ld\n",
               howto->name,
               (int) r_type,
               sym_name,
@@ -5425,10 +5687,9 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 }
 
 static enum elf_reloc_type_class
-ppc_elf_reloc_type_class (rela)
-     const Elf_Internal_Rela *rela;
+ppc_elf_reloc_type_class (const Elf_Internal_Rela *rela)
 {
-  switch ((int) ELF32_R_TYPE (rela->r_info))
+  switch (ELF32_R_TYPE (rela->r_info))
     {
     case R_PPC_RELATIVE:
       return reloc_class_relative;
@@ -5446,9 +5707,7 @@ ppc_elf_reloc_type_class (rela)
 /* Support for core dump NOTE sections.  */
 
 static bfd_boolean
-ppc_elf_grok_prstatus (abfd, note)
-     bfd *abfd;
-     Elf_Internal_Note *note;
+ppc_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 {
   int offset;
   unsigned int raw_size;
@@ -5478,9 +5737,7 @@ ppc_elf_grok_prstatus (abfd, note)
 }
 
 static bfd_boolean
-ppc_elf_grok_psinfo (abfd, note)
-     bfd *abfd;
-     Elf_Internal_Note *note;
+ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   switch (note->descsz)
     {
@@ -5517,31 +5774,17 @@ typedef struct apuinfo_list
 }
 apuinfo_list;
 
-static apuinfo_list * head;
-
-static void apuinfo_list_init PARAMS ((void));
-static void apuinfo_list_add PARAMS ((unsigned long));
-static unsigned apuinfo_list_length PARAMS ((void));
-static unsigned long apuinfo_list_element PARAMS ((unsigned long));
-static void apuinfo_list_finish PARAMS ((void));
-
-extern void ppc_elf_begin_write_processing
-  PARAMS ((bfd *, struct bfd_link_info *));
-extern void ppc_elf_final_write_processing
-  PARAMS ((bfd *, bfd_boolean));
-extern bfd_boolean ppc_elf_write_section
-  PARAMS ((bfd *, asection *, bfd_byte *));
+static apuinfo_list *head;
 
 
 static void
-apuinfo_list_init PARAMS ((void))
+apuinfo_list_init (void)
 {
   head = NULL;
 }
 
 static void
-apuinfo_list_add (value)
-     unsigned long value;
+apuinfo_list_add (unsigned long value)
 {
   apuinfo_list *entry = head;
 
@@ -5562,7 +5805,7 @@ apuinfo_list_add (value)
 }
 
 static unsigned
-apuinfo_list_length PARAMS ((void))
+apuinfo_list_length (void)
 {
   apuinfo_list *entry;
   unsigned long count;
@@ -5576,8 +5819,7 @@ apuinfo_list_length PARAMS ((void))
 }
 
 static inline unsigned long
-apuinfo_list_element (number)
-     unsigned long number;
+apuinfo_list_element (unsigned long number)
 {
   apuinfo_list * entry;
 
@@ -5590,7 +5832,7 @@ apuinfo_list_element (number)
 }
 
 static void
-apuinfo_list_finish PARAMS ((void))
+apuinfo_list_finish (void)
 {
   apuinfo_list *entry;
 
@@ -5610,10 +5852,8 @@ apuinfo_list_finish PARAMS ((void))
 /* Scan the input BFDs and create a linked list of
    the APUinfo values that will need to be emitted.  */
 
-void
-ppc_elf_begin_write_processing (abfd, link_info)
-     bfd *abfd;
-     struct bfd_link_info *link_info;
+static void
+ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
 {
   bfd *ibfd;
   asection *asec;
@@ -5703,9 +5943,9 @@ ppc_elf_begin_write_processing (abfd, link_info)
       if (strcmp (ptr + 12, APUINFO_LABEL) != 0)
        goto fail;
 
-      /* Get the number of apuinfo entries.  */
+      /* Get the number of bytes used for apuinfo entries.  */
       datum = bfd_get_32 (ibfd, ptr + 4);
-      if ((datum * 4 + 20) != length)
+      if (datum + 20 != length)
        goto fail;
 
       /* Make sure that we do not run off the end of the section.  */
@@ -5713,8 +5953,8 @@ ppc_elf_begin_write_processing (abfd, link_info)
        goto fail;
 
       /* Scan the apuinfo section, building a list of apuinfo numbers.  */
-      for (i = 0; i < datum; i++)
-       apuinfo_list_add (bfd_get_32 (ibfd, ptr + 20 + (i * 4)));
+      for (i = 0; i < datum; i += 4)
+       apuinfo_list_add (bfd_get_32 (ibfd, ptr + 20 + i));
 
       /* Update the offset.  */
       offset += length;
@@ -5744,11 +5984,10 @@ ppc_elf_begin_write_processing (abfd, link_info)
 /* Prevent the output section from accumulating the input sections'
    contents.  We have already stored this in our linked list structure.  */
 
-bfd_boolean
-ppc_elf_write_section (abfd, asec, contents)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *asec;
-     bfd_byte *contents ATTRIBUTE_UNUSED;
+static bfd_boolean
+ppc_elf_write_section (bfd *abfd ATTRIBUTE_UNUSED,
+                      asection *asec,
+                      bfd_byte *contents ATTRIBUTE_UNUSED)
 {
   return (apuinfo_list_length ()
          && strcmp (asec->name, APUINFO_SECTION_NAME) == 0);
@@ -5757,10 +5996,8 @@ ppc_elf_write_section (abfd, asec, contents)
 
 /* Finally we can generate the output section.  */
 
-void
-ppc_elf_final_write_processing (abfd, linker)
-     bfd *abfd;
-     bfd_boolean linker ATTRIBUTE_UNUSED;
+static void
+ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
 {
   bfd_byte *buffer;
   asection *asec;
@@ -5790,7 +6027,7 @@ ppc_elf_final_write_processing (abfd, linker)
   /* Create the apuinfo header.  */
   num_entries = apuinfo_list_length ();
   bfd_put_32 (abfd, sizeof APUINFO_LABEL, buffer);
-  bfd_put_32 (abfd, num_entries, buffer + 4);
+  bfd_put_32 (abfd, num_entries * 4, buffer + 4);
   bfd_put_32 (abfd, 0x2, buffer + 8);
   strcpy (buffer + 12, APUINFO_LABEL);
 
This page took 0.050037 seconds and 4 git commands to generate.