* Makefile.am: "make dep-am".
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index 58ffce4b76e92125de225cac0bb84d6681ce7bed..4c9ff8297f97d50fff2b3360a36cef9de55d69ab 100644 (file)
@@ -1,5 +1,6 @@
 /* PowerPC-specific support for 32-bit ELF
 /* PowerPC-specific support for 32-bit ELF
-   Copyright 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
    Written by Ian Lance Taylor, Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -37,10 +38,12 @@ static reloc_howto_type *ppc_elf_reloc_type_lookup
 static void ppc_elf_info_to_howto
   PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst));
 static void ppc_elf_howto_init PARAMS ((void));
 static void ppc_elf_info_to_howto
   PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst));
 static void ppc_elf_howto_init PARAMS ((void));
+static int ppc_elf_sort_rela PARAMS ((const PTR, const PTR));
+static boolean ppc_elf_relax_section
+  PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
 static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
 static boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword));
 static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
 static boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword));
-static boolean ppc_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
 static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
 
 static int ppc_elf_additional_program_headers PARAMS ((bfd *));
 static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
 
 static int ppc_elf_additional_program_headers PARAMS ((bfd *));
@@ -104,6 +107,12 @@ static boolean ppc_elf_finish_dynamic_symbol PARAMS ((bfd *,
                                                      Elf_Internal_Sym *));
 
 static boolean ppc_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
                                                      Elf_Internal_Sym *));
 
 static 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 boolean ppc_elf_grok_prstatus
+  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
+static boolean ppc_elf_grok_psinfo
+  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
 
 #define BRANCH_PREDICT_BIT 0x200000            /* branch prediction bit for branch taken relocs */
 #define RA_REGISTER_MASK 0x001f0000            /* mask to set RA in memory instructions */
 
 #define BRANCH_PREDICT_BIT 0x200000            /* branch prediction bit for branch taken relocs */
 #define RA_REGISTER_MASK 0x001f0000            /* mask to set RA in memory instructions */
@@ -988,8 +997,8 @@ ppc_elf_howto_init ()
 
 static int
 ppc_elf_sort_rela (arg1, arg2)
 
 static int
 ppc_elf_sort_rela (arg1, arg2)
-     const void *arg1;
-     const void *arg2;
+     const PTR arg1;
+     const PTR 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 **rela1 = (const Elf_Internal_Rela**) arg1;
   const Elf_Internal_Rela **rela2 = (const Elf_Internal_Rela**) arg2;
@@ -1050,6 +1059,7 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
       if (isec->reloc_count)
        {
           unsigned n;
       if (isec->reloc_count)
        {
           unsigned n;
+         bfd_size_type amt;
 
           /* Get a copy of the native relocations.  */
           internal_relocs = _bfd_elf32_link_read_relocs (
 
           /* Get a copy of the native relocations.  */
           internal_relocs = _bfd_elf32_link_read_relocs (
@@ -1061,8 +1071,9 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
              free_relocs = internal_relocs;
 
           /* Setup a faster access method for the reloc info we need.  */
              free_relocs = internal_relocs;
 
           /* Setup a faster access method for the reloc info we need.  */
-          rela_comb = (Elf_Internal_Rela**)
-           bfd_malloc (isec->reloc_count*sizeof (Elf_Internal_Rela*));
+         amt = isec->reloc_count;
+         amt *= sizeof (Elf_Internal_Rela*);
+          rela_comb = (Elf_Internal_Rela**) bfd_malloc (amt);
           if (rela_comb == NULL)
               goto error_return;
           for (n = 0; n < isec->reloc_count; ++n)
           if (rela_comb == NULL)
               goto error_return;
           for (n = 0; n < isec->reloc_count; ++n)
@@ -1191,7 +1202,7 @@ ppc_elf_relax_section (abfd, isec, link_info, again)
 #undef BO4
               if (modified)
                {
 #undef BO4
               if (modified)
                {
-                  bfd_put_32 (abfd, insn, contents + isec_offset);
+                  bfd_put_32 (abfd, (bfd_vma) insn, contents + isec_offset);
                  section_modified = true;
                }
             }
                  section_modified = true;
                }
             }
@@ -1382,24 +1393,6 @@ ppc_elf_set_private_flags (abfd, flags)
   return true;
 }
 
   return true;
 }
 
-/* Copy backend specific data from one object module to another */
-static boolean
-ppc_elf_copy_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
-{
-  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
-      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return true;
-
-  BFD_ASSERT (!elf_flags_init (obfd)
-             || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
-
-  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
-  elf_flags_init (obfd) = true;
-  return true;
-}
-
 /* Merge backend specific data from an object file to the output
    object file when linking */
 static boolean
 /* Merge backend specific data from an object file to the output
    object file when linking */
 static boolean
@@ -1441,7 +1434,7 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd)
          error = true;
          (*_bfd_error_handler)
            (_("%s: compiled with -mrelocatable and linked with modules compiled normally"),
          error = true;
          (*_bfd_error_handler)
            (_("%s: compiled with -mrelocatable and linked with modules compiled normally"),
-            bfd_get_filename (ibfd));
+            bfd_archive_filename (ibfd));
        }
       else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
               && (old_flags & EF_PPC_RELOCATABLE) != 0)
        }
       else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
               && (old_flags & EF_PPC_RELOCATABLE) != 0)
@@ -1449,7 +1442,7 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd)
          error = true;
          (*_bfd_error_handler)
            (_("%s: compiled normally and linked with modules compiled with -mrelocatable"),
          error = true;
          (*_bfd_error_handler)
            (_("%s: compiled normally and linked with modules compiled with -mrelocatable"),
-            bfd_get_filename (ibfd));
+            bfd_archive_filename (ibfd));
        }
 
       /* The output is -mrelocatable-lib iff both the input files are.  */
        }
 
       /* The output is -mrelocatable-lib iff both the input files are.  */
@@ -1475,7 +1468,7 @@ 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)"),
          error = true;
          (*_bfd_error_handler)
            (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
-            bfd_get_filename (ibfd), (long) new_flags, (long) old_flags);
+            bfd_archive_filename (ibfd), (long) new_flags, (long) old_flags);
        }
 
       if (error)
        }
 
       if (error)
@@ -1487,7 +1480,6 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd)
 
   return true;
 }
 
   return true;
 }
-
 \f
 /* Handle a PowerPC specific section when reading an object file.  This
    is called when elfcode.h finds a section with an unknown type.  */
 \f
 /* Handle a PowerPC specific section when reading an object file.  This
    is called when elfcode.h finds a section with an unknown type.  */
@@ -1515,7 +1507,6 @@ ppc_elf_section_from_shdr (abfd, hdr, name)
   bfd_set_section_flags (abfd, newsect, flags);
   return true;
 }
   bfd_set_section_flags (abfd, newsect, flags);
   return true;
 }
-
 \f
 /* Set up any other section flags and such that may be necessary.  */
 
 \f
 /* Set up any other section flags and such that may be necessary.  */
 
@@ -1533,7 +1524,6 @@ ppc_elf_fake_sections (abfd, shdr, asect)
 
   return true;
 }
 
   return true;
 }
-
 \f
 /* Create a special linker section */
 static elf_linker_section_t *
 \f
 /* Create a special linker section */
 static elf_linker_section_t *
@@ -1788,6 +1778,8 @@ ppc_elf_adjust_dynamic_symbol (info, h)
 
       return true;
     }
 
       return true;
     }
+  else
+    h->plt.offset = (bfd_vma) -1;
 
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
 
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
@@ -1877,14 +1869,13 @@ ppc_elf_adjust_dynamic_symbol (info, h)
 
 static boolean
 ppc_elf_size_dynamic_sections (output_bfd, info)
 
 static boolean
 ppc_elf_size_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
+     bfd *output_bfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
   bfd *dynobj;
   asection *s;
   boolean plt;
   boolean relocs;
      struct bfd_link_info *info;
 {
   bfd *dynobj;
   asection *s;
   boolean plt;
   boolean relocs;
-  boolean reltext;
 
 #ifdef DEBUG
   fprintf (stderr, "ppc_elf_size_dynamic_sections called\n");
 
 #ifdef DEBUG
   fprintf (stderr, "ppc_elf_size_dynamic_sections called\n");
@@ -1929,7 +1920,6 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
      memory for them.  */
   plt = false;
   relocs = false;
      memory for them.  */
   plt = false;
   relocs = false;
-  reltext = false;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char *name;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char *name;
@@ -1975,22 +1965,9 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
            }
          else
            {
            }
          else
            {
-             asection *target;
-             const char *outname;
-
              /* Remember whether there are any relocation sections.  */
              relocs = true;
 
              /* Remember whether there are any relocation sections.  */
              relocs = true;
 
-             /* If this relocation section applies to a read only
-                section, then we probably need a DT_TEXTREL entry.  */
-             outname = bfd_get_section_name (output_bfd,
-                                             s->output_section);
-             target = bfd_get_section_by_name (output_bfd, outname + 5);
-             if (target != NULL
-                 && (target->flags & SEC_READONLY) != 0
-                 && (target->flags & SEC_ALLOC) != 0)
-               reltext = true;
-
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
              s->reloc_count = 0;
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
              s->reloc_count = 0;
@@ -2023,41 +2000,43 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
         must add the entries now so that we get the correct size for
         the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */
         must add the entries now so that we get the correct size for
         the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */
-      if (! info->shared)
+#define add_dynamic_entry(TAG, VAL) \
+  bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+
+      if (!info->shared)
        {
        {
-         if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+         if (!add_dynamic_entry (DT_DEBUG, 0))
            return false;
        }
 
       if (plt)
        {
            return false;
        }
 
       if (plt)
        {
-         if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
-             || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
-             || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
-             || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+         if (!add_dynamic_entry (DT_PLTGOT, 0)
+             || !add_dynamic_entry (DT_PLTRELSZ, 0)
+             || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+             || !add_dynamic_entry (DT_JMPREL, 0))
            return false;
        }
 
       if (relocs)
        {
            return false;
        }
 
       if (relocs)
        {
-         if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
-             || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
-             || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
-                                               sizeof (Elf32_External_Rela)))
+         if (!add_dynamic_entry (DT_RELA, 0)
+             || !add_dynamic_entry (DT_RELASZ, 0)
+             || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
            return false;
        }
 
            return false;
        }
 
-      if (reltext)
+      if ((info->flags & DF_TEXTREL) != 0)
        {
        {
-         if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+         if (!add_dynamic_entry (DT_TEXTREL, 0))
            return false;
          info->flags |= DF_TEXTREL;
        }
     }
            return false;
          info->flags |= DF_TEXTREL;
        }
     }
+#undef add_dynamic_entry
 
   return true;
 }
 
   return true;
 }
-
 \f
 /* Look through the relocs for a section during the first phase, and
    allocate space in the global offset table or procedure linkage
 \f
 /* Look through the relocs for a section during the first phase, and
    allocate space in the global offset table or procedure linkage
@@ -2088,7 +2067,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
 #ifdef DEBUG
   fprintf (stderr, "ppc_elf_check_relocs called for section %s in %s\n",
           bfd_get_section_name (abfd, sec),
 #ifdef DEBUG
   fprintf (stderr, "ppc_elf_check_relocs called for section %s in %s\n",
           bfd_get_section_name (abfd, sec),
-          bfd_get_filename (abfd));
+          bfd_archive_filename (abfd));
 #endif
 
   /* Create the linker generated sections all the time so that the
 #endif
 
   /* Create the linker generated sections all the time so that the
@@ -2188,7 +2167,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
 
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
+             if (h->got.refcount == 0)
                {
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
                {
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
@@ -2199,28 +2178,25 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
                  sgot->_raw_size += 4;
                  /* Allocate relocation space.  */
                  srelgot->_raw_size += sizeof (Elf32_External_Rela);
                  sgot->_raw_size += 4;
                  /* Allocate relocation space.  */
                  srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
-                 h->got.refcount = 1;
                }
                }
-             else
-               h->got.refcount++;
+             h->got.refcount++;
            }
          else
            {
              /* This is a global offset table entry for a local symbol.  */
              if (local_got_refcounts == NULL)
                {
            }
          else
            {
              /* This is a global offset table entry for a local symbol.  */
              if (local_got_refcounts == NULL)
                {
-                 size_t size;
+                 bfd_size_type size;
 
 
-                 size = symtab_hdr->sh_info * sizeof (bfd_signed_vma);
-                 local_got_refcounts = (bfd_signed_vma *)
-                   bfd_alloc (abfd, size);
+                 size = symtab_hdr->sh_info;
+                 size *= sizeof (bfd_signed_vma);
+                 local_got_refcounts
+                   = (bfd_signed_vma *) bfd_zalloc (abfd, size);
                  if (local_got_refcounts == NULL)
                    return false;
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
                  if (local_got_refcounts == NULL)
                    return false;
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
-                 memset (local_got_refcounts, -1, size);
                }
                }
-             if (local_got_refcounts[r_symndx] == -1)
+             if (local_got_refcounts[r_symndx] == 0)
                {
                  sgot->_raw_size += 4;
 
                {
                  sgot->_raw_size += 4;
 
@@ -2229,11 +2205,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
                      dynamic linker can adjust this GOT entry.  */
                  if (info->shared)
                    srelgot->_raw_size += sizeof (Elf32_External_Rela);
                      dynamic linker can adjust this GOT entry.  */
                  if (info->shared)
                    srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
-                 local_got_refcounts[r_symndx] = 1;
                }
                }
-             else
-               local_got_refcounts[r_symndx]++;
+             local_got_refcounts[r_symndx]++;
            }
          break;
 
            }
          break;
 
@@ -2243,7 +2216,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
            {
              ((*_bfd_error_handler)
               (_("%s: relocation %s cannot be used when making a shared object"),
            {
              ((*_bfd_error_handler)
               (_("%s: relocation %s cannot be used when making a shared object"),
-               bfd_get_filename (abfd), "R_PPC_EMB_SDAI16"));
+               bfd_archive_filename (abfd), "R_PPC_EMB_SDAI16"));
              return false;
            }
 
              return false;
            }
 
@@ -2277,7 +2250,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
            {
              ((*_bfd_error_handler)
               (_("%s: relocation %s cannot be used when making a shared object"),
            {
              ((*_bfd_error_handler)
               (_("%s: relocation %s cannot be used when making a shared object"),
-               bfd_get_filename (abfd), "R_PPC_EMB_SDA2I16"));
+               bfd_archive_filename (abfd), "R_PPC_EMB_SDA2I16"));
              return false;
            }
 
              return false;
            }
 
@@ -2312,7 +2285,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
            {
              ((*_bfd_error_handler)
               (_("%s: relocation %s cannot be used when making a shared object"),
            {
              ((*_bfd_error_handler)
               (_("%s: relocation %s cannot be used when making a shared object"),
-               bfd_get_filename (abfd),
+               bfd_archive_filename (abfd),
                ppc_elf_howto_table[(int) ELF32_R_TYPE (rel->r_info)]->name));
              return false;
            }
                ppc_elf_howto_table[(int) ELF32_R_TYPE (rel->r_info)]->name));
              return false;
            }
@@ -2346,13 +2319,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
              if (! bfd_elf32_link_record_dynamic_symbol (info, h))
                return false;
            }
              if (! bfd_elf32_link_record_dynamic_symbol (info, h))
                return false;
            }
-         if (h->plt.refcount == -1)
-           {
-             h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-             h->plt.refcount = 1;
-           }
-         else
-           h->plt.refcount++;
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->plt.refcount++;
          break;
 
          /* The following relocations don't need to propagate the
          break;
 
          /* The following relocations don't need to propagate the
@@ -2433,6 +2401,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
                          || ! bfd_set_section_alignment (dynobj, sreloc, 2))
                        return false;
                    }
                          || ! bfd_set_section_alignment (dynobj, sreloc, 2))
                        return false;
                    }
+                 if (sec->flags & SEC_READONLY)
+                   info->flags |= DF_TEXTREL;
                }
 
              sreloc->_raw_size += sizeof (Elf32_External_Rela);
                }
 
              sreloc->_raw_size += sizeof (Elf32_External_Rela);
@@ -2488,13 +2458,7 @@ ppc_elf_gc_mark_hook (abfd, info, rel, h, sym)
     }
   else
     {
     }
   else
     {
-      if (!(elf_bad_symtab (abfd)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-               && sym->st_shndx != SHN_COMMON))
-       {
-         return bfd_section_from_elf_index (abfd, sym->st_shndx);
-       }
+      return bfd_section_from_elf_index (abfd, sym->st_shndx);
     }
 
   return NULL;
     }
 
   return NULL;
@@ -2578,7 +2542,7 @@ ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
 {
   if (sym->st_shndx == SHN_COMMON
       && !info->relocateable
 {
   if (sym->st_shndx == SHN_COMMON
       && !info->relocateable
-      && sym->st_size <= (bfd_vma) bfd_get_gp_size (abfd))
+      && sym->st_size <= elf_gp_size (abfd))
     {
       /* Common symbols less than or equal to -G nn bytes are automatically
         put into .sdata.  */
     {
       /* Common symbols less than or equal to -G nn bytes are automatically
         put into .sdata.  */
@@ -2587,21 +2551,24 @@ ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
 
       if (!sdata->bss_section)
        {
 
       if (!sdata->bss_section)
        {
+         bfd_size_type amt;
+
          /* We don't go through bfd_make_section, because we don't
              want to attach this common section to DYNOBJ.  The linker
              will move the symbols to the appropriate output section
              when it defines common symbols.  */
          /* We don't go through bfd_make_section, because we don't
              want to attach this common section to DYNOBJ.  The linker
              will move the symbols to the appropriate output section
              when it defines common symbols.  */
-         sdata->bss_section = ((asection *)
-                               bfd_zalloc (abfd, sizeof (asection)));
+         amt = sizeof (asection);
+         sdata->bss_section = (asection *) 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;
          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;
-         sdata->bss_section->symbol =
-           (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+         amt = sizeof (asymbol);
+         sdata->bss_section->symbol = (asymbol *) bfd_zalloc (abfd, amt);
+         amt = sizeof (asymbol *);
          sdata->bss_section->symbol_ptr_ptr =
          sdata->bss_section->symbol_ptr_ptr =
-           (asymbol **) bfd_zalloc (abfd, sizeof (asymbol *));
+           (asymbol **) bfd_zalloc (abfd, amt);
          if (sdata->bss_section->symbol == NULL
              || sdata->bss_section->symbol_ptr_ptr == NULL)
            return false;
          if (sdata->bss_section->symbol == NULL
              || sdata->bss_section->symbol_ptr_ptr == NULL)
            return false;
@@ -2705,7 +2672,7 @@ ppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       rela.r_offset = (sgot->output_section->vma
                       + sgot->output_offset
 
       rela.r_offset = (sgot->output_section->vma
                       + sgot->output_offset
-                      + (h->got.offset &~ 1));
+                      + (h->got.offset &~ (bfd_vma) 1));
 
       /* If this is a -Bsymbolic link, and the symbol is defined
         locally, we just want to emit a RELATIVE reloc.  The entry in
 
       /* If this is a -Bsymbolic link, and the symbol is defined
         locally, we just want to emit a RELATIVE reloc.  The entry in
@@ -2850,7 +2817,7 @@ ppc_elf_finish_dynamic_sections (output_bfd, info)
   if (sgot)
     {
       unsigned char *contents = sgot->contents;
   if (sgot)
     {
       unsigned char *contents = sgot->contents;
-      bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, contents);
+      bfd_put_32 (output_bfd, (bfd_vma) 0x4e800021 /* blrl */, contents);
 
       if (sdyn == NULL)
        bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4);
 
       if (sdyn == NULL)
        bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4);
@@ -2922,7 +2889,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
 #ifdef DEBUG
   fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
 
 #ifdef DEBUG
   fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
-          bfd_get_filename (input_bfd),
+          bfd_archive_filename (input_bfd),
           bfd_section_name(input_bfd, input_section),
           (long) input_section->reloc_count,
           (info->relocateable) ? " (relocatable)" : "");
           bfd_section_name(input_bfd, input_section),
           (long) input_section->reloc_count,
           (info->relocateable) ? " (relocatable)" : "");
@@ -2961,7 +2928,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          || !ppc_elf_howto_table[(int) r_type])
        {
          (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
          || !ppc_elf_howto_table[(int) r_type])
        {
          (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
-                                bfd_get_filename (input_bfd),
+                                bfd_archive_filename (input_bfd),
                                 (int) r_type);
 
          bfd_set_error (bfd_error_bad_value);
                                 (int) r_type);
 
          bfd_set_error (bfd_error_bad_value);
@@ -3006,9 +2973,8 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          sec = local_sections[r_symndx];
          sym_name = "<local symbol>";
 
          sec = local_sections[r_symndx];
          sym_name = "<local symbol>";
 
-         relocation = (sec->output_section->vma
-                       + sec->output_offset
-                       + sym->st_value);
+         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+         addend = rel->r_addend;
          /* Relocs to local symbols are always resolved.  */
          will_become_local = 1;
        }
          /* Relocs to local symbols are always resolved.  */
          will_become_local = 1;
        }
@@ -3094,7 +3060,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                {
                   (*_bfd_error_handler)
                     (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
                {
                   (*_bfd_error_handler)
                     (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
-                     bfd_get_filename (input_bfd), h->root.root.string,
+                     bfd_archive_filename (input_bfd), h->root.root.string,
                      bfd_get_section_name (input_bfd, input_section));
                  relocation = 0;
                }
                      bfd_get_section_name (input_bfd, input_section));
                  relocation = 0;
                }
@@ -3105,7 +3071,9 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            }
          else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
            }
          else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
-         else if (info->shared && !info->symbolic && !info->no_undefined
+         else if (info->shared
+                  && (!info->symbolic || info->allow_shlib_undefined)
+                  && !info->no_undefined
                   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
            relocation = 0;
          else
                   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
            relocation = 0;
          else
@@ -3127,13 +3095,16 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        {
        default:
          (*_bfd_error_handler) (_("%s: unknown relocation type %d for symbol %s"),
        {
        default:
          (*_bfd_error_handler) (_("%s: unknown relocation type %d for symbol %s"),
-                                bfd_get_filename (input_bfd),
+                                bfd_archive_filename (input_bfd),
                                 (int) r_type, sym_name);
 
          bfd_set_error (bfd_error_bad_value);
          ret = false;
          continue;
 
                                 (int) r_type, sym_name);
 
          bfd_set_error (bfd_error_bad_value);
          ret = false;
          continue;
 
+       case (int) R_PPC_NONE:
+         continue;
+
        /* Relocations that need no special processing.  */
        case (int) R_PPC_LOCAL24PC:
          /* It makes no sense to point a local relocation
        /* Relocations that need no special processing.  */
        case (int) R_PPC_LOCAL24PC:
          /* It makes no sense to point a local relocation
@@ -3169,7 +3140,6 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
        /* Relocations that always need to be propagated if this is a shared
            object.  */
 
        /* Relocations that always need to be propagated if this is a shared
            object.  */
-       case (int) R_PPC_NONE:
        case (int) R_PPC_ADDR32:
        case (int) R_PPC_ADDR24:
        case (int) R_PPC_ADDR16:
        case (int) R_PPC_ADDR32:
        case (int) R_PPC_ADDR24:
        case (int) R_PPC_ADDR16:
@@ -3179,7 +3149,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        case (int) R_PPC_ADDR14:
        case (int) R_PPC_UADDR32:
        case (int) R_PPC_UADDR16:
        case (int) R_PPC_ADDR14:
        case (int) R_PPC_UADDR32:
        case (int) R_PPC_UADDR16:
-         if (info->shared)
+         if (info->shared && r_symndx != 0)
            {
              Elf_Internal_Rela outrel;
              boolean skip;
            {
              Elf_Internal_Rela outrel;
              boolean skip;
@@ -3215,22 +3185,11 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
              skip = false;
 
 
              skip = false;
 
-             if (elf_section_data (input_section)->stab_info == NULL)
-               outrel.r_offset = rel->r_offset;
-             else
-               {
-                 bfd_vma off;
-
-                 off = (_bfd_stab_section_offset
-                        (output_bfd, &elf_hash_table (info)->stab_info,
-                         input_section,
-                         &elf_section_data (input_section)->stab_info,
-                         rel->r_offset));
-                 if (off == (bfd_vma) -1)
-                   skip = true;
-                 outrel.r_offset = off;
-               }
-
+             outrel.r_offset =
+               _bfd_elf_section_offset (output_bfd, info, input_section,
+                                        rel->r_offset);
+             if (outrel.r_offset == (bfd_vma) -1)
+               skip = true;
              outrel.r_offset += (input_section->output_section->vma
                                  + input_section->output_offset);
 
              outrel.r_offset += (input_section->output_section->vma
                                  + input_section->output_offset);
 
@@ -3328,7 +3287,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            insn &= ~BRANCH_PREDICT_BIT;
          else
            insn |= BRANCH_PREDICT_BIT;
            insn &= ~BRANCH_PREDICT_BIT;
          else
            insn |= BRANCH_PREDICT_BIT;
-         bfd_put_32 (output_bfd, insn, contents + offset);
+         bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
          break;
 
        /* branch not taken predicition relocations */
          break;
 
        /* branch not taken predicition relocations */
@@ -3339,7 +3298,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            insn |= BRANCH_PREDICT_BIT;
          else
            insn &= ~BRANCH_PREDICT_BIT;
            insn |= BRANCH_PREDICT_BIT;
          else
            insn &= ~BRANCH_PREDICT_BIT;
-         bfd_put_32 (output_bfd, insn, contents + offset);
+         bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
          break;
 
        /* GOT16 relocations */
          break;
 
        /* GOT16 relocations */
@@ -3491,7 +3450,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                && strcmp (name, ".sbss") != 0)
              {
                (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
                && strcmp (name, ".sbss") != 0)
              {
                (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
-                                      bfd_get_filename (input_bfd),
+                                      bfd_archive_filename (input_bfd),
                                       sym_name,
                                       ppc_elf_howto_table[(int) r_type]->name,
                                       name);
                                       sym_name,
                                       ppc_elf_howto_table[(int) r_type]->name,
                                       name);
@@ -3512,7 +3471,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            if (strcmp (name, ".sdata2") != 0 && strcmp (name, ".sbss2") != 0)
              {
                (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
            if (strcmp (name, ".sdata2") != 0 && strcmp (name, ".sbss2") != 0)
              {
                (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
-                                      bfd_get_filename (input_bfd),
+                                      bfd_archive_filename (input_bfd),
                                       sym_name,
                                       ppc_elf_howto_table[(int) r_type]->name,
                                       name);
                                       sym_name,
                                       ppc_elf_howto_table[(int) r_type]->name,
                                       name);
@@ -3562,7 +3521,7 @@ 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)"),
            else
              {
                (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
-                                      bfd_get_filename (input_bfd),
+                                      bfd_archive_filename (input_bfd),
                                       sym_name,
                                       ppc_elf_howto_table[(int) r_type]->name,
                                       name);
                                       sym_name,
                                       ppc_elf_howto_table[(int) r_type]->name,
                                       name);
@@ -3576,7 +3535,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              {                 /* fill in register field */
                insn = bfd_get_32 (output_bfd, contents + offset);
                insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
              {                 /* fill in register field */
                insn = bfd_get_32 (output_bfd, contents + offset);
                insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
-               bfd_put_32 (output_bfd, insn, contents + offset);
+               bfd_put_32 (output_bfd, (bfd_vma) insn, contents + offset);
              }
          }
          break;
              }
          }
          break;
@@ -3628,7 +3587,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        case (int) R_PPC_EMB_RELST_HA:
        case (int) R_PPC_EMB_BIT_FLD:
          (*_bfd_error_handler) (_("%s: Relocation %s is not yet supported for symbol %s."),
        case (int) R_PPC_EMB_RELST_HA:
        case (int) R_PPC_EMB_BIT_FLD:
          (*_bfd_error_handler) (_("%s: Relocation %s is not yet supported for symbol %s."),
-                                bfd_get_filename (input_bfd),
+                                bfd_archive_filename (input_bfd),
                                 ppc_elf_howto_table[(int) r_type]->name,
                                 sym_name);
 
                                 ppc_elf_howto_table[(int) r_type]->name,
                                 sym_name);
 
@@ -3712,6 +3671,90 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
   return ret;
 }
 
   return ret;
 }
+
+static enum elf_reloc_type_class
+ppc_elf_reloc_type_class (rela)
+     const Elf_Internal_Rela *rela;
+{
+  switch ((int) ELF32_R_TYPE (rela->r_info))
+    {
+    case R_PPC_RELATIVE:
+      return reloc_class_relative;
+    case R_PPC_REL24:
+    case R_PPC_ADDR24:
+    case R_PPC_JMP_SLOT:
+      return reloc_class_plt;
+    case R_PPC_COPY:
+      return reloc_class_copy;
+    default:
+      return reloc_class_normal;
+    }
+}
+\f
+/* Support for core dump NOTE sections */
+static boolean
+ppc_elf_grok_prstatus (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  int offset;
+  unsigned int raw_size;
+
+  switch (note->descsz)
+    {
+      default:
+       return false;
+
+      case 268:                /* Linux/PPC */
+       /* pr_cursig */
+       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+
+       /* pr_pid */
+       elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+
+       /* pr_reg */
+       offset = 72;
+       raw_size = 192;
+
+       break;
+    }
+
+  /* Make a ".reg/999" section.  */
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+                                         raw_size, note->descpos + offset);
+}
+
+static boolean
+ppc_elf_grok_psinfo (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  switch (note->descsz)
+    {
+      default:
+       return false;
+
+      case 128:                /* Linux/PPC elf_prpsinfo */
+       elf_tdata (abfd)->core_program
+        = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+       elf_tdata (abfd)->core_command
+        = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+    }
+
+  /* Note that for some reason, a spurious space is tacked
+     onto the end of the args in some (at least one anyway)
+     implementations, so strip it off if it exists.  */
+
+  {
+    char *command = elf_tdata (abfd)->core_command;
+    int n = strlen (command);
+
+    if (0 < n && command[n - 1] == ' ')
+      command[n - 1] = '\0';
+  }
+
+  return true;
+}
 \f
 #define TARGET_LITTLE_SYM      bfd_elf32_powerpcle_vec
 #define TARGET_LITTLE_NAME     "elf32-powerpcle"
 \f
 #define TARGET_LITTLE_SYM      bfd_elf32_powerpcle_vec
 #define TARGET_LITTLE_NAME     "elf32-powerpcle"
@@ -3733,10 +3776,10 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 #define elf_backend_plt_not_loaded     1
 #define elf_backend_got_symbol_offset  4
 #define elf_backend_can_gc_sections    1
 #define elf_backend_plt_not_loaded     1
 #define elf_backend_got_symbol_offset  4
 #define elf_backend_can_gc_sections    1
+#define elf_backend_can_refcount       1
 #define elf_backend_got_header_size    12
 #define elf_backend_plt_header_size    PLT_INITIAL_ENTRY_SIZE
 
 #define elf_backend_got_header_size    12
 #define elf_backend_plt_header_size    PLT_INITIAL_ENTRY_SIZE
 
-#define bfd_elf32_bfd_copy_private_bfd_data    ppc_elf_copy_private_bfd_data
 #define bfd_elf32_bfd_merge_private_bfd_data   ppc_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_relax_section             ppc_elf_relax_section
 #define bfd_elf32_bfd_reloc_type_lookup                ppc_elf_reloc_type_lookup
 #define bfd_elf32_bfd_merge_private_bfd_data   ppc_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_relax_section             ppc_elf_relax_section
 #define bfd_elf32_bfd_reloc_type_lookup                ppc_elf_reloc_type_lookup
@@ -3757,5 +3800,8 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 #define elf_backend_fake_sections              ppc_elf_fake_sections
 #define elf_backend_additional_program_headers ppc_elf_additional_program_headers
 #define elf_backend_modify_segment_map         ppc_elf_modify_segment_map
 #define elf_backend_fake_sections              ppc_elf_fake_sections
 #define elf_backend_additional_program_headers ppc_elf_additional_program_headers
 #define elf_backend_modify_segment_map         ppc_elf_modify_segment_map
+#define elf_backend_grok_prstatus              ppc_elf_grok_prstatus
+#define elf_backend_grok_psinfo                        ppc_elf_grok_psinfo
+#define elf_backend_reloc_type_class           ppc_elf_reloc_type_class
 
 #include "elf32-target.h"
 
 #include "elf32-target.h"
This page took 0.033824 seconds and 4 git commands to generate.