* vaxnbsd-tdep.c: New file.
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index 1b10e5682c595f40a37d3ee548aa77deb0e3b253..4eb08ad3e67383905f122ce4e918b2a4e4a2205c 100644 (file)
@@ -1,6 +1,6 @@
 /* PowerPC-specific support for 32-bit ELF
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -336,7 +336,8 @@ ppc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
     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));
+                                  | ELF_LINK_HASH_REF_REGULAR_NONWEAK
+                                  | ELF_LINK_HASH_NEEDS_PLT));
   else
     _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
@@ -1531,19 +1532,33 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  /* Phony reloc to handle branch stubs.  */
-  HOWTO (R_PPC_RELAX32,         /* type */
-        0,                     /* rightshift */
-        0,                     /* size */
+  /* Phony relocs to handle branch stubs.  */
+  HOWTO (R_PPC_RELAX32,                /* type */
+        0,                     /* rightshift */
+        0,                     /* size */
+        0,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_PPC_RELAX32",       /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_PPC_RELAX32PC,      /* type */
+        0,                     /* rightshift */
+        0,                     /* size */
         0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_RELAX32",       /* name */
+        "R_PPC_RELAX32PC",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0,                     /* dst_mask */
+        0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* GNU extension to record C++ vtable hierarchy.  */
@@ -1611,90 +1626,26 @@ ppc_elf_howto_init (void)
     }
 }
 \f
-static bfd_reloc_status_type
-ppc_elf_install_value (bfd *abfd,
-                      bfd_byte *hit_addr,
-                      bfd_vma v,
-                      unsigned int r_type)
-{
-  bfd_vma t0, t1;
-#ifdef BFD_HOST_U_64_BIT
-  BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
-#else
-  bfd_vma val = v;
-#endif
-
-  switch (r_type)
-    {
-    case R_PPC_RELAX32:
-      /* Do stuff here.  */
-      t0 = bfd_get_32 (abfd, hit_addr);
-      t1 = bfd_get_32 (abfd, hit_addr + 4);
-
-      /* We're clearing the bits for R_PPC_ADDR16_HA
-        and R_PPC_ADDR16_LO here.  */
-      t0 &= ~0xffff;
-      t1 &= ~0xffff;
-
-      /* t0 is HA, t1 is lo */
-      t0 |= ((val + 0x8000) >> 16) & 0xffff;
-      t1 |= val & 0xffff;
-
-      bfd_put_32 (abfd, t0, hit_addr);
-      bfd_put_32 (abfd, t1, hit_addr + 4);
-      break;
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
-    case R_PPC_REL24:
-      t0 = bfd_get_32 (abfd, hit_addr);
-      t0 &= ~0x3fffffc;
-      t0 |= val & 0x3fffffc;
-      bfd_put_32 (abfd, t0, hit_addr);
-      break;
-
-    case R_PPC_REL14:
-    case R_PPC_REL14_BRTAKEN:
-    case R_PPC_REL14_BRNTAKEN:
-      t0 = bfd_get_32 (abfd, hit_addr);
-      t0 &= ~0xfffc;
-      t0 |= val & 0xfffc;
-      bfd_put_32 (abfd, t0, hit_addr);
-      break;
-
-    case R_PPC_LOCAL24PC:
-    case R_PPC_PLTREL24:
-      t0 = bfd_get_32 (abfd, hit_addr);
-      t0 &= ~0x3fffffc;
-      t0 |= val & 0x3fffffc;
-      bfd_put_32 (abfd, t0, hit_addr);
-      break;
-
-    default:
-      return bfd_reloc_notsupported;
-    }
-
-  return bfd_reloc_ok;
-}
-
-static const bfd_byte shared_stub_entry[] =
+static const int shared_stub_entry[] =
   {
-    0x48, 0x00, 0x00, 0x24, /* b .+36 */
-    0x7c, 0x08, 0x02, 0xa6, /* mflr 0 */
-    0x42, 0x9f, 0x00, 0x05, /* bcl 20, 31, .Lxxx */
-    0x7d, 0x68, 0x02, 0xa6, /* mflr 11 */
-    0x3d, 0x60, 0x00, 0x00, /* addis 11, 11, (xxx-.Lxxx)@ha */
-    0x39, 0x6b, 0x00, 0x18, /* addi 11, 11, (xxx-.Lxxx)@l */
-    0x7c, 0x08, 0x03, 0xa6, /* mtlr 0 */
-    0x7d, 0x69, 0x03, 0xa6, /* mtctr 11 */
-    0x4e, 0x80, 0x04, 0x20, /* bctr */
+    0x7c0802a6, /* mflr 0 */
+    0x429f0005, /* bcl 20, 31, .Lxxx */
+    0x7d6802a6, /* mflr 11 */
+    0x3d6b0000, /* addis 11, 11, (xxx-.Lxxx)@ha */
+    0x396b0018, /* addi 11, 11, (xxx-.Lxxx)@l */
+    0x7c0803a6, /* mtlr 0 */
+    0x7d6903a6, /* mtctr 11 */
+    0x4e800420, /* bctr */
   };
 
-static const bfd_byte stub_entry[] =
+static const int stub_entry[] =
   {
-    0x48, 0x00, 0x00, 0x14, /* b .+20 */
-    0x3d, 0x60, 0x00, 0x00, /* lis 11,xxx@ha */
-    0x39, 0x6b, 0x00, 0x00, /* addi 11,11,xxx@l */
-    0x7d, 0x69, 0x03, 0xa6, /* mtctr 11 */
-    0x4e, 0x80, 0x04, 0x20, /* bctr */
+    0x3d600000, /* lis 11,xxx@ha */
+    0x396b0000, /* addi 11,11,xxx@l */
+    0x7d6903a6, /* mtctr 11 */
+    0x4e800420, /* bctr */
   };
 
 
@@ -1718,23 +1669,24 @@ ppc_elf_relax_section (bfd *abfd,
   Elf_Internal_Rela *internal_relocs = NULL;
   Elf_Internal_Rela *irel, *irelend;
   struct one_fixup *fixups = NULL;
-  bfd_boolean changed_contents = FALSE;
-  bfd_boolean changed_relocs = FALSE;
+  bfd_boolean changed;
   struct ppc_elf_link_hash_table *ppc_info;
+  bfd_size_type trampoff;
 
   *again = FALSE;
 
-  /* Nothing to do if there are no relocations and no need for
-     the relax finalize pass.  */
-  if ((isec->flags & SEC_RELOC) == 0
-      || isec->reloc_count == 0
-      || link_info->relax_finalizing)
+  /* Nothing to do if there are no relocations.  */
+  if ((isec->flags & SEC_RELOC) == 0 || isec->reloc_count == 0)
     return TRUE;
 
   /* If needed, initialize this section's cooked size.  */
   if (isec->_cooked_size == 0)
     isec->_cooked_size = isec->_raw_size;
 
+  trampoff = (isec->_cooked_size + 3) & (bfd_vma) -4;
+  /* Space for a branch around any trampolines.  */
+  trampoff += 4;
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
   /* Get a copy of the native relocations.  */
@@ -1764,21 +1716,26 @@ ppc_elf_relax_section (bfd *abfd,
   for (irel = internal_relocs; irel < irelend; irel++)
     {
       unsigned long r_type = ELF32_R_TYPE (irel->r_info);
-      bfd_vma symaddr, reladdr, trampoff, toff, roff;
+      bfd_vma symaddr, reladdr, toff, roff;
       asection *tsec;
-      bfd_size_type amt;
       struct one_fixup *f;
       size_t insn_offset = 0;
-      bfd_vma max_branch_offset;
+      bfd_vma max_branch_offset, val;
+      bfd_byte *hit_addr;
+      unsigned long t0;
 
       switch (r_type)
        {
        case R_PPC_REL24:
        case R_PPC_LOCAL24PC:
+       case R_PPC_PLTREL24:
+         max_branch_offset = 1 << 25;
+         break;
+
        case R_PPC_REL14:
        case R_PPC_REL14_BRTAKEN:
        case R_PPC_REL14_BRNTAKEN:
-       case R_PPC_PLTREL24:
+         max_branch_offset = 1 << 15;
          break;
 
        default:
@@ -1804,7 +1761,7 @@ ppc_elf_relax_section (bfd *abfd,
            }
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
          if (isym->st_shndx == SHN_UNDEF)
-           continue;   /* We can't do anthing with undefined symbols.  */
+           continue;   /* We can't do anything with undefined symbols.  */
          else if (isym->st_shndx == SHN_ABS)
            tsec = bfd_abs_section_ptr;
          else if (isym->st_shndx == SHN_COMMON)
@@ -1816,7 +1773,7 @@ ppc_elf_relax_section (bfd *abfd,
        }
       else
        {
-         /* Need dynamic symbol handling.  */
+         /* Global symbol handling.  */
          unsigned long indx;
          struct elf_link_hash_entry *h;
 
@@ -1827,85 +1784,42 @@ ppc_elf_relax_section (bfd *abfd,
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
-         if (r_type == R_PPC_PLTREL24)
+         if (r_type == R_PPC_PLTREL24
+             && ppc_info->plt != NULL
+             && h->plt.offset != (bfd_vma) -1)
            {
-             Elf_Internal_Sym *isym;
-
-             if (h->plt.offset == (bfd_vma) -1
-                 || ppc_info->plt == NULL)
-               {
-
-                 /* Read this BFD's local symbols.  */
-                 if (isymbuf == NULL)
-                   {
-                     isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
-                     if (isymbuf == NULL)
-                       isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
-                                                       symtab_hdr->sh_info, 0,
-                                                       NULL, NULL, NULL);
-                     if (isymbuf == 0)
-                       goto error_return;
-                   }
-                 isym = isymbuf + ELF32_R_SYM (irel->r_info);
-
-                 if (isym->st_shndx == SHN_UNDEF)
-                   /* We can't do anthing with undefined symbols.  */
-                   continue;
-                 else if (isym->st_shndx == SHN_ABS)
-                   tsec = bfd_abs_section_ptr;
-                 else if (isym->st_shndx == SHN_COMMON)
-                   tsec = bfd_com_section_ptr;
-                 else
-                   tsec = h->root.u.def.section;
-
-                 toff = h->root.u.def.value;
-               }
-             else
-               {
-                 tsec = ppc_info->plt;
-                 toff = h->plt.offset;
-               }
+             tsec = ppc_info->plt;
+             toff = h->plt.offset;
            }
-         else if (h->root.type == bfd_link_hash_undefined
-                  || h->root.type == bfd_link_hash_undefweak)
-           continue;
-
-         else
+         else if (h->root.type == bfd_link_hash_defined
+                  || h->root.type == bfd_link_hash_defweak)
            {
              tsec = h->root.u.def.section;
              toff = h->root.u.def.value;
            }
+         else
+           continue;
        }
 
+      /* If the branch and target are in the same section, you have
+        no hope of adding stubs.  We'll error out later should the
+        branch overflow.  */
+      if (tsec == isec)
+       continue;
+
+      toff += irel->r_addend;
       if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
        toff = _bfd_merged_section_offset (abfd, &tsec,
                                           elf_section_data (tsec)->sec_info,
-                                          toff + irel->r_addend, 0);
-      else
-       toff += irel->r_addend;
+                                          toff, 0);
 
       symaddr = tsec->output_section->vma + tsec->output_offset + toff;
 
       roff = irel->r_offset;
-
-      reladdr = (isec->output_section->vma
-                + isec->output_offset
-                + roff) & (bfd_vma) -4;
+      reladdr = isec->output_section->vma + isec->output_offset + roff;
 
       /* If the branch is in range, no need to do anything.  */
-      max_branch_offset = 1 << 25;
-      if (r_type != R_PPC_REL24
-         && r_type != R_PPC_LOCAL24PC
-         && r_type != R_PPC_PLTREL24)
-       max_branch_offset = 1 << 15;
-
-      if ((bfd_vma) (symaddr - reladdr) + max_branch_offset
-         <= 2 * max_branch_offset)
-       continue;
-
-      /* If the branch and target are in the same section, you have
-        no hope.  We'll error out later.  */
-      if (tsec == isec)
+      if (symaddr - reladdr + max_branch_offset < 2 * max_branch_offset)
        continue;
 
       /* Look for an existing fixup to this address.  */
@@ -1916,40 +1830,31 @@ ppc_elf_relax_section (bfd *abfd,
       if (f == NULL)
        {
          size_t size;
+         unsigned long stub_rtype;
 
-         if (link_info->shared
-             || tsec == ppc_info->plt
-             || r_type == R_PPC_LOCAL24PC)
+         val = trampoff - roff;
+         if (val >= max_branch_offset)
+           /* Oh dear, we can't reach a trampoline.  Don't try to add
+              one.  We'll report an error later.  */
+           continue;
+
+         if (link_info->shared)
            {
-             size = sizeof (shared_stub_entry);
-             insn_offset = 16;
+             size = 4 * ARRAY_SIZE (shared_stub_entry);
+             insn_offset = 12;
+             stub_rtype = R_PPC_RELAX32PC;
            }
          else
            {
-             size = sizeof (stub_entry);
-             insn_offset = 4;
+             size = 4 * ARRAY_SIZE (stub_entry);
+             insn_offset = 0;
+             stub_rtype = R_PPC_RELAX32;
            }
 
-         /* Resize the current section to make room for the new branch.  */
-         trampoff = (isec->_cooked_size + 3) & (bfd_vma) - 4;
-         amt = trampoff + size;
-         contents = bfd_realloc (contents, amt);
-         if (contents == NULL)
-           abort ();
-
-         isec->_cooked_size = amt;
-
-         if (link_info->shared
-             || tsec == ppc_info->plt
-             || r_type == R_PPC_LOCAL24PC)
-           memcpy (contents + trampoff, shared_stub_entry, size);
-         else
-           memcpy (contents + trampoff, stub_entry, size);
-
          /* Hijack the old relocation.  Since we need two
             relocations for this use a "composite" reloc.  */
          irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-                                      R_PPC_RELAX32);
+                                      stub_rtype);
          irel->r_offset = trampoff + insn_offset;
 
          /* Record the fixup so we don't do it again this section.  */
@@ -1959,31 +1864,95 @@ ppc_elf_relax_section (bfd *abfd,
          f->toff = toff;
          f->trampoff = trampoff;
          fixups = f;
+
+         trampoff += size;
        }
       else
        {
+         val = f->trampoff - roff;
+         if (val >= max_branch_offset)
+           continue;
+
          /* Nop out the reloc, since we're finalizing things here.  */
          irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
        }
 
-      /* Fix up the existing branch to hit the trampoline.  Hope like
-        hell this doesn't overflow too.  */
-      if (ppc_elf_install_value (abfd, contents + roff,
-                                f->trampoff - (roff & (bfd_vma) -3) + 4,
-                                r_type) != bfd_reloc_ok)
-       abort ();
+      /* Fix up the existing branch to hit the trampoline.  */
+      hit_addr = contents + roff;
+      switch (r_type)
+       {
+       case R_PPC_REL24:
+       case R_PPC_LOCAL24PC:
+       case R_PPC_PLTREL24:
+         t0 = bfd_get_32 (abfd, hit_addr);
+         t0 &= ~0x3fffffc;
+         t0 |= val & 0x3fffffc;
+         bfd_put_32 (abfd, t0, hit_addr);
+         break;
 
-      changed_contents = TRUE;
-      changed_relocs = TRUE;
+       case R_PPC_REL14:
+       case R_PPC_REL14_BRTAKEN:
+       case R_PPC_REL14_BRNTAKEN:
+         t0 = bfd_get_32 (abfd, hit_addr);
+         t0 &= ~0xfffc;
+         t0 |= val & 0xfffc;
+         bfd_put_32 (abfd, t0, hit_addr);
+         break;
+       }
     }
 
-  /* Clean up.  */
-  while (fixups)
+  /* Write out the trampolines.  */
+  changed = fixups != NULL;
+  if (fixups != NULL)
     {
-      struct one_fixup *f = fixups;
-      fixups = fixups->next;
-      free (f);
+      const int *stub;
+      bfd_byte *dest;
+      bfd_vma val;
+      int i, size;
+
+      do
+       {
+         struct one_fixup *f = fixups;
+         fixups = fixups->next;
+         free (f);
+       }
+      while (fixups);
+
+      contents = bfd_realloc (contents, trampoff);
+      if (contents == NULL)
+       goto error_return;
+
+      isec->_cooked_size = (isec->_cooked_size + 3) & (bfd_vma) -4;
+      /* Branch around the trampolines.  */
+      val = trampoff - isec->_cooked_size + 0x48000000;
+      dest = contents + isec->_cooked_size;
+      isec->_cooked_size = trampoff;
+      bfd_put_32 (abfd, val, dest);
+      dest += 4;
+
+      if (link_info->shared)
+       {
+         stub = shared_stub_entry;
+         size = ARRAY_SIZE (shared_stub_entry);
+       }
+      else
+       {
+         stub = stub_entry;
+         size = ARRAY_SIZE (stub_entry);
+       }
+
+      i = 0;
+      while (dest < contents + trampoff)
+       {
+         bfd_put_32 (abfd, stub[i], dest);
+         i++;
+         if (i == size)
+           i = 0;
+         dest += 4;
+       }
+      BFD_ASSERT (i == 0);
     }
+
   if (isymbuf != NULL
       && symtab_hdr->contents != (unsigned char *) isymbuf)
     {
@@ -1999,7 +1968,7 @@ ppc_elf_relax_section (bfd *abfd,
   if (contents != NULL
       && elf_section_data (isec)->this_hdr.contents != contents)
     {
-      if (!changed_contents && !link_info->keep_memory)
+      if (!changed && !link_info->keep_memory)
        free (contents);
       else
        {
@@ -2010,13 +1979,13 @@ ppc_elf_relax_section (bfd *abfd,
 
   if (elf_section_data (isec)->relocs != internal_relocs)
     {
-      if (!changed_relocs)
+      if (!changed)
        free (internal_relocs);
       else
        elf_section_data (isec)->relocs = internal_relocs;
     }
 
-  *again = changed_contents || changed_relocs;
+  *again = changed;
   return TRUE;
 
  error_return:
@@ -2423,7 +2392,7 @@ elf_create_pointer_linker_section (bfd *abfd,
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (h->dynindx == -1)
        {
-         if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
 
@@ -2716,7 +2685,7 @@ ppc_elf_create_linker_section (bfd *abfd,
       lsect->sym_hash = h;
 
       if (info->shared
-         && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+         && ! bfd_elf_link_record_dynamic_symbol (info, h))
        return NULL;
     }
 
@@ -2764,7 +2733,8 @@ ppc_elf_additional_program_headers (bfd *abfd)
 /* Modify the segment map if needed.  */
 
 static bfd_boolean
-ppc_elf_modify_segment_map (bfd *abfd ATTRIBUTE_UNUSED)
+ppc_elf_modify_segment_map (bfd *abfd ATTRIBUTE_UNUSED,
+                           struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   return TRUE;
 }
@@ -3023,17 +2993,6 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   return TRUE;
 }
 \f
-/* This is the condition under which finish_dynamic_symbol will be
-   called from elflink.h.  If elflink.h doesn't call our
-   finish_dynamic_symbol routine, we'll need to do something about
-   initializing any .plt and .got entries in relocate_section.  */
-#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \
-  ((DYN)                                                               \
-   && ((SHARED)                                                                \
-       || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)     \
-   && ((H)->dynindx != -1                                              \
-       || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
-
 /* Of those relocs that might be copied as dynamic relocs, this macro
    selects those that must be copied when linking a shared library,
    even when the symbol is local.  */
@@ -3072,7 +3031,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       if (h->dynindx == -1
          && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
        {
-         if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
 
@@ -3135,7 +3094,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       if (eh->elf.dynindx == -1
          && (eh->elf.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
        {
-         if (!bfd_elf32_link_record_dynamic_symbol (info, &eh->elf))
+         if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
            return FALSE;
        }
 
@@ -3216,6 +3175,18 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
          && h->root.type == bfd_link_hash_undefweak)
        eh->dyn_relocs = NULL;
+
+      /* Make sure undefined weak symbols are output as a dynamic symbol
+        in PIEs.  */
+      if (info->pie
+         && eh->dyn_relocs != NULL
+         && h->dynindx == -1
+         && h->root.type == bfd_link_hash_undefweak
+         && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+       {
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
+           return FALSE;
+       }
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
@@ -3232,7 +3203,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
          if (h->dynindx == -1
              && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
            {
-             if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+             if (! bfd_elf_link_record_dynamic_symbol (info, h))
                return FALSE;
            }
 
@@ -3488,7 +3459,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         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, (TAG), (VAL))
+  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
       if (info->executable)
        {
@@ -3824,14 +3795,14 @@ ppc_elf_check_relocs (bfd *abfd,
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
        case R_PPC_GNU_VTINHERIT:
-         if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+         if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
 
          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
        case R_PPC_GNU_VTENTRY:
-         if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
 
@@ -4394,7 +4365,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
 static bfd_boolean
 ppc_elf_add_symbol_hook (bfd *abfd,
                         struct bfd_link_info *info,
-                        const Elf_Internal_Sym *sym,
+                        Elf_Internal_Sym *sym,
                         const char **namep ATTRIBUTE_UNUSED,
                         flagword *flagsp ATTRIBUTE_UNUSED,
                         asection **secp,
@@ -4715,15 +4686,15 @@ ppc_elf_relocate_section (bfd *output_bfd,
          sec = local_sections[r_symndx];
          sym_name = bfd_elf_local_sym_name (input_bfd, sym);
 
-         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
        }
       else
        {
-         RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
-                                  symtab_hdr, relocation, sec,
-                                  unresolved_reloc, info,
-                                  warned);
-         
+         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                  r_symndx, symtab_hdr, sym_hashes,
+                                  h, sec, relocation,
+                                  unresolved_reloc, warned);
+
          sym_name = h->root.root.string;
        }
 
@@ -4943,7 +4914,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
          branch_bit = BRANCH_PREDICT_BIT;
          /* Fall thru */
 
-         /* Branch not taken predicition relocations.  */
+         /* Branch not taken prediction relocations.  */
        case R_PPC_ADDR14_BRNTAKEN:
        case R_PPC_REL14_BRNTAKEN:
          insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
@@ -5440,45 +5411,33 @@ ppc_elf_relocate_section (bfd *output_bfd,
            }
          break;
 
+       case R_PPC_RELAX32PC:
+         relocation -= (input_section->output_section->vma
+                        + input_section->output_offset
+                        + rel->r_offset - 4);
+         /* Fall thru */
        case R_PPC_RELAX32:
          {
-           unsigned long r_symndx;
-           Elf_Internal_Sym *sym;
-           asection *sym_sec;
-           bfd_byte *hit_addr = 0;
-           bfd_vma value = 0;
+           unsigned long t0;
+           unsigned long t1;
 
-           r_symndx = ELF32_R_SYM (rel->r_info);
+           t0 = bfd_get_32 (output_bfd, contents + rel->r_offset);
+           t1 = bfd_get_32 (output_bfd, contents + rel->r_offset + 4);
 
-           if (r_symndx < symtab_hdr->sh_info)
-             {
-               sym = local_syms + r_symndx;
-               sym_sec = local_sections[r_symndx];
+           /* We're clearing the bits for R_PPC_ADDR16_HA
+              and R_PPC_ADDR16_LO here.  */
+           t0 &= ~0xffff;
+           t1 &= ~0xffff;
 
-               value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
-             }
-           else
-             {
-               bfd_boolean warned;
-               bfd_boolean unresolved_reloc;
-
-               RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd),
-                                        r_symndx, symtab_hdr,
-                                        value, sym_sec,
-                                        unresolved_reloc, info,
-                                        warned);
-               if (warned)
-                 continue;
-             }
-           hit_addr = contents + rel->r_offset;
-           value += rel->r_addend;
+           /* t0 is HA, t1 is LO */
+           relocation += addend;
+           t0 |= ((relocation + 0x8000) >> 16) & 0xffff;
+           t1 |= relocation & 0xffff;
 
-           r = ppc_elf_install_value (output_bfd, hit_addr, value, r_type);
-           if (r != bfd_reloc_ok)
-             break;
-           else
-             continue;
+           bfd_put_32 (output_bfd, t0, contents + rel->r_offset);
+           bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4);
          }
+         continue;
 
          /* Indirect .sdata relocation.  */
        case R_PPC_EMB_SDAI16:
This page took 0.03691 seconds and 4 git commands to generate.