* config/tc-mips.c (append_insn): Set fx_tcbit for composite relocs.
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index dff4126e155ef99786dc7186640ae3756f2c7c99..a9a246dc3a540600c26f767c37ae55ed8401d6cd 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.
@@ -205,9 +205,6 @@ struct ppc_elf_link_hash_table
   elf_linker_section_t *sdata2;
   asection *sbss;
 
-  /* Short-cut to first output tls section.  */
-  asection *tls_sec;
-
   /* Shortcut to .__tls_get_addr.  */
   struct elf_link_hash_entry *tls_get_addr;
 
@@ -285,7 +282,7 @@ ppc_elf_link_hash_table_create (bfd *abfd)
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-ppc_elf_copy_indirect_symbol (struct elf_backend_data *bed,
+ppc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
                              struct elf_link_hash_entry *dir,
                              struct elf_link_hash_entry *ind)
 {
@@ -332,14 +329,16 @@ ppc_elf_copy_indirect_symbol (struct elf_backend_data *bed,
 
   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));
+      && dir->dynamic_adjusted)
+    {
+      /* If called to transfer flags for a weakdef during processing
+        of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+        We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
+      dir->ref_dynamic |= ind->ref_dynamic;
+      dir->ref_regular |= ind->ref_regular;
+      dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+      dir->needs_plt |= ind->needs_plt;
+    }
   else
     _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
@@ -1534,19 +1533,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 */
+        "R_PPC_RELAX32",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0,                     /* dst_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_RELAX32PC",     /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* GNU extension to record C++ vtable hierarchy.  */
@@ -1614,90 +1627,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 */
   };
 
 
@@ -1721,22 +1670,19 @@ 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->size + 3) & (bfd_vma) -4;
+  /* Space for a branch around any trampolines.  */
+  trampoff += 4;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
@@ -1749,39 +1695,30 @@ ppc_elf_relax_section (bfd *abfd,
   ppc_info = ppc_elf_hash_table (link_info);
   irelend = internal_relocs + isec->reloc_count;
 
-  /* Get the section contents.  */
-  /* Get cached copy if it exists.  */
-  if (elf_section_data (isec)->this_hdr.contents != NULL)
-    contents = elf_section_data (isec)->this_hdr.contents;
-  else
-    {
-      /* Go get them off disk.  */
-      contents = bfd_malloc (isec->_raw_size);
-      if (contents == NULL)
-       goto error_return;
-
-      if (!bfd_get_section_contents (abfd, isec, contents, 0, isec->_raw_size))
-       goto error_return;
-    }
-
   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;
+      unsigned char sym_type;
 
       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:
@@ -1807,7 +1744,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,10 +1753,11 @@ ppc_elf_relax_section (bfd *abfd,
            tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
 
          toff = isym->st_value;
+         sym_type = ELF_ST_TYPE (isym->st_info);
        }
       else
        {
-         /* Need dynamic symbol handling.  */
+         /* Global symbol handling.  */
          unsigned long indx;
          struct elf_link_hash_entry *h;
 
@@ -1830,85 +1768,74 @@ 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;
+
+         sym_type = h->type;
        }
 
-      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);
+      /* 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;
+
+      /* There probably isn't any reason to handle symbols in
+        SEC_MERGE sections;  SEC_MERGE doesn't seem a likely
+        attribute for a code section, and we are only looking at
+        branches.  However, implement it correctly here as a
+        reference for other target relax_section functions.  */
+      if (0 && tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
+       {
+         /* At this stage in linking, no SEC_MERGE symbol has been
+            adjusted, so all references to such symbols need to be
+            passed through _bfd_merged_section_offset.  (Later, in
+            relocate_section, all SEC_MERGE symbols *except* for
+            section symbols have been adjusted.)
+
+            gas may reduce relocations against symbols in SEC_MERGE
+            sections to a relocation against the section symbol when
+            the original addend was zero.  When the reloc is against
+            a section symbol we should include the addend in the
+            offset passed to _bfd_merged_section_offset, since the
+            location of interest is the original symbol.  On the
+            other hand, an access to "sym+addend" where "sym" is not
+            a section symbol should not include the addend;  Such an
+            access is presumed to be an offset from "sym";  The
+            location of interest is just "sym".  */
+         if (sym_type == STT_SECTION)
+           toff += irel->r_addend;
+
+         toff = _bfd_merged_section_offset (abfd, &tsec,
+                                            elf_section_data (tsec)->sec_info,
+                                            toff);
+
+         if (sym_type != STT_SECTION)
+           toff += irel->r_addend;
+       }
       else
        toff += irel->r_addend;
 
       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.  */
@@ -1919,40 +1846,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.  */
@@ -1962,31 +1880,109 @@ 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 ();
+      /* Get the section contents.  */
+      if (contents == NULL)
+       {
+         /* Get cached copy if it exists.  */
+         if (elf_section_data (isec)->this_hdr.contents != NULL)
+           contents = elf_section_data (isec)->this_hdr.contents;
+         else
+           {
+             /* Go get them off disk.  */
+             if (!bfd_malloc_and_get_section (abfd, isec, &contents))
+               goto error_return;
+           }
+       }
+
+      /* 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->size = (isec->size + 3) & (bfd_vma) -4;
+      /* Branch around the trampolines.  */
+      val = trampoff - isec->size + 0x48000000;
+      dest = contents + isec->size;
+      isec->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)
     {
@@ -2002,7 +1998,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
        {
@@ -2013,13 +2009,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:
@@ -2169,7 +2165,7 @@ ppc_elf_addr16_ha_reloc (bfd *abfd ATTRIBUTE_UNUSED,
       return bfd_reloc_ok;
     }
 
-  if (reloc_entry->address > input_section->_cooked_size)
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
 
   if (bfd_is_com_section (symbol->section))
@@ -2287,18 +2283,16 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
        {
          error = TRUE;
          (*_bfd_error_handler)
-           (_("%s: compiled with -mrelocatable and linked with "
-              "modules compiled normally"),
-            bfd_archive_filename (ibfd));
+           (_("%B: compiled with -mrelocatable and linked with "
+              "modules compiled normally"), ibfd);
        }
       else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
               && (old_flags & EF_PPC_RELOCATABLE) != 0)
        {
          error = TRUE;
          (*_bfd_error_handler)
-           (_("%s: compiled normally and linked with "
-              "modules compiled with -mrelocatable"),
-            bfd_archive_filename (ibfd));
+           (_("%B: compiled normally and linked with "
+              "modules compiled with -mrelocatable"), ibfd);
        }
 
       /* The output is -mrelocatable-lib iff both the input files are.  */
@@ -2324,9 +2318,9 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
        {
          error = TRUE;
          (*_bfd_error_handler)
-           (_("%s: uses different e_flags (0x%lx) fields "
+           (_("%B: uses different e_flags (0x%lx) fields "
               "than previous modules (0x%lx)"),
-            bfd_archive_filename (ibfd), (long) new_flags, (long) old_flags);
+            ibfd, (long) new_flags, (long) old_flags);
        }
 
       if (error)
@@ -2426,12 +2420,12 @@ 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;
        }
 
       if (lsect->rel_section)
-       lsect->rel_section->_raw_size += sizeof (Elf32_External_Rela);
+       lsect->rel_section->size += sizeof (Elf32_External_Rela);
     }
   else
     {
@@ -2467,7 +2461,7 @@ elf_create_pointer_linker_section (bfd *abfd,
             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);
+         lsect->rel_section->size += sizeof (Elf32_External_Rela);
        }
     }
 
@@ -2486,14 +2480,14 @@ elf_create_pointer_linker_section (bfd *abfd,
   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;
+  linker_section_ptr->offset = lsect->section->size;
+  lsect->section->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);
+          (long) lsect->section->size);
 #endif
 
   return TRUE;
@@ -2533,7 +2527,7 @@ elf_finish_pointer_linker_section (bfd *output_bfd,
       if (! elf_hash_table (info)->dynamic_sections_created
          || (info->shared
              && info->symbolic
-             && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+             && h->def_regular))
        {
          /* This is actually a static link, or it is a
             -Bsymbolic link and the symbol is defined
@@ -2581,11 +2575,12 @@ elf_finish_pointer_linker_section (bfd *output_bfd,
              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);
+             const struct elf_backend_data *bed;
              unsigned int i;
 
              BFD_ASSERT (srel != NULL);
 
+             bed = get_elf_backend_data (output_bfd);
              for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
                {
                  outrel[i].r_offset = (lsect->section->output_section->vma
@@ -2626,7 +2621,7 @@ ppc_elf_create_linker_section (bfd *abfd,
 {
   elf_linker_section_t *lsect;
   struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
-  asection *s;
+  asection *s, *sym_sec;
   bfd_size_type amt;
   flagword flags;
   const char *name;
@@ -2675,13 +2670,15 @@ ppc_elf_create_linker_section (bfd *abfd,
   lsect->sym_offset = sym_offset;
 
   /* See if the sections already exist.  */
-  s = bfd_get_section_by_name (htab->elf.dynobj, name);
+  sym_sec = s = bfd_get_section_by_name (htab->elf.dynobj, name);
   if (s == NULL || (s->flags & flags) != flags)
     {
       s = bfd_make_section_anyway (htab->elf.dynobj, name);
       if (s == NULL
          || !bfd_set_section_flags (htab->elf.dynobj, s, flags))
        return NULL;
+      if (sym_sec == NULL)
+       sym_sec = s;
     }
   lsect->section = s;
 
@@ -2689,11 +2686,11 @@ ppc_elf_create_linker_section (bfd *abfd,
       && !bfd_set_section_alignment (htab->elf.dynobj, s, 2))
     return NULL;
 
-  s->_raw_size = align_power (s->_raw_size, 2);
+  s->size = align_power (s->size, 2);
 
 #ifdef DEBUG
   fprintf (stderr, "Creating section %s, current size = %ld\n",
-          name, (long) s->_raw_size);
+          name, (long) s->size);
 #endif
 
   if (sym_name)
@@ -2709,7 +2706,7 @@ ppc_elf_create_linker_section (bfd *abfd,
 
       if ((bh == NULL || bh->type == bfd_link_hash_undefined)
          && !(_bfd_generic_link_add_one_symbol
-              (info, abfd, sym_name, BSF_GLOBAL, s, sym_offset, NULL,
+              (info, abfd, sym_name, BSF_GLOBAL, sym_sec, sym_offset, NULL,
                FALSE, get_elf_backend_data (abfd)->collect, &bh)))
        return NULL;
       h = (struct elf_link_hash_entry *) bh;
@@ -2718,7 +2715,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;
     }
 
@@ -2753,23 +2750,15 @@ ppc_elf_additional_program_headers (bfd *abfd)
     ++ret;
 
   s = bfd_get_section_by_name (abfd, ".sbss2");
-  if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0)
+  if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size > 0)
     ++ret;
 
   s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0");
-  if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0)
+  if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size > 0)
     ++ret;
 
   return ret;
 }
-
-/* Modify the segment map if needed.  */
-
-static bfd_boolean
-ppc_elf_modify_segment_map (bfd *abfd ATTRIBUTE_UNUSED)
-{
-  return TRUE;
-}
 \f
 /* The powerpc .got has a blrl instruction in it.  Mark it executable.  */
 
@@ -2875,18 +2864,15 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* Make sure we know what is going on here.  */
   htab = ppc_elf_hash_table (info);
   BFD_ASSERT (htab->elf.dynobj != NULL
-             && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
-                 || h->weakdef != NULL
-                 || ((h->elf_link_hash_flags
-                      & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_REF_REGULAR) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+             && (h->needs_plt
+                 || h->u.weakdef != NULL
+                 || (h->def_dynamic
+                     && h->ref_regular
+                     && !h->def_regular)));
 
   /* Deal with function syms.  */
   if (h->type == STT_FUNC
-      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+      || h->needs_plt)
     {
       /* Clear procedure linkage table information for any symbol that
         won't need a .plt entry.  */
@@ -2906,7 +2892,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
             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;
+         h->needs_plt = 0;
        }
       return TRUE;
     }
@@ -2916,16 +2902,14 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (h->weakdef != NULL)
+  if (h->u.weakdef != NULL)
     {
-      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
-                 || h->weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->weakdef->root.u.def.section;
-      h->root.u.def.value = h->weakdef->root.u.def.value;
+      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->u.weakdef->root.u.def.section;
+      h->root.u.def.value = h->u.weakdef->root.u.def.value;
       if (ELIMINATE_COPY_RELOCS)
-       h->elf_link_hash_flags
-         = ((h->elf_link_hash_flags & ~ELF_LINK_NON_GOT_REF)
-            | (h->weakdef->elf_link_hash_flags & ELF_LINK_NON_GOT_REF));
+       h->non_got_ref = h->u.weakdef->non_got_ref;
       return TRUE;
     }
 
@@ -2941,7 +2925,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   /* If there are no references to this symbol that do not use the
      GOT, we don't need to generate a copy reloc.  */
-  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
+  if (!h->non_got_ref)
     return TRUE;
 
   if (ELIMINATE_COPY_RELOCS)
@@ -2958,7 +2942,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
         we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
       if (p == NULL)
        {
-         h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
+         h->non_got_ref = 0;
          return TRUE;
        }
     }
@@ -2996,8 +2980,8 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       else
        srel = htab->relbss;
       BFD_ASSERT (srel != NULL);
-      srel->_raw_size += sizeof (Elf32_External_Rela);
-      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+      srel->size += sizeof (Elf32_External_Rela);
+      h->needs_copy = 1;
     }
 
   /* We need to figure out the alignment required for this symbol.  I
@@ -3007,8 +2991,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
     power_of_two = 4;
 
   /* Apply the required alignment.  */
-  s->_raw_size = BFD_ALIGN (s->_raw_size,
-                           (bfd_size_type) (1 << power_of_two));
+  s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
   if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
     {
       if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
@@ -3017,25 +3000,14 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   /* Define the symbol as being at this point in the section.  */
   h->root.u.def.section = s;
-  h->root.u.def.value = s->_raw_size;
+  h->root.u.def.value = s->size;
 
   /* Increment the section size to make room for the symbol.  */
-  s->_raw_size += h->size;
+  s->size += h->size;
 
   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,9 +3044,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     {
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (h->dynindx == -1
-         && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+         && !h->forced_local)
        {
-         if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
 
@@ -3085,15 +3057,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
          /* If this is the first .plt entry, make room for the special
             first entry.  */
-         if (s->_raw_size == 0)
-           s->_raw_size += PLT_INITIAL_ENTRY_SIZE;
+         if (s->size == 0)
+           s->size += PLT_INITIAL_ENTRY_SIZE;
 
          /* The PowerPC PLT is actually composed of two parts, the
             first part is 2 words (for a load and a jump), and then
             there is a remaining word available at the end.  */
          h->plt.offset = (PLT_INITIAL_ENTRY_SIZE
                           + (PLT_SLOT_SIZE
-                             * ((s->_raw_size - PLT_INITIAL_ENTRY_SIZE)
+                             * ((s->size - PLT_INITIAL_ENTRY_SIZE)
                                 / PLT_ENTRY_SIZE)));
 
          /* If this symbol is not defined in a regular file, and we
@@ -3102,7 +3074,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
             function pointers compare as equal between the normal
             executable and the shared library.  */
          if (! info->shared
-             && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+             && !h->def_regular)
            {
              h->root.u.def.section = s;
              h->root.u.def.value = h->plt.offset;
@@ -3110,24 +3082,24 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
          /* Make room for this entry.  After the 8192nd entry, room
             for two entries is allocated.  */
-         s->_raw_size += PLT_ENTRY_SIZE;
-         if ((s->_raw_size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
+         s->size += PLT_ENTRY_SIZE;
+         if ((s->size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
              > PLT_NUM_SINGLE_ENTRIES)
-           s->_raw_size += PLT_ENTRY_SIZE;
+           s->size += PLT_ENTRY_SIZE;
 
          /* We also need to make an entry in the .rela.plt section.  */
-         htab->relplt->_raw_size += sizeof (Elf32_External_Rela);
+         htab->relplt->size += sizeof (Elf32_External_Rela);
        }
       else
        {
          h->plt.offset = (bfd_vma) -1;
-         h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+         h->needs_plt = 0;
        }
     }
   else
     {
       h->plt.offset = (bfd_vma) -1;
-      h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+      h->needs_plt = 0;
     }
 
   eh = (struct ppc_elf_link_hash_entry *) h;
@@ -3135,33 +3107,33 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     {
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (eh->elf.dynindx == -1
-         && (eh->elf.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+         && !eh->elf.forced_local)
        {
-         if (!bfd_elf32_link_record_dynamic_symbol (info, &eh->elf))
+         if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
            return FALSE;
        }
 
       if (eh->tls_mask == (TLS_TLS | TLS_LD)
-         && !(eh->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC))
+         && !eh->elf.def_dynamic)
        /* If just an LD reloc, we'll just use htab->tlsld_got.offset.  */
        eh->elf.got.offset = (bfd_vma) -1;
       else
        {
          bfd_boolean dyn;
-         eh->elf.got.offset = htab->got->_raw_size;
+         eh->elf.got.offset = htab->got->size;
          if ((eh->tls_mask & TLS_TLS) != 0)
            {
              if ((eh->tls_mask & TLS_LD) != 0)
-               htab->got->_raw_size += 8;
+               htab->got->size += 8;
              if ((eh->tls_mask & TLS_GD) != 0)
-               htab->got->_raw_size += 8;
+               htab->got->size += 8;
              if ((eh->tls_mask & (TLS_TPREL | TLS_TPRELGD)) != 0)
-               htab->got->_raw_size += 4;
+               htab->got->size += 4;
              if ((eh->tls_mask & TLS_DTPREL) != 0)
-               htab->got->_raw_size += 4;
+               htab->got->size += 4;
            }
          else
-           htab->got->_raw_size += 4;
+           htab->got->size += 4;
          dyn = htab->elf.dynamic_sections_created;
          if ((info->shared
               || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
@@ -3169,12 +3141,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
                  || eh->elf.root.type != bfd_link_hash_undefweak))
            {
              /* All the entries we allocated need relocs.  */
-             htab->relgot->_raw_size
-               += ((htab->got->_raw_size - eh->elf.got.offset) / 4
+             htab->relgot->size
+               += ((htab->got->size - eh->elf.got.offset) / 4
                    * sizeof (Elf32_External_Rela));
              /* Except LD only needs one.  */
              if ((eh->tls_mask & TLS_LD) != 0)
-               htab->relgot->_raw_size -= sizeof (Elf32_External_Rela);
+               htab->relgot->size -= sizeof (Elf32_External_Rela);
            }
        }
     }
@@ -3218,6 +3190,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->forced_local)
+       {
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
+           return FALSE;
+       }
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
@@ -3225,16 +3209,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
         symbols which turn out to need copy relocs or are not
         dynamic.  */
 
-      if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
-         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+      if (!h->non_got_ref
+         && h->def_dynamic
+         && !h->def_regular)
        {
          /* Make sure this symbol is output as a dynamic symbol.
             Undefined weak syms won't yet be marked as dynamic.  */
          if (h->dynindx == -1
-             && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+             && !h->forced_local)
            {
-             if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+             if (! bfd_elf_link_record_dynamic_symbol (info, h))
                return FALSE;
            }
 
@@ -3253,7 +3237,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
     {
       asection *sreloc = elf_section_data (p->sec)->sreloc;
-      sreloc->_raw_size += p->count * sizeof (Elf32_External_Rela);
+      sreloc->size += p->count * sizeof (Elf32_External_Rela);
     }
 
   return TRUE;
@@ -3314,17 +3298,17 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        {
          s = bfd_get_section_by_name (htab->elf.dynobj, ".interp");
          BFD_ASSERT (s != NULL);
-         s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
        }
     }
 
   if (htab->tlsld_got.refcount > 0)
     {
-      htab->tlsld_got.offset = htab->got->_raw_size;
-      htab->got->_raw_size += 8;
+      htab->tlsld_got.offset = htab->got->size;
+      htab->got->size += 8;
       if (info->shared)
-       htab->relgot->_raw_size += sizeof (Elf32_External_Rela);
+       htab->relgot->size += sizeof (Elf32_External_Rela);
     }
   else
     htab->tlsld_got.offset = (bfd_vma) -1;
@@ -3362,7 +3346,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                }
              else if (p->count != 0)
                {
-                 elf_section_data (p->sec)->sreloc->_raw_size
+                 elf_section_data (p->sec)->sreloc->size
                    += p->count * sizeof (Elf32_External_Rela);
                  if ((p->sec->output_section->flags
                       & (SEC_READONLY | SEC_ALLOC))
@@ -3391,30 +3375,30 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                   htab->tlsld_got.offset.  */
                if (htab->tlsld_got.offset == (bfd_vma) -1)
                  {
-                   htab->tlsld_got.offset = s->_raw_size;
-                   s->_raw_size += 8;
+                   htab->tlsld_got.offset = s->size;
+                   s->size += 8;
                    if (info->shared)
-                     srel->_raw_size += sizeof (Elf32_External_Rela);
+                     srel->size += sizeof (Elf32_External_Rela);
                  }
                *local_got = (bfd_vma) -1;
              }
            else
              {
-               *local_got = s->_raw_size;
+               *local_got = s->size;
                if ((*lgot_masks & TLS_TLS) != 0)
                  {
                    if ((*lgot_masks & TLS_GD) != 0)
-                     s->_raw_size += 8;
+                     s->size += 8;
                    if ((*lgot_masks & (TLS_TPREL | TLS_TPRELGD)) != 0)
-                     s->_raw_size += 4;
+                     s->size += 4;
                    if ((*lgot_masks & TLS_DTPREL) != 0)
-                     s->_raw_size += 4;
+                     s->size += 4;
                  }
                else
-                 s->_raw_size += 4;
+                 s->size += 4;
                if (info->shared)
-                 srel->_raw_size += ((s->_raw_size - *local_got) / 4
-                                     * sizeof (Elf32_External_Rela));
+                 srel->size += ((s->size - *local_got) / 4
+                                * sizeof (Elf32_External_Rela));
              }
          }
        else
@@ -3442,7 +3426,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        }
       else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
        {
-         if (s->_raw_size == 0)
+         if (s->size == 0)
            {
              /* If we don't need this section, strip it from the
                 output file.  This is mostly to handle .rela.bss and
@@ -3470,14 +3454,14 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          continue;
        }
 
-      if (s->_raw_size == 0)
+      if (s->size == 0)
        {
          _bfd_strip_section_from_output (info, s);
          continue;
        }
 
       /* Allocate memory for the section contents.  */
-      s->contents = bfd_zalloc (htab->elf.dynobj, s->_raw_size);
+      s->contents = bfd_zalloc (htab->elf.dynobj, s->size);
       if (s->contents == NULL)
        return FALSE;
     }
@@ -3490,7 +3474,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)
        {
@@ -3498,7 +3482,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
            return FALSE;
        }
 
-      if (htab->plt != NULL && htab->plt->_raw_size != 0)
+      if (htab->plt != NULL && htab->plt->size != 0)
        {
          if (!add_dynamic_entry (DT_PLTGOT, 0)
              || !add_dynamic_entry (DT_PLTRELSZ, 0)
@@ -3562,8 +3546,8 @@ static void
 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),
+    (_("%B: relocation %s cannot be used when making a shared object"),
+     abfd,
      ppc_elf_howto_table[r_type]->name);
   bfd_set_error (bfd_error_bad_value);
 }
@@ -3589,9 +3573,8 @@ ppc_elf_check_relocs (bfd *abfd,
     return TRUE;
 
 #ifdef DEBUG
-  fprintf (stderr, "ppc_elf_check_relocs called for section %s in %s\n",
-          bfd_get_section_name (abfd, sec),
-          bfd_archive_filename (abfd));
+  _bfd_error_handler ("ppc_elf_check_relocs called for section %A in %B",
+                     sec, abfd);
 #endif
 
   /* Initialize howto table if not already done.  */
@@ -3768,17 +3751,17 @@ ppc_elf_check_relocs (bfd *abfd,
            {
              /* 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 "
+             (*_bfd_error_handler) (_("%B(%A+0x%lx): %s reloc against "
                                       "local symbol"),
-                                    bfd_archive_filename (abfd),
-                                    sec->name,
+                                    abfd,
+                                    sec,
                                     (long) rel->r_offset,
                                     ppc_elf_howto_table[r_type]->name);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
 
-         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->needs_plt = 1;
          h->plt.refcount++;
          break;
 
@@ -3826,14 +3809,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;
 
@@ -3887,7 +3870,7 @@ ppc_elf_check_relocs (bfd *abfd,
              h->plt.refcount++;
 
              /* We may need a copy reloc too.  */
-             h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+             h->non_got_ref = 1;
            }
 
        dodyn:
@@ -3917,15 +3900,13 @@ ppc_elf_check_relocs (bfd *abfd,
                   || (h != NULL
                       && (! info->symbolic
                           || h->root.type == bfd_link_hash_defweak
-                          || (h->elf_link_hash_flags
-                              & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+                          || !h->def_regular))))
              || (ELIMINATE_COPY_RELOCS
                  && !info->shared
                  && (sec->flags & SEC_ALLOC) != 0
                  && h != NULL
                  && (h->root.type == bfd_link_hash_defweak
-                     || (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+                     || !h->def_regular)))
            {
              struct ppc_elf_dyn_relocs *p;
              struct ppc_elf_dyn_relocs **head;
@@ -4183,25 +4164,18 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
   return TRUE;
 }
 
-/* Set htab->tls_sec and htab->tls_get_addr.  */
+/* Set htab->tls_get_addr and call the generic ELF tls_setup function.  */
 
-bfd_boolean
+asection *
 ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
 {
-  asection *tls;
   struct ppc_elf_link_hash_table *htab;
 
   htab = ppc_elf_hash_table (info);
   htab->tls_get_addr = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
                                             FALSE, FALSE, TRUE);
 
-  for (tls = obfd->sections; tls != NULL; tls = tls->next)
-    if ((tls->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
-       == (SEC_THREAD_LOCAL | SEC_LOAD))
-      break;
-  htab->tls_sec = tls;
-
-  return tls != NULL;
+  return _bfd_elf_tls_setup (obfd, info);
 }
 
 /* Run through all the TLS relocs looking for optimization
@@ -4261,7 +4235,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
 
                is_local = FALSE;
                if (h == NULL
-                   || !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC))
+                   || !h->def_dynamic)
                  is_local = TRUE;
 
                r_type = ELF32_R_TYPE (rel->r_info);
@@ -4403,7 +4377,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,
@@ -4489,7 +4463,7 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
             + reloc_index * sizeof (Elf32_External_Rela));
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
 
-      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+      if (!h->def_regular)
        {
          /* Mark the symbol as undefined, rather than as defined in
             the .plt section.  Leave the value alone.  */
@@ -4498,13 +4472,12 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
             Otherwise, the PLT entry would provide a definition for
             the symbol even if the symbol wasn't defined anywhere,
             and so the symbol would never be NULL.  */
-         if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK)
-             == 0)
+         if (!h->ref_regular_nonweak)
            sym->st_value = 0;
        }
     }
 
-  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+  if (h->needs_copy)
     {
       asection *s;
       Elf_Internal_Rela rela;
@@ -4569,7 +4542,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
       BFD_ASSERT (htab->plt != NULL && sdyn != NULL);
 
       dyncon = (Elf32_External_Dyn *) sdyn->contents;
-      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
       for (; dyncon < dynconend; dyncon++)
        {
          Elf_Internal_Dyn dyn;
@@ -4585,7 +4558,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_PLTRELSZ:
-             dyn.d_un.d_val = htab->relplt->_raw_size;
+             dyn.d_un.d_val = htab->relplt->size;
              break;
 
            case DT_JMPREL:
@@ -4672,12 +4645,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
   bfd_boolean ret = TRUE;
 
 #ifdef DEBUG
-  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->relocatable) ? " (relocatable)" : "");
+  _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, "
+                     "%ld relocations%s",
+                     input_bfd, input_section,
+                     (long) input_section->reloc_count,
+                     (info->relocatable) ? " (relocatable)" : "");
 #endif
 
   if (info->relocatable)
@@ -4717,54 +4689,23 @@ ppc_elf_relocate_section (bfd *output_bfd,
       unresolved_reloc = FALSE;
       warned = FALSE;
       r_symndx = ELF32_R_SYM (rel->r_info);
+
       if (r_symndx < symtab_hdr->sh_info)
        {
          sym = local_syms + r_symndx;
          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
        {
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-         sym_name = h->root.root.string;
+         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                  r_symndx, symtab_hdr, sym_hashes,
+                                  h, sec, relocation,
+                                  unresolved_reloc, warned);
 
-         relocation = 0;
-         if (h->root.type == bfd_link_hash_defined
-             || h->root.type == bfd_link_hash_defweak)
-           {
-             sec = h->root.u.def.section;
-             /* Set a flag that will be cleared later if we find a
-                relocation value for this symbol.  output_section
-                is typically NULL for symbols satisfied by a shared
-                library.  */
-             if (sec->output_section == NULL)
-               unresolved_reloc = TRUE;
-             else
-               relocation = (h->root.u.def.value
-                             + sec->output_section->vma
-                             + sec->output_offset);
-           }
-         else if (h->root.type == bfd_link_hash_undefweak)
-           ;
-         else if (!info->executable
-                  && !info->no_undefined
-                  && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-           ;
-         else
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd, input_section,
-                     rel->r_offset, (!info->shared
-                                     || info->no_undefined
-                                     || ELF_ST_VISIBILITY (h->other)))))
-               return FALSE;
-             warned = TRUE;
-           }
+         sym_name = h->root.root.string;
        }
 
       /* TLS optimizations.  Replace instruction sequences and relocs
@@ -4947,8 +4888,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
                        {
                          /* Was an LD reloc.  */
                          r_symndx = 0;
-                         rel->r_addend = htab->tls_sec->vma + DTP_OFFSET;
-                         rel[1].r_addend = htab->tls_sec->vma + DTP_OFFSET;
+                         rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
+                         rel[1].r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
                        }
                      r_type = R_PPC_TPREL16_HA;
                      rel->r_info = ELF32_R_INFO (r_symndx, r_type);
@@ -4983,7 +4924,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);
@@ -5011,8 +4952,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
        {
        default:
          (*_bfd_error_handler)
-           (_("%s: unknown relocation type %d for symbol %s"),
-            bfd_archive_filename (input_bfd), (int) r_type, sym_name);
+           (_("%B: unknown relocation type %d for symbol %s"),
+            input_bfd, (int) r_type, sym_name);
 
          bfd_set_error (bfd_error_bad_value);
          ret = FALSE;
@@ -5075,7 +5016,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
            indx = 0;
            if (tls_type == (TLS_TLS | TLS_LD)
                && (h == NULL
-                   || !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)))
+                   || !h->def_dynamic))
              offp = &htab->tlsld_got.offset;
            else if (h != NULL)
              {
@@ -5118,8 +5059,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
                if (offp == &htab->tlsld_got.offset)
                  tls_m = TLS_LD;
                else if (h == NULL
-                        || !(h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_DYNAMIC))
+                        || !h->def_dynamic)
                  tls_m &= ~TLS_LD;
 
                /* We might have multiple got entries for this sym.
@@ -5186,7 +5126,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
                          {
                            outrel.r_addend += relocation;
                            if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL))
-                             outrel.r_addend -= htab->tls_sec->vma;
+                             outrel.r_addend -= htab->elf.tls_sec->vma;
                          }
                        loc = htab->relgot->contents;
                        loc += (htab->relgot->reloc_count++
@@ -5204,7 +5144,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
                          value = 1;
                        else if (tls_ty != 0)
                          {
-                           value -= htab->tls_sec->vma + DTP_OFFSET;
+                           value -= htab->elf.tls_sec->vma + DTP_OFFSET;
                            if (tls_ty == (TLS_TLS | TLS_TPREL))
                              value += DTP_OFFSET - TP_OFFSET;
 
@@ -5238,8 +5178,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
                  {
                    if ((tls_mask & TLS_LD) != 0
                        && !(h == NULL
-                            || !(h->elf_link_hash_flags
-                                 & ELF_LINK_HASH_DEF_DYNAMIC)))
+                            || !h->def_dynamic))
                      off += 8;
                    if (tls_type != (TLS_TLS | TLS_GD))
                      {
@@ -5262,9 +5201,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
               got at entry m+n bears little relation to the entry m.  */
            if (addend != 0)
              (*_bfd_error_handler)
-               (_("%s(%s+0x%lx): non-zero addend on %s reloc against `%s'"),
-                bfd_archive_filename (input_bfd),
-                bfd_get_section_name (input_bfd, input_section),
+               (_("%B(%A+0x%lx): non-zero addend on %s reloc against `%s'"),
+                input_bfd,
+                input_section,
                 (long) rel->r_offset,
                 howto->name,
                 sym_name);
@@ -5292,7 +5231,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
        case R_PPC_DTPREL16_LO:
        case R_PPC_DTPREL16_HI:
        case R_PPC_DTPREL16_HA:
-         addend -= htab->tls_sec->vma + DTP_OFFSET;
+         addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
          break;
 
          /* Relocations that may need to be propagated if this is a shared
@@ -5301,18 +5240,18 @@ ppc_elf_relocate_section (bfd *output_bfd,
        case R_PPC_TPREL16_LO:
        case R_PPC_TPREL16_HI:
        case R_PPC_TPREL16_HA:
-         addend -= htab->tls_sec->vma + TP_OFFSET;
+         addend -= htab->elf.tls_sec->vma + TP_OFFSET;
          /* The TPREL16 relocs shouldn't really be used in shared
             libs as they will result in DT_TEXTREL being set, but
             support them anyway.  */
          goto dodyn;
 
        case R_PPC_TPREL32:
-         addend -= htab->tls_sec->vma + TP_OFFSET;
+         addend -= htab->elf.tls_sec->vma + TP_OFFSET;
          goto dodyn;
 
        case R_PPC_DTPREL32:
-         addend -= htab->tls_sec->vma + DTP_OFFSET;
+         addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
          goto dodyn;
 
        case R_PPC_DTPMOD32:
@@ -5364,9 +5303,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
                  && (input_section->flags & SEC_ALLOC) != 0
                  && h != NULL
                  && h->dynindx != -1
-                 && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
-                 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-                 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0))
+                 && !h->non_got_ref
+                 && h->def_dynamic
+                 && !h->def_regular))
            {
              int skip;
 
@@ -5480,78 +5419,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
-             {
-               long indx;
-
-               indx = r_symndx - symtab_hdr->sh_info;
-               h = elf_sym_hashes (input_bfd)[indx];
-               while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-                 h = (struct elf_link_hash_entry *) h->root.u.i.link;
+           /* t0 is HA, t1 is LO */
+           relocation += addend;
+           t0 |= ((relocation + 0x8000) >> 16) & 0xffff;
+           t1 |= relocation & 0xffff;
 
-               value = 0;
-               if (h->root.type == bfd_link_hash_defined
-                   || h->root.type == bfd_link_hash_defweak)
-                 {
-                   sym_sec = h->root.u.def.section;
-
-                   /* Detect the cases that sym_sec->output_section is
-                      expected to be NULL -- all cases in which the symbol
-                      is defined in another shared module.  This includes
-                      PLT relocs for which we've created a PLT entry and
-                      other relocs for which we're prepared to create
-                      dynamic relocations.  */
-                   /* ??? Just accept it NULL and continue.  */
-
-                   if (sym_sec->output_section != NULL)
-                     {
-                       value = (h->root.u.def.value
-                                + sym_sec->output_section->vma
-                                + sym_sec->output_offset);
-                     }
-                 }
-               else if (info->shared
-                        && !info->no_undefined
-                        && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-                 ;
-               else
-                 {
-                   if (! ((*info->callbacks->undefined_symbol)
-                          (info, h->root.root.string, input_bfd,
-                           input_section, rel->r_offset,
-                           (!info->shared || info->no_undefined
-                            || ELF_ST_VISIBILITY (h->other)))))
-                     return FALSE;
-                   continue;
-                 }
-             }
-           hit_addr = contents + rel->r_offset;
-           value += rel->r_addend;
-
-           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:
@@ -5618,9 +5512,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
                       && (name[5] == 0 || name[5] == '.'))))
              {
                (*_bfd_error_handler)
-                 (_("%s: the target (%s) of a %s relocation is "
+                 (_("%B: the target (%s) of a %s relocation is "
                     "in the wrong output section (%s)"),
-                  bfd_archive_filename (input_bfd),
+                  input_bfd,
                   sym_name,
                   howto->name,
                   name);
@@ -5644,9 +5538,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
                   || strncmp (name, ".sbss2", 6) == 0))
              {
                (*_bfd_error_handler)
-                 (_("%s: the target (%s) of a %s relocation is "
+                 (_("%B: the target (%s) of a %s relocation is "
                     "in the wrong output section (%s)"),
-                  bfd_archive_filename (input_bfd),
+                  input_bfd,
                   sym_name,
                   howto->name,
                   name);
@@ -5703,9 +5597,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
            else
              {
                (*_bfd_error_handler)
-                 (_("%s: the target (%s) of a %s relocation is "
+                 (_("%B: the target (%s) of a %s relocation is "
                     "in the wrong output section (%s)"),
-                  bfd_archive_filename (input_bfd),
+                  input_bfd,
                   sym_name,
                   howto->name,
                   name);
@@ -5758,8 +5652,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
        case R_PPC_EMB_RELST_HA:
        case R_PPC_EMB_BIT_FLD:
          (*_bfd_error_handler)
-           (_("%s: relocation %s is not yet supported for symbol %s."),
-            bfd_archive_filename (input_bfd),
+           (_("%B: relocation %s is not yet supported for symbol %s."),
+            input_bfd,
             howto->name,
             sym_name);
 
@@ -5810,12 +5704,12 @@ ppc_elf_relocate_section (bfd *output_bfd,
 
       if (unresolved_reloc
          && !((input_section->flags & SEC_DEBUGGING) != 0
-              && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
+              && h->def_dynamic))
        {
          (*_bfd_error_handler)
-           (_("%s(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
-            bfd_archive_filename (input_bfd),
-            bfd_get_section_name (input_bfd, input_section),
+           (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+            input_bfd,
+            input_section,
             (long) rel->r_offset,
             howto->name,
             sym_name);
@@ -5863,9 +5757,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
          else
            {
              (*_bfd_error_handler)
-               (_("%s(%s+0x%lx): %s reloc against `%s': error %d"),
-                bfd_archive_filename (input_bfd),
-                bfd_get_section_name (input_bfd, input_section),
+               (_("%B(%A+0x%lx): %s reloc against `%s': error %d"),
+                input_bfd, input_section,
                 (long) rel->r_offset, howto->name, sym_name, (int) r);
              ret = FALSE;
            }
@@ -5903,7 +5796,7 @@ static bfd_boolean
 ppc_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 {
   int offset;
-  unsigned int raw_size;
+  unsigned int size;
 
   switch (note->descsz)
     {
@@ -5919,14 +5812,14 @@ ppc_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
       /* pr_reg */
       offset = 72;
-      raw_size = 192;
+      size = 192;
 
       break;
     }
 
   /* Make a ".reg/999" section.  */
   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
-                                         raw_size, note->descpos + offset);
+                                         size, note->descpos + offset);
 }
 
 static bfd_boolean
@@ -6072,7 +5965,7 @@ ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
       if (asec)
        {
          ++ num_input_sections;
-         output_section_size += asec->_raw_size;
+         output_section_size += asec->size;
        }
     }
 
@@ -6104,23 +5997,23 @@ ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
       if (asec == NULL)
        continue;
 
-      length = asec->_raw_size;
+      length = asec->size;
       if (length < 24)
        {
-         error_message = _("corrupt or empty %s section in %s");
+         error_message = _("corrupt or empty %s section in %B");
          goto fail;
        }
 
       if (bfd_seek (ibfd, asec->filepos, SEEK_SET) != 0
          || (bfd_bread (buffer + offset, length, ibfd) != length))
        {
-         error_message = _("unable to read in %s section from %s");
+         error_message = _("unable to read in %s section from %B");
          goto fail;
        }
 
       /* Process the contents of the section.  */
       ptr = buffer + offset;
-      error_message = _("corrupt %s section in %s");
+      error_message = _("corrupt %s section in %B");
 
       /* Verify the contents of the header.  Note - we have to
         extract the values this way in order to allow for a
@@ -6163,14 +6056,13 @@ ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
 
   if (! bfd_set_section_size (abfd, asec, output_section_size))
     ibfd = abfd,
-      error_message = _("warning: unable to set size of %s section in %s");
+      error_message = _("warning: unable to set size of %s section in %B");
 
  fail:
   free (buffer);
 
   if (error_message)
-    (*_bfd_error_handler) (error_message, APUINFO_SECTION_NAME,
-                          bfd_archive_filename (ibfd));
+    (*_bfd_error_handler) (error_message, ibfd, APUINFO_SECTION_NAME);
 }
 
 
@@ -6205,7 +6097,7 @@ ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
   if (apuinfo_list_length () == 0)
     return;
 
-  length = asec->_raw_size;
+  length = asec->size;
   if (length < 20)
     return;
 
@@ -6231,7 +6123,7 @@ ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
       length += 4;
     }
 
-  if (length != asec->_raw_size)
+  if (length != asec->size)
     (*_bfd_error_handler) (_("failed to compute new APUinfo section."));
 
   if (! bfd_set_section_contents (abfd, asec, buffer, (file_ptr) 0, length))
@@ -6242,6 +6134,17 @@ ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
   apuinfo_list_finish ();
 }
 
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+   or (bfd_vma) -1 if it should not be included.  */
+
+static bfd_vma
+ppc_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
+                    const asection *plt ATTRIBUTE_UNUSED,
+                    const arelent *rel)
+{
+  return rel->address;
+}
+
 /* Add extra PPC sections -- Note, for now, make .sbss2 and
    .PPC.EMB.sbss0 a normal section, and not a bss section so
    that the linker doesn't crater when trying to make more than
@@ -6249,26 +6152,16 @@ ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
 
 static struct bfd_elf_special_section const ppc_elf_special_sections[]=
 {
-  { ".tags",           0,      NULL,   0,
-    SHT_ORDERED,       SHF_ALLOC },
-  { ".sdata",          0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_WRITE },
-  { ".sbss",           0,      NULL,   0,
-    SHT_NOBITS,                SHF_ALLOC + SHF_WRITE },
-  { ".sdata2",         0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC },
-  { ".sbss2",          0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC },
-  { ".PPC.EMB.apuinfo",        0,      NULL,   0,
-    SHT_NOTE,          0 },
-  { ".PPC.EMB.sdata0", 0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC },
-  { ".PPC.EMB.sbss0",  0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC },
-  { ".plt",            0,      NULL,   0,
-    SHT_NOBITS,                0 },
-  { NULL,              0,      NULL,   0,
-    0,                 0 }
+  { ".tags",             5,  0, SHT_ORDERED,  SHF_ALLOC },
+  { ".sdata",            6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { ".sbss",             5, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
+  { ".sdata2",           7, -2, SHT_PROGBITS, SHF_ALLOC },
+  { ".sbss2",            6, -2, SHT_PROGBITS, SHF_ALLOC },
+  { ".PPC.EMB.apuinfo", 16,  0, SHT_NOTE,     0 },
+  { ".PPC.EMB.sdata0",  15,  0, SHT_PROGBITS, SHF_ALLOC },
+  { ".PPC.EMB.sbss0",   14,  0, SHT_PROGBITS, SHF_ALLOC },
+  { ".plt",              4,  0, SHT_NOBITS,   SHF_ALLOC + SHF_EXECINSTR },
+  { NULL,                0,  0, 0,            0 }
 };
 \f
 #define TARGET_LITTLE_SYM      bfd_elf32_powerpcle_vec
@@ -6297,7 +6190,6 @@ static struct bfd_elf_special_section const ppc_elf_special_sections[]=
 #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_rela_normal                1
 
 #define bfd_elf32_mkobject                     ppc_elf_mkobject
@@ -6322,7 +6214,6 @@ static struct bfd_elf_special_section const ppc_elf_special_sections[]=
 #define elf_backend_finish_dynamic_sections    ppc_elf_finish_dynamic_sections
 #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
@@ -6330,5 +6221,6 @@ static struct bfd_elf_special_section const ppc_elf_special_sections[]=
 #define elf_backend_final_write_processing     ppc_elf_final_write_processing
 #define elf_backend_write_section              ppc_elf_write_section
 #define elf_backend_special_sections           ppc_elf_special_sections
+#define elf_backend_plt_sym_val                        ppc_elf_plt_sym_val
 
 #include "elf32-target.h"
This page took 0.050483 seconds and 4 git commands to generate.