PPC gold doesn't check for overflow properly
[platform/upstream/binutils.git] / bfd / elf64-ppc.c
index 63d4eb9..0245a2c 100644 (file)
@@ -1,6 +1,5 @@
 /* PowerPC64-specific support for 64-bit ELF.
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 1999-2014 Free Software Foundation, Inc.
    Written by Linus Nordberg, Swox AB <info@swox.com>,
    based on elf32-ppc.c by Ian Lance Taylor.
    Largely rewritten by Alan Modra.
@@ -57,9 +56,9 @@ static bfd_reloc_status_type ppc64_elf_unhandled_reloc
 static bfd_vma opd_entry_value
   (asection *, bfd_vma, asection **, bfd_vma *, bfd_boolean);
 
-#define TARGET_LITTLE_SYM      bfd_elf64_powerpcle_vec
+#define TARGET_LITTLE_SYM      powerpc_elf64_le_vec
 #define TARGET_LITTLE_NAME     "elf64-powerpcle"
-#define TARGET_BIG_SYM         bfd_elf64_powerpc_vec
+#define TARGET_BIG_SYM         powerpc_elf64_vec
 #define TARGET_BIG_NAME                "elf64-powerpc"
 #define ELF_ARCH               bfd_arch_powerpc
 #define ELF_TARGET_ID          PPC64_ELF_DATA
@@ -81,10 +80,10 @@ static bfd_vma opd_entry_value
 #define bfd_elf64_mkobject                   ppc64_elf_mkobject
 #define bfd_elf64_bfd_reloc_type_lookup              ppc64_elf_reloc_type_lookup
 #define bfd_elf64_bfd_reloc_name_lookup              ppc64_elf_reloc_name_lookup
-#define bfd_elf64_bfd_merge_private_bfd_data  _bfd_generic_verify_endian_match
+#define bfd_elf64_bfd_merge_private_bfd_data  ppc64_elf_merge_private_bfd_data
+#define bfd_elf64_bfd_print_private_bfd_data  ppc64_elf_print_private_bfd_data
 #define bfd_elf64_new_section_hook           ppc64_elf_new_section_hook
 #define bfd_elf64_bfd_link_hash_table_create  ppc64_elf_link_hash_table_create
-#define bfd_elf64_bfd_link_hash_table_free    ppc64_elf_link_hash_table_free
 #define bfd_elf64_get_synthetic_symtab       ppc64_elf_get_synthetic_symtab
 #define bfd_elf64_bfd_link_just_syms         ppc64_elf_link_just_syms
 
@@ -95,7 +94,7 @@ static bfd_vma opd_entry_value
 #define elf_backend_create_dynamic_sections   ppc64_elf_create_dynamic_sections
 #define elf_backend_copy_indirect_symbol      ppc64_elf_copy_indirect_symbol
 #define elf_backend_add_symbol_hook          ppc64_elf_add_symbol_hook
-#define elf_backend_check_directives         ppc64_elf_process_dot_syms
+#define elf_backend_check_directives         ppc64_elf_before_check_relocs
 #define elf_backend_notice_as_needed         ppc64_elf_notice_as_needed
 #define elf_backend_archive_symbol_lookup     ppc64_elf_archive_symbol_lookup
 #define elf_backend_check_relocs             ppc64_elf_check_relocs
@@ -108,6 +107,7 @@ static bfd_vma opd_entry_value
 #define elf_backend_maybe_function_sym       ppc64_elf_maybe_function_sym
 #define elf_backend_always_size_sections      ppc64_elf_func_desc_adjust
 #define elf_backend_size_dynamic_sections     ppc64_elf_size_dynamic_sections
+#define elf_backend_hash_symbol                      ppc64_elf_hash_symbol
 #define elf_backend_init_index_section       _bfd_elf_init_2_index_sections
 #define elf_backend_action_discarded         ppc64_elf_action_discarded
 #define elf_backend_relocate_section         ppc64_elf_relocate_section
@@ -116,17 +116,25 @@ static bfd_vma opd_entry_value
 #define elf_backend_finish_dynamic_sections   ppc64_elf_finish_dynamic_sections
 #define elf_backend_link_output_symbol_hook   ppc64_elf_output_symbol_hook
 #define elf_backend_special_sections         ppc64_elf_special_sections
-#define elf_backend_post_process_headers      _bfd_elf_set_osabi
+#define elf_backend_merge_symbol_attribute    ppc64_elf_merge_symbol_attribute
 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
 
 /* The size in bytes of an entry in the procedure linkage table.  */
-#define PLT_ENTRY_SIZE 24
+#define PLT_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 8)
 
 /* The initial size of the plt reserved for the dynamic linker.  */
-#define PLT_INITIAL_ENTRY_SIZE PLT_ENTRY_SIZE
+#define PLT_INITIAL_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 16)
+
+/* Offsets to some stack save slots.  */
+#define STK_LR 16
+#define STK_TOC(htab) (htab->opd_abi ? 40 : 24)
+/* This one is dodgy.  ELFv2 does not have a linker word, so use the
+   CR save slot.  Used only by optimised __tls_get_addr call stub,
+   relying on __tls_get_addr_opt not saving CR..  */
+#define STK_LINKER(htab) (htab->opd_abi ? 32 : 8)
 
 /* TOC base pointers offset from start of TOC.  */
 #define TOC_BASE_OFF   0x8000
@@ -137,33 +145,36 @@ static bfd_vma opd_entry_value
 
 /* .plt call stub instructions.  The normal stub is like this, but
    sometimes the .plt entry crosses a 64k boundary and we need to
-   insert an addi to adjust r12.  */
-#define PLT_CALL_STUB_SIZE (7*4)
-#define ADDIS_R12_R2   0x3d820000      /* addis %r12,%r2,xxx@ha     */
-#define STD_R2_40R1    0xf8410028      /* std   %r2,40(%r1)         */
-#define LD_R11_0R12    0xe96c0000      /* ld    %r11,xxx+0@l(%r12)  */
-#define MTCTR_R11      0x7d6903a6      /* mtctr %r11                */
-#define LD_R2_0R12     0xe84c0000      /* ld    %r2,xxx+8@l(%r12)   */
-                                       /* ld    %r11,xxx+16@l(%r12) */
+   insert an addi to adjust r11.  */
+#define STD_R2_0R1     0xf8410000      /* std   %r2,0+40(%r1)       */
+#define ADDIS_R11_R2   0x3d620000      /* addis %r11,%r2,xxx@ha     */
+#define LD_R12_0R11    0xe98b0000      /* ld    %r12,xxx+0@l(%r11)  */
+#define MTCTR_R12      0x7d8903a6      /* mtctr %r12                */
+#define LD_R2_0R11     0xe84b0000      /* ld    %r2,xxx+8@l(%r11)   */
+#define LD_R11_0R11    0xe96b0000      /* ld    %r11,xxx+16@l(%r11) */
 #define BCTR           0x4e800420      /* bctr                      */
 
-
-#define ADDIS_R12_R12  0x3d8c0000      /* addis %r12,%r12,off@ha  */
-#define ADDI_R12_R12   0x398c0000      /* addi %r12,%r12,off@l  */
+#define ADDI_R11_R11   0x396b0000      /* addi %r11,%r11,off@l  */
 #define ADDIS_R2_R2    0x3c420000      /* addis %r2,%r2,off@ha  */
 #define ADDI_R2_R2     0x38420000      /* addi  %r2,%r2,off@l   */
 
-#define XOR_R11_R11_R11        0x7d6b5a78      /* xor   %r11,%r11,%r11  */
-#define ADD_R12_R12_R11        0x7d8c5a14      /* add   %r12,%r12,%r11  */
+#define XOR_R2_R12_R12 0x7d826278      /* xor   %r2,%r12,%r12   */
+#define ADD_R11_R11_R2 0x7d6b1214      /* add   %r11,%r11,%r2   */
+#define XOR_R11_R12_R12        0x7d8b6278      /* xor   %r11,%r12,%r12  */
 #define ADD_R2_R2_R11  0x7c425a14      /* add   %r2,%r2,%r11    */
 #define CMPLDI_R2_0    0x28220000      /* cmpldi %r2,0          */
 #define BNECTR         0x4ca20420      /* bnectr+               */
 #define BNECTR_P4      0x4ce20420      /* bnectr+               */
 
+#define LD_R12_0R2     0xe9820000      /* ld    %r12,xxx+0(%r2) */
 #define LD_R11_0R2     0xe9620000      /* ld    %r11,xxx+0(%r2) */
 #define LD_R2_0R2      0xe8420000      /* ld    %r2,xxx+0(%r2)  */
 
-#define LD_R2_40R1     0xe8410028      /* ld    %r2,40(%r1)     */
+#define LD_R2_0R1      0xe8410000      /* ld    %r2,0(%r1)      */
+
+#define ADDIS_R12_R2   0x3d820000      /* addis %r12,%r2,xxx@ha     */
+#define ADDIS_R12_R12  0x3d8c0000      /* addis %r12,%r12,xxx@ha */
+#define LD_R12_0R12    0xe98c0000      /* ld    %r12,xxx@l(%r12) */
 
 /* glink call stub instructions.  We enter with the index in R0.  */
 #define GLINK_CALL_STUB_SIZE (16*4)
@@ -174,14 +185,19 @@ static bfd_vma opd_entry_value
 #define BCL_20_31      0x429f0005      /*  bcl 20,31,1f                */
                                        /* 1:                           */
 #define MFLR_R11       0x7d6802a6      /*  mflr %11                    */
-#define LD_R2_M16R11   0xe84bfff0      /*  ld %2,(0b-1b)(%11)          */
+                                       /*  ld %2,(0b-1b)(%11)          */
 #define MTLR_R12       0x7d8803a6      /*  mtlr %12                    */
-#define ADD_R12_R2_R11 0x7d825a14      /*  add %12,%2,%11              */
-                                       /*  ld %11,0(%12)               */
-                                       /*  ld %2,8(%12)                */
-                                       /*  mtctr %11                   */
-                                       /*  ld %11,16(%12)              */
+#define ADD_R11_R2_R11 0x7d625a14      /*  add %11,%2,%11              */
+                                       /*  ld %12,0(%11)               */
+                                       /*  ld %2,8(%11)                */
+                                       /*  mtctr %12                   */
+                                       /*  ld %11,16(%11)              */
                                        /*  bctr                        */
+#define MFLR_R0                0x7c0802a6      /*  mflr %r0                    */
+#define MTLR_R0                0x7c0803a6      /*  mtlr %r0                    */
+#define SUB_R12_R12_R11        0x7d8b6050      /*  subf %r12,%r11,%r12         */
+#define ADDI_R0_R12    0x380c0000      /*  addi %r0,%r12,0             */
+#define SRDI_R0_R0_2   0x7800f082      /*  rldicl %r0,%r0,62,2         */
 
 /* Pad with this.  */
 #define NOP            0x60000000
@@ -219,6 +235,19 @@ static bfd_vma opd_entry_value
 #ifndef NO_OPD_RELOCS
 #define NO_OPD_RELOCS 0
 #endif
+
+static inline int
+abiversion (bfd *abfd)
+{
+  return elf_elfheader (abfd)->e_flags & EF_PPC64_ABI;
+}
+
+static inline void
+set_abiversion (bfd *abfd, int ver)
+{
+  elf_elfheader (abfd)->e_flags &= ~EF_PPC64_ABI;
+  elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI;
+}
 \f
 #define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
 
@@ -341,7 +370,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_branch_reloc, /* special_function */
         "R_PPC64_ADDR14",      /* name */
         FALSE,                 /* partial_inplace */
@@ -358,7 +387,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_brtaken_reloc, /* special_function */
         "R_PPC64_ADDR14_BRTAKEN",/* name */
         FALSE,                 /* partial_inplace */
@@ -375,7 +404,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_brtaken_reloc, /* special_function */
         "R_PPC64_ADDR14_BRNTAKEN",/* name */
         FALSE,                 /* partial_inplace */
@@ -616,7 +645,6 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         32,                    /* bitsize */
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
-        /* FIXME: Verify.  Was complain_overflow_bitfield.  */
         complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_PPC64_REL32",       /* name */
@@ -711,7 +739,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_sectoff_reloc, /* special_function */
         "R_PPC64_SECTOFF",     /* name */
         FALSE,                 /* partial_inplace */
@@ -999,7 +1027,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         64,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         ppc64_elf_toc64_reloc, /* special_function */
         "R_PPC64_TOC",         /* name */
         FALSE,                 /* partial_inplace */
@@ -1087,7 +1115,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_PPC64_ADDR16_DS",   /* name */
         FALSE,                 /* partial_inplace */
@@ -1162,7 +1190,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_sectoff_reloc, /* special_function */
         "R_PPC64_SECTOFF_DS",  /* name */
         FALSE,                 /* partial_inplace */
@@ -1934,7 +1962,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_PPC64_REL16",       /* name */
         FALSE,                 /* partial_inplace */
@@ -2078,6 +2106,21 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  /* Like ADDR64, but use local entry point of function.  */
+  HOWTO (R_PPC64_ADDR64_LOCAL, /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+        64,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_PPC64_ADDR64_LOCAL", /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ONES (64),             /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
   /* GNU extension to record C++ vtable hierarchy.  */
   HOWTO (R_PPC64_GNU_VTINHERIT,        /* type */
         0,                     /* rightshift */
@@ -2366,6 +2409,8 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
       break;
     case BFD_RELOC_HI16_S_PCREL:               r = R_PPC64_REL16_HA;
       break;
+    case BFD_RELOC_PPC64_ADDR64_LOCAL:         r = R_PPC64_ADDR64_LOCAL;
+      break;
     case BFD_RELOC_VTABLE_INHERIT:             r = R_PPC64_GNU_VTINHERIT;
       break;
     case BFD_RELOC_VTABLE_ENTRY:               r = R_PPC64_GNU_VTENTRY;
@@ -2455,6 +2500,29 @@ ppc64_elf_branch_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
                                      + symbol->section->output_section->vma
                                      + symbol->section->output_offset);
     }
+  else
+    {
+      elf_symbol_type *elfsym = (elf_symbol_type *) symbol;
+
+      if (symbol->section->owner != abfd
+         && abiversion (symbol->section->owner) >= 2)
+       {
+         unsigned int i;
+
+         for (i = 0; i < symbol->section->owner->symcount; ++i)
+           {
+             asymbol *symdef = symbol->section->owner->outsymbols[i];
+
+             if (strcmp (symdef->name, symbol->name) == 0)
+               {
+                 elfsym = (elf_symbol_type *) symdef;
+                 break;
+               }
+           }
+       }
+      reloc_entry->addend
+       += PPC64_LOCAL_ENTRY_OFFSET (elfsym->internal_elf_sym.st_other);
+    }
   return bfd_reloc_continue;
 }
 
@@ -3089,15 +3157,19 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
   long count;
   char *names;
   long symcount, codesecsym, codesecsymend, secsymend, opdsymend;
-  asection *opd;
+  asection *opd = NULL;
   bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
   asymbol **syms;
+  int abi = abiversion (abfd);
 
   *ret = NULL;
 
-  opd = bfd_get_section_by_name (abfd, ".opd");
-  if (opd == NULL)
-    return 0;
+  if (abi < 2)
+    {
+      opd = bfd_get_section_by_name (abfd, ".opd");
+      if (opd == NULL && abi == 1)
+       return 0;
+    }
 
   symcount = static_count;
   if (!relocatable)
@@ -3266,20 +3338,18 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
   else
     {
       bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
-      bfd_byte *contents;
+      bfd_byte *contents = NULL;
       size_t size;
       long plt_count = 0;
       bfd_vma glink_vma = 0, resolv_vma = 0;
       asection *dynamic, *glink = NULL, *relplt = NULL;
       arelent *p;
 
-      if (!bfd_malloc_and_get_section (abfd, opd, &contents))
+      if (opd != NULL && !bfd_malloc_and_get_section (abfd, opd, &contents))
        {
+       free_contents_and_exit:
          if (contents)
-           {
-           free_contents_and_exit:
-             free (contents);
-           }
+           free (contents);
          count = -1;
          goto done;
        }
@@ -3328,9 +3398,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
 
              if (dyn.d_tag == DT_PPC64_GLINK)
                {
-                 /* The first glink stub starts at offset 32; see comment in
-                    ppc64_elf_finish_dynamic_sections. */
-                 glink_vma = dyn.d_un.d_val + 32;
+                 /* The first glink stub starts at offset 32; see
+                    comment in ppc64_elf_finish_dynamic_sections. */
+                 glink_vma = dyn.d_un.d_val + GLINK_CALL_STUB_SIZE - 8 * 4;
                  /* The .glink section usually does not survive the final
                     link; search for the section (usually .text) where the
                     glink stubs now reside.  */
@@ -3348,13 +3418,21 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
          /* Determine __glink trampoline by reading the relative branch
             from the first glink stub.  */
          bfd_byte buf[4];
-         if (bfd_get_section_contents (abfd, glink, buf,
-                                       glink_vma + 4 - glink->vma, 4))
+         unsigned int off = 0;
+
+         while (bfd_get_section_contents (abfd, glink, buf,
+                                          glink_vma + off - glink->vma, 4))
            {
              unsigned int insn = bfd_get_32 (abfd, buf);
              insn ^= B_DOT;
              if ((insn & ~0x3fffffc) == 0)
-               resolv_vma = glink_vma + 4 + (insn ^ 0x2000000) - 0x2000000;
+               {
+                 resolv_vma = glink_vma + off + (insn ^ 0x2000000) - 0x2000000;
+                 break;
+               }
+             off += 4;
+             if (off > 4)
+               break;
            }
 
          if (resolv_vma)
@@ -3507,8 +3585,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
              memcpy (names, "@plt", sizeof ("@plt"));
              names += sizeof ("@plt");
              s++;
-             glink_vma += 8;
-             if (i >= 0x8000)
+             if (abi < 2)
+               {
+                 glink_vma += 8;
+                 if (i >= 0x8000)
+                   glink_vma += 4;
+               }
+             else
                glink_vma += 4;
            }
          count += plt_count;
@@ -3559,13 +3642,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
    .
    .
    .   .foo_stub:
-   .           addis   12,2,Lfoo@toc@ha        # in practice, the call stub
-   .           addi    12,12,Lfoo@toc@l        # is slightly optimized, but
-   .           std     2,40(1)                 # this is the general idea
-   .           ld      11,0(12)
-   .           ld      2,8(12)
-   .           mtctr   11
-   .           ld      11,16(12)
+   .           std     2,40(1)                 # in practice, the call stub
+   .           addis   11,2,Lfoo@toc@ha        # is slightly optimized, but
+   .           addi    11,11,Lfoo@toc@l        # this is the general idea
+   .           ld      12,0(11)
+   .           ld      2,8(11)
+   .           mtctr   12
+   .           ld      11,16(11)
    .           bctr
    .
    .           .section .plt
@@ -3657,21 +3740,21 @@ must_be_dyn_reloc (struct bfd_link_info *info,
    ppc_stub_plt_branch:
    Similar to the above, but a 24 bit branch in the stub section won't
    reach its destination.
-   .   addis   %r12,%r2,xxx@toc@ha
-   .   ld      %r11,xxx@toc@l(%r12)
-   .   mtctr   %r11
+   .   addis   %r11,%r2,xxx@toc@ha
+   .   ld      %r12,xxx@toc@l(%r11)
+   .   mtctr   %r12
    .   bctr
 
    ppc_stub_plt_call:
    Used to call a function in a shared library.  If it so happens that
    the plt entry referenced crosses a 64k boundary, then an extra
-   "addi %r12,%r12,xxx@toc@l" will be inserted before the "mtctr".
-   .   addis   %r12,%r2,xxx@toc@ha
+   "addi %r11,%r11,xxx@toc@l" will be inserted before the "mtctr".
    .   std     %r2,40(%r1)
-   .   ld      %r11,xxx+0@toc@l(%r12)
-   .   mtctr   %r11
-   .   ld      %r2,xxx+8@toc@l(%r12)
-   .   ld      %r11,xxx+16@toc@l(%r12)
+   .   addis   %r11,%r2,xxx@toc@ha
+   .   ld      %r12,xxx+0@toc@l(%r11)
+   .   mtctr   %r12
+   .   ld      %r2,xxx+8@toc@l(%r11)
+   .   ld      %r11,xxx+16@toc@l(%r11)
    .   bctr
 
    ppc_stub_long_branch and ppc_stub_plt_branch may also have additional
@@ -3684,11 +3767,11 @@ must_be_dyn_reloc (struct bfd_link_info *info,
 
    A ppc_stub_plt_branch with an r2 offset looks like:
    .   std     %r2,40(%r1)
-   .   addis   %r12,%r2,xxx@toc@ha
-   .   ld      %r11,xxx@toc@l(%r12)
+   .   addis   %r11,%r2,xxx@toc@ha
+   .   ld      %r12,xxx@toc@l(%r11)
    .   addis   %r2,%r2,off@ha
    .   addi    %r2,%r2,off@l
-   .   mtctr   %r11
+   .   mtctr   %r12
    .   bctr
 
    In cases where the "addis" instruction would add zero, the "addis" is
@@ -3702,7 +3785,8 @@ enum ppc_stub_type {
   ppc_stub_plt_branch,
   ppc_stub_plt_branch_r2off,
   ppc_stub_plt_call,
-  ppc_stub_plt_call_r2save
+  ppc_stub_plt_call_r2save,
+  ppc_stub_global_entry
 };
 
 struct ppc_stub_hash_entry {
@@ -3730,6 +3814,9 @@ struct ppc_stub_hash_entry {
   /* Where this stub is being called from, or, in the case of combined
      stub sections, the first input section in the group.  */
   asection *id_sec;
+
+  /* Symbol st_other.  */
+  unsigned char other;
 };
 
 struct ppc_branch_hash_entry {
@@ -3825,12 +3912,8 @@ struct ppc_link_hash_table
   /* Hash table for function prologue tocsave.  */
   htab_t tocsave_htab;
 
-  /* Linker stub bfd.  */
-  bfd *stub_bfd;
-
-  /* Linker call-backs.  */
-  asection * (*add_stub_section) (const char *, asection *);
-  void (*layout_sections_again) (void);
+  /* Various options and other info passed from the linker.  */
+  struct ppc64_elf_params *params;
 
   /* Array to keep track of which stub sections have been created, and
      information on stub grouping.  */
@@ -3860,12 +3943,7 @@ struct ppc_link_hash_table
   /* List of input sections for each output section.  */
   asection **input_list;
 
-  /* Short-cuts to get to dynamic linker sections.  */
-  asection *got;
-  asection *plt;
-  asection *relplt;
-  asection *iplt;
-  asection *reliplt;
+  /* Shortcuts to get to dynamic linker sections.  */
   asection *dynbss;
   asection *relbss;
   asection *glink;
@@ -3882,25 +3960,13 @@ struct ppc_link_hash_table
   bfd_size_type got_reli_size;
 
   /* Statistics.  */
-  unsigned long stub_count[ppc_stub_plt_call_r2save];
+  unsigned long stub_count[ppc_stub_global_entry];
 
   /* Number of stubs against global syms.  */
   unsigned long stub_globals;
 
-  /* Alignment of PLT call stubs.  */
-  unsigned int plt_stub_align:4;
-
-  /* Set if PLT call stubs should load r11.  */
-  unsigned int plt_static_chain:1;
-
-  /* Set if PLT call stubs need a read-read barrier.  */
-  unsigned int plt_thread_safe:1;
-
-  /* Set if we should emit symbols for stubs.  */
-  unsigned int emit_stub_syms:1;
-
-  /* Set if __tls_get_addr optimization should not be done.  */
-  unsigned int no_tls_get_addr_opt:1;
+  /* Set if we're linking code with function descriptors.  */
+  unsigned int opd_abi:1;
 
   /* Support for multiple toc sections.  */
   unsigned int do_multi_toc:1;
@@ -3911,7 +3977,7 @@ struct ppc_link_hash_table
   /* Set on error.  */
   unsigned int stub_error:1;
 
-  /* Temp used by ppc64_elf_process_dot_syms.  */
+  /* Temp used by ppc64_elf_before_check_relocs.  */
   unsigned int twiddled_syms:1;
 
   /* Incremented every time we size stubs.  */
@@ -3985,7 +4051,9 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
       eh->target_value = 0;
       eh->target_section = NULL;
       eh->h = NULL;
+      eh->plt_ent = NULL;
       eh->id_sec = NULL;
+      eh->other = 0;
     }
 
   return entry;
@@ -4097,6 +4165,21 @@ tocsave_htab_eq (const void *p1, const void *p2)
   return e1->sec == e2->sec && e1->offset == e2->offset;
 }
 
+/* Destroy a ppc64 ELF linker hash table.  */
+
+static void
+ppc64_elf_link_hash_table_free (bfd *obfd)
+{
+  struct ppc_link_hash_table *htab;
+
+  htab = (struct ppc_link_hash_table *) obfd->link.hash;
+  if (htab->tocsave_htab)
+    htab_delete (htab->tocsave_htab);
+  bfd_hash_table_free (&htab->branch_hash_table);
+  bfd_hash_table_free (&htab->stub_hash_table);
+  _bfd_elf_link_hash_table_free (obfd);
+}
+
 /* Create a ppc64 ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
@@ -4120,19 +4203,30 @@ ppc64_elf_link_hash_table_create (bfd *abfd)
   /* Init the stub hash table too.  */
   if (!bfd_hash_table_init (&htab->stub_hash_table, stub_hash_newfunc,
                            sizeof (struct ppc_stub_hash_entry)))
-    return NULL;
+    {
+      _bfd_elf_link_hash_table_free (abfd);
+      return NULL;
+    }
 
   /* And the branch hash table.  */
   if (!bfd_hash_table_init (&htab->branch_hash_table, branch_hash_newfunc,
                            sizeof (struct ppc_branch_hash_entry)))
-    return NULL;
+    {
+      bfd_hash_table_free (&htab->stub_hash_table);
+      _bfd_elf_link_hash_table_free (abfd);
+      return NULL;
+    }
 
   htab->tocsave_htab = htab_try_create (1024,
                                        tocsave_htab_hash,
                                        tocsave_htab_eq,
                                        NULL);
   if (htab->tocsave_htab == NULL)
-    return NULL;
+    {
+      ppc64_elf_link_hash_table_free (abfd);
+      return NULL;
+    }
+  htab->elf.root.hash_table_free = ppc64_elf_link_hash_table_free;
 
   /* Initializing two fields of the union is just cosmetic.  We really
      only care about glist, but when compiled on a 32-bit host the
@@ -4150,20 +4244,6 @@ ppc64_elf_link_hash_table_create (bfd *abfd)
   return &htab->elf.root;
 }
 
-/* Free the derived linker hash table.  */
-
-static void
-ppc64_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
-{
-  struct ppc_link_hash_table *htab = (struct ppc_link_hash_table *) hash;
-
-  bfd_hash_table_free (&htab->stub_hash_table);
-  bfd_hash_table_free (&htab->branch_hash_table);
-  if (htab->tocsave_htab)
-    htab_delete (htab->tocsave_htab);
-  _bfd_elf_link_hash_table_free (hash);
-}
-
 /* Create sections for linker generated code.  */
 
 static bfd_boolean
@@ -4203,18 +4283,17 @@ create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
     }
 
   flags = SEC_ALLOC | SEC_LINKER_CREATED;
-  htab->iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
-  if (htab->iplt == NULL
-      || ! bfd_set_section_alignment (dynobj, htab->iplt, 3))
+  htab->elf.iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
+  if (htab->elf.iplt == NULL
+      || ! bfd_set_section_alignment (dynobj, htab->elf.iplt, 3))
     return FALSE;
 
   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
           | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-  htab->reliplt = bfd_make_section_anyway_with_flags (dynobj,
-                                                     ".rela.iplt",
-                                                     flags);
-  if (htab->reliplt == NULL
-      || ! bfd_set_section_alignment (dynobj, htab->reliplt, 3))
+  htab->elf.irelplt
+    = bfd_make_section_anyway_with_flags (dynobj, ".rela.iplt", flags);
+  if (htab->elf.irelplt == NULL
+      || ! bfd_set_section_alignment (dynobj, htab->elf.irelplt, 3))
     return FALSE;
 
   /* Create branch lookup table for plt_branch stubs.  */
@@ -4244,11 +4323,12 @@ create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
 /* Satisfy the ELF linker by filling in some fields in our fake bfd.  */
 
 bfd_boolean
-ppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
+ppc64_elf_init_stub_bfd (struct bfd_link_info *info,
+                        struct ppc64_elf_params *params)
 {
   struct ppc_link_hash_table *htab;
 
-  elf_elfheader (abfd)->e_ident[EI_CLASS] = ELFCLASS64;
+  elf_elfheader (params->stub_bfd)->e_ident[EI_CLASS] = ELFCLASS64;
 
 /* Always hook our dynamic sections into the first bfd, which is the
    linker created stub bfd.  This ensures that the GOT header is at
@@ -4256,8 +4336,8 @@ ppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
   htab = ppc_hash_table (info);
   if (htab == NULL)
     return FALSE;
-  htab->stub_bfd = abfd;
-  htab->elf.dynobj = abfd;
+  htab->elf.dynobj = params->stub_bfd;
+  htab->params = params;
 
   if (info->relocatable)
     return TRUE;
@@ -4382,13 +4462,13 @@ ppc_add_stub (const char *stub_name,
 
          namelen = strlen (link_sec->name);
          len = namelen + sizeof (STUB_SUFFIX);
-         s_name = bfd_alloc (htab->stub_bfd, len);
+         s_name = bfd_alloc (htab->params->stub_bfd, len);
          if (s_name == NULL)
            return NULL;
 
          memcpy (s_name, link_sec->name, namelen);
          memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
-         stub_sec = (*htab->add_stub_section) (s_name, link_sec);
+         stub_sec = (*htab->params->add_stub_section) (s_name, link_sec);
          if (stub_sec == NULL)
            return NULL;
          htab->stub_group[link_sec->id].stub_sec = stub_sec;
@@ -4427,15 +4507,9 @@ create_got_section (bfd *abfd, struct bfd_link_info *info)
   if (htab == NULL)
     return FALSE;
 
-  if (!htab->got)
-    {
-      if (! _bfd_elf_create_got_section (htab->elf.dynobj, info))
-       return FALSE;
-
-      htab->got = bfd_get_linker_section (htab->elf.dynobj, ".got");
-      if (!htab->got)
-       abort ();
-    }
+  if (!htab->elf.sgot
+      && !_bfd_elf_create_got_section (htab->elf.dynobj, info))
+    return FALSE;
 
   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
           | SEC_LINKER_CREATED);
@@ -4470,15 +4544,11 @@ ppc64_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   if (htab == NULL)
     return FALSE;
 
-  if (!htab->got)
-    htab->got = bfd_get_linker_section (dynobj, ".got");
-  htab->plt = bfd_get_linker_section (dynobj, ".plt");
-  htab->relplt = bfd_get_linker_section (dynobj, ".rela.plt");
   htab->dynbss = bfd_get_linker_section (dynobj, ".dynbss");
   if (!info->shared)
     htab->relbss = bfd_get_linker_section (dynobj, ".rela.bss");
 
-  if (!htab->got || !htab->plt || !htab->relplt || !htab->dynbss
+  if (!htab->elf.sgot || !htab->elf.splt || !htab->elf.srelplt || !htab->dynbss
       || (!info->shared && !htab->relbss))
     abort ();
 
@@ -4573,6 +4643,7 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
   edir->elf.ref_regular |= eind->elf.ref_regular;
   edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
   edir->elf.needs_plt |= eind->elf.needs_plt;
+  edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
 
   /* Copy over any dynamic relocs we may have on the indirect sym.  */
   if (eind->dyn_relocs != NULL)
@@ -4731,29 +4802,68 @@ static bfd_boolean
 ppc64_elf_add_symbol_hook (bfd *ibfd,
                           struct bfd_link_info *info,
                           Elf_Internal_Sym *isym,
-                          const char **name ATTRIBUTE_UNUSED,
+                          const char **name,
                           flagword *flags ATTRIBUTE_UNUSED,
                           asection **sec,
-                          bfd_vma *value ATTRIBUTE_UNUSED)
+                          bfd_vma *value)
 {
-  if ((ibfd->flags & DYNAMIC) == 0
-      && ELF_ST_BIND (isym->st_info) == STB_GNU_UNIQUE)
+  if ((ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
+       || ELF_ST_BIND (isym->st_info) == STB_GNU_UNIQUE)
+      && (ibfd->flags & DYNAMIC) == 0
+      && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
     elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
 
-  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+  if (*sec != NULL
+      && strcmp ((*sec)->name, ".opd") == 0)
     {
-      if ((ibfd->flags & DYNAMIC) == 0)
-       elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+      asection *code_sec;
+
+      if (!(ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
+           || ELF_ST_TYPE (isym->st_info) == STT_FUNC))
+       isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
+
+      /* If the symbol is a function defined in .opd, and the function
+        code is in a discarded group, let it appear to be undefined.  */
+      if (!info->relocatable
+         && (*sec)->reloc_count != 0
+         && opd_entry_value (*sec, *value, &code_sec, NULL,
+                             FALSE) != (bfd_vma) -1
+         && discarded_section (code_sec))
+       {
+         *sec = bfd_und_section_ptr;
+         isym->st_shndx = SHN_UNDEF;
+       }
+    }
+
+  if ((STO_PPC64_LOCAL_MASK & isym->st_other) != 0)
+    {
+      if (abiversion (ibfd) == 0)
+       set_abiversion (ibfd, 2);
+      else if (abiversion (ibfd) == 1)
+       {
+         info->callbacks->einfo (_("%P: symbol '%s' has invalid st_other"
+                                   " for ABI version 1\n"), name);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
     }
-  else if (ELF_ST_TYPE (isym->st_info) == STT_FUNC)
-    ;
-  else if (*sec != NULL
-          && strcmp ((*sec)->name, ".opd") == 0)
-    isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
 
   return TRUE;
 }
 
+/* Merge non-visibility st_other attributes: local entry point.  */
+
+static void
+ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
+                                 const Elf_Internal_Sym *isym,
+                                 bfd_boolean definition,
+                                 bfd_boolean dynamic)
+{
+  if (definition && !dynamic)
+    h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
+               | ELF_ST_VISIBILITY (h->other));
+}
+
 /* This function makes an old ABI object reference to ".bar" cause the
    inclusion of a new ABI object archive that defines "bar".
    NAME is a symbol defined in an archive.  Return a symbol in the hash
@@ -4857,13 +4967,53 @@ add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
   return TRUE;
 }
 
-/* Process list of dot-symbols we made in link_hash_newfunc.  */
+/* Set up opd section info and abiversion for IBFD, and process list
+   of dot-symbols we made in link_hash_newfunc.  */
 
 static bfd_boolean
-ppc64_elf_process_dot_syms (bfd *ibfd, struct bfd_link_info *info)
+ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
   struct ppc_link_hash_entry **p, *eh;
+  asection *opd = bfd_get_section_by_name (ibfd, ".opd");
+
+  if (opd != NULL && opd->size != 0)
+    {
+      if (abiversion (ibfd) == 0)
+       set_abiversion (ibfd, 1);
+      else if (abiversion (ibfd) == 2)
+       {
+         info->callbacks->einfo (_("%P: %B .opd not allowed in ABI"
+                                   " version %d\n"),
+                                 ibfd, abiversion (ibfd));
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+
+      if ((ibfd->flags & DYNAMIC) == 0
+         && (opd->flags & SEC_RELOC) != 0
+         && opd->reloc_count != 0
+         && !bfd_is_abs_section (opd->output_section))
+       {
+         /* Garbage collection needs some extra help with .opd sections.
+            We don't want to necessarily keep everything referenced by
+            relocs in .opd, as that would keep all functions.  Instead,
+            if we reference an .opd symbol (a function descriptor), we
+            want to keep the function code symbol's section.  This is
+            easy for global symbols, but for local syms we need to keep
+            information about the associated function section.  */
+         bfd_size_type amt;
+         asection **opd_sym_map;
+
+         amt = opd->size * sizeof (*opd_sym_map) / 8;
+         opd_sym_map = bfd_zalloc (ibfd, amt);
+         if (opd_sym_map == NULL)
+           return FALSE;
+         ppc64_elf_section_data (opd)->u.opd.func_sec = opd_sym_map;
+         BFD_ASSERT (ppc64_elf_section_data (opd)->sec_type == sec_normal);
+         ppc64_elf_section_data (opd)->sec_type = sec_opd;
+       }
+    }
 
   if (!is_ppc64_elf (info->output_bfd))
     return TRUE;
@@ -4871,21 +5021,29 @@ ppc64_elf_process_dot_syms (bfd *ibfd, struct bfd_link_info *info)
   if (htab == NULL)
     return FALSE;
 
-  if (is_ppc64_elf (ibfd))
+  /* For input files without an explicit abiversion in e_flags
+     we should have flagged any with symbol st_other bits set
+     as ELFv1 and above flagged those with .opd as ELFv2.
+     Set the output abiversion if not yet set, and for any input
+     still ambiguous, take its abiversion from the output.
+     Differences in ABI are reported later.  */
+  if (abiversion (info->output_bfd) == 0)
+    set_abiversion (info->output_bfd, abiversion (ibfd));
+  else if (abiversion (ibfd) == 0)
+    set_abiversion (ibfd, abiversion (info->output_bfd));
+
+  p = &htab->dot_syms;
+  while ((eh = *p) != NULL)
     {
-      p = &htab->dot_syms;
-      while ((eh = *p) != NULL)
-       {
-         *p = NULL;
-         if (&eh->elf == htab->elf.hgot)
-           ;
-         else if (htab->elf.hgot == NULL
-                  && strcmp (eh->elf.root.root.string, ".TOC.") == 0)
-           htab->elf.hgot = &eh->elf;
-         else if (!add_symbol_adjust (eh, info))
-           return FALSE;
-         p = &eh->u.next_dot_sym;
-       }
+      *p = NULL;
+      if (&eh->elf == htab->elf.hgot)
+       ;
+      else if (htab->elf.hgot == NULL
+              && strcmp (eh->elf.root.root.string, ".TOC.") == 0)
+       htab->elf.hgot = &eh->elf;
+      else if (!add_symbol_adjust (eh, info))
+       return FALSE;
+      p = &eh->u.next_dot_sym;
     }
 
   /* Clear the list for non-ppc64 input files.  */
@@ -4936,10 +5094,8 @@ ppc64_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
       && (sec->owner->flags & (EXEC_P | DYNAMIC)) != 0
       && is_ppc64_elf (sec->owner))
     {
-      asection *got = bfd_get_section_by_name (sec->owner, ".got");
-      if (got != NULL
-         && got->size >= elf_backend_got_header_size
-         && bfd_get_section_by_name (sec->owner, ".opd") != NULL)
+      if (abiversion (sec->owner) >= 2
+         || bfd_get_section_by_name (sec->owner, ".opd") != NULL)
        sec->has_toc_reloc = 1;
     }
   _bfd_elf_link_just_syms (sec, info);
@@ -5078,25 +5234,9 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   sym_hashes = elf_sym_hashes (abfd);
   sreloc = NULL;
   opd_sym_map = NULL;
-  if (strcmp (sec->name, ".opd") == 0)
-    {
-      /* Garbage collection needs some extra help with .opd sections.
-        We don't want to necessarily keep everything referenced by
-        relocs in .opd, as that would keep all functions.  Instead,
-        if we reference an .opd symbol (a function descriptor), we
-        want to keep the function code symbol's section.  This is
-        easy for global symbols, but for local syms we need to keep
-        information about the associated function section.  */
-      bfd_size_type amt;
-
-      amt = sec->size * sizeof (*opd_sym_map) / 8;
-      opd_sym_map = bfd_zalloc (abfd, amt);
-      if (opd_sym_map == NULL)
-       return FALSE;
-      ppc64_elf_section_data (sec)->u.opd.func_sec = opd_sym_map;
-      BFD_ASSERT (ppc64_elf_section_data (sec)->sec_type == sec_normal);
-      ppc64_elf_section_data (sec)->sec_type = sec_opd;
-    }
+  if (ppc64_elf_section_data (sec) != NULL
+      && ppc64_elf_section_data (sec)->sec_type == sec_opd)
+    opd_sym_map = ppc64_elf_section_data (sec)->u.opd.func_sec;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -5197,7 +5337,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_GOT_TPREL16_LO_DS:
        case R_PPC64_GOT_TPREL16_HI:
        case R_PPC64_GOT_TPREL16_HA:
-         if (!info->executable)
+         if (info->shared)
            info->flags |= DF_STATIC_TLS;
          tls_type = TLS_TLS | TLS_TPREL;
          goto dogottls;
@@ -5267,6 +5407,14 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
            if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
                                        rel->r_addend, tls_type))
              return FALSE;
+
+         /* We may also need a plt entry if the symbol turns out to be
+            an ifunc.  */
+         if (h != NULL && !info->shared && abiversion (abfd) != 1)
+           {
+             if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
+               return FALSE;
+           }
          break;
 
        case R_PPC64_PLT16_HA:
@@ -5327,6 +5475,21 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_REL16_HA:
          break;
 
+         /* Not supported as a dynamic relocation.  */
+       case R_PPC64_ADDR64_LOCAL:
+         if (info->shared)
+           {
+             if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
+               ppc_howto_init ();
+             info->callbacks->einfo (_("%P: %H: %s reloc unsupported "
+                                       "in shared libraries and PIEs.\n"),
+                                     abfd, sec, rel->r_offset,
+                                     ppc64_elf_howto_table[r_type]->name);
+             bfd_set_error (bfd_error_bad_value);
+             return FALSE;
+           }
+         break;
+
        case R_PPC64_TOC16:
        case R_PPC64_TOC16_DS:
          htab->do_multi_toc = 1;
@@ -5404,7 +5567,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
        case R_PPC64_TPREL64:
          tls_type = TLS_EXPLICIT | TLS_TLS | TLS_TPREL;
-         if (!info->executable)
+         if (info->shared)
            info->flags |= DF_STATIC_TLS;
          goto dotlstoc;
 
@@ -5482,8 +5645,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_TPREL16_HIGHESTA:
          if (info->shared)
            {
-             if (!info->executable)
-               info->flags |= DF_STATIC_TLS;
+             info->flags |= DF_STATIC_TLS;
              goto dodyn;
            }
          break;
@@ -5519,12 +5681,6 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
            }
          /* Fall through.  */
 
-       case R_PPC64_REL30:
-       case R_PPC64_REL32:
-       case R_PPC64_REL64:
-       case R_PPC64_ADDR14:
-       case R_PPC64_ADDR14_BRNTAKEN:
-       case R_PPC64_ADDR14_BRTAKEN:
        case R_PPC64_ADDR16:
        case R_PPC64_ADDR16_DS:
        case R_PPC64_ADDR16_HA:
@@ -5537,6 +5693,23 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_ADDR16_HIGHESTA:
        case R_PPC64_ADDR16_LO:
        case R_PPC64_ADDR16_LO_DS:
+         if (h != NULL && !info->shared && abiversion (abfd) != 1
+             && rel->r_addend == 0)
+           {
+             /* We may need a .plt entry if this reloc refers to a
+                function in a shared lib.  */
+             if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
+               return FALSE;
+             h->pointer_equality_needed = 1;
+           }
+         /* Fall through.  */
+
+       case R_PPC64_REL30:
+       case R_PPC64_REL32:
+       case R_PPC64_REL64:
+       case R_PPC64_ADDR14:
+       case R_PPC64_ADDR14_BRNTAKEN:
+       case R_PPC64_ADDR14_BRTAKEN:
        case R_PPC64_ADDR24:
        case R_PPC64_ADDR32:
        case R_PPC64_UADDR16:
@@ -5674,8 +5847,74 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   return TRUE;
 }
 
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
+static bfd_boolean
+ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+  unsigned long iflags, oflags;
+
+  if ((ibfd->flags & BFD_LINKER_CREATED) != 0)
+    return TRUE;
+
+  if (!is_ppc64_elf (ibfd) || !is_ppc64_elf (obfd))
+    return TRUE;
+
+  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+    return FALSE;
+
+  iflags = elf_elfheader (ibfd)->e_flags;
+  oflags = elf_elfheader (obfd)->e_flags;
+
+  if (iflags & ~EF_PPC64_ABI)
+    {
+      (*_bfd_error_handler)
+       (_("%B uses unknown e_flags 0x%lx"), ibfd, iflags);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+  else if (iflags != oflags && iflags != 0)
+    {
+      (*_bfd_error_handler)
+       (_("%B: ABI version %ld is not compatible with ABI version %ld output"),
+        ibfd, iflags, oflags);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
+  /* Merge Tag_compatibility attributes and any common GNU ones.  */
+  _bfd_elf_merge_object_attributes (ibfd, obfd);
+
+  return TRUE;
+}
+
+static bfd_boolean
+ppc64_elf_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+  /* Print normal ELF private data.  */
+  _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+  if (elf_elfheader (abfd)->e_flags != 0)
+    {
+      FILE *file = ptr;
+
+      /* xgettext:c-format */
+      fprintf (file, _("private flags = 0x%lx:"),
+              elf_elfheader (abfd)->e_flags);
+
+      if ((elf_elfheader (abfd)->e_flags & EF_PPC64_ABI) != 0)
+       fprintf (file, _(" [abiv%ld]"),
+                elf_elfheader (abfd)->e_flags & EF_PPC64_ABI);
+      fputc ('\n', file);
+    }
+
+  return TRUE;
+}
+
 /* OFFSET in OPD_SEC specifies a function descriptor.  Return the address
-   of the code entry point, and its section.  */
+   of the code entry point, and its section, which must be in the same
+   object as OPD_SEC.  Returns (bfd_vma) -1 on error.  */
 
 static bfd_vma
 opd_entry_value (asection *opd_sec,
@@ -5758,32 +5997,10 @@ opd_entry_value (asection *opd_sec,
              && ELF64_R_TYPE ((look + 1)->r_info) == R_PPC64_TOC)
            {
              unsigned long symndx = ELF64_R_SYM (look->r_info);
-             asection *sec;
-
-             if (symndx < symtab_hdr->sh_info
-                 || elf_sym_hashes (opd_bfd) == NULL)
-               {
-                 Elf_Internal_Sym *sym;
+             asection *sec = NULL;
 
-                 sym = (Elf_Internal_Sym *) symtab_hdr->contents;
-                 if (sym == NULL)
-                   {
-                     size_t symcnt = symtab_hdr->sh_info;
-                     if (elf_sym_hashes (opd_bfd) == NULL)
-                       symcnt = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
-                     sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr, symcnt,
-                                                 0, NULL, NULL, NULL);
-                     if (sym == NULL)
-                       break;
-                     symtab_hdr->contents = (bfd_byte *) sym;
-                   }
-
-                 sym += symndx;
-                 val = sym->st_value;
-                 sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
-                 BFD_ASSERT ((sec->flags & SEC_MERGE) == 0);
-               }
-             else
+             if (symndx >= symtab_hdr->sh_info
+                 && elf_sym_hashes (opd_bfd) != NULL)
                {
                  struct elf_link_hash_entry **sym_hashes;
                  struct elf_link_hash_entry *rh;
@@ -5797,24 +6014,48 @@ opd_entry_value (asection *opd_sec,
                                  || rh->root.type == bfd_link_hash_defweak);
                      val = rh->root.u.def.value;
                      sec = rh->root.u.def.section;
+                     if (sec->owner != opd_bfd)
+                       {
+                         sec = NULL;
+                         val = (bfd_vma) -1;
+                       }
+                   }
+               }
+
+             if (sec == NULL)
+               {
+                 Elf_Internal_Sym *sym;
+
+                 if (symndx < symtab_hdr->sh_info)
+                   {
+                     sym = (Elf_Internal_Sym *) symtab_hdr->contents;
+                     if (sym == NULL)
+                       {
+                         size_t symcnt = symtab_hdr->sh_info;
+                         sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr,
+                                                     symcnt, 0,
+                                                     NULL, NULL, NULL);
+                         if (sym == NULL)
+                           break;
+                         symtab_hdr->contents = (bfd_byte *) sym;
+                       }
+                     sym += symndx;
                    }
                  else
                    {
-                     /* Handle the odd case where we can be called
-                        during bfd_elf_link_add_symbols before the
-                        symbol hashes have been fully populated.  */
-                     Elf_Internal_Sym *sym;
-
-                     sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr, 1,
-                                                 symndx, NULL, NULL, NULL);
+                     sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr,
+                                                 1, symndx,
+                                                 NULL, NULL, NULL);
                      if (sym == NULL)
                        break;
-
-                     val = sym->st_value;
-                     sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
-                     free (sym);
                    }
+                 sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
+                 if (sec == NULL)
+                   break;
+                 BFD_ASSERT ((sec->flags & SEC_MERGE) == 0);
+                 val = sym->st_value;
                }
+
              val += look->r_addend;
              if (code_off != NULL)
                *code_off = val;
@@ -5825,7 +6066,7 @@ opd_entry_value (asection *opd_sec,
                  else
                    *code_sec = sec;
                }
-             if (sec != NULL && sec->output_section != NULL)
+             if (sec->output_section != NULL)
                val += sec->output_section->vma + sec->output_offset;
            }
          break;
@@ -5979,6 +6220,7 @@ ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
   struct bfd_link_info *info = (struct bfd_link_info *) inf;
   struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
   struct ppc_link_hash_entry *fdh;
+  struct bfd_elf_dynamic_list *d = info->dynamic_list;
 
   /* Dynamic linking info is on the func descriptor sym.  */
   fdh = defined_func_desc (eh);
@@ -5988,10 +6230,14 @@ ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
   if ((eh->elf.root.type == bfd_link_hash_defined
        || eh->elf.root.type == bfd_link_hash_defweak)
       && (eh->elf.ref_dynamic
-         || (!info->executable
-             && eh->elf.def_regular
+         || (eh->elf.def_regular
              && ELF_ST_VISIBILITY (eh->elf.other) != STV_INTERNAL
              && ELF_ST_VISIBILITY (eh->elf.other) != STV_HIDDEN
+             && (!info->executable
+                 || info->export_dynamic
+                 || (eh->elf.dynamic
+                     && d != NULL
+                     && (*d->match) (&d->head, NULL, eh->elf.root.root.string)))
              && (strchr (eh->elf.root.root.string, ELF_VER_CHR) != NULL
                  || !bfd_hide_sym_by_version (info->version_info,
                                               eh->elf.root.root.string)))))
@@ -6356,7 +6602,7 @@ static bfd_byte *
 savegpr0_tail (bfd *abfd, bfd_byte *p, int r)
 {
   p = savegpr0 (abfd, p, r);
-  bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
+  bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
   p = p + 4;
   bfd_put_32 (abfd, BLR, p);
   return p + 4;
@@ -6372,7 +6618,7 @@ restgpr0 (bfd *abfd, bfd_byte *p, int r)
 static bfd_byte *
 restgpr0_tail (bfd *abfd, bfd_byte *p, int r)
 {
-  bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
+  bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
   p = p + 4;
   p = restgpr0 (abfd, p, r);
   bfd_put_32 (abfd, MTLR_R0, p);
@@ -6427,7 +6673,7 @@ static bfd_byte *
 savefpr0_tail (bfd *abfd, bfd_byte *p, int r)
 {
   p = savefpr (abfd, p, r);
-  bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
+  bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
   p = p + 4;
   bfd_put_32 (abfd, BLR, p);
   return p + 4;
@@ -6443,7 +6689,7 @@ restfpr (bfd *abfd, bfd_byte *p, int r)
 static bfd_byte *
 restfpr0_tail (bfd *abfd, bfd_byte *p, int r)
 {
-  bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
+  bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
   p = p + 4;
   p = restfpr (abfd, p, r);
   bfd_put_32 (abfd, MTLR_R0, p);
@@ -6672,7 +6918,18 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
 
   if (!info->relocatable
       && htab->elf.hgot != NULL)
-    _bfd_elf_link_hash_hide_symbol (info, htab->elf.hgot, TRUE);
+    {
+      _bfd_elf_link_hash_hide_symbol (info, htab->elf.hgot, TRUE);
+      /* Make .TOC. defined so as to prevent it being made dynamic.
+        The wrong value here is fixed later in ppc64_elf_set_toc.  */
+      htab->elf.hgot->type = STT_OBJECT;
+      htab->elf.hgot->root.type = bfd_link_hash_defined;
+      htab->elf.hgot->root.u.def.value = 0;
+      htab->elf.hgot->root.u.def.section = bfd_abs_section_ptr;
+      htab->elf.hgot->def_regular = 1;
+      htab->elf.hgot->other = ((htab->elf.hgot->other & ~ELF_ST_VISIBILITY (-1))
+                              | STV_HIDDEN);
+    }
 
   if (htab->sfpr == NULL)
     /* We don't have any relocs.  */
@@ -6680,7 +6937,7 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
 
   /* Provide any missing _save* and _rest* functions.  */
   htab->sfpr->size = 0;
-  if (!info->relocatable)
+  if (htab->params->save_restore_funcs)
     for (i = 0; i < sizeof (funcs) / sizeof (funcs[0]); i++)
       if (!sfpr_define (info, &funcs[i]))
        return FALSE;
@@ -6693,6 +6950,25 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
   return TRUE;
 }
 
+/* Return true if we have dynamic relocs that apply to read-only sections.  */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct ppc_link_hash_entry *eh;
+  struct elf_dyn_relocs *p;
+
+  eh = (struct ppc_link_hash_entry *) h;
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+       return TRUE;
+    }
+  return FALSE;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -6729,6 +7005,39 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
        {
          h->plt.plist = NULL;
          h->needs_plt = 0;
+         h->pointer_equality_needed = 0;
+       }
+      else if (abiversion (info->output_bfd) == 2)
+       {
+         /* Taking a function's address in a read/write section
+            doesn't require us to define the function symbol in the
+            executable on a global entry stub.  A dynamic reloc can
+            be used instead.  */
+         if (h->pointer_equality_needed
+             && h->type != STT_GNU_IFUNC
+             && !readonly_dynrelocs (h))
+           {
+             h->pointer_equality_needed = 0;
+             h->non_got_ref = 0;
+           }
+
+         /* After adjust_dynamic_symbol, non_got_ref set in the
+            non-shared case means that we have allocated space in
+            .dynbss for the symbol and thus dyn_relocs for this
+            symbol should be discarded.
+            If we get here we know we are making a PLT entry for this
+            symbol, and in an executable we'd normally resolve
+            relocations against this symbol to the PLT entry.  Allow
+            dynamic relocs if the reference is weak, and the dynamic
+            relocs will not cause text relocation.  */
+         else if (!h->ref_regular_nonweak
+                  && h->non_got_ref
+                  && h->type != STT_GNU_IFUNC
+                  && !readonly_dynrelocs (h))
+           h->non_got_ref = 0;
+
+         /* If making a plt entry, then we don't need copy relocs.  */
+         return TRUE;
        }
     }
   else
@@ -6764,26 +7073,12 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (!h->def_dynamic || !h->ref_regular || h->def_regular)
     return TRUE;
 
-  if (ELIMINATE_COPY_RELOCS)
+  /* If we didn't find any dynamic relocs in read-only sections, then
+     we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
+  if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (h))
     {
-      struct ppc_link_hash_entry * eh;
-      struct elf_dyn_relocs *p;
-
-      eh = (struct ppc_link_hash_entry *) h;
-      for (p = eh->dyn_relocs; p != NULL; p = p->next)
-       {
-         s = p->sec->output_section;
-         if (s != NULL && (s->flags & SEC_READONLY) != 0)
-           break;
-       }
-
-      /* If we didn't find any dynamic relocs in read-only sections, then
-        we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
-      if (p == NULL)
-       {
-         h->non_got_ref = 0;
-         return TRUE;
-       }
+      h->non_got_ref = 0;
+      return TRUE;
     }
 
   if (h->plt.plist != NULL)
@@ -7299,13 +7594,18 @@ dec_dynrel_count (bfd_vma r_info,
    applications.  */
 
 bfd_boolean
-ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
+ppc64_elf_edit_opd (struct bfd_link_info *info)
 {
   bfd *ibfd;
   bfd_boolean some_edited = FALSE;
   asection *need_pad = NULL;
+  struct ppc_link_hash_table *htab;
 
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  htab = ppc_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       asection *sec;
       Elf_Internal_Rela *relstart, *rel, *relend;
@@ -7456,7 +7756,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
            goto broken_opd;
        }
 
-      add_aux_fields = non_overlapping && cnt_16b > 0;
+      add_aux_fields = htab->params->non_overlapping_opd && cnt_16b > 0;
 
       if (need_edit || add_aux_fields)
        {
@@ -7547,12 +7847,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
                  if (h != NULL
                      && h->root.root.string[0] == '.')
                    {
-                     struct ppc_link_hash_table *htab;
-
-                     htab = ppc_hash_table (info);
-                     if (htab != NULL)
-                       fdh = lookup_fdh ((struct ppc_link_hash_entry *) h,
-                                         htab);
+                     fdh = lookup_fdh ((struct ppc_link_hash_entry *) h, htab);
                      if (fdh != NULL
                          && fdh->elf.root.type != bfd_link_hash_defined
                          && fdh->elf.root.type != bfd_link_hash_defweak)
@@ -7701,9 +7996,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
 /* Set htab->tls_get_addr and call the generic ELF tls_setup function.  */
 
 asection *
-ppc64_elf_tls_setup (struct bfd_link_info *info,
-                    int no_tls_get_addr_opt,
-                    int *no_multi_toc)
+ppc64_elf_tls_setup (struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
 
@@ -7711,10 +8004,13 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
   if (htab == NULL)
     return NULL;
 
-  if (*no_multi_toc)
+  if (abiversion (info->output_bfd) == 1)
+    htab->opd_abi = 1;
+
+  if (htab->params->no_multi_toc)
     htab->do_multi_toc = 0;
   else if (!htab->do_multi_toc)
-    *no_multi_toc = 1;
+    htab->params->no_multi_toc = 1;
 
   htab->tls_get_addr = ((struct ppc_link_hash_entry *)
                        elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
@@ -7725,7 +8021,7 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
   htab->tls_get_addr_fd = ((struct ppc_link_hash_entry *)
                           elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
                                                 FALSE, FALSE, TRUE));
-  if (!no_tls_get_addr_opt)
+  if (!htab->params->no_tls_get_addr_opt)
     {
       struct elf_link_hash_entry *opt, *opt_fd, *tga, *tga_fd;
 
@@ -7793,9 +8089,8 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
            }
        }
       else
-       no_tls_get_addr_opt = TRUE;
+       htab->params->no_tls_get_addr_opt = TRUE;
     }
-  htab->no_tls_get_addr_opt = no_tls_get_addr_opt;
   return _bfd_elf_tls_setup (info->output_bfd, info);
 }
 
@@ -7857,7 +8152,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
      and plt refcounts.  */
   toc_ref = NULL;
   for (pass = 0; pass < 2; ++pass)
-    for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+    for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
       {
        Elf_Internal_Sym *locsyms = NULL;
        asection *toc = bfd_get_section_by_name (ibfd, ".toc");
@@ -7872,7 +8167,10 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
              relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
                                                    info->keep_memory);
              if (relstart == NULL)
-               return FALSE;
+               {
+                 free (toc_ref);
+                 return FALSE;
+               }
 
              relend = relstart + sec->reloc_count;
              for (rel = relstart; rel < relend; rel++)
@@ -8045,7 +8343,10 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
                      else
                        value = sym->st_value;
                      value += rel->r_addend;
-                     BFD_ASSERT (value < toc->size && value % 8 == 0);
+                     if (value % 8 != 0)
+                       continue;
+                     BFD_ASSERT (value < toc->size
+                                 && toc->output_offset % 8 == 0);
                      toc_ref_index = (value + toc->output_offset) / 8;
                      if (r_type == R_PPC64_TLS
                          || r_type == R_PPC64_TLSGD
@@ -8351,7 +8652,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
 
   htab->do_toc_opt = 1;
   toc_inf.global_toc_syms = TRUE;
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       asection *toc, *sec;
       Elf_Internal_Shdr *symtab_hdr;
@@ -8494,7 +8795,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
                  || discarded_section (sym_sec))
                continue;
 
-             if (!SYMBOL_CALLS_LOCAL (info, h))
+             if (!SYMBOL_REFERENCES_LOCAL (info, h))
                continue;
 
              if (h != NULL)
@@ -8580,7 +8881,10 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
          relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
                                                info->keep_memory);
          if (relstart == NULL)
-           goto error_ret;
+           {
+             free (used);
+             goto error_ret;
+           }
 
          /* Mark toc entries referenced as used.  */
          do
@@ -9023,7 +9327,7 @@ allocate_got (struct elf_link_hash_entry *h,
   dyn = htab->elf.dynamic_sections_created;
   if (h->type == STT_GNU_IFUNC)
     {
-      htab->reliplt->size += rentsize;
+      htab->elf.irelplt->size += rentsize;
       htab->got_reli_size += rentsize;
     }
   else if ((info->shared
@@ -9090,35 +9394,40 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
            if (!htab->elf.dynamic_sections_created
                || h->dynindx == -1)
              {
-               s = htab->iplt;
+               s = htab->elf.iplt;
                pent->plt.offset = s->size;
-               s->size += PLT_ENTRY_SIZE;
-               s = htab->reliplt;
+               s->size += PLT_ENTRY_SIZE (htab);
+               s = htab->elf.irelplt;
              }
            else
              {
                /* If this is the first .plt entry, make room for the special
                   first entry.  */
-               s = htab->plt;
+               s = htab->elf.splt;
                if (s->size == 0)
-                 s->size += PLT_INITIAL_ENTRY_SIZE;
+                 s->size += PLT_INITIAL_ENTRY_SIZE (htab);
 
                pent->plt.offset = s->size;
 
                /* Make room for this entry.  */
-               s->size += PLT_ENTRY_SIZE;
+               s->size += PLT_ENTRY_SIZE (htab);
 
                /* Make room for the .glink code.  */
                s = htab->glink;
                if (s->size == 0)
                  s->size += GLINK_CALL_STUB_SIZE;
-               /* We need bigger stubs past index 32767.  */
-               if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
+               if (htab->opd_abi)
+                 {
+                   /* We need bigger stubs past index 32767.  */
+                   if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
+                     s->size += 4;
+                   s->size += 2*4;
+                 }
+               else
                  s->size += 4;
-               s->size += 2*4;
 
                /* We also need to make an entry in the .rela.plt section.  */
-               s = htab->relplt;
+               s = htab->elf.srelplt;
              }
            s->size += sizeof (Elf64_External_Rela);
            doneone = TRUE;
@@ -9297,35 +9606,72 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     {
       asection *sreloc = elf_section_data (p->sec)->sreloc;
       if (eh->elf.type == STT_GNU_IFUNC)
-       sreloc = htab->reliplt;
+       sreloc = htab->elf.irelplt;
       sreloc->size += p->count * sizeof (Elf64_External_Rela);
     }
 
   return TRUE;
 }
 
-/* Find any dynamic relocs that apply to read-only sections.  */
+/* Called via elf_link_hash_traverse from ppc64_elf_size_dynamic_sections
+   to set up space for global entry stubs.  These are put in glink,
+   after the branch table.  */
 
 static bfd_boolean
-readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
 {
-  struct ppc_link_hash_entry *eh;
-  struct elf_dyn_relocs *p;
+  struct bfd_link_info *info;
+  struct ppc_link_hash_table *htab;
+  struct plt_entry *pent;
+  asection *s;
 
-  eh = (struct ppc_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-       {
-         struct bfd_link_info *info = inf;
+  if (!h->pointer_equality_needed)
+    return TRUE;
+
+  if (h->def_regular)
+    return TRUE;
 
-         info->flags |= DF_TEXTREL;
+  info = inf;
+  htab = ppc_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
-         /* Not an error, just cut short the traversal.  */
-         return FALSE;
-       }
+  s = htab->glink;
+  for (pent = h->plt.plist; pent != NULL; pent = pent->next)
+    if (pent->plt.offset != (bfd_vma) -1
+       && pent->addend == 0)
+      {
+       /* For ELFv2, if this symbol is not defined in a regular file
+          and we are not generating a shared library or pie, then we
+          need to define the symbol in the executable on a call stub.
+          This is to avoid text relocations.  */
+       s->size = (s->size + 15) & -16;
+       h->root.u.def.section = s;
+       h->root.u.def.value = s->size;
+       s->size += 16;
+       break;
+      }
+  return TRUE;
+}
+
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+   read-only sections.  */
+
+static bfd_boolean
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info)
+{
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
+
+  if (readonly_dynrelocs (h))
+    {
+      ((struct bfd_link_info *) info)->flags |= DF_TEXTREL;
+
+      /* Not an error, just cut short the traversal.  */
+      return FALSE;
     }
   return TRUE;
 }
@@ -9333,7 +9679,7 @@ readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
-ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ppc64_elf_size_dynamic_sections (bfd *output_bfd,
                                 struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
@@ -9366,7 +9712,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   /* Set up .got offsets for local syms, and space for local dynamic
      relocs.  */
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       struct got_entry **lgot_ents;
       struct got_entry **end_lgot_ents;
@@ -9397,7 +9743,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                {
                  asection *srel = elf_section_data (p->sec)->sreloc;
                  if (p->ifunc)
-                   srel = htab->reliplt;
+                   srel = htab->elf.irelplt;
                  srel->size += p->count * sizeof (Elf64_External_Rela);
                  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
                    info->flags |= DF_TEXTREL;
@@ -9443,7 +9789,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                    s->size += ent_size;
                    if ((*lgot_masks & PLT_IFUNC) != 0)
                      {
-                       htab->reliplt->size += rel_size;
+                       htab->elf.irelplt->size += rel_size;
                        htab->got_reli_size += rel_size;
                      }
                    else if (info->shared)
@@ -9466,11 +9812,11 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          for (ent = *local_plt; ent != NULL; ent = ent->next)
            if (ent->plt.refcount > 0)
              {
-               s = htab->iplt;
+               s = htab->elf.iplt;
                ent->plt.offset = s->size;
-               s->size += PLT_ENTRY_SIZE;
+               s->size += PLT_ENTRY_SIZE (htab);
 
-               htab->reliplt->size += sizeof (Elf64_External_Rela);
+               htab->elf.irelplt->size += sizeof (Elf64_External_Rela);
              }
            else
              ent->plt.offset = (bfd_vma) -1;
@@ -9480,9 +9826,15 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
+  /* Stash the end of glink branch table.  */
+  if (htab->glink != NULL)
+    htab->glink->rawsize = htab->glink->size;
+
+  if (!htab->opd_abi && !info->shared)
+    elf_link_hash_traverse (&htab->elf, size_global_entry_stubs, info);
 
   first_tlsld = NULL;
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       struct got_entry *ent;
 
@@ -9527,9 +9879,9 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (s == htab->brlt || s == htab->relbrlt)
        /* These haven't been allocated yet;  don't strip.  */
        continue;
-      else if (s == htab->got
-              || s == htab->plt
-              || s == htab->iplt
+      else if (s == htab->elf.sgot
+              || s == htab->elf.splt
+              || s == htab->elf.iplt
               || s == htab->glink
               || s == htab->dynbss)
        {
@@ -9546,7 +9898,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        {
          if (s->size != 0)
            {
-             if (s != htab->relplt)
+             if (s != htab->elf.srelplt)
                relocs = TRUE;
 
              /* We use the reloc_count field as a counter if we need
@@ -9590,13 +9942,13 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        return FALSE;
     }
 
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       if (!is_ppc64_elf (ibfd))
        continue;
 
       s = ppc64_elf_tdata (ibfd)->got;
-      if (s != NULL && s != htab->got)
+      if (s != NULL && s != htab->elf.sgot)
        {
          if (s->size == 0)
            s->flags |= SEC_EXCLUDE;
@@ -9625,6 +9977,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   if (htab->elf.dynamic_sections_created)
     {
+      bfd_boolean tls_opt;
+
       /* Add some entries to the .dynamic section.  We fill in the
         values later, in ppc64_elf_finish_dynamic_sections, but we
         must add the entries now so that we get the correct size for
@@ -9639,7 +9993,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
            return FALSE;
        }
 
-      if (htab->plt != NULL && htab->plt->size != 0)
+      if (htab->elf.splt != NULL && htab->elf.splt->size != 0)
        {
          if (!add_dynamic_entry (DT_PLTGOT, 0)
              || !add_dynamic_entry (DT_PLTRELSZ, 0)
@@ -9649,18 +10003,21 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
            return FALSE;
        }
 
-      if (NO_OPD_RELOCS)
+      if (NO_OPD_RELOCS && abiversion (output_bfd) <= 1)
        {
          if (!add_dynamic_entry (DT_PPC64_OPD, 0)
              || !add_dynamic_entry (DT_PPC64_OPDSZ, 0))
            return FALSE;
        }
 
-      if (!htab->no_tls_get_addr_opt
-         && htab->tls_get_addr_fd != NULL
-         && htab->tls_get_addr_fd->elf.plt.plist != NULL
-         && !add_dynamic_entry (DT_PPC64_TLSOPT, 0))
-       return FALSE;
+      tls_opt = (!htab->params->no_tls_get_addr_opt
+                && htab->tls_get_addr_fd != NULL
+                && htab->tls_get_addr_fd->elf.plt.plist != NULL);
+      if (tls_opt || !htab->opd_abi)
+       {
+         if (!add_dynamic_entry (DT_PPC64_OPT, tls_opt ? PPC64_OPT_TLS : 0))
+           return FALSE;
+       }
 
       if (relocs)
        {
@@ -9672,7 +10029,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
          if ((info->flags & DF_TEXTREL) == 0)
-           elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
+           elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
 
          if ((info->flags & DF_TEXTREL) != 0)
            {
@@ -9686,6 +10043,19 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   return TRUE;
 }
 
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
+
+static bfd_boolean
+ppc64_elf_hash_symbol (struct elf_link_hash_entry *h)
+{
+  if (h->plt.plist != NULL
+      && !h->def_regular
+      && !h->pointer_equality_needed)
+    return FALSE;
+
+  return _bfd_elf_hash_symbol (h);
+}
+
 /* Determine the type of stub needed, if any, for a call.  */
 
 static inline enum ppc_stub_type
@@ -9693,7 +10063,8 @@ ppc_type_of_stub (asection *input_sec,
                  const Elf_Internal_Rela *rel,
                  struct ppc_link_hash_entry **hash,
                  struct plt_entry **plt_ent,
-                 bfd_vma destination)
+                 bfd_vma destination,
+                 unsigned long local_off)
 {
   struct ppc_link_hash_entry *h = *hash;
   bfd_vma location;
@@ -9762,7 +10133,7 @@ ppc_type_of_stub (asection *input_sec,
   if (r_type != R_PPC64_REL24)
     max_branch_offset = 1 << 15;
 
-  if (branch_offset + max_branch_offset >= 2 * max_branch_offset)
+  if (branch_offset + max_branch_offset >= 2 * max_branch_offset - local_off)
     /* We need a stub.  Figure out whether a long_branch or plt_branch
        is needed later.  */
     return ppc_stub_long_branch;
@@ -9779,9 +10150,9 @@ ppc_type_of_stub (asection *input_sec,
    the appropriate glink entry if so.
 
    .   fake dep barrier        compare
-   .   ld 11,xxx(2)            ld 11,xxx(2)
-   .   mtctr 11                mtctr 11
-   .   xor 11,11,11            ld 2,xxx+8(2)
+   .   ld 12,xxx(2)            ld 12,xxx(2)
+   .   mtctr 12                mtctr 12
+   .   xor 11,12,12            ld 2,xxx+8(2)
    .   add 2,2,11              cmpldi 2,0
    .   ld 2,xxx+8(2)           bnectr+
    .   bctr                    b <glink_entry>
@@ -9801,23 +10172,27 @@ plt_stub_size (struct ppc_link_hash_table *htab,
               struct ppc_stub_hash_entry *stub_entry,
               bfd_vma off)
 {
-  unsigned size = PLT_CALL_STUB_SIZE;
-
-  if (!(ALWAYS_EMIT_R2SAVE
-       || stub_entry->stub_type == ppc_stub_plt_call_r2save))
-    size -= 4;
-  if (!htab->plt_static_chain)
-    size -= 4;
-  if (htab->plt_thread_safe)
-    size += 8;
-  if (PPC_HA (off) == 0)
-    size -= 4;
-  if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
+  unsigned size = 12;
+
+  if (ALWAYS_EMIT_R2SAVE
+      || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+    size += 4;
+  if (PPC_HA (off) != 0)
     size += 4;
+  if (htab->opd_abi)
+    {
+      size += 4;
+      if (htab->params->plt_static_chain)
+       size += 4;
+      if (htab->params->plt_thread_safe)
+       size += 8;
+      if (PPC_HA (off + 8 + 8 * htab->params->plt_static_chain) != PPC_HA (off))
+       size += 4;
+    }
   if (stub_entry->h != NULL
       && (stub_entry->h == htab->tls_get_addr_fd
          || stub_entry->h == htab->tls_get_addr)
-      && !htab->no_tls_get_addr_opt)
+      && !htab->params->no_tls_get_addr_opt)
     size += 13 * 4;
   return size;
 }
@@ -9829,7 +10204,7 @@ plt_stub_pad (struct ppc_link_hash_table *htab,
              struct ppc_stub_hash_entry *stub_entry,
              bfd_vma plt_off)
 {
-  int stub_align = 1 << htab->plt_stub_align;
+  int stub_align = 1 << htab->params->plt_stub_align;
   unsigned stub_size = plt_stub_size (htab, stub_entry, plt_off);
   bfd_vma stub_off = stub_entry->stub_sec->size;
 
@@ -9846,21 +10221,24 @@ build_plt_stub (struct ppc_link_hash_table *htab,
                struct ppc_stub_hash_entry *stub_entry,
                bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
 {
-  bfd *obfd = htab->stub_bfd;
-  bfd_boolean plt_static_chain = htab->plt_static_chain;
-  bfd_boolean plt_thread_safe = htab->plt_thread_safe;
+  bfd *obfd = htab->params->stub_bfd;
+  bfd_boolean plt_load_toc = htab->opd_abi;
+  bfd_boolean plt_static_chain = htab->params->plt_static_chain;
+  bfd_boolean plt_thread_safe = htab->params->plt_thread_safe;
   bfd_boolean use_fake_dep = plt_thread_safe;
   bfd_vma cmp_branch_off = 0;
 
   if (!ALWAYS_USE_FAKE_DEP
+      && plt_load_toc
       && plt_thread_safe
       && !(stub_entry->h != NULL
           && (stub_entry->h == htab->tls_get_addr_fd
               || stub_entry->h == htab->tls_get_addr)
-          && !htab->no_tls_get_addr_opt))
+          && !htab->params->no_tls_get_addr_opt))
     {
       bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1;
-      bfd_vma pltindex = (pltoff - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE;
+      bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab))
+                         / PLT_ENTRY_SIZE (htab));
       bfd_vma glinkoff = GLINK_CALL_STUB_SIZE + pltindex * 8;
       bfd_vma to, from;
 
@@ -9894,44 +10272,59 @@ build_plt_stub (struct ppc_link_hash_table *htab,
          r[1].r_offset = r[0].r_offset + 4;
          r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
          r[1].r_addend = r[0].r_addend;
-         if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+         if (plt_load_toc)
            {
-             r[2].r_offset = r[1].r_offset + 4;
-             r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
-             r[2].r_addend = r[0].r_addend;
-           }
-         else
-           {
-             r[2].r_offset = r[1].r_offset + 8 + 8 * use_fake_dep;
-             r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
-             r[2].r_addend = r[0].r_addend + 8;
-             if (plt_static_chain)
+             if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+               {
+                 r[2].r_offset = r[1].r_offset + 4;
+                 r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
+                 r[2].r_addend = r[0].r_addend;
+               }
+             else
                {
-                 r[3].r_offset = r[2].r_offset + 4;
-                 r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
-                 r[3].r_addend = r[0].r_addend + 16;
+                 r[2].r_offset = r[1].r_offset + 8 + 8 * use_fake_dep;
+                 r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
+                 r[2].r_addend = r[0].r_addend + 8;
+                 if (plt_static_chain)
+                   {
+                     r[3].r_offset = r[2].r_offset + 4;
+                     r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
+                     r[3].r_addend = r[0].r_addend + 16;
+                   }
                }
            }
        }
       if (ALWAYS_EMIT_R2SAVE
          || stub_entry->stub_type == ppc_stub_plt_call_r2save)
-       bfd_put_32 (obfd, STD_R2_40R1, p),                      p += 4;
-      bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p),    p += 4;
-      bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),     p += 4;
-      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+       bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p),      p += 4;
+      if (plt_load_toc)
+       {
+         bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4;
+         bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p),  p += 4;
+       }
+      else
+       {
+         bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p), p += 4;
+         bfd_put_32 (obfd, LD_R12_0R12 | PPC_LO (offset), p),  p += 4;
+       }
+      if (plt_load_toc
+         && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
        {
-         bfd_put_32 (obfd, ADDI_R12_R12 | PPC_LO (offset), p), p += 4;
+         bfd_put_32 (obfd, ADDI_R11_R11 | PPC_LO (offset), p), p += 4;
          offset = 0;
        }
-      bfd_put_32 (obfd, MTCTR_R11, p),                         p += 4;
-      if (use_fake_dep)
+      bfd_put_32 (obfd, MTCTR_R12, p),                         p += 4;
+      if (plt_load_toc)
        {
-         bfd_put_32 (obfd, XOR_R11_R11_R11, p),                p += 4;
-         bfd_put_32 (obfd, ADD_R12_R12_R11, p),                p += 4;
+         if (use_fake_dep)
+           {
+             bfd_put_32 (obfd, XOR_R2_R12_R12, p),             p += 4;
+             bfd_put_32 (obfd, ADD_R11_R11_R2, p),             p += 4;
+           }
+         bfd_put_32 (obfd, LD_R2_0R11 | PPC_LO (offset + 8), p), p += 4;
+         if (plt_static_chain)
+           bfd_put_32 (obfd, LD_R11_0R11 | PPC_LO (offset + 16), p), p += 4;
        }
-      bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset + 8), p),  p += 4;
-      if (plt_static_chain)
-       bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset + 16), p), p += 4;
     }
   else
     {
@@ -9941,45 +10334,52 @@ build_plt_stub (struct ppc_link_hash_table *htab,
              || stub_entry->stub_type == ppc_stub_plt_call_r2save)
            r[0].r_offset += 4;
          r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
-         if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
-           {
-             r[1].r_offset = r[0].r_offset + 4;
-             r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
-             r[1].r_addend = r[0].r_addend;
-           }
-         else
+         if (plt_load_toc)
            {
-             r[1].r_offset = r[0].r_offset + 8 + 8 * use_fake_dep;
-             r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
-             r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
-             if (plt_static_chain)
+             if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
                {
-                 r[2].r_offset = r[1].r_offset + 4;
-                 r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
-                 r[2].r_addend = r[0].r_addend + 8;
+                 r[1].r_offset = r[0].r_offset + 4;
+                 r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
+                 r[1].r_addend = r[0].r_addend;
+               }
+             else
+               {
+                 r[1].r_offset = r[0].r_offset + 8 + 8 * use_fake_dep;
+                 r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
+                 r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
+                 if (plt_static_chain)
+                   {
+                     r[2].r_offset = r[1].r_offset + 4;
+                     r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
+                     r[2].r_addend = r[0].r_addend + 8;
+                   }
                }
            }
        }
       if (ALWAYS_EMIT_R2SAVE
          || stub_entry->stub_type == ppc_stub_plt_call_r2save)
-       bfd_put_32 (obfd, STD_R2_40R1, p),                      p += 4;
-      bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset), p),      p += 4;
-      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+       bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p),      p += 4;
+      bfd_put_32 (obfd, LD_R12_0R2 | PPC_LO (offset), p),      p += 4;
+      if (plt_load_toc
+         && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
        {
          bfd_put_32 (obfd, ADDI_R2_R2 | PPC_LO (offset), p),   p += 4;
          offset = 0;
        }
-      bfd_put_32 (obfd, MTCTR_R11, p),                         p += 4;
-      if (use_fake_dep)
+      bfd_put_32 (obfd, MTCTR_R12, p),                         p += 4;
+      if (plt_load_toc)
        {
-         bfd_put_32 (obfd, XOR_R11_R11_R11, p),                p += 4;
-         bfd_put_32 (obfd, ADD_R2_R2_R11, p),                  p += 4;
+         if (use_fake_dep)
+           {
+             bfd_put_32 (obfd, XOR_R11_R12_R12, p),            p += 4;
+             bfd_put_32 (obfd, ADD_R2_R2_R11, p),              p += 4;
+           }
+         if (plt_static_chain)
+           bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
+         bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p), p += 4;
        }
-      if (plt_static_chain)
-       bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
-      bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p),   p += 4;
     }
-  if (plt_thread_safe && !use_fake_dep)
+  if (plt_load_toc && plt_thread_safe && !use_fake_dep)
     {
       bfd_put_32 (obfd, CMPLDI_R2_0, p),                       p += 4;
       bfd_put_32 (obfd, BNECTR_P4, p),                         p += 4;
@@ -9999,11 +10399,9 @@ build_plt_stub (struct ppc_link_hash_table *htab,
 #define ADD_R3_R12_R13 0x7c6c6a14
 #define BEQLR          0x4d820020
 #define MR_R3_R0       0x7c030378
-#define MFLR_R11       0x7d6802a6
 #define STD_R11_0R1    0xf9610000
 #define BCTRL          0x4e800421
 #define LD_R11_0R1     0xe9610000
-#define LD_R2_0R1      0xe8410000
 #define MTLR_R11       0x7d6803a6
 
 static inline bfd_byte *
@@ -10011,7 +10409,7 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
                         struct ppc_stub_hash_entry *stub_entry,
                         bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
 {
-  bfd *obfd = htab->stub_bfd;
+  bfd *obfd = htab->params->stub_bfd;
 
   bfd_put_32 (obfd, LD_R11_0R3 + 0, p),                p += 4;
   bfd_put_32 (obfd, LD_R12_0R3 + 8, p),                p += 4;
@@ -10021,15 +10419,15 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
   bfd_put_32 (obfd, BEQLR, p),                 p += 4;
   bfd_put_32 (obfd, MR_R3_R0, p),              p += 4;
   bfd_put_32 (obfd, MFLR_R11, p),              p += 4;
-  bfd_put_32 (obfd, STD_R11_0R1 + 32, p),      p += 4;
+  bfd_put_32 (obfd, STD_R11_0R1 + STK_LINKER (htab), p), p += 4;
 
   if (r != NULL)
     r[0].r_offset += 9 * 4;
   p = build_plt_stub (htab, stub_entry, p, offset, r);
   bfd_put_32 (obfd, BCTRL, p - 4);
 
-  bfd_put_32 (obfd, LD_R11_0R1 + 32, p),       p += 4;
-  bfd_put_32 (obfd, LD_R2_0R1 + 40, p),                p += 4;
+  bfd_put_32 (obfd, LD_R11_0R1 + STK_LINKER (htab), p),        p += 4;
+  bfd_put_32 (obfd, LD_R2_0R1 + STK_TOC (htab), p),    p += 4;
   bfd_put_32 (obfd, MTLR_R11, p),              p += 4;
   bfd_put_32 (obfd, BLR, p),                   p += 4;
 
@@ -10078,6 +10476,8 @@ get_r2off (struct bfd_link_info *info,
       /* Support linking -R objects.  Get the toc pointer from the
         opd entry.  */
       char buf[8];
+      if (!htab->opd_abi)
+       return r2off;
       asection *opd = stub_entry->h->elf.root.u.def.section;
       bfd_vma opd_off = stub_entry->h->elf.root.u.def.value;
 
@@ -10130,9 +10530,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
     case ppc_stub_long_branch:
     case ppc_stub_long_branch_r2off:
       /* Branches are relative.  This is where we are going to.  */
-      off = dest = (stub_entry->target_value
-                   + stub_entry->target_section->output_offset
-                   + stub_entry->target_section->output_section->vma);
+      dest = (stub_entry->target_value
+             + stub_entry->target_section->output_offset
+             + stub_entry->target_section->output_section->vma);
+      dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
+      off = dest;
 
       /* And this is where we are coming from.  */
       off -= (stub_entry->stub_offset
@@ -10149,20 +10551,21 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              htab->stub_error = TRUE;
              return FALSE;
            }
-         bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
+         bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
          loc += 4;
          size = 12;
          if (PPC_HA (r2off) != 0)
            {
              size = 16;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R2_R2 | PPC_HA (r2off), loc);
              loc += 4;
            }
-         bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
+         bfd_put_32 (htab->params->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
          loc += 4;
          off -= size - 4;
        }
-      bfd_put_32 (htab->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
+      bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
 
       if (off + (1 << 25) >= (bfd_vma) (1 << 26))
        {
@@ -10187,16 +10590,16 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              unsigned long symndx;
              struct ppc_link_hash_entry *h;
 
-             hashes = elf_sym_hashes (htab->stub_bfd);
+             hashes = elf_sym_hashes (htab->params->stub_bfd);
              if (hashes == NULL)
                {
                  bfd_size_type hsize;
 
                  hsize = (htab->stub_globals + 1) * sizeof (*hashes);
-                 hashes = bfd_zalloc (htab->stub_bfd, hsize);
+                 hashes = bfd_zalloc (htab->params->stub_bfd, hsize);
                  if (hashes == NULL)
                    return FALSE;
-                 elf_sym_hashes (htab->stub_bfd) = hashes;
+                 elf_sym_hashes (htab->params->stub_bfd) = hashes;
                  htab->stub_globals = 1;
                }
              symndx = htab->stub_globals++;
@@ -10235,6 +10638,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       dest = (stub_entry->target_value
              + stub_entry->target_section->output_offset
              + stub_entry->target_section->output_section->vma);
+      if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
+       dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
 
       bfd_put_64 (htab->brlt->owner, dest,
                  htab->brlt->contents + br_entry->offset);
@@ -10321,55 +10726,63 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          if (PPC_HA (off) != 0)
            {
              size = 16;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R12_R2 | PPC_HA (off), loc);
              loc += 4;
-             bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         LD_R12_0R12 | PPC_LO (off), loc);
            }
          else
            {
              size = 12;
-             bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         LD_R12_0R2 | PPC_LO (off), loc);
            }
        }
       else
        {
          bfd_vma r2off = get_r2off (info, stub_entry);
 
-         if (r2off == 0)
+         if (r2off == 0 && htab->opd_abi)
            {
              htab->stub_error = TRUE;
              return FALSE;
            }
 
-         bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
+         bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
          loc += 4;
-         size = 20;
+         size = 16;
          if (PPC_HA (off) != 0)
            {
              size += 4;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
-             loc += 4;
-             bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R12_R2 | PPC_HA (off), loc);
              loc += 4;
+             bfd_put_32 (htab->params->stub_bfd,
+                         LD_R12_0R12 | PPC_LO (off), loc);
            }
          else
+           bfd_put_32 (htab->params->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
+
+         if (PPC_HA (r2off) != 0)
            {
-             bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
+             size += 4;
              loc += 4;
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R2_R2 | PPC_HA (r2off), loc);
            }
-
-         if (PPC_HA (r2off) != 0)
+         if (PPC_LO (r2off) != 0)
            {
              size += 4;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
              loc += 4;
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDI_R2_R2 | PPC_LO (r2off), loc);
            }
-         bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
        }
       loc += 4;
-      bfd_put_32 (htab->stub_bfd, MTCTR_R11, loc);
+      bfd_put_32 (htab->params->stub_bfd, MTCTR_R12, loc);
       loc += 4;
-      bfd_put_32 (htab->stub_bfd, BCTR, loc);
+      bfd_put_32 (htab->params->stub_bfd, BCTR, loc);
       break;
 
     case ppc_stub_plt_call:
@@ -10397,11 +10810,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (dest >= (bfd_vma) -2)
        abort ();
 
-      plt = htab->plt;
+      plt = htab->elf.splt;
       if (!htab->elf.dynamic_sections_created
          || stub_entry->h == NULL
          || stub_entry->h->elf.dynindx == -1)
-       plt = htab->iplt;
+       plt = htab->elf.iplt;
 
       dest += plt->output_offset + plt->output_section->vma;
 
@@ -10412,13 +10825,16 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          bfd_byte *rl;
 
          rela.r_offset = dest;
-         rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
+         if (htab->opd_abi)
+           rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
+         else
+           rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
          rela.r_addend = (stub_entry->target_value
                           + stub_entry->target_section->output_offset
                           + stub_entry->target_section->output_section->vma);
 
-         rl = (htab->reliplt->contents
-               + (htab->reliplt->reloc_count++
+         rl = (htab->elf.irelplt->contents
+               + (htab->elf.irelplt->reloc_count++
                   * sizeof (Elf64_External_Rela)));
          bfd_elf64_swap_reloca_out (info->output_bfd, &rela, rl);
          stub_entry->plt_ent->plt.offset |= 1;
@@ -10440,7 +10856,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          return FALSE;
        }
 
-      if (htab->plt_stub_align != 0)
+      if (htab->params->plt_stub_align != 0)
        {
          unsigned pad = plt_stub_pad (htab, stub_entry, off);
 
@@ -10453,10 +10869,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (info->emitrelocations)
        {
          r = get_relocs (stub_entry->stub_sec,
-                         (2
-                          + (PPC_HA (off) != 0)
-                          + (htab->plt_static_chain
-                             && PPC_HA (off + 16) == PPC_HA (off))));
+                         ((PPC_HA (off) != 0)
+                          + (htab->opd_abi
+                             ? 2 + (htab->params->plt_static_chain
+                                    && PPC_HA (off + 16) == PPC_HA (off))
+                             : 1)));
          if (r == NULL)
            return FALSE;
          r[0].r_offset = loc - stub_entry->stub_sec->contents;
@@ -10467,7 +10884,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (stub_entry->h != NULL
          && (stub_entry->h == htab->tls_get_addr_fd
              || stub_entry->h == htab->tls_get_addr)
-         && !htab->no_tls_get_addr_opt)
+         && !htab->params->no_tls_get_addr_opt)
        p = build_tls_get_addr_stub (htab, stub_entry, loc, off, r);
       else
        p = build_plt_stub (htab, stub_entry, loc, off, r);
@@ -10481,7 +10898,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 
   stub_entry->stub_sec->size += size;
 
-  if (htab->emit_stub_syms)
+  if (htab->params->emit_stub_syms)
     {
       struct elf_link_hash_entry *h;
       size_t len1, len2;
@@ -10548,26 +10965,27 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       off = stub_entry->plt_ent->plt.offset & ~(bfd_vma) 1;
       if (off >= (bfd_vma) -2)
        abort ();
-      plt = htab->plt;
+      plt = htab->elf.splt;
       if (!htab->elf.dynamic_sections_created
          || stub_entry->h == NULL
          || stub_entry->h->elf.dynindx == -1)
-       plt = htab->iplt;
+       plt = htab->elf.iplt;
       off += (plt->output_offset
              + plt->output_section->vma
              - elf_gp (plt->output_section->owner)
              - htab->stub_group[stub_entry->id_sec->id].toc_off);
 
       size = plt_stub_size (htab, stub_entry, off);
-      if (htab->plt_stub_align)
+      if (htab->params->plt_stub_align)
        size += plt_stub_pad (htab, stub_entry, off);
       if (info->emitrelocations)
        {
          stub_entry->stub_sec->reloc_count
-           += (2
-               + (PPC_HA (off) != 0)
-               + (htab->plt_static_chain
-                  && PPC_HA (off + 16) == PPC_HA (off)));
+           += ((PPC_HA (off) != 0)
+               + (htab->opd_abi
+                  ? 2 + (htab->params->plt_static_chain
+                         && PPC_HA (off + 16) == PPC_HA (off))
+                  : 1));
          stub_entry->stub_sec->flags |= SEC_RELOC;
        }
     }
@@ -10576,6 +10994,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       /* ppc_stub_long_branch or ppc_stub_plt_branch, or their r2off
         variants.  */
       bfd_vma r2off = 0;
+      bfd_vma local_off = 0;
 
       off = (stub_entry->target_value
             + stub_entry->target_section->output_offset
@@ -10593,7 +11012,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
        {
          r2off = get_r2off (info, stub_entry);
-         if (r2off == 0)
+         if (r2off == 0 && htab->opd_abi)
            {
              htab->stub_error = TRUE;
              return FALSE;
@@ -10604,8 +11023,13 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          off -= size - 4;
        }
 
-      /* If the branch offset if too big, use a ppc_stub_plt_branch.  */
-      if (off + (1 << 25) >= (bfd_vma) (1 << 26))
+      local_off = PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
+
+      /* If the branch offset if too big, use a ppc_stub_plt_branch.
+        Do the same for -R objects without function descriptors.  */
+      if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
+         || (stub_entry->stub_type == ppc_stub_long_branch_r2off
+             && r2off == 0))
        {
          struct ppc_branch_hash_entry *br_entry;
 
@@ -10656,12 +11080,14 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
            }
          else
            {
-             size = 20;
+             size = 16;
              if (PPC_HA (off) != 0)
                size += 4;
 
              if (PPC_HA (r2off) != 0)
                size += 4;
+             if (PPC_LO (r2off) != 0)
+               size += 4;
            }
        }
       else if (info->emitrelocations)
@@ -10680,10 +11106,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
    0 when no stubs will be needed, and 1 on success.  */
 
 int
-ppc64_elf_setup_section_lists
-  (struct bfd_link_info *info,
-   asection *(*add_stub_section) (const char *, asection *),
-   void (*layout_sections_again) (void))
+ppc64_elf_setup_section_lists (struct bfd_link_info *info)
 {
   bfd *input_bfd;
   int top_id, top_index, id;
@@ -10694,14 +11117,11 @@ ppc64_elf_setup_section_lists
 
   if (htab == NULL)
     return -1;
-  /* Stash our params away.  */
-  htab->add_stub_section = add_stub_section;
-  htab->layout_sections_again = layout_sections_again;
 
   /* Find the top input section id.  */
   for (input_bfd = info->input_bfds, top_id = 3;
        input_bfd != NULL;
-       input_bfd = input_bfd->link_next)
+       input_bfd = input_bfd->link.next)
     {
       for (section = input_bfd->sections;
           section != NULL;
@@ -10882,7 +11302,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
   elf_link_hash_traverse (&htab->elf, merge_global_got, info);
 
   /* And tlsld_got.  */
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       struct got_entry *ent, *ent2;
 
@@ -10893,7 +11313,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
       if (!ent->is_indirect
          && ent->got.offset != (bfd_vma) -1)
        {
-         for (ibfd2 = ibfd->link_next; ibfd2 != NULL; ibfd2 = ibfd2->link_next)
+         for (ibfd2 = ibfd->link.next; ibfd2 != NULL; ibfd2 = ibfd2->link.next)
            {
              if (!is_ppc64_elf (ibfd2))
                continue;
@@ -10911,11 +11331,11 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
     }
 
   /* Zap sizes of got sections.  */
-  htab->reliplt->rawsize = htab->reliplt->size;
-  htab->reliplt->size -= htab->got_reli_size;
+  htab->elf.irelplt->rawsize = htab->elf.irelplt->size;
+  htab->elf.irelplt->size -= htab->got_reli_size;
   htab->got_reli_size = 0;
 
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       asection *got, *relgot;
 
@@ -10935,7 +11355,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
 
   /* Now reallocate the got, local syms first.  We don't need to
      allocate section contents again since we never increase size.  */
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       struct got_entry **lgot_ents;
       struct got_entry **end_lgot_ents;
@@ -10978,7 +11398,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
              s->size += ent_size;
              if ((*lgot_masks & PLT_IFUNC) != 0)
                {
-                 htab->reliplt->size += rel_size;
+                 htab->elf.irelplt->size += rel_size;
                  htab->got_reli_size += rel_size;
                }
              else if (info->shared)
@@ -10992,7 +11412,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
 
   elf_link_hash_traverse (&htab->elf, reallocate_got, info);
 
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       struct got_entry *ent;
 
@@ -11014,9 +11434,9 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
        }
     }
 
-  done_something = htab->reliplt->rawsize != htab->reliplt->size;
+  done_something = htab->elf.irelplt->rawsize != htab->elf.irelplt->size;
   if (!done_something)
-    for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+    for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
       {
        asection *got;
 
@@ -11033,7 +11453,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
       }
 
   if (done_something)
-    (*htab->layout_sections_again) ();
+    (*htab->params->layout_sections_again) ();
 
   /* Set up for second pass over toc sections to recalculate elf_gp
      on input sections.  */
@@ -11202,7 +11622,10 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
             need a plt_branch stub.  A plt_branch stub uses r2.  */
          else if (dest - (isec->output_offset
                           + isec->output_section->vma
-                          + rel->r_offset) + (1 << 25) >= (2 << 25))
+                          + rel->r_offset) + (1 << 25)
+                  >= (2u << 25) - PPC64_LOCAL_ENTRY_OFFSET (h
+                                                            ? h->other
+                                                            : sym->st_other))
            {
              ret = 1;
              break;
@@ -11296,42 +11719,25 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
 
   if (htab->multi_toc_needed)
     {
-      /* If a code section has a function that uses the TOC then we need
-        to use the right TOC (obviously).  Also, make sure that .opd gets
-        the correct TOC value for R_PPC64_TOC relocs that don't have or
-        can't find their function symbol (shouldn't ever happen now).
-        Also specially treat .fixup for the linux kernel.  .fixup
-        contains branches, but only back to the function that hit an
-        exception.  */
-      if (isec->has_toc_reloc
-         || (isec->flags & SEC_CODE) == 0
-         || strcmp (isec->name, ".fixup") == 0)
-       {
-         if (elf_gp (isec->owner) != 0)
-           htab->toc_curr = elf_gp (isec->owner);
-       }
-      else
+      /* Analyse sections that aren't already flagged as needing a
+        valid toc pointer.  Exclude .fixup for the linux kernel.
+        .fixup contains branches, but only back to the function that
+        hit an exception.  */
+      if (!(isec->has_toc_reloc
+           || (isec->flags & SEC_CODE) == 0
+           || strcmp (isec->name, ".fixup") == 0
+           || isec->call_check_done))
        {
-         if (!isec->call_check_done
-             && toc_adjusting_stub_needed (info, isec) < 0)
+         if (toc_adjusting_stub_needed (info, isec) < 0)
            return FALSE;
-         /* If we make a local call from this section, ie. a branch
-            without a following nop, then we have no place to put a
-            toc restoring insn.  We must use the same toc group as
-            the callee.
-            Testing makes_toc_func_call actually tests for *any*
-            calls to functions that need a good toc pointer.  A more
-            precise test would be better, as this one will set
-            incorrect values for pasted .init/.fini fragments.
-            (Fixed later in check_pasted_section.)  */
-         if (isec->makes_toc_func_call
-             && elf_gp (isec->owner) != 0)
-           htab->toc_curr = elf_gp (isec->owner);
-       }
-    }
-
-  /* Functions that don't use the TOC can belong in any TOC group.
-     Use the last TOC base.  */
+       }
+      /* Make all sections use the TOC assigned for this object file.
+        This will be wrong for pasted sections;  We fix that in
+        check_pasted_section().  */
+      if (elf_gp (isec->owner) != 0)
+       htab->toc_curr = elf_gp (isec->owner);
+    }
+
   htab->stub_group[isec->id].toc_off = htab->toc_curr;
   return TRUE;
 }
@@ -11399,7 +11805,7 @@ group_sections (struct ppc_link_hash_table *htab,
   bfd_boolean suppress_size_errors;
 
   suppress_size_errors = FALSE;
-  stub14_group_size = stub_group_size;
+  stub14_group_size = stub_group_size >> 10;
   if (stub_group_size == 1)
     {
       /* Default values.  */
@@ -11503,7 +11909,8 @@ static const unsigned char glink_eh_frame_cie[] =
   65,                                  /* RA reg.  */
   1,                                   /* Augmentation size.  */
   DW_EH_PE_pcrel | DW_EH_PE_sdata4,    /* FDE encoding.  */
-  DW_CFA_def_cfa, 1, 0                 /* def_cfa: r1 offset 0.  */
+  DW_CFA_def_cfa, 1, 0,                        /* def_cfa: r1 offset 0.  */
+  0, 0, 0, 0
 };
 
 /* Stripping output sections is normally done before dynamic section
@@ -11534,9 +11941,7 @@ maybe_strip_output (struct bfd_link_info *info, asection *isec)
    instruction.  */
 
 bfd_boolean
-ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
-                     bfd_boolean plt_static_chain, int plt_thread_safe,
-                     int plt_stub_align)
+ppc64_elf_size_stubs (struct bfd_link_info *info)
 {
   bfd_size_type stub_group_size;
   bfd_boolean stubs_always_before_branch;
@@ -11545,11 +11950,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
   if (htab == NULL)
     return FALSE;
 
-  htab->plt_static_chain = plt_static_chain;
-  htab->plt_stub_align = plt_stub_align;
-  if (plt_thread_safe == -1 && !info->executable)
-    plt_thread_safe = 1;
-  if (plt_thread_safe == -1)
+  if (htab->params->plt_thread_safe == -1 && !info->executable)
+    htab->params->plt_thread_safe = 1;
+  if (!htab->opd_abi)
+    htab->params->plt_thread_safe = 0;
+  else if (htab->params->plt_thread_safe == -1)
     {
       static const char *const thread_starter[] =
        {
@@ -11562,12 +11967,20 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
          /* libanl */
          "getaddrinfo_a",
          /* libgomp */
+         "GOMP_parallel",
          "GOMP_parallel_start",
+         "GOMP_parallel_loop_static",
          "GOMP_parallel_loop_static_start",
+         "GOMP_parallel_loop_dynamic",
          "GOMP_parallel_loop_dynamic_start",
+         "GOMP_parallel_loop_guided",
          "GOMP_parallel_loop_guided_start",
+         "GOMP_parallel_loop_runtime",
          "GOMP_parallel_loop_runtime_start",
+         "GOMP_parallel_sections",
          "GOMP_parallel_sections_start",
+         /* libgo */
+         "__go_go",
        };
       unsigned i;
 
@@ -11576,17 +11989,16 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
          struct elf_link_hash_entry *h;
          h = elf_link_hash_lookup (&htab->elf, thread_starter[i],
                                    FALSE, FALSE, TRUE);
-         plt_thread_safe = h != NULL && h->ref_regular;
-         if (plt_thread_safe)
+         htab->params->plt_thread_safe = h != NULL && h->ref_regular;
+         if (htab->params->plt_thread_safe)
            break;
        }
     }
-  htab->plt_thread_safe = plt_thread_safe;
-  stubs_always_before_branch = group_size < 0;
-  if (group_size < 0)
-    stub_group_size = -group_size;
+  stubs_always_before_branch = htab->params->group_size < 0;
+  if (htab->params->group_size < 0)
+    stub_group_size = -htab->params->group_size;
   else
-    stub_group_size = group_size;
+    stub_group_size = htab->params->group_size;
 
   group_sections (htab, stub_group_size, stubs_always_before_branch);
 
@@ -11600,7 +12012,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
 
       for (input_bfd = info->input_bfds, bfd_indx = 0;
           input_bfd != NULL;
-          input_bfd = input_bfd->link_next, bfd_indx++)
+          input_bfd = input_bfd->link.next, bfd_indx++)
        {
          Elf_Internal_Shdr *symtab_hdr;
          asection *section;
@@ -11655,6 +12067,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
                  asection *sym_sec, *code_sec;
                  bfd_vma sym_value, code_value;
                  bfd_vma destination;
+                 unsigned long local_off;
                  bfd_boolean ok_dest;
                  struct ppc_link_hash_entry *hash;
                  struct ppc_link_hash_entry *fdh;
@@ -11731,12 +12144,16 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
                    }
 
                  destination = 0;
+                 local_off = 0;
                  if (ok_dest)
                    {
                      sym_value += irela->r_addend;
                      destination = (sym_value
                                     + sym_sec->output_offset
                                     + sym_sec->output_section->vma);
+                     local_off = PPC64_LOCAL_ENTRY_OFFSET (hash
+                                                           ? hash->elf.other
+                                                           : sym->st_other);
                    }
 
                  code_sec = sym_sec;
@@ -11773,7 +12190,8 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
                  /* Determine what (if any) linker stub is needed.  */
                  plt_ent = NULL;
                  stub_type = ppc_type_of_stub (section, irela, &hash,
-                                               &plt_ent, destination);
+                                               &plt_ent, destination,
+                                               local_off);
 
                  if (stub_type != ppc_stub_plt_call)
                    {
@@ -11873,6 +12291,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
                    }
                  stub_entry->h = hash;
                  stub_entry->plt_ent = plt_ent;
+                 stub_entry->other = hash ? hash->elf.other : sym->st_other;
 
                  if (stub_entry->h != NULL)
                    htab->stub_globals += 1;
@@ -11895,7 +12314,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
 
       /* We may have added some stubs.  Find out the new size of the
         stub sections.  */
-      for (stub_sec = htab->stub_bfd->sections;
+      for (stub_sec = htab->params->stub_bfd->sections;
           stub_sec != NULL;
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
@@ -11927,11 +12346,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
        {
          size_t size = 0, align;
 
-         for (stub_sec = htab->stub_bfd->sections;
+         for (stub_sec = htab->params->stub_bfd->sections;
               stub_sec != NULL;
               stub_sec = stub_sec->next)
            if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
-             size += 20;
+             size += 24;
          if (htab->glink != NULL && htab->glink->size != 0)
            size += 24;
          if (size != 0)
@@ -11944,15 +12363,16 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
          htab->glink_eh_frame->size = size;
        }
 
-      if (htab->plt_stub_align != 0)
-       for (stub_sec = htab->stub_bfd->sections;
+      if (htab->params->plt_stub_align != 0)
+       for (stub_sec = htab->params->stub_bfd->sections;
             stub_sec != NULL;
             stub_sec = stub_sec->next)
          if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
-           stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1)
-                             & (-1 << htab->plt_stub_align));
+           stub_sec->size = ((stub_sec->size
+                              + (1 << htab->params->plt_stub_align) - 1)
+                             & (-1 << htab->params->plt_stub_align));
 
-      for (stub_sec = htab->stub_bfd->sections;
+      for (stub_sec = htab->params->stub_bfd->sections;
           stub_sec != NULL;
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
@@ -11967,7 +12387,90 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
        break;
 
       /* Ask the linker to do its stuff.  */
-      (*htab->layout_sections_again) ();
+      (*htab->params->layout_sections_again) ();
+    }
+
+  if (htab->glink_eh_frame != NULL
+      && htab->glink_eh_frame->size != 0)
+    {
+      bfd_vma val;
+      bfd_byte *p, *last_fde;
+      size_t last_fde_len, size, align, pad;
+      asection *stub_sec;
+
+      p = bfd_zalloc (htab->glink_eh_frame->owner, htab->glink_eh_frame->size);
+      if (p == NULL)
+       return FALSE;
+      htab->glink_eh_frame->contents = p;
+      last_fde = p;
+
+      memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
+      /* CIE length (rewrite in case little-endian).  */
+      last_fde_len = sizeof (glink_eh_frame_cie) - 4;
+      bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
+      p += sizeof (glink_eh_frame_cie);
+
+      for (stub_sec = htab->params->stub_bfd->sections;
+          stub_sec != NULL;
+          stub_sec = stub_sec->next)
+       if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+         {
+           last_fde = p;
+           last_fde_len = 20;
+           /* FDE length.  */
+           bfd_put_32 (htab->elf.dynobj, 20, p);
+           p += 4;
+           /* CIE pointer.  */
+           val = p - htab->glink_eh_frame->contents;
+           bfd_put_32 (htab->elf.dynobj, val, p);
+           p += 4;
+           /* Offset to stub section, written later.  */
+           p += 4;
+           /* stub section size.  */
+           bfd_put_32 (htab->elf.dynobj, stub_sec->size, p);
+           p += 4;
+           /* Augmentation.  */
+           p += 1;
+           /* Pad.  */
+           p += 7;
+         }
+      if (htab->glink != NULL && htab->glink->size != 0)
+       {
+         last_fde = p;
+         last_fde_len = 20;
+         /* FDE length.  */
+         bfd_put_32 (htab->elf.dynobj, 20, p);
+         p += 4;
+         /* CIE pointer.  */
+         val = p - htab->glink_eh_frame->contents;
+         bfd_put_32 (htab->elf.dynobj, val, p);
+         p += 4;
+         /* Offset to .glink, written later.  */
+         p += 4;
+         /* .glink size.  */
+         bfd_put_32 (htab->elf.dynobj, htab->glink->size - 8, p);
+         p += 4;
+         /* Augmentation.  */
+         p += 1;
+
+         *p++ = DW_CFA_advance_loc + 1;
+         *p++ = DW_CFA_register;
+         *p++ = 65;
+         *p++ = 12;
+         *p++ = DW_CFA_advance_loc + 4;
+         *p++ = DW_CFA_restore_extended;
+         *p++ = 65;
+       }
+      /* Subsume any padding into the last FDE if user .eh_frame
+        sections are aligned more than glink_eh_frame.  Otherwise any
+        zero padding will be seen as a terminator.  */
+      size = p - htab->glink_eh_frame->contents;
+      align = 1;
+      align <<= htab->glink_eh_frame->output_section->alignment_power;
+      align -= 1;
+      pad = ((size + align) & ~align) - size;
+      htab->glink_eh_frame->size = size + pad;
+      bfd_put_32 (htab->elf.dynobj, last_fde_len + pad, last_fde);
     }
 
   maybe_strip_output (info, htab->brlt);
@@ -12034,49 +12537,145 @@ ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd)
 
   _bfd_set_gp_value (obfd, TOCstart);
 
-  if (info != NULL && s != NULL && is_ppc64_elf (obfd))
+  if (info != NULL && s != NULL)
     {
       struct ppc_link_hash_table *htab = ppc_hash_table (info);
 
-      if (htab != NULL
-         && htab->elf.hgot != NULL)
+      if (htab != NULL)
+       {
+         if (htab->elf.hgot != NULL)
+           {
+             htab->elf.hgot->root.u.def.value = TOC_BASE_OFF;
+             htab->elf.hgot->root.u.def.section = s;
+           }
+       }
+      else
        {
-         htab->elf.hgot->type = STT_OBJECT;
-         htab->elf.hgot->root.type = bfd_link_hash_defined;
-         htab->elf.hgot->root.u.def.value = TOC_BASE_OFF;
-         htab->elf.hgot->root.u.def.section = s;
+         struct bfd_link_hash_entry *bh = NULL;
+         _bfd_generic_link_add_one_symbol (info, obfd, ".TOC.", BSF_GLOBAL,
+                                           s, TOC_BASE_OFF, NULL, FALSE,
+                                           FALSE, &bh);
        }
     }
   return TOCstart;
 }
 
-/* Build all the stubs associated with the current output file.
-   The stubs are kept in a hash table attached to the main linker
-   hash table.  This function is called via gldelf64ppc_finish.  */
+/* Called via elf_link_hash_traverse from ppc64_elf_build_stubs to
+   write out any global entry stubs.  */
 
-bfd_boolean
-ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
-                      struct bfd_link_info *info,
-                      char **stats)
+static bfd_boolean
+build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
 {
-  struct ppc_link_hash_table *htab = ppc_hash_table (info);
-  asection *stub_sec;
-  bfd_byte *p;
-  int stub_sec_count = 0;
+  struct bfd_link_info *info;
+  struct ppc_link_hash_table *htab;
+  struct plt_entry *pent;
+  asection *s;
+
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
+
+  if (!h->pointer_equality_needed)
+    return TRUE;
+
+  if (h->def_regular)
+    return TRUE;
 
+  info = inf;
+  htab = ppc_hash_table (info);
   if (htab == NULL)
     return FALSE;
 
-  htab->emit_stub_syms = emit_stub_syms;
+  s = htab->glink;
+  for (pent = h->plt.plist; pent != NULL; pent = pent->next)
+    if (pent->plt.offset != (bfd_vma) -1
+       && pent->addend == 0)
+      {
+       bfd_byte *p;
+       asection *plt;
+       bfd_vma off;
+
+       p = s->contents + h->root.u.def.value;
+       plt = htab->elf.splt;
+       if (!htab->elf.dynamic_sections_created
+           || h->dynindx == -1)
+         plt = htab->elf.iplt;
+       off = pent->plt.offset + plt->output_offset + plt->output_section->vma;
+       off -= h->root.u.def.value + s->output_offset + s->output_section->vma;
+
+       if (off + 0x80008000 > 0xffffffff || (off & 3) != 0)
+         {
+           info->callbacks->einfo
+             (_("%P: linkage table error against `%T'\n"),
+              h->root.root.string);
+           bfd_set_error (bfd_error_bad_value);
+           htab->stub_error = TRUE;
+         }
+
+       htab->stub_count[ppc_stub_global_entry - 1] += 1;
+       if (htab->params->emit_stub_syms)
+         {
+           size_t len = strlen (h->root.root.string);
+           char *name = bfd_malloc (sizeof "12345678.global_entry." + len);
+
+           if (name == NULL)
+             return FALSE;
+
+           sprintf (name, "%08x.global_entry.%s", s->id, h->root.root.string);
+           h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+           if (h == NULL)
+             return FALSE;
+           if (h->root.type == bfd_link_hash_new)
+             {
+               h->root.type = bfd_link_hash_defined;
+               h->root.u.def.section = s;
+               h->root.u.def.value = p - s->contents;
+               h->ref_regular = 1;
+               h->def_regular = 1;
+               h->ref_regular_nonweak = 1;
+               h->forced_local = 1;
+               h->non_elf = 0;
+             }
+         }
+
+       if (PPC_HA (off) != 0)
+         {
+           bfd_put_32 (s->owner, ADDIS_R12_R12 | PPC_HA (off), p);
+           p += 4;
+         }
+       bfd_put_32 (s->owner, LD_R12_0R12 | PPC_LO (off), p);
+       p += 4;
+       bfd_put_32 (s->owner, MTCTR_R12, p);
+       p += 4;
+       bfd_put_32 (s->owner, BCTR, p);
+       break;
+      }
+  return TRUE;
+}
+
+/* Build all the stubs associated with the current output file.
+   The stubs are kept in a hash table attached to the main linker
+   hash table.  This function is called via gldelf64ppc_finish.  */
+
+bfd_boolean
+ppc64_elf_build_stubs (struct bfd_link_info *info,
+                      char **stats)
+{
+  struct ppc_link_hash_table *htab = ppc_hash_table (info);
+  asection *stub_sec;
+  bfd_byte *p;
+  int stub_sec_count = 0;
+
+  if (htab == NULL)
+    return FALSE;
 
   /* Allocate memory to hold the linker stubs.  */
-  for (stub_sec = htab->stub_bfd->sections;
+  for (stub_sec = htab->params->stub_bfd->sections;
        stub_sec != NULL;
        stub_sec = stub_sec->next)
     if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
        && stub_sec->size != 0)
       {
-       stub_sec->contents = bfd_zalloc (htab->stub_bfd, stub_sec->size);
+       stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size);
        if (stub_sec->contents == NULL)
          return FALSE;
        /* We want to check that built size is the same as calculated
@@ -12091,7 +12690,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
       bfd_vma plt0;
 
       /* Build the .glink plt call stub.  */
-      if (htab->emit_stub_syms)
+      if (htab->params->emit_stub_syms)
        {
          struct elf_link_hash_entry *h;
          h = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
@@ -12110,7 +12709,9 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
              h->non_elf = 0;
            }
        }
-      plt0 = htab->plt->output_section->vma + htab->plt->output_offset - 16;
+      plt0 = (htab->elf.splt->output_section->vma
+             + htab->elf.splt->output_offset
+             - 16);
       if (info->emitrelocations)
        {
          Elf_Internal_Rela *r = get_relocs (htab->glink, 1);
@@ -12125,26 +12726,56 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
       plt0 -= htab->glink->output_section->vma + htab->glink->output_offset;
       bfd_put_64 (htab->glink->owner, plt0, p);
       p += 8;
-      bfd_put_32 (htab->glink->owner, MFLR_R12, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, BCL_20_31, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, MFLR_R11, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, LD_R2_M16R11, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, MTLR_R12, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, ADD_R12_R2_R11, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, LD_R11_0R12, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, LD_R2_0R12 | 8, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, MTCTR_R11, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, LD_R11_0R12 | 16, p);
-      p += 4;
+      if (htab->opd_abi)
+       {
+         bfd_put_32 (htab->glink->owner, MFLR_R12, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, BCL_20_31, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, MFLR_R11, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, MTLR_R12, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, LD_R2_0R11 | 8, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 16, p);
+         p += 4;
+       }
+      else
+       {
+         bfd_put_32 (htab->glink->owner, MFLR_R0, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, BCL_20_31, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, MFLR_R11, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, MTLR_R0, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, ADDI_R0_R12 | (-48 & 0xffff), p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, SRDI_R0_R0_2, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
+         p += 4;
+         bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 8, p);
+         p += 4;
+       }
       bfd_put_32 (htab->glink->owner, BCTR, p);
       p += 4;
       while (p - htab->glink->contents < GLINK_CALL_STUB_SIZE)
@@ -12155,29 +12786,36 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
 
       /* Build the .glink lazy link call stubs.  */
       indx = 0;
-      while (p < htab->glink->contents + htab->glink->size)
+      while (p < htab->glink->contents + htab->glink->rawsize)
        {
-         if (indx < 0x8000)
-           {
-             bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
-             p += 4;
-           }
-         else
+         if (htab->opd_abi)
            {
-             bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
-             p += 4;
-             bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
-             p += 4;
+             if (indx < 0x8000)
+               {
+                 bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
+                 p += 4;
+               }
+             else
+               {
+                 bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
+                 p += 4;
+                 bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx),
+                             p);
+                 p += 4;
+               }
            }
          bfd_put_32 (htab->glink->owner,
                      B_DOT | ((htab->glink->contents - p + 8) & 0x3fffffc), p);
          indx++;
          p += 4;
        }
-      htab->glink->rawsize = p - htab->glink->contents;
+
+      /* Build .glink global entry stubs.  */
+      if (htab->glink->size > htab->glink->rawsize)
+       elf_link_hash_traverse (&htab->elf, build_global_entry_stubs, info);
     }
 
-  if (htab->brlt->size != 0)
+  if (htab->brlt != NULL && htab->brlt->size != 0)
     {
       htab->brlt->contents = bfd_zalloc (htab->brlt->owner,
                                         htab->brlt->size);
@@ -12192,132 +12830,22 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
        return FALSE;
     }
 
-  if (htab->glink_eh_frame != NULL
-      && htab->glink_eh_frame->size != 0)
-    {
-      bfd_vma val;
-      bfd_byte *last_fde;
-      size_t last_fde_len, size, align, pad;
-
-      p = bfd_zalloc (htab->glink_eh_frame->owner, htab->glink_eh_frame->size);
-      if (p == NULL)
-       return FALSE;
-      htab->glink_eh_frame->contents = p;
-      last_fde = p;
-
-      htab->glink_eh_frame->rawsize = htab->glink_eh_frame->size;
-
-      memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
-      /* CIE length (rewrite in case little-endian).  */
-      last_fde_len = sizeof (glink_eh_frame_cie) - 4;
-      bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
-      p += sizeof (glink_eh_frame_cie);
-
-      for (stub_sec = htab->stub_bfd->sections;
-          stub_sec != NULL;
-          stub_sec = stub_sec->next)
-       if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
-         {
-           last_fde = p;
-           last_fde_len = 16;
-           /* FDE length.  */
-           bfd_put_32 (htab->elf.dynobj, 16, p);
-           p += 4;
-           /* CIE pointer.  */
-           val = p - htab->glink_eh_frame->contents;
-           bfd_put_32 (htab->elf.dynobj, val, p);
-           p += 4;
-           /* Offset to stub section.  */
-           val = (stub_sec->output_section->vma
-                  + stub_sec->output_offset);
-           val -= (htab->glink_eh_frame->output_section->vma
-                   + htab->glink_eh_frame->output_offset);
-           val -= p - htab->glink_eh_frame->contents;
-           if (val + 0x80000000 > 0xffffffff)
-             {
-               info->callbacks->einfo
-                 (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
-                  stub_sec->name);
-               return FALSE;
-             }
-           bfd_put_32 (htab->elf.dynobj, val, p);
-           p += 4;
-           /* stub section size.  */
-           bfd_put_32 (htab->elf.dynobj, stub_sec->rawsize, p);
-           p += 4;
-           /* Augmentation.  */
-           p += 1;
-           /* Pad.  */
-           p += 3;
-         }
-      if (htab->glink != NULL && htab->glink->size != 0)
-       {
-         last_fde = p;
-         last_fde_len = 20;
-         /* FDE length.  */
-         bfd_put_32 (htab->elf.dynobj, 20, p);
-         p += 4;
-         /* CIE pointer.  */
-         val = p - htab->glink_eh_frame->contents;
-         bfd_put_32 (htab->elf.dynobj, val, p);
-         p += 4;
-         /* Offset to .glink.  */
-         val = (htab->glink->output_section->vma
-                + htab->glink->output_offset
-                + 8);
-         val -= (htab->glink_eh_frame->output_section->vma
-                 + htab->glink_eh_frame->output_offset);
-         val -= p - htab->glink_eh_frame->contents;
-         if (val + 0x80000000 > 0xffffffff)
-           {
-             info->callbacks->einfo
-               (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
-                htab->glink->name);
-             return FALSE;
-           }
-         bfd_put_32 (htab->elf.dynobj, val, p);
-         p += 4;
-         /* .glink size.  */
-         bfd_put_32 (htab->elf.dynobj, htab->glink->rawsize - 8, p);
-         p += 4;
-         /* Augmentation.  */
-         p += 1;
-
-         *p++ = DW_CFA_advance_loc + 1;
-         *p++ = DW_CFA_register;
-         *p++ = 65;
-         *p++ = 12;
-         *p++ = DW_CFA_advance_loc + 4;
-         *p++ = DW_CFA_restore_extended;
-         *p++ = 65;
-       }
-      /* Subsume any padding into the last FDE if user .eh_frame
-        sections are aligned more than glink_eh_frame.  Otherwise any
-        zero padding will be seen as a terminator.  */
-      size = p - htab->glink_eh_frame->contents;
-      align = 1;
-      align <<= htab->glink_eh_frame->output_section->alignment_power;
-      align -= 1;
-      pad = ((size + align) & ~align) - size;
-      htab->glink_eh_frame->size = size + pad;
-      bfd_put_32 (htab->elf.dynobj, last_fde_len + pad, last_fde);
-    }
-
   /* Build the stubs as directed by the stub hash table.  */
   bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
 
   if (htab->relbrlt != NULL)
     htab->relbrlt->reloc_count = 0;
 
-  if (htab->plt_stub_align != 0)
-    for (stub_sec = htab->stub_bfd->sections;
+  if (htab->params->plt_stub_align != 0)
+    for (stub_sec = htab->params->stub_bfd->sections;
         stub_sec != NULL;
         stub_sec = stub_sec->next)
       if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
-       stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1)
-                         & (-1 << htab->plt_stub_align));
+       stub_sec->size = ((stub_sec->size
+                          + (1 << htab->params->plt_stub_align) - 1)
+                         & (-1 << htab->params->plt_stub_align));
 
-  for (stub_sec = htab->stub_bfd->sections;
+  for (stub_sec = htab->params->stub_bfd->sections;
        stub_sec != NULL;
        stub_sec = stub_sec->next)
     if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
@@ -12327,8 +12855,10 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
          break;
       }
 
+  /* Note that the glink_eh_frame check here is not only testing that
+     the generated size matched the calculated size but also that
+     bfd_elf_discard_info didn't make any changes to the section.  */
   if (stub_sec != NULL
-      || htab->glink->rawsize != htab->glink->size
       || (htab->glink_eh_frame != NULL
          && htab->glink_eh_frame->rawsize != htab->glink_eh_frame->size))
     {
@@ -12351,7 +12881,8 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
                         "  long branch  %lu\n"
                         "  long toc adj %lu\n"
                         "  plt call     %lu\n"
-                        "  plt call toc %lu"),
+                        "  plt call toc %lu\n"
+                        "  global entry %lu"),
               stub_sec_count,
               stub_sec_count == 1 ? "" : "s",
               htab->stub_count[ppc_stub_long_branch - 1],
@@ -12359,7 +12890,8 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
               htab->stub_count[ppc_stub_plt_branch - 1],
               htab->stub_count[ppc_stub_plt_branch_r2off - 1],
               htab->stub_count[ppc_stub_plt_call - 1],
-              htab->stub_count[ppc_stub_plt_call_r2save - 1]);
+              htab->stub_count[ppc_stub_plt_call_r2save - 1],
+              htab->stub_count[ppc_stub_global_entry - 1]);
     }
   return TRUE;
 }
@@ -12472,7 +13004,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
     return FALSE;
 
   /* Don't relocate stub sections.  */
-  if (input_section->owner == htab->stub_bfd)
+  if (input_section->owner == htab->params->stub_bfd)
     return TRUE;
 
   BFD_ASSERT (is_ppc64_elf (input_bfd));
@@ -12510,6 +13042,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
       bfd_vma max_br_offset;
       bfd_vma from;
       const Elf_Internal_Rela orig_rel = *rel;
+      reloc_howto_type *howto;
+      struct reloc_howto_struct alt_howto;
 
       r_type = ELF64_R_TYPE (rel->r_info);
       r_symndx = ELF64_R_SYM (rel->r_info);
@@ -12562,10 +13096,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        }
       else
        {
+         bfd_boolean ignored;
+
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h_elf, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
          sym_name = h_elf->root.root.string;
          sym_type = h_elf->type;
          if (sec != NULL
@@ -13070,6 +13606,40 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              rel->r_info = ELF64_R_INFO (r_symndx, r_type);
            }
          break;
+
+       case R_PPC64_REL16_HA:
+         /* If we are generating a non-PIC executable, edit
+            .  0:      addis 2,12,.TOC.-0b@ha
+            .          addi 2,2,.TOC.-0b@l
+            used by ELFv2 global entry points to set up r2, to
+            .          lis 2,.TOC.@ha
+            .          addi 2,2,.TOC.@l
+            if .TOC. is in range.  */
+         if (!info->shared
+             && !info->traditional_format
+             && h != NULL && &h->elf == htab->elf.hgot
+             && rel + 1 < relend
+             && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)
+             && rel[1].r_offset == rel->r_offset + 4
+             && rel[1].r_addend == rel->r_addend + 4
+             && relocation + 0x80008000 <= 0xffffffff)
+           {
+             unsigned int insn1, insn2;
+             bfd_vma offset = rel->r_offset - d_offset;
+             insn1 = bfd_get_32 (output_bfd, contents + offset);
+             insn2 = bfd_get_32 (output_bfd, contents + offset + 4);
+             if ((insn1 & 0xffff0000) == 0x3c4c0000 /* addis 2,12 */
+                 && (insn2 & 0xffff0000) == 0x38420000 /* addi 2,2 */)
+               {
+                 r_type = R_PPC64_ADDR16_HA;
+                 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+                 rel->r_addend -= d_offset;
+                 rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_ADDR16_LO);
+                 rel[1].r_addend -= d_offset + 4;
+                 bfd_put_32 (output_bfd, 0x3c400000, contents + offset);
+               }
+           }
+         break;
        }
 
       /* Handle other relocations that tweak non-addend part of insn.  */
@@ -13092,7 +13662,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
              if (insn == NOP
                  || insn == CROR_151515 || insn == CROR_313131)
-               bfd_put_32 (input_bfd, STD_R2_40R1,
+               bfd_put_32 (input_bfd,
+                           STD_R2_0R1 + STK_TOC (htab),
                            contents + rel->r_offset);
            }
          break;
@@ -13157,12 +13728,13 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                          if (h != NULL
                              && (h == htab->tls_get_addr_fd
                                  || h == htab->tls_get_addr)
-                             && !htab->no_tls_get_addr_opt)
+                             && !htab->params->no_tls_get_addr_opt)
                            {
                              /* Special stub used, leave nop alone.  */
                            }
                          else
-                           bfd_put_32 (input_bfd, LD_R2_40R1,
+                           bfd_put_32 (input_bfd,
+                                       LD_R2_0R1 + STK_TOC (htab),
                                        contents + rel->r_offset + 4);
                          can_plt_call = TRUE;
                        }
@@ -13212,10 +13784,17 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 
              if (!can_plt_call)
                {
-                 info->callbacks->einfo
-                   (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
-                      "recompile with -fPIC"),
-                    input_bfd, input_section, rel->r_offset, sym_name);
+                 if (stub_entry->stub_type == ppc_stub_plt_call
+                     || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+                   info->callbacks->einfo
+                     (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
+                        "recompile with -fPIC\n"),
+                      input_bfd, input_section, rel->r_offset, sym_name);
+                 else
+                   info->callbacks->einfo
+                     (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
+                        "(-mcmodel=small toc adjust stub)\n"),
+                      input_bfd, input_section, rel->r_offset, sym_name);
 
                  bfd_set_error (bfd_error_bad_value);
                  ret = FALSE;
@@ -13251,6 +13830,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                  + input_section->output_offset
                  + input_section->output_section->vma);
 
+         relocation += PPC64_LOCAL_ENTRY_OFFSET (fdh
+                                                 ? fdh->elf.other
+                                                 : sym->st_other);
+
          if (stub_entry != NULL
              && (stub_entry->stub_type == ppc_stub_long_branch
                  || stub_entry->stub_type == ppc_stub_plt_branch)
@@ -13404,7 +13987,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                    if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
                                                          &h->elf)
                        || (info->shared
-                           && SYMBOL_CALLS_LOCAL (info, &h->elf)))
+                           && SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
                      /* This is actually a static link, or it is a
                         -Bsymbolic link and the symbol is defined
                         locally, or the symbol was forced to be local
@@ -13461,7 +14044,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                         ? h->elf.type == STT_GNU_IFUNC
                         : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC);
                if (ifunc)
-                 relgot = htab->reliplt;
+                 relgot = htab->elf.irelplt;
                else if ((info->shared || indx != 0)
                         && (h == NULL
                             || (tls_type == (TLS_TLS | TLS_LD)
@@ -13575,17 +14158,18 @@ ppc64_elf_relocate_section (bfd *output_bfd,
             symbol.  This happens when statically linking PIC code,
             or when using -Bsymbolic.  Go find a match if there is a
             PLT entry.  */
-         if (htab->plt != NULL)
+         if (htab->elf.splt != NULL)
            {
              struct plt_entry *ent;
              for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
-               if (ent->addend == orig_rel.r_addend
-                   && ent->plt.offset != (bfd_vma) -1)
+               if (ent->plt.offset != (bfd_vma) -1
+                   && ent->addend == orig_rel.r_addend)
                  {
-                   relocation = (htab->plt->output_section->vma
-                                 + htab->plt->output_offset
+                   relocation = (htab->elf.splt->output_section->vma
+                                 + htab->elf.splt->output_offset
                                  + ent->plt.offset);
                    unresolved_reloc = FALSE;
+                   break;
                  }
            }
          break;
@@ -13690,6 +14274,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
          break;
 
+       case R_PPC64_ADDR64_LOCAL:
+         addend += PPC64_LOCAL_ENTRY_OFFSET (h != NULL
+                                             ? h->elf.other
+                                             : sym->st_other);
+         break;
+
        case R_PPC64_DTPMOD64:
          relocation = 1;
          addend = 0;
@@ -13788,7 +14378,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 
              if (skip)
                memset (&outrel, 0, sizeof outrel);
-             else if (!SYMBOL_CALLS_LOCAL (info, &h->elf)
+             else if (!SYMBOL_REFERENCES_LOCAL (info, &h->elf)
                       && !is_opd
                       && r_type != R_PPC64_TOC)
                {
@@ -13891,7 +14481,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              if (h != NULL
                  ? h->elf.type == STT_GNU_IFUNC
                  : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-               sreloc = htab->reliplt;
+               sreloc = htab->elf.irelplt;
              if (sreloc == NULL)
                abort ();
 
@@ -14026,6 +14616,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        }
 
       /* Do any further special processing.  */
+      howto = ppc64_elf_howto_table[(int) r_type];
       switch (r_type)
        {
        default:
@@ -14100,7 +14691,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
              info->callbacks->einfo
                (_("%P: %H: error: %s not a multiple of %u\n"),
                 input_bfd, input_section, rel->r_offset,
-                ppc64_elf_howto_table[r_type]->name,
+                howto->name,
                 mask + 1);
              bfd_set_error (bfd_error_bad_value);
              ret = FALSE;
@@ -14121,23 +14712,46 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          info->callbacks->einfo
            (_("%P: %H: unresolvable %s against `%T'\n"),
             input_bfd, input_section, rel->r_offset,
-            ppc64_elf_howto_table[(int) r_type]->name,
+            howto->name,
             h->elf.root.root.string);
          ret = FALSE;
        }
 
-      r = _bfd_final_link_relocate (ppc64_elf_howto_table[(int) r_type],
-                                   input_bfd,
-                                   input_section,
-                                   contents,
-                                   rel->r_offset,
-                                   relocation,
-                                   addend);
+      /* 16-bit fields in insns mostly have signed values, but a
+        few insns have 16-bit unsigned values.  Really, we should
+        have different reloc types.  */
+      if (howto->complain_on_overflow != complain_overflow_dont
+         && howto->dst_mask == 0xffff
+         && (input_section->flags & SEC_CODE) != 0)
+       {
+         enum complain_overflow complain = complain_overflow_signed;
+
+         insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
+         if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
+           complain = complain_overflow_bitfield;
+         else if (howto->rightshift == 0
+                  ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
+                     || (insn & (0x3f << 26)) == 24u << 26 /* ori */
+                     || (insn & (0x3f << 26)) == 26u << 26 /* xori */)
+                  : ((insn & (0x3f << 26)) == 29u << 26 /* andis */
+                     || (insn & (0x3f << 26)) == 25u << 26 /* oris */
+                     || (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
+           complain = complain_overflow_unsigned;
+         if (howto->complain_on_overflow != complain)
+           {
+             alt_howto = *howto;
+             alt_howto.complain_on_overflow = complain;
+             howto = &alt_howto;
+           }
+       }
+
+      r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
+                                   rel->r_offset, relocation, addend);
 
       if (r != bfd_reloc_ok)
        {
          char *more_info = NULL;
-         const char *reloc_name = ppc64_elf_howto_table[r_type]->name;
+         const char *reloc_name = howto->name;
 
          if (reloc_dest != DEST_NORMAL)
            {
@@ -14157,7 +14771,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                continue;
              if (h != NULL
                  && h->elf.root.type == bfd_link_hash_undefweak
-                 && ppc64_elf_howto_table[r_type]->pc_relative)
+                 && howto->pc_relative)
                {
                  /* Assume this is a call protected by other code that
                     detects the symbol is undefined.  If this is the case,
@@ -14268,30 +14882,57 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
                        && h->def_regular
                        && (h->root.type == bfd_link_hash_defined
                            || h->root.type == bfd_link_hash_defweak));
-           rela.r_offset = (htab->iplt->output_section->vma
-                            + htab->iplt->output_offset
+           rela.r_offset = (htab->elf.iplt->output_section->vma
+                            + htab->elf.iplt->output_offset
                             + ent->plt.offset);
-           rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
+           if (htab->opd_abi)
+             rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
+           else
+             rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
            rela.r_addend = (h->root.u.def.value
                             + h->root.u.def.section->output_offset
                             + h->root.u.def.section->output_section->vma
                             + ent->addend);
-           loc = (htab->reliplt->contents
-                  + (htab->reliplt->reloc_count++
+           loc = (htab->elf.irelplt->contents
+                  + (htab->elf.irelplt->reloc_count++
                      * sizeof (Elf64_External_Rela)));
          }
        else
          {
-           rela.r_offset = (htab->plt->output_section->vma
-                            + htab->plt->output_offset
+           rela.r_offset = (htab->elf.splt->output_section->vma
+                            + htab->elf.splt->output_offset
                             + ent->plt.offset);
            rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
            rela.r_addend = ent->addend;
-           loc = (htab->relplt->contents
-                  + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE)
-                     / (PLT_ENTRY_SIZE / sizeof (Elf64_External_Rela))));
+           loc = (htab->elf.srelplt->contents
+                  + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE (htab))
+                     / PLT_ENTRY_SIZE (htab) * sizeof (Elf64_External_Rela)));
          }
        bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+
+       if (!htab->opd_abi)
+         {
+           if (!h->def_regular)
+             {
+               /* Mark the symbol as undefined, rather than as
+                  defined in glink.  Leave the value if there were
+                  any relocations where pointer equality matters
+                  (this is a clue for the dynamic linker, to make
+                  function pointer comparisons work between an
+                  application and shared library), otherwise set it
+                  to zero.  */
+               sym->st_shndx = SHN_UNDEF;
+               if (!h->pointer_equality_needed)
+                 sym->st_value = 0;
+               else if (!h->ref_regular_nonweak)
+                 {
+                   /* This breaks function pointer comparisons, but
+                      that is better than breaking tests for a NULL
+                      function pointer.  */
+                   sym->st_value = 0;
+                 }
+             }
+         }
       }
 
   if (h->needs_copy)
@@ -14328,7 +14969,7 @@ ppc64_elf_reloc_type_class (const struct bfd_link_info *info,
   enum elf_ppc64_reloc_type r_type;
   struct ppc_link_hash_table *htab = ppc_hash_table (info);
 
-  if (rel_sec == htab->reliplt)
+  if (rel_sec == htab->elf.irelplt)
     return reloc_class_ifunc;
 
   r_type = ELF64_R_TYPE (rela->r_info);
@@ -14366,7 +15007,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
     {
       Elf64_External_Dyn *dyncon, *dynconend;
 
-      if (sdyn == NULL || htab->got == NULL)
+      if (sdyn == NULL || htab->elf.sgot == NULL)
        abort ();
 
       dyncon = (Elf64_External_Dyn *) sdyn->contents;
@@ -14390,7 +15031,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
                 of glink rather than the first entry point, which is
                 what ld.so needs, and now have a bigger stub to
                 support automatic multiple TOCs.  */
-             dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 32;
+             dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 8 * 4;
              break;
 
            case DT_PPC64_OPD:
@@ -14400,6 +15041,11 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
              dyn.d_un.d_ptr = s->vma;
              break;
 
+           case DT_PPC64_OPT:
+             if (htab->do_multi_toc && htab->multi_toc_needed)
+               dyn.d_un.d_val |= PPC64_OPT_MULTI_TOC;
+             break;
+
            case DT_PPC64_OPDSZ:
              s = bfd_get_section_by_name (output_bfd, ".opd");
              if (s == NULL)
@@ -14408,23 +15054,23 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_PLTGOT:
-             s = htab->plt;
+             s = htab->elf.splt;
              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              break;
 
            case DT_JMPREL:
-             s = htab->relplt;
+             s = htab->elf.srelplt;
              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              break;
 
            case DT_PLTRELSZ:
-             dyn.d_un.d_val = htab->relplt->size;
+             dyn.d_un.d_val = htab->elf.srelplt->size;
              break;
 
            case DT_RELASZ:
              /* Don't count procedure linkage table relocs in the
                 overall reloc count.  */
-             s = htab->relplt;
+             s = htab->elf.srelplt;
              if (s == NULL)
                continue;
              dyn.d_un.d_val -= s->size;
@@ -14434,7 +15080,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
              /* We may not be using the standard ELF linker script.
                 If .rela.plt is the first .rela section, we adjust
                 DT_RELA to not include it.  */
-             s = htab->relplt;
+             s = htab->elf.srelplt;
              if (s == NULL)
                continue;
              if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
@@ -14447,23 +15093,23 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
        }
     }
 
-  if (htab->got != NULL && htab->got->size != 0)
+  if (htab->elf.sgot != NULL && htab->elf.sgot->size != 0)
     {
       /* Fill in the first entry in the global offset table.
         We use it to hold the link-time TOCbase.  */
       bfd_put_64 (output_bfd,
                  elf_gp (output_bfd) + TOC_BASE_OFF,
-                 htab->got->contents);
+                 htab->elf.sgot->contents);
 
       /* Set .got entry size.  */
-      elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 8;
+      elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 8;
     }
 
-  if (htab->plt != NULL && htab->plt->size != 0)
+  if (htab->elf.splt != NULL && htab->elf.splt->size != 0)
     {
       /* Set .plt entry size.  */
-      elf_section_data (htab->plt->output_section)->this_hdr.sh_entsize
-       = PLT_ENTRY_SIZE;
+      elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize
+       = PLT_ENTRY_SIZE (htab);
     }
 
   /* brlt is SEC_LINKER_CREATED, so we need to write out relocs for
@@ -14486,18 +15132,86 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
                                       NULL))
     return FALSE;
 
-
   if (htab->glink_eh_frame != NULL
-      && htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
-      && !_bfd_elf_write_section_eh_frame (output_bfd, info,
-                                          htab->glink_eh_frame,
-                                          htab->glink_eh_frame->contents))
-    return FALSE;
+      && htab->glink_eh_frame->size != 0)
+    {
+      bfd_vma val;
+      bfd_byte *p;
+      asection *stub_sec;
+
+      p = htab->glink_eh_frame->contents + sizeof (glink_eh_frame_cie);
+      for (stub_sec = htab->params->stub_bfd->sections;
+          stub_sec != NULL;
+          stub_sec = stub_sec->next)
+       if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+         {
+           /* FDE length.  */
+           p += 4;
+           /* CIE pointer.  */
+           p += 4;
+           /* Offset to stub section.  */
+           val = (stub_sec->output_section->vma
+                  + stub_sec->output_offset);
+           val -= (htab->glink_eh_frame->output_section->vma
+                   + htab->glink_eh_frame->output_offset
+                   + (p - htab->glink_eh_frame->contents));
+           if (val + 0x80000000 > 0xffffffff)
+             {
+               info->callbacks->einfo
+                 (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
+                  stub_sec->name);
+               return FALSE;
+             }
+           bfd_put_32 (dynobj, val, p);
+           p += 4;
+           /* stub section size.  */
+           p += 4;
+           /* Augmentation.  */
+           p += 1;
+           /* Pad.  */
+           p += 7;
+         }
+      if (htab->glink != NULL && htab->glink->size != 0)
+       {
+         /* FDE length.  */
+         p += 4;
+         /* CIE pointer.  */
+         p += 4;
+         /* Offset to .glink.  */
+         val = (htab->glink->output_section->vma
+                + htab->glink->output_offset
+                + 8);
+         val -= (htab->glink_eh_frame->output_section->vma
+                 + htab->glink_eh_frame->output_offset
+                 + (p - htab->glink_eh_frame->contents));
+         if (val + 0x80000000 > 0xffffffff)
+           {
+             info->callbacks->einfo
+               (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
+                htab->glink->name);
+             return FALSE;
+           }
+         bfd_put_32 (dynobj, val, p);
+         p += 4;
+         /* .glink size.  */
+         p += 4;
+         /* Augmentation.  */
+         p += 1;
+         /* Ops.  */
+         p += 7;
+       }
+
+      if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
+         && !_bfd_elf_write_section_eh_frame (output_bfd, info,
+                                              htab->glink_eh_frame,
+                                              htab->glink_eh_frame->contents))
+       return FALSE;
+    }
 
   /* We need to handle writing out multiple GOT sections ourselves,
      since we didn't add them to DYNOBJ.  We know dynobj is the first
      bfd.  */
-  while ((dynobj = dynobj->link_next) != NULL)
+  while ((dynobj = dynobj->link.next) != NULL)
     {
       asection *s;
 
@@ -14533,7 +15247,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
 #undef  TARGET_LITTLE_NAME
 
 #undef  TARGET_BIG_SYM
-#define TARGET_BIG_SYM bfd_elf64_powerpc_freebsd_vec
+#define TARGET_BIG_SYM powerpc_elf64_fbsd_vec
 #undef  TARGET_BIG_NAME
 #define TARGET_BIG_NAME "elf64-powerpc-freebsd"