Blame SOURCES/binutils-ppc64le-1.patch

881b8e
2014-03-12  Aldy Hernandez  <aldyh@redhat.com>
881b8e
881b8e
	* Partial PowerPC little endian patch for binutils.
881b8e
881b8e
diff --git a/IBM-binutils-2.24-2013-11-11-ppc64le_abiv2.patch.gz b/IBM-binutils-2.24-2013-11-11-ppc64le_abiv2.patch.gz
881b8e
new file mode 100644
881b8e
index 0000000..e869701
881b8e
Binary files /dev/null and b/IBM-binutils-2.24-2013-11-11-ppc64le_abiv2.patch.gz differ
881b8e
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
881b8e
index 8c9903f..af72703 100644
881b8e
--- a/bfd/bfd-in2.h
881b8e
+++ b/bfd/bfd-in2.h
881b8e
@@ -3189,6 +3189,8 @@ instruction.  */
881b8e
   BFD_RELOC_PPC64_TOC16_LO_DS,
881b8e
   BFD_RELOC_PPC64_PLTGOT16_DS,
881b8e
   BFD_RELOC_PPC64_PLTGOT16_LO_DS,
881b8e
+  BFD_RELOC_PPC64_ADDR16_HIGH,
881b8e
+  BFD_RELOC_PPC64_ADDR16_HIGHA,
881b8e
 
881b8e
 /* PowerPC and PowerPC64 thread-local storage relocations.  */
881b8e
   BFD_RELOC_PPC_TLS,
881b8e
@@ -3233,6 +3235,10 @@ instruction.  */
881b8e
   BFD_RELOC_PPC64_DTPREL16_HIGHERA,
881b8e
   BFD_RELOC_PPC64_DTPREL16_HIGHEST,
881b8e
   BFD_RELOC_PPC64_DTPREL16_HIGHESTA,
881b8e
+  BFD_RELOC_PPC64_TPREL16_HIGH,
881b8e
+  BFD_RELOC_PPC64_TPREL16_HIGHA,
881b8e
+  BFD_RELOC_PPC64_DTPREL16_HIGH,
881b8e
+  BFD_RELOC_PPC64_DTPREL16_HIGHA,
881b8e
 
881b8e
 /* IBM 370/390 relocations  */
881b8e
   BFD_RELOC_I370_D12,
881b8e
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
881b8e
index fbc4e54..a3680f2 100644
881b8e
--- a/bfd/elf32-ppc.c
881b8e
+++ b/bfd/elf32-ppc.c
881b8e
@@ -6443,7 +6443,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
 	  if (!htab->no_tls_get_addr_opt
881b8e
 	      && htab->tls_get_addr != NULL
881b8e
 	      && htab->tls_get_addr->plt.plist != NULL
881b8e
-	      && !add_dynamic_entry (DT_PPC_TLSOPT, 0))
881b8e
+	      && !add_dynamic_entry (DT_PPC_OPT, PPC_OPT_TLS))
881b8e
 	    return FALSE;
881b8e
 	}
881b8e
 
881b8e
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
881b8e
index 8872673..80c2a4d 100644
881b8e
--- a/bfd/elf64-ppc.c
881b8e
+++ b/bfd/elf64-ppc.c
881b8e
@@ -81,7 +81,8 @@ static bfd_vma opd_entry_value
881b8e
 #define bfd_elf64_mkobject		      ppc64_elf_mkobject
881b8e
 #define bfd_elf64_bfd_reloc_type_lookup	      ppc64_elf_reloc_type_lookup
881b8e
 #define bfd_elf64_bfd_reloc_name_lookup	      ppc64_elf_reloc_name_lookup
881b8e
-#define bfd_elf64_bfd_merge_private_bfd_data  _bfd_generic_verify_endian_match
881b8e
+#define bfd_elf64_bfd_merge_private_bfd_data  ppc64_elf_merge_private_bfd_data
881b8e
+#define bfd_elf64_bfd_print_private_bfd_data  ppc64_elf_print_private_bfd_data
881b8e
 #define bfd_elf64_new_section_hook	      ppc64_elf_new_section_hook
881b8e
 #define bfd_elf64_bfd_link_hash_table_create  ppc64_elf_link_hash_table_create
881b8e
 #define bfd_elf64_bfd_link_hash_table_free    ppc64_elf_link_hash_table_free
881b8e
@@ -108,6 +109,7 @@ static bfd_vma opd_entry_value
881b8e
 #define elf_backend_maybe_function_sym	      ppc64_elf_maybe_function_sym
881b8e
 #define elf_backend_always_size_sections      ppc64_elf_func_desc_adjust
881b8e
 #define elf_backend_size_dynamic_sections     ppc64_elf_size_dynamic_sections
881b8e
+#define elf_backend_hash_symbol		      ppc64_elf_hash_symbol
881b8e
 #define elf_backend_init_index_section	      _bfd_elf_init_2_index_sections
881b8e
 #define elf_backend_action_discarded	      ppc64_elf_action_discarded
881b8e
 #define elf_backend_relocate_section	      ppc64_elf_relocate_section
881b8e
@@ -117,16 +119,25 @@ static bfd_vma opd_entry_value
881b8e
 #define elf_backend_link_output_symbol_hook   ppc64_elf_output_symbol_hook
881b8e
 #define elf_backend_special_sections	      ppc64_elf_special_sections
881b8e
 #define elf_backend_post_process_headers      _bfd_elf_set_osabi
881b8e
+#define elf_backend_merge_symbol_attribute    ppc64_elf_merge_symbol_attribute
881b8e
 
881b8e
 /* The name of the dynamic interpreter.  This is put in the .interp
881b8e
    section.  */
881b8e
 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
881b8e
 
881b8e
 /* The size in bytes of an entry in the procedure linkage table.  */
881b8e
-#define PLT_ENTRY_SIZE 24
881b8e
+#define PLT_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 8)
881b8e
 
881b8e
 /* The initial size of the plt reserved for the dynamic linker.  */
881b8e
-#define PLT_INITIAL_ENTRY_SIZE PLT_ENTRY_SIZE
881b8e
+#define PLT_INITIAL_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 16)
881b8e
+
881b8e
+/* Offsets to some stack save slots.  */
881b8e
+#define STK_LR 16
881b8e
+#define STK_TOC(htab) (htab->opd_abi ? 40 : 24)
881b8e
+/* This one is dodgy.  ABIv2 does not have a linker word, so use the
881b8e
+   CR save slot.  Used only by optimised __tls_get_addr call stub,
881b8e
+   relying on __tls_get_addr_opt not saving CR..  */
881b8e
+#define STK_LINKER(htab) (htab->opd_abi ? 32 : 8)
881b8e
 
881b8e
 /* TOC base pointers offset from start of TOC.  */
881b8e
 #define TOC_BASE_OFF	0x8000
881b8e
@@ -137,33 +148,35 @@ static bfd_vma opd_entry_value
881b8e
 
881b8e
 /* .plt call stub instructions.  The normal stub is like this, but
881b8e
    sometimes the .plt entry crosses a 64k boundary and we need to
881b8e
-   insert an addi to adjust r12.  */
881b8e
-#define PLT_CALL_STUB_SIZE (7*4)
881b8e
-#define ADDIS_R12_R2	0x3d820000	/* addis %r12,%r2,xxx@ha     */
881b8e
-#define STD_R2_40R1	0xf8410028	/* std	 %r2,40(%r1)	     */
881b8e
-#define LD_R11_0R12	0xe96c0000	/* ld	 %r11,xxx+0@l(%r12)  */
881b8e
-#define MTCTR_R11	0x7d6903a6	/* mtctr %r11		     */
881b8e
-#define LD_R2_0R12	0xe84c0000	/* ld	 %r2,xxx+8@l(%r12)   */
881b8e
-					/* ld	 %r11,xxx+16@l(%r12) */
881b8e
+   insert an addi to adjust r11.  */
881b8e
+#define STD_R2_0R1	0xf8410000	/* std	 %r2,0+40(%r1)	     */
881b8e
+#define ADDIS_R11_R2	0x3d620000	/* addis %r11,%r2,xxx@ha     */
881b8e
+#define LD_R12_0R11	0xe98b0000	/* ld	 %r12,xxx+0@l(%r11)  */
881b8e
+#define MTCTR_R12	0x7d8903a6	/* mtctr %r12		     */
881b8e
+#define LD_R2_0R11	0xe84b0000	/* ld	 %r2,xxx+8@l(%r11)   */
881b8e
+#define LD_R11_0R11	0xe96b0000	/* ld	 %r11,xxx+16@l(%r11) */
881b8e
 #define BCTR		0x4e800420	/* bctr			     */
881b8e
 
881b8e
-
881b8e
-#define ADDIS_R12_R12	0x3d8c0000	/* addis %r12,%r12,off@ha  */
881b8e
-#define ADDI_R12_R12	0x398c0000	/* addi %r12,%r12,off@l  */
881b8e
+#define ADDI_R11_R11	0x396b0000	/* addi %r11,%r11,off@l  */
881b8e
 #define ADDIS_R2_R2	0x3c420000	/* addis %r2,%r2,off@ha  */
881b8e
 #define ADDI_R2_R2	0x38420000	/* addi  %r2,%r2,off@l   */
881b8e
 
881b8e
-#define XOR_R11_R11_R11	0x7d6b5a78	/* xor   %r11,%r11,%r11  */
881b8e
-#define ADD_R12_R12_R11	0x7d8c5a14	/* add   %r12,%r12,%r11  */
881b8e
+#define XOR_R2_R12_R12	0x7d826278	/* xor   %r2,%r12,%r12   */
881b8e
+#define ADD_R11_R11_R2	0x7d6b1214	/* add   %r11,%r11,%r2   */
881b8e
+#define XOR_R11_R12_R12	0x7d8b6278	/* xor   %r11,%r12,%r12  */
881b8e
 #define ADD_R2_R2_R11	0x7c425a14	/* add   %r2,%r2,%r11    */
881b8e
 #define CMPLDI_R2_0	0x28220000	/* cmpldi %r2,0          */
881b8e
 #define BNECTR		0x4ca20420	/* bnectr+               */
881b8e
 #define BNECTR_P4	0x4ce20420	/* bnectr+               */
881b8e
 
881b8e
+#define LD_R12_0R2	0xe9820000	/* ld	 %r12,xxx+0(%r2) */
881b8e
 #define LD_R11_0R2	0xe9620000	/* ld	 %r11,xxx+0(%r2) */
881b8e
 #define LD_R2_0R2	0xe8420000	/* ld	 %r2,xxx+0(%r2)  */
881b8e
 
881b8e
-#define LD_R2_40R1	0xe8410028	/* ld    %r2,40(%r1)     */
881b8e
+#define LD_R2_0R1	0xe8410000	/* ld    %r2,0(%r1)      */
881b8e
+
881b8e
+#define ADDIS_R12_R12	0x3d8c0000	/* addis %r12,%r12,xxx@ha */
881b8e
+#define LD_R12_0R12	0xe98c0000	/* ld    %r12,xxx@l(%r12) */
881b8e
 
881b8e
 /* glink call stub instructions.  We enter with the index in R0.  */
881b8e
 #define GLINK_CALL_STUB_SIZE (16*4)
881b8e
@@ -174,14 +187,19 @@ static bfd_vma opd_entry_value
881b8e
 #define BCL_20_31	0x429f0005	/*  bcl 20,31,1f		*/
881b8e
 					/* 1:				*/
881b8e
 #define MFLR_R11	0x7d6802a6	/*  mflr %11			*/
881b8e
-#define LD_R2_M16R11	0xe84bfff0	/*  ld %2,(0b-1b)(%11)		*/
881b8e
+					/*  ld %2,(0b-1b)(%11)		*/
881b8e
 #define MTLR_R12	0x7d8803a6	/*  mtlr %12			*/
881b8e
-#define ADD_R12_R2_R11	0x7d825a14	/*  add %12,%2,%11		*/
881b8e
-					/*  ld %11,0(%12)		*/
881b8e
-					/*  ld %2,8(%12)		*/
881b8e
-					/*  mtctr %11			*/
881b8e
-					/*  ld %11,16(%12)		*/
881b8e
+#define ADD_R11_R2_R11	0x7d625a14	/*  add %11,%2,%11		*/
881b8e
+					/*  ld %12,0(%11)		*/
881b8e
+					/*  ld %2,8(%11)		*/
881b8e
+					/*  mtctr %12			*/
881b8e
+					/*  ld %11,16(%11)		*/
881b8e
 					/*  bctr			*/
881b8e
+#define MFLR_R0		0x7c0802a6	/*  mflr %r0			*/
881b8e
+#define MTLR_R0		0x7c0803a6	/*  mtlr %r0			*/
881b8e
+#define SUB_R12_R12_R11	0x7d8b6050	/*  subf %r12,%r11,%r12		*/
881b8e
+#define ADDI_R0_R12	0x380c0000	/*  addi %r0,%r12,0		*/
881b8e
+#define SRDI_R0_R0_2	0x7800f082	/*  rldicl %r0,%r0,62,2		*/
881b8e
 
881b8e
 /* Pad with this.  */
881b8e
 #define NOP		0x60000000
881b8e
@@ -309,7 +327,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 bfd_elf_generic_reloc,	/* special_function */
881b8e
 	 "R_PPC64_ADDR16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -325,7 +343,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_ha_reloc,	/* special_function */
881b8e
 	 "R_PPC64_ADDR16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -487,7 +505,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont,/* complain_on_overflow */
881b8e
+	 complain_overflow_signed,/* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -503,7 +521,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont,/* complain_on_overflow */
881b8e
+	 complain_overflow_signed,/* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -680,7 +698,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_PLT16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -696,7 +714,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_PLT16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -741,7 +759,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_sectoff_reloc, /* special_function */
881b8e
 	 "R_PPC64_SECTOFF_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -756,7 +774,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_sectoff_ha_reloc, /* special_function */
881b8e
 	 "R_PPC64_SECTOFF_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -963,7 +981,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_toc_reloc,	/* special_function */
881b8e
 	 "R_PPC64_TOC16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -982,7 +1000,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_toc_ha_reloc, /* special_function */
881b8e
 	 "R_PPC64_TOC16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1054,7 +1072,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_PLTGOT16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1072,7 +1090,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont,/* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_PLTGOT16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1374,7 +1392,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_DTPREL16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1389,7 +1407,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_DTPREL16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1540,7 +1558,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_TPREL16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1555,7 +1573,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_TPREL16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1692,7 +1710,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_TLSGD16_HI", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1707,7 +1725,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_TLSGD16_HA", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1754,7 +1772,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_TLSLD16_HI", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1769,7 +1787,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_TLSLD16_HA", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1815,7 +1833,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_DTPREL16_HI", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1830,7 +1848,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_DTPREL16_HA", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1876,7 +1894,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_TPREL16_HI", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1891,7 +1909,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 FALSE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
 	 "R_PPC64_GOT_TPREL16_HA", /* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1964,7 +1982,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 TRUE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 bfd_elf_generic_reloc,	/* special_function */
881b8e
 	 "R_PPC64_REL16_HI",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1980,7 +1998,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 16,			/* bitsize */
881b8e
 	 TRUE,			/* pc_relative */
881b8e
 	 0,			/* bitpos */
881b8e
-	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 complain_overflow_signed, /* complain_on_overflow */
881b8e
 	 ppc64_elf_ha_reloc,	/* special_function */
881b8e
 	 "R_PPC64_REL16_HA",	/* name */
881b8e
 	 FALSE,			/* partial_inplace */
881b8e
@@ -1988,6 +2006,96 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
881b8e
 	 0xffff,		/* dst_mask */
881b8e
 	 TRUE),			/* pcrel_offset */
881b8e
 
881b8e
+  /* Like R_PPC64_ADDR16_HI, but no overflow.  */
881b8e
+  HOWTO (R_PPC64_ADDR16_HIGH,	/* type */
881b8e
+	 16,			/* rightshift */
881b8e
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
881b8e
+	 16,			/* bitsize */
881b8e
+	 FALSE,			/* pc_relative */
881b8e
+	 0,			/* bitpos */
881b8e
+	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 bfd_elf_generic_reloc,	/* special_function */
881b8e
+	 "R_PPC64_ADDR16_HIGH",	/* name */
881b8e
+	 FALSE,			/* partial_inplace */
881b8e
+	 0,			/* src_mask */
881b8e
+	 0xffff,		/* dst_mask */
881b8e
+	 FALSE),		/* pcrel_offset */
881b8e
+
881b8e
+  /* Like R_PPC64_ADDR16_HA, but no overflow.  */
881b8e
+  HOWTO (R_PPC64_ADDR16_HIGHA,	/* type */
881b8e
+	 16,			/* rightshift */
881b8e
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
881b8e
+	 16,			/* bitsize */
881b8e
+	 FALSE,			/* pc_relative */
881b8e
+	 0,			/* bitpos */
881b8e
+	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 ppc64_elf_ha_reloc,	/* special_function */
881b8e
+	 "R_PPC64_ADDR16_HIGHA",	/* name */
881b8e
+	 FALSE,			/* partial_inplace */
881b8e
+	 0,			/* src_mask */
881b8e
+	 0xffff,		/* dst_mask */
881b8e
+	 FALSE),		/* pcrel_offset */
881b8e
+
881b8e
+  /* Like R_PPC64_DTPREL16_HI, but no overflow.  */
881b8e
+  HOWTO (R_PPC64_DTPREL16_HIGH,
881b8e
+	 16,			/* rightshift */
881b8e
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
881b8e
+	 16,			/* bitsize */
881b8e
+	 FALSE,			/* pc_relative */
881b8e
+	 0,			/* bitpos */
881b8e
+	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
+	 "R_PPC64_DTPREL16_HIGH", /* name */
881b8e
+	 FALSE,			/* partial_inplace */
881b8e
+	 0,			/* src_mask */
881b8e
+	 0xffff,		/* dst_mask */
881b8e
+	 FALSE),		/* pcrel_offset */
881b8e
+
881b8e
+  /* Like R_PPC64_DTPREL16_HA, but no overflow.  */
881b8e
+  HOWTO (R_PPC64_DTPREL16_HIGHA,
881b8e
+	 16,			/* rightshift */
881b8e
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
881b8e
+	 16,			/* bitsize */
881b8e
+	 FALSE,			/* pc_relative */
881b8e
+	 0,			/* bitpos */
881b8e
+	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
+	 "R_PPC64_DTPREL16_HIGHA", /* name */
881b8e
+	 FALSE,			/* partial_inplace */
881b8e
+	 0,			/* src_mask */
881b8e
+	 0xffff,		/* dst_mask */
881b8e
+	 FALSE),		/* pcrel_offset */
881b8e
+
881b8e
+  /* Like R_PPC64_TPREL16_HI, but no overflow.  */
881b8e
+  HOWTO (R_PPC64_TPREL16_HIGH,
881b8e
+	 16,			/* rightshift */
881b8e
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
881b8e
+	 16,			/* bitsize */
881b8e
+	 FALSE,			/* pc_relative */
881b8e
+	 0,			/* bitpos */
881b8e
+	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
+	 "R_PPC64_TPREL16_HIGH",	/* name */
881b8e
+	 FALSE,			/* partial_inplace */
881b8e
+	 0,			/* src_mask */
881b8e
+	 0xffff,		/* dst_mask */
881b8e
+	 FALSE),		/* pcrel_offset */
881b8e
+
881b8e
+  /* Like R_PPC64_TPREL16_HA, but no overflow.  */
881b8e
+  HOWTO (R_PPC64_TPREL16_HIGHA,
881b8e
+	 16,			/* rightshift */
881b8e
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
881b8e
+	 16,			/* bitsize */
881b8e
+	 FALSE,			/* pc_relative */
881b8e
+	 0,			/* bitpos */
881b8e
+	 complain_overflow_dont, /* complain_on_overflow */
881b8e
+	 ppc64_elf_unhandled_reloc, /* special_function */
881b8e
+	 "R_PPC64_TPREL16_HIGHA",	/* name */
881b8e
+	 FALSE,			/* partial_inplace */
881b8e
+	 0,			/* src_mask */
881b8e
+	 0xffff,		/* dst_mask */
881b8e
+	 FALSE),		/* pcrel_offset */
881b8e
+
881b8e
   /* GNU extension to record C++ vtable hierarchy.  */
881b8e
   HOWTO (R_PPC64_GNU_VTINHERIT,	/* type */
881b8e
 	 0,			/* rightshift */
881b8e
@@ -2066,8 +2174,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
881b8e
       break;
881b8e
     case BFD_RELOC_HI16:			r = R_PPC64_ADDR16_HI;
881b8e
       break;
881b8e
+    case BFD_RELOC_PPC64_ADDR16_HIGH:		r = R_PPC64_ADDR16_HIGH;
881b8e
+      break;
881b8e
     case BFD_RELOC_HI16_S:			r = R_PPC64_ADDR16_HA;
881b8e
       break;
881b8e
+    case BFD_RELOC_PPC64_ADDR16_HIGHA:		r = R_PPC64_ADDR16_HIGHA;
881b8e
+      break;
881b8e
     case BFD_RELOC_PPC_BA16:			r = R_PPC64_ADDR14;
881b8e
       break;
881b8e
     case BFD_RELOC_PPC_BA16_BRTAKEN:		r = R_PPC64_ADDR14_BRTAKEN;
881b8e
@@ -2186,8 +2298,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
881b8e
       break;
881b8e
     case BFD_RELOC_PPC_TPREL16_HI:		r = R_PPC64_TPREL16_HI;
881b8e
       break;
881b8e
+    case BFD_RELOC_PPC64_TPREL16_HIGH:		r = R_PPC64_TPREL16_HIGH;
881b8e
+      break;
881b8e
     case BFD_RELOC_PPC_TPREL16_HA:		r = R_PPC64_TPREL16_HA;
881b8e
       break;
881b8e
+    case BFD_RELOC_PPC64_TPREL16_HIGHA:		r = R_PPC64_TPREL16_HIGHA;
881b8e
+      break;
881b8e
     case BFD_RELOC_PPC_TPREL:			r = R_PPC64_TPREL64;
881b8e
       break;
881b8e
     case BFD_RELOC_PPC_DTPREL16:		r = R_PPC64_DTPREL16;
881b8e
@@ -2196,8 +2312,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
881b8e
       break;
881b8e
     case BFD_RELOC_PPC_DTPREL16_HI:		r = R_PPC64_DTPREL16_HI;
881b8e
       break;
881b8e
+    case BFD_RELOC_PPC64_DTPREL16_HIGH:		r = R_PPC64_DTPREL16_HIGH;
881b8e
+      break;
881b8e
     case BFD_RELOC_PPC_DTPREL16_HA:		r = R_PPC64_DTPREL16_HA;
881b8e
       break;
881b8e
+    case BFD_RELOC_PPC64_DTPREL16_HIGHA:	r = R_PPC64_DTPREL16_HIGHA;
881b8e
+      break;
881b8e
     case BFD_RELOC_PPC_DTPREL:			r = R_PPC64_DTPREL64;
881b8e
       break;
881b8e
     case BFD_RELOC_PPC_GOT_TLSGD16:		r = R_PPC64_GOT_TLSGD16;
881b8e
@@ -2836,6 +2956,19 @@ get_opd_info (asection * sec)
881b8e
     return &ppc64_elf_section_data (sec)->u.opd;
881b8e
   return NULL;
881b8e
 }
881b8e
+
881b8e
+static inline int
881b8e
+abiversion (bfd *abfd)
881b8e
+{
881b8e
+  return elf_elfheader (abfd)->e_flags & EF_PPC64_ABI;
881b8e
+}
881b8e
+
881b8e
+static inline void
881b8e
+set_abiversion (bfd *abfd, int ver)
881b8e
+{
881b8e
+  elf_elfheader (abfd)->e_flags &= ~EF_PPC64_ABI;
881b8e
+  elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI;
881b8e
+}
881b8e
 
881b8e
 /* Parameters for the qsort hook.  */
881b8e
 static bfd_boolean synthetic_relocatable;
881b8e
@@ -2982,15 +3115,19 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
881b8e
   long count;
881b8e
   char *names;
881b8e
   long symcount, codesecsym, codesecsymend, secsymend, opdsymend;
881b8e
-  asection *opd;
881b8e
+  asection *opd = NULL;
881b8e
   bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
881b8e
   asymbol **syms;
881b8e
+  int abi = abiversion (abfd);
881b8e
 
881b8e
   *ret = NULL;
881b8e
 
881b8e
-  opd = bfd_get_section_by_name (abfd, ".opd");
881b8e
-  if (opd == NULL)
881b8e
-    return 0;
881b8e
+  if (abi < 2)
881b8e
+    {
881b8e
+      opd = bfd_get_section_by_name (abfd, ".opd");
881b8e
+      if (opd == NULL && abi == 1)
881b8e
+	return 0;
881b8e
+    }
881b8e
 
881b8e
   symcount = static_count;
881b8e
   if (!relocatable)
881b8e
@@ -3159,20 +3296,18 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
881b8e
   else
881b8e
     {
881b8e
       bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
881b8e
-      bfd_byte *contents;
881b8e
+      bfd_byte *contents = NULL;
881b8e
       size_t size;
881b8e
       long plt_count = 0;
881b8e
       bfd_vma glink_vma = 0, resolv_vma = 0;
881b8e
       asection *dynamic, *glink = NULL, *relplt = NULL;
881b8e
       arelent *p;
881b8e
 
881b8e
-      if (!bfd_malloc_and_get_section (abfd, opd, &contents))
881b8e
+      if (opd != NULL && !bfd_malloc_and_get_section (abfd, opd, &contents))
881b8e
 	{
881b8e
+	free_contents_and_exit:
881b8e
 	  if (contents)
881b8e
-	    {
881b8e
-	    free_contents_and_exit:
881b8e
-	      free (contents);
881b8e
-	    }
881b8e
+	    free (contents);
881b8e
 	  count = -1;
881b8e
 	  goto done;
881b8e
 	}
881b8e
@@ -3221,9 +3356,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
881b8e
 
881b8e
 	      if (dyn.d_tag == DT_PPC64_GLINK)
881b8e
 		{
881b8e
-		  /* The first glink stub starts at offset 32; see comment in
881b8e
-		     ppc64_elf_finish_dynamic_sections. */
881b8e
-		  glink_vma = dyn.d_un.d_val + 32;
881b8e
+		  /* The first glink stub starts at offset 32; see
881b8e
+		     comment in ppc64_elf_finish_dynamic_sections. */
881b8e
+		  glink_vma = dyn.d_un.d_val + GLINK_CALL_STUB_SIZE - 8 * 4;
881b8e
 		  /* The .glink section usually does not survive the final
881b8e
 		     link; search for the section (usually .text) where the
881b8e
 		     glink stubs now reside.  */
881b8e
@@ -3241,13 +3376,21 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
881b8e
 	  /* Determine __glink trampoline by reading the relative branch
881b8e
 	     from the first glink stub.  */
881b8e
 	  bfd_byte buf[4];
881b8e
-	  if (bfd_get_section_contents (abfd, glink, buf,
881b8e
-					glink_vma + 4 - glink->vma, 4))
881b8e
+	  unsigned int off = 0;
881b8e
+
881b8e
+	  while (bfd_get_section_contents (abfd, glink, buf,
881b8e
+					   glink_vma + off - glink->vma, 4))
881b8e
 	    {
881b8e
 	      unsigned int insn = bfd_get_32 (abfd, buf);
881b8e
 	      insn ^= B_DOT;
881b8e
 	      if ((insn & ~0x3fffffc) == 0)
881b8e
-		resolv_vma = glink_vma + 4 + (insn ^ 0x2000000) - 0x2000000;
881b8e
+		{
881b8e
+		  resolv_vma = glink_vma + off + (insn ^ 0x2000000) - 0x2000000;
881b8e
+		  break;
881b8e
+		}
881b8e
+	      off += 4;
881b8e
+	      if (off > 4)
881b8e
+		break;
881b8e
 	    }
881b8e
 
881b8e
 	  if (resolv_vma)
881b8e
@@ -3400,8 +3543,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
881b8e
 	      memcpy (names, "@plt", sizeof ("@plt"));
881b8e
 	      names += sizeof ("@plt");
881b8e
 	      s++;
881b8e
-	      glink_vma += 8;
881b8e
-	      if (i >= 0x8000)
881b8e
+	      if (abi < 2)
881b8e
+		{
881b8e
+		  glink_vma += 8;
881b8e
+		  if (i >= 0x8000)
881b8e
+		    glink_vma += 4;
881b8e
+		}
881b8e
+	      else
881b8e
 		glink_vma += 4;
881b8e
 	    }
881b8e
 	  count += plt_count;
881b8e
@@ -3452,13 +3600,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
881b8e
    .
881b8e
    .
881b8e
    .	.foo_stub:
881b8e
-   .		addis	12,2,Lfoo@toc@ha	# in practice, the call stub
881b8e
-   .		addi	12,12,Lfoo@toc@l	# is slightly optimized, but
881b8e
-   .		std	2,40(1)			# this is the general idea
881b8e
-   .		ld	11,0(12)
881b8e
-   .		ld	2,8(12)
881b8e
-   .		mtctr	11
881b8e
-   .		ld	11,16(12)
881b8e
+   .		std	2,40(1)			# in practice, the call stub
881b8e
+   .		addis	11,2,Lfoo@toc@ha	# is slightly optimized, but
881b8e
+   .		addi	11,11,Lfoo@toc@l	# this is the general idea
881b8e
+   .		ld	12,0(11)
881b8e
+   .		ld	2,8(11)
881b8e
+   .		mtctr	12
881b8e
+   .		ld	11,16(11)
881b8e
    .		bctr
881b8e
    .
881b8e
    .		.section .plt
881b8e
@@ -3509,6 +3657,8 @@ must_be_dyn_reloc (struct bfd_link_info *info,
881b8e
     case R_PPC64_TPREL16_HA:
881b8e
     case R_PPC64_TPREL16_DS:
881b8e
     case R_PPC64_TPREL16_LO_DS:
881b8e
+    case R_PPC64_TPREL16_HIGH:
881b8e
+    case R_PPC64_TPREL16_HIGHA:
881b8e
     case R_PPC64_TPREL16_HIGHER:
881b8e
     case R_PPC64_TPREL16_HIGHERA:
881b8e
     case R_PPC64_TPREL16_HIGHEST:
881b8e
@@ -3548,21 +3698,21 @@ must_be_dyn_reloc (struct bfd_link_info *info,
881b8e
    ppc_stub_plt_branch:
881b8e
    Similar to the above, but a 24 bit branch in the stub section won't
881b8e
    reach its destination.
881b8e
-   .	addis	%r12,%r2,xxx@toc@ha
881b8e
-   .	ld	%r11,xxx@toc@l(%r12)
881b8e
-   .	mtctr	%r11
881b8e
+   .	addis	%r11,%r2,xxx@toc@ha
881b8e
+   .	ld	%r12,xxx@toc@l(%r11)
881b8e
+   .	mtctr	%r12
881b8e
    .	bctr
881b8e
 
881b8e
    ppc_stub_plt_call:
881b8e
    Used to call a function in a shared library.  If it so happens that
881b8e
    the plt entry referenced crosses a 64k boundary, then an extra
881b8e
-   "addi %r12,%r12,xxx@toc@l" will be inserted before the "mtctr".
881b8e
-   .	addis	%r12,%r2,xxx@toc@ha
881b8e
+   "addi %r11,%r11,xxx@toc@l" will be inserted before the "mtctr".
881b8e
    .	std	%r2,40(%r1)
881b8e
-   .	ld	%r11,xxx+0@toc@l(%r12)
881b8e
-   .	mtctr	%r11
881b8e
-   .	ld	%r2,xxx+8@toc@l(%r12)
881b8e
-   .	ld	%r11,xxx+16@toc@l(%r12)
881b8e
+   .	addis	%r11,%r2,xxx@toc@ha
881b8e
+   .	ld	%r12,xxx+0@toc@l(%r11)
881b8e
+   .	mtctr	%r12
881b8e
+   .	ld	%r2,xxx+8@toc@l(%r11)
881b8e
+   .	ld	%r11,xxx+16@toc@l(%r11)
881b8e
    .	bctr
881b8e
 
881b8e
    ppc_stub_long_branch and ppc_stub_plt_branch may also have additional
881b8e
@@ -3575,11 +3725,11 @@ must_be_dyn_reloc (struct bfd_link_info *info,
881b8e
 
881b8e
    A ppc_stub_plt_branch with an r2 offset looks like:
881b8e
    .	std	%r2,40(%r1)
881b8e
-   .	addis	%r12,%r2,xxx@toc@ha
881b8e
-   .	ld	%r11,xxx@toc@l(%r12)
881b8e
+   .	addis	%r11,%r2,xxx@toc@ha
881b8e
+   .	ld	%r12,xxx@toc@l(%r11)
881b8e
    .	addis	%r2,%r2,off@ha
881b8e
    .	addi	%r2,%r2,off@l
881b8e
-   .	mtctr	%r11
881b8e
+   .	mtctr	%r12
881b8e
    .	bctr
881b8e
 
881b8e
    In cases where the "addis" instruction would add zero, the "addis" is
881b8e
@@ -3624,6 +3774,9 @@ struct ppc_stub_hash_entry {
881b8e
   /* Where this stub is being called from, or, in the case of combined
881b8e
      stub sections, the first input section in the group.  */
881b8e
   asection *id_sec;
881b8e
+
881b8e
+  /* Symbol st_other.  */
881b8e
+  unsigned char other;
881b8e
 };
881b8e
 
881b8e
 struct ppc_branch_hash_entry {
881b8e
@@ -3772,6 +3925,9 @@ struct ppc_link_hash_table
881b8e
   /* Alignment of PLT call stubs.  */
881b8e
   unsigned int plt_stub_align:4;
881b8e
 
881b8e
+  /* Set if we're linking code with function descriptors.  */
881b8e
+  unsigned int opd_abi:1;
881b8e
+
881b8e
   /* Set if PLT call stubs should load r11.  */
881b8e
   unsigned int plt_static_chain:1;
881b8e
 
881b8e
@@ -3867,7 +4023,9 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
881b8e
       eh->target_value = 0;
881b8e
       eh->target_section = NULL;
881b8e
       eh->h = NULL;
881b8e
+      eh->plt_ent = NULL;
881b8e
       eh->id_sec = NULL;
881b8e
+      eh->other = 0;
881b8e
     }
881b8e
 
881b8e
   return entry;
881b8e
@@ -4452,6 +4610,7 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
881b8e
   edir->elf.ref_regular |= eind->elf.ref_regular;
881b8e
   edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
881b8e
   edir->elf.needs_plt |= eind->elf.needs_plt;
881b8e
+  edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
881b8e
 
881b8e
   /* Copy over any dynamic relocs we may have on the indirect sym.  */
881b8e
   if (eind->dyn_relocs != NULL)
881b8e
@@ -4610,7 +4769,7 @@ static bfd_boolean
881b8e
 ppc64_elf_add_symbol_hook (bfd *ibfd,
881b8e
 			   struct bfd_link_info *info,
881b8e
 			   Elf_Internal_Sym *isym,
881b8e
-			   const char **name ATTRIBUTE_UNUSED,
881b8e
+			   const char **name,
881b8e
 			   flagword *flags ATTRIBUTE_UNUSED,
881b8e
 			   asection **sec,
881b8e
 			   bfd_vma *value ATTRIBUTE_UNUSED)
881b8e
@@ -4630,9 +4789,35 @@ ppc64_elf_add_symbol_hook (bfd *ibfd,
881b8e
 	   && strcmp ((*sec)->name, ".opd") == 0)
881b8e
     isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
881b8e
 
881b8e
+  if ((STO_PPC64_LOCAL_MASK & isym->st_other) != 0)
881b8e
+    {
881b8e
+      if (abiversion (ibfd) == 0)
881b8e
+	set_abiversion (ibfd, 2);
881b8e
+      else if (abiversion (ibfd) == 1)
881b8e
+	{
881b8e
+	  info->callbacks->einfo (_("%P: symbol '%s' has invalid st_other"
881b8e
+				    " for ABI version 1\n"), name);
881b8e
+	  bfd_set_error (bfd_error_bad_value);
881b8e
+	  return FALSE;
881b8e
+	}
881b8e
+    }
881b8e
+
881b8e
   return TRUE;
881b8e
 }
881b8e
 
881b8e
+/* Merge non-visibility st_other attributes: local entry point.  */
881b8e
+
881b8e
+static void
881b8e
+ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
881b8e
+				  const Elf_Internal_Sym *isym,
881b8e
+				  bfd_boolean definition,
881b8e
+				  bfd_boolean dynamic)
881b8e
+{
881b8e
+  if (definition && !dynamic)
881b8e
+    h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
881b8e
+		| ELF_ST_VISIBILITY (h->other));
881b8e
+}
881b8e
+
881b8e
 /* This function makes an old ABI object reference to ".bar" cause the
881b8e
    inclusion of a new ABI object archive that defines "bar".
881b8e
    NAME is a symbol defined in an archive.  Return a symbol in the hash
881b8e
@@ -4959,6 +5144,15 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
881b8e
 	 information about the associated function section.  */
881b8e
       bfd_size_type amt;
881b8e
 
881b8e
+      if (abiversion (abfd) == 0)
881b8e
+	set_abiversion (abfd, 1);
881b8e
+      else if (abiversion (abfd) == 2)
881b8e
+	{
881b8e
+	  info->callbacks->einfo (_("%P: .opd not allowed in ABI version %d\n"),
881b8e
+				  abiversion (abfd));
881b8e
+	  bfd_set_error (bfd_error_bad_value);
881b8e
+	  return FALSE;
881b8e
+	}
881b8e
       amt = sec->size * sizeof (*opd_sym_map) / 8;
881b8e
       opd_sym_map = bfd_zalloc (abfd, amt);
881b8e
       if (opd_sym_map == NULL)
881b8e
@@ -5134,6 +5328,14 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
881b8e
 	    if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
881b8e
 					rel->r_addend, tls_type))
881b8e
 	      return FALSE;
881b8e
+
881b8e
+	  /* We may also need a plt entry if the symbol turns out to be
881b8e
+	     an ifunc.  */
881b8e
+	  if (h != NULL && !info->shared && abiversion (abfd) == 2)
881b8e
+	    {
881b8e
+	      if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
881b8e
+		return FALSE;
881b8e
+	    }
881b8e
 	  break;
881b8e
 
881b8e
 	case R_PPC64_PLT16_HA:
881b8e
@@ -5179,6 +5381,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
881b8e
 	case R_PPC64_DTPREL16_HA:
881b8e
 	case R_PPC64_DTPREL16_DS:
881b8e
 	case R_PPC64_DTPREL16_LO_DS:
881b8e
+	case R_PPC64_DTPREL16_HIGH:
881b8e
+	case R_PPC64_DTPREL16_HIGHA:
881b8e
 	case R_PPC64_DTPREL16_HIGHER:
881b8e
 	case R_PPC64_DTPREL16_HIGHERA:
881b8e
 	case R_PPC64_DTPREL16_HIGHEST:
881b8e
@@ -5339,6 +5543,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
881b8e
 	case R_PPC64_TPREL16_HA:
881b8e
 	case R_PPC64_TPREL16_DS:
881b8e
 	case R_PPC64_TPREL16_LO_DS:
881b8e
+	case R_PPC64_TPREL16_HIGH:
881b8e
+	case R_PPC64_TPREL16_HIGHA:
881b8e
 	case R_PPC64_TPREL16_HIGHER:
881b8e
 	case R_PPC64_TPREL16_HIGHERA:
881b8e
 	case R_PPC64_TPREL16_HIGHEST:
881b8e
@@ -5382,22 +5588,35 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
881b8e
 	    }
881b8e
 	  /* Fall through.  */
881b8e
 
881b8e
-	case R_PPC64_REL30:
881b8e
-	case R_PPC64_REL32:
881b8e
-	case R_PPC64_REL64:
881b8e
-	case R_PPC64_ADDR14:
881b8e
-	case R_PPC64_ADDR14_BRNTAKEN:
881b8e
-	case R_PPC64_ADDR14_BRTAKEN:
881b8e
 	case R_PPC64_ADDR16:
881b8e
 	case R_PPC64_ADDR16_DS:
881b8e
 	case R_PPC64_ADDR16_HA:
881b8e
 	case R_PPC64_ADDR16_HI:
881b8e
+	case R_PPC64_ADDR16_HIGH:
881b8e
+	case R_PPC64_ADDR16_HIGHA:
881b8e
 	case R_PPC64_ADDR16_HIGHER:
881b8e
 	case R_PPC64_ADDR16_HIGHERA:
881b8e
 	case R_PPC64_ADDR16_HIGHEST:
881b8e
 	case R_PPC64_ADDR16_HIGHESTA:
881b8e
 	case R_PPC64_ADDR16_LO:
881b8e
 	case R_PPC64_ADDR16_LO_DS:
881b8e
+	  if (h != NULL && !info->shared && abiversion (abfd) == 2
881b8e
+	      && rel->r_addend == 0)
881b8e
+	    {
881b8e
+	      /* We may need a .plt entry if this reloc refers to a
881b8e
+		 function in a shared lib.  */
881b8e
+	      if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
881b8e
+		return FALSE;
881b8e
+	      h->pointer_equality_needed = 1;
881b8e
+	    }
881b8e
+	  /* Fall through.  */
881b8e
+
881b8e
+	case R_PPC64_REL30:
881b8e
+	case R_PPC64_REL32:
881b8e
+	case R_PPC64_REL64:
881b8e
+	case R_PPC64_ADDR14:
881b8e
+	case R_PPC64_ADDR14_BRNTAKEN:
881b8e
+	case R_PPC64_ADDR14_BRTAKEN:
881b8e
 	case R_PPC64_ADDR24:
881b8e
 	case R_PPC64_ADDR32:
881b8e
 	case R_PPC64_UADDR16:
881b8e
@@ -5518,6 +5737,78 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
881b8e
   return TRUE;
881b8e
 }
881b8e
 
881b8e
+/* Merge backend specific data from an object file to the output
881b8e
+   object file when linking.  */
881b8e
+
881b8e
+static bfd_boolean
881b8e
+ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
881b8e
+{
881b8e
+  unsigned long iflags, oflags;
881b8e
+
881b8e
+  if ((ibfd->flags & BFD_LINKER_CREATED) != 0)
881b8e
+    return TRUE;
881b8e
+
881b8e
+  if (!is_ppc64_elf (ibfd) || !is_ppc64_elf (obfd))
881b8e
+    return TRUE;
881b8e
+
881b8e
+  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
881b8e
+    return FALSE;
881b8e
+
881b8e
+  iflags = elf_elfheader (ibfd)->e_flags;
881b8e
+  oflags = elf_elfheader (obfd)->e_flags;
881b8e
+
881b8e
+  if (!elf_flags_init (obfd) || oflags == 0)
881b8e
+    {
881b8e
+      elf_flags_init (obfd) = TRUE;
881b8e
+      elf_elfheader (obfd)->e_flags = iflags;
881b8e
+    }
881b8e
+  else if (iflags == oflags || iflags == 0)
881b8e
+    ;
881b8e
+  else if (iflags & ~EF_PPC64_ABI)
881b8e
+    {
881b8e
+      (*_bfd_error_handler)
881b8e
+	(_("%B uses unknown e_flags 0x%lx"), ibfd, iflags);
881b8e
+      bfd_set_error (bfd_error_bad_value);
881b8e
+      return FALSE;
881b8e
+    }
881b8e
+  else
881b8e
+    {
881b8e
+      (*_bfd_error_handler)
881b8e
+	(_("%B: ABI version %ld is not compatible with ABI version %ld output"),
881b8e
+	 ibfd, iflags, oflags);
881b8e
+      bfd_set_error (bfd_error_bad_value);
881b8e
+      return FALSE;
881b8e
+    }
881b8e
+
881b8e
+  /* Merge Tag_compatibility attributes and any common GNU ones.  */
881b8e
+  _bfd_elf_merge_object_attributes (ibfd, obfd);
881b8e
+
881b8e
+  return TRUE;
881b8e
+}
881b8e
+
881b8e
+static bfd_boolean
881b8e
+ppc64_elf_print_private_bfd_data (bfd *abfd, void *ptr)
881b8e
+{
881b8e
+  /* Print normal ELF private data.  */
881b8e
+  _bfd_elf_print_private_bfd_data (abfd, ptr);
881b8e
+
881b8e
+  if (elf_elfheader (abfd)->e_flags != 0)
881b8e
+    {
881b8e
+      FILE *file = ptr;
881b8e
+
881b8e
+      /* xgettext:c-format */
881b8e
+      fprintf (file, _("private flags = 0x%lx:"),
881b8e
+	       elf_elfheader (abfd)->e_flags);
881b8e
+
881b8e
+      if ((elf_elfheader (abfd)->e_flags & EF_PPC64_ABI) != 0)
881b8e
+	fprintf (file, _(" [abiv%ld]"),
881b8e
+		 elf_elfheader (abfd)->e_flags & EF_PPC64_ABI);
881b8e
+      fputc ('\n', file);
881b8e
+    }
881b8e
+
881b8e
+  return TRUE;
881b8e
+}
881b8e
+
881b8e
 /* OFFSET in OPD_SEC specifies a function descriptor.  Return the address
881b8e
    of the code entry point, and its section.  */
881b8e
 
881b8e
@@ -6177,7 +6468,7 @@ static bfd_byte *
881b8e
 savegpr0_tail (bfd *abfd, bfd_byte *p, int r)
881b8e
 {
881b8e
   p = savegpr0 (abfd, p, r);
881b8e
-  bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
881b8e
+  bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
881b8e
   p = p + 4;
881b8e
   bfd_put_32 (abfd, BLR, p);
881b8e
   return p + 4;
881b8e
@@ -6193,7 +6484,7 @@ restgpr0 (bfd *abfd, bfd_byte *p, int r)
881b8e
 static bfd_byte *
881b8e
 restgpr0_tail (bfd *abfd, bfd_byte *p, int r)
881b8e
 {
881b8e
-  bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
881b8e
+  bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
881b8e
   p = p + 4;
881b8e
   p = restgpr0 (abfd, p, r);
881b8e
   bfd_put_32 (abfd, MTLR_R0, p);
881b8e
@@ -6248,7 +6539,7 @@ static bfd_byte *
881b8e
 savefpr0_tail (bfd *abfd, bfd_byte *p, int r)
881b8e
 {
881b8e
   p = savefpr (abfd, p, r);
881b8e
-  bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
881b8e
+  bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
881b8e
   p = p + 4;
881b8e
   bfd_put_32 (abfd, BLR, p);
881b8e
   return p + 4;
881b8e
@@ -6264,7 +6555,7 @@ restfpr (bfd *abfd, bfd_byte *p, int r)
881b8e
 static bfd_byte *
881b8e
 restfpr0_tail (bfd *abfd, bfd_byte *p, int r)
881b8e
 {
881b8e
-  bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
881b8e
+  bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
881b8e
   p = p + 4;
881b8e
   p = restfpr (abfd, p, r);
881b8e
   bfd_put_32 (abfd, MTLR_R0, p);
881b8e
@@ -6510,6 +6801,25 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
881b8e
   return TRUE;
881b8e
 }
881b8e
 
881b8e
+/* Return true if we have dynamic relocs that apply to read-only sections.  */
881b8e
+
881b8e
+static bfd_boolean
881b8e
+readonly_dynrelocs (struct elf_link_hash_entry *h)
881b8e
+{
881b8e
+  struct ppc_link_hash_entry *eh;
881b8e
+  struct elf_dyn_relocs *p;
881b8e
+
881b8e
+  eh = (struct ppc_link_hash_entry *) h;
881b8e
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
881b8e
+    {
881b8e
+      asection *s = p->sec->output_section;
881b8e
+
881b8e
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
881b8e
+	return TRUE;
881b8e
+    }
881b8e
+  return FALSE;
881b8e
+}
881b8e
+
881b8e
 /* Adjust a symbol defined by a dynamic object and referenced by a
881b8e
    regular object.  The current definition is in some section of the
881b8e
    dynamic object, but we're not including those sections.  We have to
881b8e
@@ -6547,6 +6857,26 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
881b8e
 	  h->plt.plist = NULL;
881b8e
 	  h->needs_plt = 0;
881b8e
 	}
881b8e
+      else if (abiversion (info->output_bfd) == 2)
881b8e
+	{
881b8e
+	  /* After adjust_dynamic_symbol, non_got_ref set in the
881b8e
+	     non-shared case means that we have allocated space in
881b8e
+	     .dynbss for the symbol and thus dyn_relocs for this
881b8e
+	     symbol should be discarded.
881b8e
+	     If we get here we know we are making a PLT entry for this
881b8e
+	     symbol, and in an executable we'd normally resolve
881b8e
+	     relocations against this symbol to the PLT entry.  Allow
881b8e
+	     dynamic relocs if the reference is weak, and the dynamic
881b8e
+	     relocs will not cause text relocation.  */
881b8e
+	  if (!h->ref_regular_nonweak
881b8e
+	      && h->non_got_ref
881b8e
+	      && h->type != STT_GNU_IFUNC
881b8e
+	      && !readonly_dynrelocs (h))
881b8e
+	    h->non_got_ref = 0;
881b8e
+
881b8e
+	  /* If making a plt entry, then we don't need copy relocs.  */
881b8e
+	  return TRUE;
881b8e
+	}
881b8e
     }
881b8e
   else
881b8e
     h->plt.plist = NULL;
881b8e
@@ -6581,26 +6911,12 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
881b8e
   if (!h->def_dynamic || !h->ref_regular || h->def_regular)
881b8e
     return TRUE;
881b8e
 
881b8e
-  if (ELIMINATE_COPY_RELOCS)
881b8e
+  /* If we didn't find any dynamic relocs in read-only sections, then
881b8e
+     we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
881b8e
+  if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (h))
881b8e
     {
881b8e
-      struct ppc_link_hash_entry * eh;
881b8e
-      struct elf_dyn_relocs *p;
881b8e
-
881b8e
-      eh = (struct ppc_link_hash_entry *) h;
881b8e
-      for (p = eh->dyn_relocs; p != NULL; p = p->next)
881b8e
-	{
881b8e
-	  s = p->sec->output_section;
881b8e
-	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
881b8e
-	    break;
881b8e
-	}
881b8e
-
881b8e
-      /* If we didn't find any dynamic relocs in read-only sections, then
881b8e
-	 we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
881b8e
-      if (p == NULL)
881b8e
-	{
881b8e
-	  h->non_got_ref = 0;
881b8e
-	  return TRUE;
881b8e
-	}
881b8e
+      h->non_got_ref = 0;
881b8e
+      return TRUE;
881b8e
     }
881b8e
 
881b8e
   if (h->plt.plist != NULL)
881b8e
@@ -6980,6 +7296,8 @@ dec_dynrel_count (bfd_vma r_info,
881b8e
     case R_PPC64_TPREL16_HA:
881b8e
     case R_PPC64_TPREL16_DS:
881b8e
     case R_PPC64_TPREL16_LO_DS:
881b8e
+    case R_PPC64_TPREL16_HIGH:
881b8e
+    case R_PPC64_TPREL16_HIGHA:
881b8e
     case R_PPC64_TPREL16_HIGHER:
881b8e
     case R_PPC64_TPREL16_HIGHERA:
881b8e
     case R_PPC64_TPREL16_HIGHEST:
881b8e
@@ -7001,6 +7319,8 @@ dec_dynrel_count (bfd_vma r_info,
881b8e
     case R_PPC64_ADDR16_DS:
881b8e
     case R_PPC64_ADDR16_HA:
881b8e
     case R_PPC64_ADDR16_HI:
881b8e
+    case R_PPC64_ADDR16_HIGH:
881b8e
+    case R_PPC64_ADDR16_HIGHA:
881b8e
     case R_PPC64_ADDR16_HIGHER:
881b8e
     case R_PPC64_ADDR16_HIGHERA:
881b8e
     case R_PPC64_ADDR16_HIGHEST:
881b8e
@@ -7504,6 +7824,9 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
881b8e
   if (htab == NULL)
881b8e
     return NULL;
881b8e
 
881b8e
+  if (abiversion (info->output_bfd) == 1)
881b8e
+    htab->opd_abi = 1;
881b8e
+
881b8e
   if (*no_multi_toc)
881b8e
     htab->do_multi_toc = 0;
881b8e
   else if (!htab->do_multi_toc)
881b8e
@@ -8287,7 +8610,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
881b8e
 		  || discarded_section (sym_sec))
881b8e
 		continue;
881b8e
 
881b8e
-	      if (!SYMBOL_CALLS_LOCAL (info, h))
881b8e
+	      if (!SYMBOL_REFERENCES_LOCAL (info, h))
881b8e
 		continue;
881b8e
 
881b8e
 	      if (h != NULL)
881b8e
@@ -8886,7 +9209,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
881b8e
 	      {
881b8e
 		s = htab->iplt;
881b8e
 		pent->plt.offset = s->size;
881b8e
-		s->size += PLT_ENTRY_SIZE;
881b8e
+		s->size += PLT_ENTRY_SIZE (htab);
881b8e
 		s = htab->reliplt;
881b8e
 	      }
881b8e
 	    else
881b8e
@@ -8895,21 +9218,26 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
881b8e
 		   first entry.  */
881b8e
 		s = htab->plt;
881b8e
 		if (s->size == 0)
881b8e
-		  s->size += PLT_INITIAL_ENTRY_SIZE;
881b8e
+		  s->size += PLT_INITIAL_ENTRY_SIZE (htab);
881b8e
 
881b8e
 		pent->plt.offset = s->size;
881b8e
 
881b8e
 		/* Make room for this entry.  */
881b8e
-		s->size += PLT_ENTRY_SIZE;
881b8e
+		s->size += PLT_ENTRY_SIZE (htab);
881b8e
 
881b8e
 		/* Make room for the .glink code.  */
881b8e
 		s = htab->glink;
881b8e
 		if (s->size == 0)
881b8e
 		  s->size += GLINK_CALL_STUB_SIZE;
881b8e
-		/* We need bigger stubs past index 32767.  */
881b8e
-		if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
881b8e
+		if (htab->opd_abi)
881b8e
+		  {
881b8e
+		    /* We need bigger stubs past index 32767.  */
881b8e
+		    if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
881b8e
+		      s->size += 4;
881b8e
+		    s->size += 2*4;
881b8e
+		  }
881b8e
+		else
881b8e
 		  s->size += 4;
881b8e
-		s->size += 2*4;
881b8e
 
881b8e
 		/* We also need to make an entry in the .rela.plt section.  */
881b8e
 		s = htab->relplt;
881b8e
@@ -9002,7 +9330,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
881b8e
 
881b8e
   if (eh->dyn_relocs == NULL
881b8e
       || (!htab->elf.dynamic_sections_created
881b8e
-	  && h->type != STT_GNU_IFUNC))
881b8e
+	  && (h->type != STT_GNU_IFUNC
881b8e
+	      || !htab->opd_abi)))
881b8e
     return TRUE;
881b8e
 
881b8e
   /* In the shared -Bsymbolic case, discard space allocated for
881b8e
@@ -9098,28 +9427,65 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
881b8e
   return TRUE;
881b8e
 }
881b8e
 
881b8e
-/* Find any dynamic relocs that apply to read-only sections.  */
881b8e
+/* Called via elf_link_hash_traverse from ppc64_elf_size_dynamic_sections
881b8e
+   to set up space for global entry stubs.  These are put in glink,
881b8e
+   after the branch table.  */
881b8e
 
881b8e
 static bfd_boolean
881b8e
-readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
881b8e
+size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
881b8e
 {
881b8e
-  struct ppc_link_hash_entry *eh;
881b8e
-  struct elf_dyn_relocs *p;
881b8e
+  struct bfd_link_info *info;
881b8e
+  struct ppc_link_hash_table *htab;
881b8e
+  struct plt_entry *pent;
881b8e
+  asection *s;
881b8e
 
881b8e
-  eh = (struct ppc_link_hash_entry *) h;
881b8e
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
881b8e
-    {
881b8e
-      asection *s = p->sec->output_section;
881b8e
+  if (h->root.type == bfd_link_hash_indirect)
881b8e
+    return TRUE;
881b8e
 
881b8e
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
881b8e
-	{
881b8e
-	  struct bfd_link_info *info = inf;
881b8e
+  if (!h->pointer_equality_needed)
881b8e
+    return TRUE;
881b8e
 
881b8e
-	  info->flags |= DF_TEXTREL;
881b8e
+  if (h->def_regular)
881b8e
+    return TRUE;
881b8e
 
881b8e
-	  /* Not an error, just cut short the traversal.  */
881b8e
-	  return FALSE;
881b8e
-	}
881b8e
+  info = inf;
881b8e
+  htab = ppc_hash_table (info);
881b8e
+  if (htab == NULL)
881b8e
+    return FALSE;
881b8e
+
881b8e
+  s = htab->glink;
881b8e
+  for (pent = h->plt.plist; pent != NULL; pent = pent->next)
881b8e
+    if (pent->plt.offset != (bfd_vma) -1
881b8e
+	&& pent->addend == 0)
881b8e
+      {
881b8e
+	/* For ELFv2, if this symbol is not defined in a regular file
881b8e
+	   and we are not generating a shared library or pie, then we
881b8e
+	   need to define the symbol in the executable on a call stub.
881b8e
+	   This is to avoid text relocations.  */
881b8e
+	s->size = (s->size + 15) & -16;
881b8e
+	h->root.u.def.section = s;
881b8e
+	h->root.u.def.value = s->size;
881b8e
+	s->size += 16;
881b8e
+	break;
881b8e
+      }
881b8e
+  return TRUE;
881b8e
+}
881b8e
+
881b8e
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
881b8e
+   read-only sections.  */
881b8e
+
881b8e
+static bfd_boolean
881b8e
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info)
881b8e
+{
881b8e
+  if (h->root.type == bfd_link_hash_indirect)
881b8e
+    return TRUE;
881b8e
+
881b8e
+  if (readonly_dynrelocs (h))
881b8e
+    {
881b8e
+      ((struct bfd_link_info *) info)->flags |= DF_TEXTREL;
881b8e
+
881b8e
+      /* Not an error, just cut short the traversal.  */
881b8e
+      return FALSE;
881b8e
     }
881b8e
   return TRUE;
881b8e
 }
881b8e
@@ -9127,7 +9493,7 @@ readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
881b8e
 /* Set the sizes of the dynamic sections.  */
881b8e
 
881b8e
 static bfd_boolean
881b8e
-ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
+ppc64_elf_size_dynamic_sections (bfd *output_bfd,
881b8e
 				 struct bfd_link_info *info)
881b8e
 {
881b8e
   struct ppc_link_hash_table *htab;
881b8e
@@ -9258,7 +9624,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
 	      {
881b8e
 		s = htab->iplt;
881b8e
 		ent->plt.offset = s->size;
881b8e
-		s->size += PLT_ENTRY_SIZE;
881b8e
+		s->size += PLT_ENTRY_SIZE (htab);
881b8e
 
881b8e
 		htab->reliplt->size += sizeof (Elf64_External_Rela);
881b8e
 	      }
881b8e
@@ -9270,6 +9636,12 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
   /* Allocate global sym .plt and .got entries, and space for global
881b8e
      sym dynamic relocs.  */
881b8e
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
881b8e
+  /* Stash the end of glink branch table.  */
881b8e
+  if (htab->glink != NULL)
881b8e
+    htab->glink->rawsize = htab->glink->size;
881b8e
+
881b8e
+  if (!htab->opd_abi && !info->shared)
881b8e
+    elf_link_hash_traverse (&htab->elf, size_global_entry_stubs, info);
881b8e
 
881b8e
   first_tlsld = NULL;
881b8e
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
881b8e
@@ -9415,6 +9787,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
 
881b8e
   if (htab->elf.dynamic_sections_created)
881b8e
     {
881b8e
+      bfd_boolean tls_opt;
881b8e
+
881b8e
       /* Add some entries to the .dynamic section.  We fill in the
881b8e
 	 values later, in ppc64_elf_finish_dynamic_sections, but we
881b8e
 	 must add the entries now so that we get the correct size for
881b8e
@@ -9439,18 +9813,21 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
 	    return FALSE;
881b8e
 	}
881b8e
 
881b8e
-      if (NO_OPD_RELOCS)
881b8e
+      if (NO_OPD_RELOCS && abiversion (output_bfd) <= 1)
881b8e
 	{
881b8e
 	  if (!add_dynamic_entry (DT_PPC64_OPD, 0)
881b8e
 	      || !add_dynamic_entry (DT_PPC64_OPDSZ, 0))
881b8e
 	    return FALSE;
881b8e
 	}
881b8e
 
881b8e
-      if (!htab->no_tls_get_addr_opt
881b8e
-	  && htab->tls_get_addr_fd != NULL
881b8e
-	  && htab->tls_get_addr_fd->elf.plt.plist != NULL
881b8e
-	  && !add_dynamic_entry (DT_PPC64_TLSOPT, 0))
881b8e
-	return FALSE;
881b8e
+      tls_opt = (!htab->no_tls_get_addr_opt
881b8e
+		 && htab->tls_get_addr_fd != NULL
881b8e
+		 && htab->tls_get_addr_fd->elf.plt.plist != NULL);
881b8e
+      if (tls_opt || !htab->opd_abi)
881b8e
+	{
881b8e
+	  if (!add_dynamic_entry (DT_PPC64_OPT, tls_opt ? PPC64_OPT_TLS : 0))
881b8e
+	    return FALSE;
881b8e
+	}
881b8e
 
881b8e
       if (relocs)
881b8e
 	{
881b8e
@@ -9462,7 +9839,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
 	  /* If any dynamic relocs apply to a read-only section,
881b8e
 	     then we need a DT_TEXTREL entry.  */
881b8e
 	  if ((info->flags & DF_TEXTREL) == 0)
881b8e
-	    elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
881b8e
+	    elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
881b8e
 
881b8e
 	  if ((info->flags & DF_TEXTREL) != 0)
881b8e
 	    {
881b8e
@@ -9476,6 +9853,19 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
881b8e
   return TRUE;
881b8e
 }
881b8e
 
881b8e
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
881b8e
+
881b8e
+static bfd_boolean
881b8e
+ppc64_elf_hash_symbol (struct elf_link_hash_entry *h)
881b8e
+{
881b8e
+  if (h->plt.plist != NULL
881b8e
+      && !h->def_regular
881b8e
+      && !h->pointer_equality_needed)
881b8e
+    return FALSE;
881b8e
+
881b8e
+  return _bfd_elf_hash_symbol (h);
881b8e
+}
881b8e
+
881b8e
 /* Determine the type of stub needed, if any, for a call.  */
881b8e
 
881b8e
 static inline enum ppc_stub_type
881b8e
@@ -9483,7 +9873,8 @@ ppc_type_of_stub (asection *input_sec,
881b8e
 		  const Elf_Internal_Rela *rel,
881b8e
 		  struct ppc_link_hash_entry **hash,
881b8e
 		  struct plt_entry **plt_ent,
881b8e
-		  bfd_vma destination)
881b8e
+		  bfd_vma destination,
881b8e
+		  unsigned long local_off)
881b8e
 {
881b8e
   struct ppc_link_hash_entry *h = *hash;
881b8e
   bfd_vma location;
881b8e
@@ -9552,7 +9943,7 @@ ppc_type_of_stub (asection *input_sec,
881b8e
   if (r_type != R_PPC64_REL24)
881b8e
     max_branch_offset = 1 << 15;
881b8e
 
881b8e
-  if (branch_offset + max_branch_offset >= 2 * max_branch_offset)
881b8e
+  if (branch_offset + max_branch_offset >= 2 * max_branch_offset - local_off)
881b8e
     /* We need a stub.  Figure out whether a long_branch or plt_branch
881b8e
        is needed later.  */
881b8e
     return ppc_stub_long_branch;
881b8e
@@ -9569,9 +9960,9 @@ ppc_type_of_stub (asection *input_sec,
881b8e
    the appropriate glink entry if so.
881b8e
 
881b8e
    .	fake dep barrier	compare
881b8e
-   .	ld 11,xxx(2)		ld 11,xxx(2)
881b8e
-   .	mtctr 11		mtctr 11
881b8e
-   .	xor 11,11,11		ld 2,xxx+8(2)
881b8e
+   .	ld 12,xxx(2)		ld 12,xxx(2)
881b8e
+   .	mtctr 12		mtctr 12
881b8e
+   .	xor 11,12,12		ld 2,xxx+8(2)
881b8e
    .	add 2,2,11		cmpldi 2,0
881b8e
    .	ld 2,xxx+8(2)		bnectr+
881b8e
    .	bctr			b <glink_entry>
881b8e
@@ -9591,19 +9982,23 @@ plt_stub_size (struct ppc_link_hash_table *htab,
881b8e
 	       struct ppc_stub_hash_entry *stub_entry,
881b8e
 	       bfd_vma off)
881b8e
 {
881b8e
-  unsigned size = PLT_CALL_STUB_SIZE;
881b8e
-
881b8e
-  if (!(ALWAYS_EMIT_R2SAVE
881b8e
-	|| stub_entry->stub_type == ppc_stub_plt_call_r2save))
881b8e
-    size -= 4;
881b8e
-  if (!htab->plt_static_chain)
881b8e
-    size -= 4;
881b8e
-  if (htab->plt_thread_safe)
881b8e
-    size += 8;
881b8e
-  if (PPC_HA (off) == 0)
881b8e
-    size -= 4;
881b8e
-  if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
881b8e
+  unsigned size = 12;
881b8e
+
881b8e
+  if (ALWAYS_EMIT_R2SAVE
881b8e
+      || stub_entry->stub_type == ppc_stub_plt_call_r2save)
881b8e
+    size += 4;
881b8e
+  if (PPC_HA (off) != 0)
881b8e
     size += 4;
881b8e
+  if (htab->opd_abi)
881b8e
+    {
881b8e
+      size += 4;
881b8e
+      if (htab->plt_static_chain)
881b8e
+	size += 4;
881b8e
+      if (htab->plt_thread_safe)
881b8e
+	size += 8;
881b8e
+      if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
881b8e
+	size += 4;
881b8e
+    }
881b8e
   if (stub_entry->h != NULL
881b8e
       && (stub_entry->h == htab->tls_get_addr_fd
881b8e
 	  || stub_entry->h == htab->tls_get_addr)
881b8e
@@ -9637,12 +10032,14 @@ build_plt_stub (struct ppc_link_hash_table *htab,
881b8e
 		bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
881b8e
 {
881b8e
   bfd *obfd = htab->stub_bfd;
881b8e
+  bfd_boolean plt_load_toc = htab->opd_abi;
881b8e
   bfd_boolean plt_static_chain = htab->plt_static_chain;
881b8e
   bfd_boolean plt_thread_safe = htab->plt_thread_safe;
881b8e
   bfd_boolean use_fake_dep = plt_thread_safe;
881b8e
   bfd_vma cmp_branch_off = 0;
881b8e
 
881b8e
   if (!ALWAYS_USE_FAKE_DEP
881b8e
+      && plt_load_toc
881b8e
       && plt_thread_safe
881b8e
       && !(stub_entry->h != NULL
881b8e
 	   && (stub_entry->h == htab->tls_get_addr_fd
881b8e
@@ -9650,7 +10047,8 @@ build_plt_stub (struct ppc_link_hash_table *htab,
881b8e
 	   && !htab->no_tls_get_addr_opt))
881b8e
     {
881b8e
       bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1;
881b8e
-      bfd_vma pltindex = (pltoff - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE;
881b8e
+      bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab))
881b8e
+			  / PLT_ENTRY_SIZE (htab));
881b8e
       bfd_vma glinkoff = GLINK_CALL_STUB_SIZE + pltindex * 8;
881b8e
       bfd_vma to, from;
881b8e
 
881b8e
@@ -9684,44 +10082,51 @@ build_plt_stub (struct ppc_link_hash_table *htab,
881b8e
 	  r[1].r_offset = r[0].r_offset + 4;
881b8e
 	  r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
881b8e
 	  r[1].r_addend = r[0].r_addend;
881b8e
-	  if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
-	    {
881b8e
-	      r[2].r_offset = r[1].r_offset + 4;
881b8e
-	      r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
881b8e
-	      r[2].r_addend = r[0].r_addend;
881b8e
-	    }
881b8e
-	  else
881b8e
+	  if (plt_load_toc)
881b8e
 	    {
881b8e
-	      r[2].r_offset = r[1].r_offset + 8 + 8 * use_fake_dep;
881b8e
-	      r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
881b8e
-	      r[2].r_addend = r[0].r_addend + 8;
881b8e
-	      if (plt_static_chain)
881b8e
+	      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
 		{
881b8e
-		  r[3].r_offset = r[2].r_offset + 4;
881b8e
-		  r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
881b8e
-		  r[3].r_addend = r[0].r_addend + 16;
881b8e
+		  r[2].r_offset = r[1].r_offset + 4;
881b8e
+		  r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
881b8e
+		  r[2].r_addend = r[0].r_addend;
881b8e
+		}
881b8e
+	      else
881b8e
+		{
881b8e
+		  r[2].r_offset = r[1].r_offset + 8 + 8 * use_fake_dep;
881b8e
+		  r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
881b8e
+		  r[2].r_addend = r[0].r_addend + 8;
881b8e
+		  if (plt_static_chain)
881b8e
+		    {
881b8e
+		      r[3].r_offset = r[2].r_offset + 4;
881b8e
+		      r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
881b8e
+		      r[3].r_addend = r[0].r_addend + 16;
881b8e
+		    }
881b8e
 		}
881b8e
 	    }
881b8e
 	}
881b8e
       if (ALWAYS_EMIT_R2SAVE
881b8e
 	  || stub_entry->stub_type == ppc_stub_plt_call_r2save)
881b8e
-	bfd_put_32 (obfd, STD_R2_40R1, p),			p += 4;
881b8e
-      bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p),	p += 4;
881b8e
-      bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),	p += 4;
881b8e
-      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
+	bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p),	p += 4;
881b8e
+      bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p),	p += 4;
881b8e
+      bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p),	p += 4;
881b8e
+      if (plt_load_toc
881b8e
+	  && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
 	{
881b8e
-	  bfd_put_32 (obfd, ADDI_R12_R12 | PPC_LO (offset), p),	p += 4;
881b8e
+	  bfd_put_32 (obfd, ADDI_R11_R11 | PPC_LO (offset), p),	p += 4;
881b8e
 	  offset = 0;
881b8e
 	}
881b8e
-      bfd_put_32 (obfd, MTCTR_R11, p),				p += 4;
881b8e
-      if (use_fake_dep)
881b8e
+      bfd_put_32 (obfd, MTCTR_R12, p),				p += 4;
881b8e
+      if (plt_load_toc)
881b8e
 	{
881b8e
-	  bfd_put_32 (obfd, XOR_R11_R11_R11, p),		p += 4;
881b8e
-	  bfd_put_32 (obfd, ADD_R12_R12_R11, p),		p += 4;
881b8e
+	  if (use_fake_dep)
881b8e
+	    {
881b8e
+	      bfd_put_32 (obfd, XOR_R2_R12_R12, p),		p += 4;
881b8e
+	      bfd_put_32 (obfd, ADD_R11_R11_R2, p),		p += 4;
881b8e
+	    }
881b8e
+	  bfd_put_32 (obfd, LD_R2_0R11 | PPC_LO (offset + 8), p), p += 4;
881b8e
+	  if (plt_static_chain)
881b8e
+	    bfd_put_32 (obfd, LD_R11_0R11 | PPC_LO (offset + 16), p), p += 4;
881b8e
 	}
881b8e
-      bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset + 8), p),	p += 4;
881b8e
-      if (plt_static_chain)
881b8e
-	bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset + 16), p), p += 4;
881b8e
     }
881b8e
   else
881b8e
     {
881b8e
@@ -9731,45 +10136,52 @@ build_plt_stub (struct ppc_link_hash_table *htab,
881b8e
 	      || stub_entry->stub_type == ppc_stub_plt_call_r2save)
881b8e
 	    r[0].r_offset += 4;
881b8e
 	  r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
881b8e
-	  if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
+	  if (plt_load_toc)
881b8e
 	    {
881b8e
-	      r[1].r_offset = r[0].r_offset + 4;
881b8e
-	      r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
881b8e
-	      r[1].r_addend = r[0].r_addend;
881b8e
-	    }
881b8e
-	  else
881b8e
-	    {
881b8e
-	      r[1].r_offset = r[0].r_offset + 8 + 8 * use_fake_dep;
881b8e
-	      r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
881b8e
-	      r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
881b8e
-	      if (plt_static_chain)
881b8e
+	      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
 		{
881b8e
-		  r[2].r_offset = r[1].r_offset + 4;
881b8e
-		  r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
881b8e
-		  r[2].r_addend = r[0].r_addend + 8;
881b8e
+		  r[1].r_offset = r[0].r_offset + 4;
881b8e
+		  r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
881b8e
+		  r[1].r_addend = r[0].r_addend;
881b8e
+		}
881b8e
+	      else
881b8e
+		{
881b8e
+		  r[1].r_offset = r[0].r_offset + 8 + 8 * use_fake_dep;
881b8e
+		  r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
881b8e
+		  r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
881b8e
+		  if (plt_static_chain)
881b8e
+		    {
881b8e
+		      r[2].r_offset = r[1].r_offset + 4;
881b8e
+		      r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
881b8e
+		      r[2].r_addend = r[0].r_addend + 8;
881b8e
+		    }
881b8e
 		}
881b8e
 	    }
881b8e
 	}
881b8e
       if (ALWAYS_EMIT_R2SAVE
881b8e
 	  || stub_entry->stub_type == ppc_stub_plt_call_r2save)
881b8e
-	bfd_put_32 (obfd, STD_R2_40R1, p),			p += 4;
881b8e
-      bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset), p),	p += 4;
881b8e
-      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
+	bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p),	p += 4;
881b8e
+      bfd_put_32 (obfd, LD_R12_0R2 | PPC_LO (offset), p),	p += 4;
881b8e
+      if (plt_load_toc
881b8e
+	  && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
881b8e
 	{
881b8e
 	  bfd_put_32 (obfd, ADDI_R2_R2 | PPC_LO (offset), p),	p += 4;
881b8e
 	  offset = 0;
881b8e
 	}
881b8e
-      bfd_put_32 (obfd, MTCTR_R11, p),				p += 4;
881b8e
-      if (use_fake_dep)
881b8e
+      bfd_put_32 (obfd, MTCTR_R12, p),				p += 4;
881b8e
+      if (plt_load_toc)
881b8e
 	{
881b8e
-	  bfd_put_32 (obfd, XOR_R11_R11_R11, p),		p += 4;
881b8e
-	  bfd_put_32 (obfd, ADD_R2_R2_R11, p),			p += 4;
881b8e
+	  if (use_fake_dep)
881b8e
+	    {
881b8e
+	      bfd_put_32 (obfd, XOR_R11_R12_R12, p),		p += 4;
881b8e
+	      bfd_put_32 (obfd, ADD_R2_R2_R11, p),		p += 4;
881b8e
+	    }
881b8e
+	  if (plt_static_chain)
881b8e
+	    bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
881b8e
+	  bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p), p += 4;
881b8e
 	}
881b8e
-      if (plt_static_chain)
881b8e
-	bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
881b8e
-      bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p),	p += 4;
881b8e
     }
881b8e
-  if (plt_thread_safe && !use_fake_dep)
881b8e
+  if (plt_load_toc && plt_thread_safe && !use_fake_dep)
881b8e
     {
881b8e
       bfd_put_32 (obfd, CMPLDI_R2_0, p),			p += 4;
881b8e
       bfd_put_32 (obfd, BNECTR_P4, p),				p += 4;
881b8e
@@ -9789,11 +10201,9 @@ build_plt_stub (struct ppc_link_hash_table *htab,
881b8e
 #define ADD_R3_R12_R13	0x7c6c6a14
881b8e
 #define BEQLR		0x4d820020
881b8e
 #define MR_R3_R0	0x7c030378
881b8e
-#define MFLR_R11	0x7d6802a6
881b8e
 #define STD_R11_0R1	0xf9610000
881b8e
 #define BCTRL		0x4e800421
881b8e
 #define LD_R11_0R1	0xe9610000
881b8e
-#define LD_R2_0R1	0xe8410000
881b8e
 #define MTLR_R11	0x7d6803a6
881b8e
 
881b8e
 static inline bfd_byte *
881b8e
@@ -9811,15 +10221,15 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
881b8e
   bfd_put_32 (obfd, BEQLR, p),			p += 4;
881b8e
   bfd_put_32 (obfd, MR_R3_R0, p),		p += 4;
881b8e
   bfd_put_32 (obfd, MFLR_R11, p),		p += 4;
881b8e
-  bfd_put_32 (obfd, STD_R11_0R1 + 32, p),	p += 4;
881b8e
+  bfd_put_32 (obfd, STD_R11_0R1 + STK_LINKER (htab), p), p += 4;
881b8e
 
881b8e
   if (r != NULL)
881b8e
     r[0].r_offset += 9 * 4;
881b8e
   p = build_plt_stub (htab, stub_entry, p, offset, r);
881b8e
   bfd_put_32 (obfd, BCTRL, p - 4);
881b8e
 
881b8e
-  bfd_put_32 (obfd, LD_R11_0R1 + 32, p),	p += 4;
881b8e
-  bfd_put_32 (obfd, LD_R2_0R1 + 40, p),		p += 4;
881b8e
+  bfd_put_32 (obfd, LD_R11_0R1 + STK_LINKER (htab), p),	p += 4;
881b8e
+  bfd_put_32 (obfd, LD_R2_0R1 + STK_TOC (htab), p),	p += 4;
881b8e
   bfd_put_32 (obfd, MTLR_R11, p),		p += 4;
881b8e
   bfd_put_32 (obfd, BLR, p),			p += 4;
881b8e
 
881b8e
@@ -9868,6 +10278,8 @@ get_r2off (struct bfd_link_info *info,
881b8e
       /* Support linking -R objects.  Get the toc pointer from the
881b8e
 	 opd entry.  */
881b8e
       char buf[8];
881b8e
+      if (!htab->opd_abi)
881b8e
+	return r2off;
881b8e
       asection *opd = stub_entry->h->elf.root.u.def.section;
881b8e
       bfd_vma opd_off = stub_entry->h->elf.root.u.def.value;
881b8e
 
881b8e
@@ -9920,9 +10332,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
     case ppc_stub_long_branch:
881b8e
     case ppc_stub_long_branch_r2off:
881b8e
       /* Branches are relative.  This is where we are going to.  */
881b8e
-      off = dest = (stub_entry->target_value
881b8e
-		    + stub_entry->target_section->output_offset
881b8e
-		    + stub_entry->target_section->output_section->vma);
881b8e
+      dest = (stub_entry->target_value
881b8e
+	      + stub_entry->target_section->output_offset
881b8e
+	      + stub_entry->target_section->output_section->vma);
881b8e
+      dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
881b8e
+      off = dest;
881b8e
 
881b8e
       /* And this is where we are coming from.  */
881b8e
       off -= (stub_entry->stub_offset
881b8e
@@ -9939,7 +10353,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	      htab->stub_error = TRUE;
881b8e
 	      return FALSE;
881b8e
 	    }
881b8e
-	  bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
881b8e
+	  bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
881b8e
 	  loc += 4;
881b8e
 	  size = 12;
881b8e
 	  if (PPC_HA (r2off) != 0)
881b8e
@@ -10025,6 +10439,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
       dest = (stub_entry->target_value
881b8e
 	      + stub_entry->target_section->output_offset
881b8e
 	      + stub_entry->target_section->output_section->vma);
881b8e
+      if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
881b8e
+	dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
881b8e
 
881b8e
       bfd_put_64 (htab->brlt->owner, dest,
881b8e
 		  htab->brlt->contents + br_entry->offset);
881b8e
@@ -10093,7 +10509,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	  r[0].r_offset = loc - stub_entry->stub_sec->contents;
881b8e
 	  if (bfd_big_endian (info->output_bfd))
881b8e
 	    r[0].r_offset += 2;
881b8e
-	  if (stub_entry->stub_type == ppc_stub_plt_branch_r2off)
881b8e
+	  if (stub_entry->stub_type == ppc_stub_plt_branch_r2off
881b8e
+	      && htab->opd_abi)
881b8e
 	    r[0].r_offset += 4;
881b8e
 	  r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
881b8e
 	  r[0].r_addend = dest;
881b8e
@@ -10106,19 +10523,20 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	    }
881b8e
 	}
881b8e
 
881b8e
-      if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
881b8e
+      if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
881b8e
+	  || !htab->opd_abi)
881b8e
 	{
881b8e
 	  if (PPC_HA (off) != 0)
881b8e
 	    {
881b8e
 	      size = 16;
881b8e
-	      bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
881b8e
+	      bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
881b8e
 	      loc += 4;
881b8e
-	      bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
881b8e
+	      bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
881b8e
 	    }
881b8e
 	  else
881b8e
 	    {
881b8e
 	      size = 12;
881b8e
-	      bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
881b8e
+	      bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
881b8e
 	    }
881b8e
 	}
881b8e
       else
881b8e
@@ -10131,20 +10549,20 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	      return FALSE;
881b8e
 	    }
881b8e
 
881b8e
-	  bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
881b8e
+	  bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
881b8e
 	  loc += 4;
881b8e
 	  size = 20;
881b8e
 	  if (PPC_HA (off) != 0)
881b8e
 	    {
881b8e
 	      size += 4;
881b8e
-	      bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
881b8e
+	      bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
881b8e
 	      loc += 4;
881b8e
-	      bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
881b8e
+	      bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
881b8e
 	      loc += 4;
881b8e
 	    }
881b8e
 	  else
881b8e
 	    {
881b8e
-	      bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
881b8e
+	      bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
881b8e
 	      loc += 4;
881b8e
 	    }
881b8e
 
881b8e
@@ -10157,7 +10575,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	  bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
881b8e
 	}
881b8e
       loc += 4;
881b8e
-      bfd_put_32 (htab->stub_bfd, MTCTR_R11, loc);
881b8e
+      bfd_put_32 (htab->stub_bfd, MTCTR_R12, loc);
881b8e
       loc += 4;
881b8e
       bfd_put_32 (htab->stub_bfd, BCTR, loc);
881b8e
       break;
881b8e
@@ -10202,7 +10620,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	  bfd_byte *rl;
881b8e
 
881b8e
 	  rela.r_offset = dest;
881b8e
-	  rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
881b8e
+	  if (htab->opd_abi)
881b8e
+	    rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
881b8e
+	  else
881b8e
+	    rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
881b8e
 	  rela.r_addend = (stub_entry->target_value
881b8e
 			   + stub_entry->target_section->output_offset
881b8e
 			   + stub_entry->target_section->output_section->vma);
881b8e
@@ -10354,10 +10775,11 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
       if (info->emitrelocations)
881b8e
 	{
881b8e
 	  stub_entry->stub_sec->reloc_count
881b8e
-	    += (2
881b8e
-		+ (PPC_HA (off) != 0)
881b8e
-		+ (htab->plt_static_chain
881b8e
-		   && PPC_HA (off + 16) == PPC_HA (off)));
881b8e
+	    += ((PPC_HA (off) != 0)
881b8e
+		+ (htab->opd_abi
881b8e
+		   ? 2 + (htab->plt_static_chain
881b8e
+			  && PPC_HA (off + 16) == PPC_HA (off))
881b8e
+		   : 1));
881b8e
 	  stub_entry->stub_sec->flags |= SEC_RELOC;
881b8e
 	}
881b8e
     }
881b8e
@@ -10366,6 +10788,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
       /* ppc_stub_long_branch or ppc_stub_plt_branch, or their r2off
881b8e
 	 variants.  */
881b8e
       bfd_vma r2off = 0;
881b8e
+      bfd_vma local_off = 0;
881b8e
 
881b8e
       off = (stub_entry->target_value
881b8e
 	     + stub_entry->target_section->output_offset
881b8e
@@ -10383,7 +10806,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
       if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
881b8e
 	{
881b8e
 	  r2off = get_r2off (info, stub_entry);
881b8e
-	  if (r2off == 0)
881b8e
+	  if (r2off == 0 && htab->opd_abi)
881b8e
 	    {
881b8e
 	      htab->stub_error = TRUE;
881b8e
 	      return FALSE;
881b8e
@@ -10394,8 +10817,13 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	  off -= size - 4;
881b8e
 	}
881b8e
 
881b8e
-      /* If the branch offset if too big, use a ppc_stub_plt_branch.  */
881b8e
-      if (off + (1 << 25) >= (bfd_vma) (1 << 26))
881b8e
+      local_off = PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
881b8e
+
881b8e
+      /* If the branch offset if too big, use a ppc_stub_plt_branch.
881b8e
+	 Do the same for -R objects without function descriptors.  */
881b8e
+      if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
881b8e
+	  || (stub_entry->stub_type == ppc_stub_long_branch_r2off
881b8e
+	      && r2off == 0))
881b8e
 	{
881b8e
 	  struct ppc_branch_hash_entry *br_entry;
881b8e
 
881b8e
@@ -10438,7 +10866,8 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
881b8e
 	      stub_entry->stub_sec->flags |= SEC_RELOC;
881b8e
 	    }
881b8e
 
881b8e
-	  if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
881b8e
+	  if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
881b8e
+	      || !htab->opd_abi)
881b8e
 	    {
881b8e
 	      size = 12;
881b8e
 	      if (PPC_HA (off) != 0)
881b8e
@@ -10991,7 +11420,10 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
881b8e
 	     need a plt_branch stub.  A plt_branch stub uses r2.  */
881b8e
 	  else if (dest - (isec->output_offset
881b8e
 			   + isec->output_section->vma
881b8e
-			   + rel->r_offset) + (1 << 25) >= (2 << 25))
881b8e
+			   + rel->r_offset) + (1 << 25)
881b8e
+		   >= (2u << 25) - PPC64_LOCAL_ENTRY_OFFSET (h
881b8e
+							     ? h->other
881b8e
+							     : sym->st_other))
881b8e
 	    {
881b8e
 	      ret = 1;
881b8e
 	      break;
881b8e
@@ -11338,7 +11770,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
881b8e
   htab->plt_stub_align = plt_stub_align;
881b8e
   if (plt_thread_safe == -1 && !info->executable)
881b8e
     plt_thread_safe = 1;
881b8e
-  if (plt_thread_safe == -1)
881b8e
+  if (!htab->opd_abi)
881b8e
+    plt_thread_safe = 0;
881b8e
+  else if (plt_thread_safe == -1)
881b8e
     {
881b8e
       static const char *const thread_starter[] =
881b8e
 	{
881b8e
@@ -11447,6 +11881,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
881b8e
 		  asection *sym_sec, *code_sec;
881b8e
 		  bfd_vma sym_value, code_value;
881b8e
 		  bfd_vma destination;
881b8e
+		  unsigned long local_off;
881b8e
 		  bfd_boolean ok_dest;
881b8e
 		  struct ppc_link_hash_entry *hash;
881b8e
 		  struct ppc_link_hash_entry *fdh;
881b8e
@@ -11523,12 +11958,16 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
881b8e
 		    }
881b8e
 
881b8e
 		  destination = 0;
881b8e
+		  local_off = 0;
881b8e
 		  if (ok_dest)
881b8e
 		    {
881b8e
 		      sym_value += irela->r_addend;
881b8e
 		      destination = (sym_value
881b8e
 				     + sym_sec->output_offset
881b8e
 				     + sym_sec->output_section->vma);
881b8e
+		      local_off = PPC64_LOCAL_ENTRY_OFFSET (hash
881b8e
+							    ? hash->elf.other
881b8e
+							    : sym->st_other);
881b8e
 		    }
881b8e
 
881b8e
 		  code_sec = sym_sec;
881b8e
@@ -11565,7 +12004,8 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
881b8e
 		  /* Determine what (if any) linker stub is needed.  */
881b8e
 		  plt_ent = NULL;
881b8e
 		  stub_type = ppc_type_of_stub (section, irela, &hash,
881b8e
-						&plt_ent, destination);
881b8e
+						&plt_ent, destination,
881b8e
+						local_off);
881b8e
 
881b8e
 		  if (stub_type != ppc_stub_plt_call)
881b8e
 		    {
881b8e
@@ -11828,6 +12268,72 @@ ppc64_elf_toc (bfd *obfd)
881b8e
   return TOCstart;
881b8e
 }
881b8e
 
881b8e
+/* Called via elf_link_hash_traverse from ppc64_elf_build_stubs to
881b8e
+   write out any global entry stubs.  */
881b8e
+
881b8e
+static bfd_boolean
881b8e
+build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
881b8e
+{
881b8e
+  struct bfd_link_info *info;
881b8e
+  struct ppc_link_hash_table *htab;
881b8e
+  struct plt_entry *pent;
881b8e
+  asection *s;
881b8e
+
881b8e
+  if (h->root.type == bfd_link_hash_indirect)
881b8e
+    return TRUE;
881b8e
+
881b8e
+  if (!h->pointer_equality_needed)
881b8e
+    return TRUE;
881b8e
+
881b8e
+  if (h->def_regular)
881b8e
+    return TRUE;
881b8e
+
881b8e
+  info = inf;
881b8e
+  htab = ppc_hash_table (info);
881b8e
+  if (htab == NULL)
881b8e
+    return FALSE;
881b8e
+
881b8e
+  s = htab->glink;
881b8e
+  for (pent = h->plt.plist; pent != NULL; pent = pent->next)
881b8e
+    if (pent->plt.offset != (bfd_vma) -1
881b8e
+	&& pent->addend == 0)
881b8e
+      {
881b8e
+	bfd_byte *p;
881b8e
+	asection *plt;
881b8e
+	bfd_vma off;
881b8e
+
881b8e
+	p = s->contents + h->root.u.def.value;
881b8e
+	plt = htab->plt;
881b8e
+	if (!htab->elf.dynamic_sections_created
881b8e
+	    || h->dynindx == -1)
881b8e
+	  plt = htab->iplt;
881b8e
+	off = pent->plt.offset + plt->output_offset + plt->output_section->vma;
881b8e
+	off -= h->root.u.def.value + s->output_offset + s->output_section->vma;
881b8e
+
881b8e
+	if (off + 0x80008000 > 0xffffffff || (off & 3) != 0)
881b8e
+	  {
881b8e
+	    info->callbacks->einfo
881b8e
+	      (_("%P: linkage table error against `%T'\n"),
881b8e
+	       h->root.root.string);
881b8e
+	    bfd_set_error (bfd_error_bad_value);
881b8e
+	    htab->stub_error = TRUE;
881b8e
+	  }
881b8e
+
881b8e
+	if (PPC_HA (off) != 0)
881b8e
+	  {
881b8e
+	    bfd_put_32 (s->owner, ADDIS_R12_R12 | PPC_HA (off), p);
881b8e
+	    p += 4;
881b8e
+	  }
881b8e
+	bfd_put_32 (s->owner, LD_R12_0R12 | PPC_LO (off), p);
881b8e
+	p += 4;
881b8e
+	bfd_put_32 (s->owner, MTCTR_R12, p);
881b8e
+	p += 4;
881b8e
+	bfd_put_32 (s->owner, BCTR, p);
881b8e
+	break;
881b8e
+      }
881b8e
+  return TRUE;
881b8e
+}
881b8e
+
881b8e
 /* Build all the stubs associated with the current output file.
881b8e
    The stubs are kept in a hash table attached to the main linker
881b8e
    hash table.  This function is called via gldelf64ppc_finish.  */
881b8e
@@ -11903,26 +12409,56 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
881b8e
       plt0 -= htab->glink->output_section->vma + htab->glink->output_offset;
881b8e
       bfd_put_64 (htab->glink->owner, plt0, p);
881b8e
       p += 8;
881b8e
-      bfd_put_32 (htab->glink->owner, MFLR_R12, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, BCL_20_31, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, MFLR_R11, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, LD_R2_M16R11, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, MTLR_R12, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, ADD_R12_R2_R11, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, LD_R11_0R12, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, LD_R2_0R12 | 8, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, MTCTR_R11, p);
881b8e
-      p += 4;
881b8e
-      bfd_put_32 (htab->glink->owner, LD_R11_0R12 | 16, p);
881b8e
-      p += 4;
881b8e
+      if (htab->opd_abi)
881b8e
+	{
881b8e
+	  bfd_put_32 (htab->glink->owner, MFLR_R12, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, BCL_20_31, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, MFLR_R11, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, MTLR_R12, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, LD_R2_0R11 | 8, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 16, p);
881b8e
+	  p += 4;
881b8e
+	}
881b8e
+      else
881b8e
+	{
881b8e
+	  bfd_put_32 (htab->glink->owner, MFLR_R0, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, BCL_20_31, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, MFLR_R11, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, MTLR_R0, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, ADDI_R0_R12 | (-48 & 0xffff), p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, SRDI_R0_R0_2, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
881b8e
+	  p += 4;
881b8e
+	  bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 8, p);
881b8e
+	  p += 4;
881b8e
+	}
881b8e
       bfd_put_32 (htab->glink->owner, BCTR, p);
881b8e
       p += 4;
881b8e
       while (p - htab->glink->contents < GLINK_CALL_STUB_SIZE)
881b8e
@@ -11933,26 +12469,33 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
881b8e
 
881b8e
       /* Build the .glink lazy link call stubs.  */
881b8e
       indx = 0;
881b8e
-      while (p < htab->glink->contents + htab->glink->size)
881b8e
+      while (p < htab->glink->contents + htab->glink->rawsize)
881b8e
 	{
881b8e
-	  if (indx < 0x8000)
881b8e
-	    {
881b8e
-	      bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
881b8e
-	      p += 4;
881b8e
-	    }
881b8e
-	  else
881b8e
+	  if (htab->opd_abi)
881b8e
 	    {
881b8e
-	      bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
881b8e
-	      p += 4;
881b8e
-	      bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
881b8e
-	      p += 4;
881b8e
+	      if (indx < 0x8000)
881b8e
+		{
881b8e
+		  bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
881b8e
+		  p += 4;
881b8e
+		}
881b8e
+	      else
881b8e
+		{
881b8e
+		  bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
881b8e
+		  p += 4;
881b8e
+		  bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx),
881b8e
+			      p);
881b8e
+		  p += 4;
881b8e
+		}
881b8e
 	    }
881b8e
 	  bfd_put_32 (htab->glink->owner,
881b8e
 		      B_DOT | ((htab->glink->contents - p + 8) & 0x3fffffc), p);
881b8e
 	  indx++;
881b8e
 	  p += 4;
881b8e
 	}
881b8e
-      htab->glink->rawsize = p - htab->glink->contents;
881b8e
+
881b8e
+      /* Build .glink global entry stubs.  */
881b8e
+      if (htab->glink->size > htab->glink->rawsize)
881b8e
+	elf_link_hash_traverse (&htab->elf, build_global_entry_stubs, info);
881b8e
     }
881b8e
 
881b8e
   if (htab->brlt->size != 0)
881b8e
@@ -12056,7 +12599,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
881b8e
 	  bfd_put_32 (htab->elf.dynobj, val, p);
881b8e
 	  p += 4;
881b8e
 	  /* .glink size.  */
881b8e
-	  bfd_put_32 (htab->elf.dynobj, htab->glink->rawsize - 8, p);
881b8e
+	  bfd_put_32 (htab->elf.dynobj, htab->glink->size - 8, p);
881b8e
 	  p += 4;
881b8e
 	  /* Augmentation.  */
881b8e
 	  p += 1;
881b8e
@@ -12106,7 +12649,6 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
881b8e
       }
881b8e
 
881b8e
   if (stub_sec != NULL
881b8e
-      || htab->glink->rawsize != htab->glink->size
881b8e
       || (htab->glink_eh_frame != NULL
881b8e
 	  && htab->glink_eh_frame->rawsize != htab->glink_eh_frame->size))
881b8e
     {
881b8e
@@ -12849,6 +13391,39 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 	      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
881b8e
 	    }
881b8e
 	  break;
881b8e
+
881b8e
+	case R_PPC64_REL16_HA:
881b8e
+	  /* If we are generating a non-PIC executable, edit
881b8e
+	     .	0:	addis 2,12,.TOC.-0b@ha
881b8e
+	     .		addi 2,2,.TOC.-0b@l
881b8e
+	     used by ELFv2 global entry points to set up r2, to
881b8e
+	     .		lis 2,.TOC.@ha
881b8e
+	     .		addi 2,2,.TOC.@l
881b8e
+	     if .TOC. is in range.  */
881b8e
+	  if (!info->shared
881b8e
+	      && h != NULL && &h->elf == htab->elf.hgot
881b8e
+	      && rel + 1 < relend
881b8e
+	      && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)
881b8e
+	      && rel[1].r_offset == rel->r_offset + 4
881b8e
+	      && rel[1].r_addend == rel->r_addend + 4
881b8e
+	      && relocation + 0x80008000 <= 0xffffffff)
881b8e
+	    {
881b8e
+	      unsigned int insn1, insn2;
881b8e
+	      bfd_vma offset = rel->r_offset - d_offset;
881b8e
+	      insn1 = bfd_get_32 (output_bfd, contents + offset);
881b8e
+	      insn2 = bfd_get_32 (output_bfd, contents + offset + 4);
881b8e
+	      if ((insn1 & 0xffff0000) == 0x3c4c0000 /* addis 2,12 */
881b8e
+		  && (insn2 & 0xffff0000) == 0x38420000 /* addi 2,2 */)
881b8e
+		{
881b8e
+		  r_type = R_PPC64_ADDR16_HA;
881b8e
+		  rel->r_info = ELF64_R_INFO (r_symndx, r_type);
881b8e
+		  rel->r_addend -= d_offset;
881b8e
+		  rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_ADDR16_LO);
881b8e
+		  rel[1].r_addend -= d_offset + 4;
881b8e
+		  bfd_put_32 (output_bfd, 0x3c400000, contents + offset);
881b8e
+		}
881b8e
+	    }
881b8e
+	  break;
881b8e
 	}
881b8e
 
881b8e
       /* Handle other relocations that tweak non-addend part of insn.  */
881b8e
@@ -12871,7 +13446,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
881b8e
 	      if (insn == NOP
881b8e
 		  || insn == CROR_151515 || insn == CROR_313131)
881b8e
-		bfd_put_32 (input_bfd, STD_R2_40R1,
881b8e
+		bfd_put_32 (input_bfd,
881b8e
+			    STD_R2_0R1 + STK_TOC (htab),
881b8e
 			    contents + rel->r_offset);
881b8e
 	    }
881b8e
 	  break;
881b8e
@@ -13001,6 +13577,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 		  + input_section->output_offset
881b8e
 		  + input_section->output_section->vma);
881b8e
 
881b8e
+	  relocation += PPC64_LOCAL_ENTRY_OFFSET (fdh
881b8e
+						  ? fdh->elf.other
881b8e
+						  : sym->st_other);
881b8e
+
881b8e
 	  if (stub_entry != NULL
881b8e
 	      && (stub_entry->stub_type == ppc_stub_long_branch
881b8e
 		  || stub_entry->stub_type == ppc_stub_plt_branch)
881b8e
@@ -13154,7 +13734,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 		    if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
881b8e
 							  &h->elf)
881b8e
 			|| (info->shared
881b8e
-			    && SYMBOL_CALLS_LOCAL (info, &h->elf)))
881b8e
+			    && SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
881b8e
 		      /* This is actually a static link, or it is a
881b8e
 			 -Bsymbolic link and the symbol is defined
881b8e
 			 locally, or the symbol was forced to be local
881b8e
@@ -13329,13 +13909,14 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 	    {
881b8e
 	      struct plt_entry *ent;
881b8e
 	      for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
881b8e
-		if (ent->addend == orig_rel.r_addend
881b8e
-		    && ent->plt.offset != (bfd_vma) -1)
881b8e
+		if (ent->plt.offset != (bfd_vma) -1
881b8e
+		    && ent->addend == orig_rel.r_addend)
881b8e
 		  {
881b8e
 		    relocation = (htab->plt->output_section->vma
881b8e
 				  + htab->plt->output_offset
881b8e
 				  + ent->plt.offset);
881b8e
 		    unresolved_reloc = FALSE;
881b8e
+		    break;
881b8e
 		  }
881b8e
 	    }
881b8e
 	  break;
881b8e
@@ -13395,6 +13976,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 	case R_PPC64_TPREL16_HA:
881b8e
 	case R_PPC64_TPREL16_DS:
881b8e
 	case R_PPC64_TPREL16_LO_DS:
881b8e
+	case R_PPC64_TPREL16_HIGH:
881b8e
+	case R_PPC64_TPREL16_HIGHA:
881b8e
 	case R_PPC64_TPREL16_HIGHER:
881b8e
 	case R_PPC64_TPREL16_HIGHERA:
881b8e
 	case R_PPC64_TPREL16_HIGHEST:
881b8e
@@ -13429,6 +14012,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 	case R_PPC64_DTPREL16_HA:
881b8e
 	case R_PPC64_DTPREL16_DS:
881b8e
 	case R_PPC64_DTPREL16_LO_DS:
881b8e
+	case R_PPC64_DTPREL16_HIGH:
881b8e
+	case R_PPC64_DTPREL16_HIGHA:
881b8e
 	case R_PPC64_DTPREL16_HIGHER:
881b8e
 	case R_PPC64_DTPREL16_HIGHERA:
881b8e
 	case R_PPC64_DTPREL16_HIGHEST:
881b8e
@@ -13461,6 +14046,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 	case R_PPC64_ADDR16_DS:
881b8e
 	case R_PPC64_ADDR16_HA:
881b8e
 	case R_PPC64_ADDR16_HI:
881b8e
+	case R_PPC64_ADDR16_HIGH:
881b8e
+	case R_PPC64_ADDR16_HIGHA:
881b8e
 	case R_PPC64_ADDR16_HIGHER:
881b8e
 	case R_PPC64_ADDR16_HIGHERA:
881b8e
 	case R_PPC64_ADDR16_HIGHEST:
881b8e
@@ -13532,7 +14119,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 
881b8e
 	      if (skip)
881b8e
 		memset (&outrel, 0, sizeof outrel);
881b8e
-	      else if (!SYMBOL_CALLS_LOCAL (info, &h->elf)
881b8e
+	      else if (!SYMBOL_REFERENCES_LOCAL (info, &h->elf)
881b8e
 		       && !is_opd
881b8e
 		       && r_type != R_PPC64_TOC)
881b8e
 		{
881b8e
@@ -13776,21 +14363,20 @@ ppc64_elf_relocate_section (bfd *output_bfd,
881b8e
 	default:
881b8e
 	  break;
881b8e
 
881b8e
-	case R_PPC64_ADDR16_HA:
881b8e
 	case R_PPC64_REL16_HA:
881b8e
+	case R_PPC64_ADDR16_HA:
881b8e
+	case R_PPC64_ADDR16_HIGHA:
881b8e
 	case R_PPC64_ADDR16_HIGHERA:
881b8e
 	case R_PPC64_ADDR16_HIGHESTA:
881b8e
 	case R_PPC64_TOC16_HA:
881b8e
 	case R_PPC64_SECTOFF_HA:
881b8e
 	case R_PPC64_TPREL16_HA:
881b8e
-	case R_PPC64_DTPREL16_HA:
881b8e
-	case R_PPC64_TPREL16_HIGHER:
881b8e
+	case R_PPC64_TPREL16_HIGHA:
881b8e
 	case R_PPC64_TPREL16_HIGHERA:
881b8e
-	case R_PPC64_TPREL16_HIGHEST:
881b8e
 	case R_PPC64_TPREL16_HIGHESTA:
881b8e
-	case R_PPC64_DTPREL16_HIGHER:
881b8e
+	case R_PPC64_DTPREL16_HA:
881b8e
+	case R_PPC64_DTPREL16_HIGHA:
881b8e
 	case R_PPC64_DTPREL16_HIGHERA:
881b8e
-	case R_PPC64_DTPREL16_HIGHEST:
881b8e
 	case R_PPC64_DTPREL16_HIGHESTA:
881b8e
 	  /* It's just possible that this symbol is a weak symbol
881b8e
 	     that's not actually defined anywhere. In that case,
881b8e
@@ -14017,7 +14603,10 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
881b8e
 	    rela.r_offset = (htab->iplt->output_section->vma
881b8e
 			     + htab->iplt->output_offset
881b8e
 			     + ent->plt.offset);
881b8e
-	    rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
881b8e
+	    if (htab->opd_abi)
881b8e
+	      rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
881b8e
+	    else
881b8e
+	      rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
881b8e
 	    rela.r_addend = (h->root.u.def.value
881b8e
 			     + h->root.u.def.section->output_offset
881b8e
 			     + h->root.u.def.section->output_section->vma
881b8e
@@ -14034,10 +14623,34 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
881b8e
 	    rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
881b8e
 	    rela.r_addend = ent->addend;
881b8e
 	    loc = (htab->relplt->contents
881b8e
-		   + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE)
881b8e
-		      / (PLT_ENTRY_SIZE / sizeof (Elf64_External_Rela))));
881b8e
+		   + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE (htab))
881b8e
+		      / PLT_ENTRY_SIZE (htab) * sizeof (Elf64_External_Rela)));
881b8e
 	  }
881b8e
 	bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
881b8e
+
881b8e
+	if (!htab->opd_abi)
881b8e
+	  {
881b8e
+	    if (!h->def_regular)
881b8e
+	      {
881b8e
+		/* Mark the symbol as undefined, rather than as
881b8e
+		   defined in glink.  Leave the value if there were
881b8e
+		   any relocations where pointer equality matters
881b8e
+		   (this is a clue for the dynamic linker, to make
881b8e
+		   function pointer comparisons work between an
881b8e
+		   application and shared library), otherwise set it
881b8e
+		   to zero.  */
881b8e
+		sym->st_shndx = SHN_UNDEF;
881b8e
+		if (!h->pointer_equality_needed)
881b8e
+		  sym->st_value = 0;
881b8e
+		else if (!h->ref_regular_nonweak)
881b8e
+		  {
881b8e
+		    /* This breaks function pointer comparisons, but
881b8e
+		       that is better than breaking tests for a NULL
881b8e
+		       function pointer.  */
881b8e
+		    sym->st_value = 0;
881b8e
+		  }
881b8e
+	      }
881b8e
+	  }
881b8e
       }
881b8e
 
881b8e
   if (h->needs_copy)
881b8e
@@ -14130,7 +14743,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
881b8e
 		 of glink rather than the first entry point, which is
881b8e
 		 what ld.so needs, and now have a bigger stub to
881b8e
 		 support automatic multiple TOCs.  */
881b8e
-	      dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 32;
881b8e
+	      dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 8 * 4;
881b8e
 	      break;
881b8e
 
881b8e
 	    case DT_PPC64_OPD:
881b8e
@@ -14140,6 +14753,11 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
881b8e
 	      dyn.d_un.d_ptr = s->vma;
881b8e
 	      break;
881b8e
 
881b8e
+	    case DT_PPC64_OPT:
881b8e
+	      if (htab->do_multi_toc && htab->multi_toc_needed)
881b8e
+		dyn.d_un.d_val |= PPC64_OPT_MULTI_TOC;
881b8e
+	      break;
881b8e
+
881b8e
 	    case DT_PPC64_OPDSZ:
881b8e
 	      s = bfd_get_section_by_name (output_bfd, ".opd");
881b8e
 	      if (s == NULL)
881b8e
@@ -14203,7 +14821,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
881b8e
     {
881b8e
       /* Set .plt entry size.  */
881b8e
       elf_section_data (htab->plt->output_section)->this_hdr.sh_entsize
881b8e
-	= PLT_ENTRY_SIZE;
881b8e
+	= PLT_ENTRY_SIZE (htab);
881b8e
     }
881b8e
 
881b8e
   /* brlt is SEC_LINKER_CREATED, so we need to write out relocs for
881b8e
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
881b8e
index bcd76a0..d3b7950 100644
881b8e
--- a/bfd/libbfd.h
881b8e
+++ b/bfd/libbfd.h
881b8e
@@ -1396,6 +1396,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
881b8e
   "BFD_RELOC_PPC64_TOC16_LO_DS",
881b8e
   "BFD_RELOC_PPC64_PLTGOT16_DS",
881b8e
   "BFD_RELOC_PPC64_PLTGOT16_LO_DS",
881b8e
+  "BFD_RELOC_PPC64_ADDR16_HIGH",
881b8e
+  "BFD_RELOC_PPC64_ADDR16_HIGHA",
881b8e
   "BFD_RELOC_PPC_TLS",
881b8e
   "BFD_RELOC_PPC_TLSGD",
881b8e
   "BFD_RELOC_PPC_TLSLD",
881b8e
@@ -1438,6 +1440,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
881b8e
   "BFD_RELOC_PPC64_DTPREL16_HIGHERA",
881b8e
   "BFD_RELOC_PPC64_DTPREL16_HIGHEST",
881b8e
   "BFD_RELOC_PPC64_DTPREL16_HIGHESTA",
881b8e
+  "BFD_RELOC_PPC64_TPREL16_HIGH",
881b8e
+  "BFD_RELOC_PPC64_TPREL16_HIGHA",
881b8e
+  "BFD_RELOC_PPC64_DTPREL16_HIGH",
881b8e
+  "BFD_RELOC_PPC64_DTPREL16_HIGHA",
881b8e
   "BFD_RELOC_I370_D12",
881b8e
   "BFD_RELOC_CTOR",
881b8e
   "BFD_RELOC_ARM_PCREL_BRANCH",
881b8e
diff --git a/bfd/reloc.c b/bfd/reloc.c
881b8e
index 626c818..b924974 100644
881b8e
--- a/bfd/reloc.c
881b8e
+++ b/bfd/reloc.c
881b8e
@@ -2892,6 +2892,10 @@ ENUMX
881b8e
   BFD_RELOC_PPC64_PLTGOT16_DS
881b8e
 ENUMX
881b8e
   BFD_RELOC_PPC64_PLTGOT16_LO_DS
881b8e
+ENUMX
881b8e
+  BFD_RELOC_PPC64_ADDR16_HIGH
881b8e
+ENUMX
881b8e
+  BFD_RELOC_PPC64_ADDR16_HIGHA
881b8e
 ENUMDOC
881b8e
   Power(rs6000) and PowerPC relocations.
881b8e
 
881b8e
@@ -2979,6 +2983,14 @@ ENUMX
881b8e
   BFD_RELOC_PPC64_DTPREL16_HIGHEST
881b8e
 ENUMX
881b8e
   BFD_RELOC_PPC64_DTPREL16_HIGHESTA
881b8e
+ENUMX
881b8e
+  BFD_RELOC_PPC64_TPREL16_HIGH
881b8e
+ENUMX
881b8e
+  BFD_RELOC_PPC64_TPREL16_HIGHA
881b8e
+ENUMX
881b8e
+  BFD_RELOC_PPC64_DTPREL16_HIGH
881b8e
+ENUMX
881b8e
+  BFD_RELOC_PPC64_DTPREL16_HIGHA
881b8e
 ENUMDOC
881b8e
   PowerPC and PowerPC64 thread-local storage relocations.
881b8e
 
881b8e
diff --git a/binutils/readelf.c b/binutils/readelf.c
881b8e
index 67aeaa8..2046ec5 100644
881b8e
--- a/binutils/readelf.c
881b8e
+++ b/binutils/readelf.c
881b8e
@@ -1556,7 +1556,7 @@ get_ppc_dynamic_type (unsigned long type)
881b8e
   switch (type)
881b8e
     {
881b8e
     case DT_PPC_GOT:    return "PPC_GOT";
881b8e
-    case DT_PPC_TLSOPT: return "PPC_TLSOPT";
881b8e
+    case DT_PPC_OPT:    return "PPC_OPT";
881b8e
     default:
881b8e
       return NULL;
881b8e
     }
881b8e
@@ -1570,7 +1570,7 @@ get_ppc64_dynamic_type (unsigned long type)
881b8e
     case DT_PPC64_GLINK:  return "PPC64_GLINK";
881b8e
     case DT_PPC64_OPD:    return "PPC64_OPD";
881b8e
     case DT_PPC64_OPDSZ:  return "PPC64_OPDSZ";
881b8e
-    case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
881b8e
+    case DT_PPC64_OPT:    return "PPC64_OPT";
881b8e
     default:
881b8e
       return NULL;
881b8e
     }
881b8e
@@ -2442,6 +2442,16 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
881b8e
 	    strcat (buf, _(", relocatable-lib"));
881b8e
 	  break;
881b8e
 
881b8e
+	case EM_PPC64:
881b8e
+	  if (e_flags & EF_PPC64_ABI)
881b8e
+	    {
881b8e
+	      char abi[] = ", abiv0";
881b8e
+
881b8e
+	      abi[6] += e_flags & EF_PPC64_ABI;
881b8e
+	      strcat (buf, abi);
881b8e
+	    }
881b8e
+	  break;
881b8e
+
881b8e
 	case EM_V800:
881b8e
 	  if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
881b8e
 	    strcat (buf, ", RH850 ABI");
881b8e
@@ -9122,6 +9132,19 @@ get_ia64_symbol_other (unsigned int other)
881b8e
 }
881b8e
 
881b8e
 static const char *
881b8e
+get_ppc64_symbol_other (unsigned int other)
881b8e
+{
881b8e
+  if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
881b8e
+    {
881b8e
+      static char buf[32];
881b8e
+      snprintf (buf, sizeof buf, _("<localentry>: %d"),
881b8e
+		PPC64_LOCAL_ENTRY_OFFSET (other));
881b8e
+      return buf;
881b8e
+    }
881b8e
+  return NULL;
881b8e
+}
881b8e
+
881b8e
+static const char *
881b8e
 get_symbol_other (unsigned int other)
881b8e
 {
881b8e
   const char * result = NULL;
881b8e
@@ -9138,6 +9161,9 @@ get_symbol_other (unsigned int other)
881b8e
     case EM_IA_64:
881b8e
       result = get_ia64_symbol_other (other);
881b8e
       break;
881b8e
+    case EM_PPC64:
881b8e
+      result = get_ppc64_symbol_other (other);
881b8e
+      break;
881b8e
     default:
881b8e
       break;
881b8e
     }
881b8e
diff --git a/elfcpp/powerpc.h b/elfcpp/powerpc.h
881b8e
index 2c803af..879055e 100644
881b8e
--- a/elfcpp/powerpc.h
881b8e
+++ b/elfcpp/powerpc.h
881b8e
@@ -164,11 +164,17 @@ enum
881b8e
   R_PPC_EMB_SDA21 = 109,
881b8e
   R_PPC64_TOCSAVE = 109,
881b8e
   R_PPC_EMB_MRKREF = 110,
881b8e
+  R_PPC64_ADDR16_HIGH = 110,
881b8e
   R_PPC_EMB_RELSEC16 = 111,
881b8e
+  R_PPC64_ADDR16_HIGHA = 111,
881b8e
   R_PPC_EMB_RELST_LO = 112,
881b8e
+  R_PPC64_TPREL16_HIGH = 112,
881b8e
   R_PPC_EMB_RELST_HI = 113,
881b8e
+  R_PPC64_TPREL16_HIGHA = 113,
881b8e
   R_PPC_EMB_RELST_HA = 114,
881b8e
+  R_PPC64_DTPREL16_HIGH = 114,
881b8e
   R_PPC_EMB_BIT_FLD = 115,
881b8e
+  R_PPC64_DTPREL16_HIGHA = 115,
881b8e
   R_PPC_EMB_RELSDA = 116,
881b8e
 
881b8e
   R_PPC_VLE_REL8 = 216,
881b8e
@@ -208,6 +214,59 @@ enum
881b8e
   EF_PPC_RELOCATABLE_LIB = 0x00008000, // PowerPC -mrelocatable-lib flag.  */
881b8e
 };
881b8e
 
881b8e
+// e_flags values defined for powerpc64
881b8e
+enum
881b8e
+{
881b8e
+  // ABI version
881b8e
+  // 1 for original function descriptor using ABI,
881b8e
+  // 2 for revised ABI without function descriptors,
881b8e
+  // 0 for unspecified or not using any features affected by the differences.
881b8e
+  EF_PPC64_ABI = 3
881b8e
+};
881b8e
+
881b8e
+enum
881b8e
+{
881b8e
+  // The ELFv2 ABI uses three bits in the symbol st_other field of a
881b8e
+  // function definition to specify the number of instructions between a
881b8e
+  // function's global entry point and local entry point.
881b8e
+  // The global entry point is used when it is necessary to set up the
881b8e
+  // toc pointer (r2) for the function.  Callers must enter the global
881b8e
+  // entry point with r12 set to the global entry point address.  On
881b8e
+  // return from the function, r2 may have a different value to that
881b8e
+  // which it had on entry.
881b8e
+  // The local entry point is used when r2 is known to already be valid
881b8e
+  // for the function.  There is no requirement on r12 when using the
881b8e
+  // local entry point, and on return r2 will contain the same value as
881b8e
+  // at entry.
881b8e
+  // A value of zero in these bits means that the function has a single
881b8e
+  // entry point with no requirement on r12 or r2, and that on return r2
881b8e
+  // will contain the same value as at entry.
881b8e
+  // Values of one and seven are reserved.
881b8e
+
881b8e
+  STO_PPC64_LOCAL_BIT = 5,
881b8e
+  STO_PPC64_LOCAL_MASK = 0xE0
881b8e
+};
881b8e
+
881b8e
+// 3 bit other field to bytes.
881b8e
+static inline unsigned int
881b8e
+ppc64_decode_local_entry(unsigned int other)
881b8e
+{
881b8e
+  return ((1 << other) >> 2) << 2;
881b8e
+}
881b8e
+
881b8e
+// bytes to field value.
881b8e
+static inline unsigned int
881b8e
+ppc64_encode_local_entry(unsigned int val)
881b8e
+{
881b8e
+  return (val >= 4 * 4
881b8e
+	  ? (val >= 8 * 4
881b8e
+	     ? (val >= 16 * 4 ? 6 : 5)
881b8e
+	     : 4)
881b8e
+	  : (val >= 2 * 4
881b8e
+	     ? 3
881b8e
+	     : (val >= 1 * 4 ? 2 : 0)));
881b8e
+}
881b8e
+
881b8e
 } // End namespace elfcpp.
881b8e
 
881b8e
 #endif // !defined(ELFCPP_POWERPC_H)
881b8e
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
881b8e
index e55d8a9..99e893d 100644
881b8e
--- a/gas/config/tc-ppc.c
881b8e
+++ b/gas/config/tc-ppc.c
881b8e
@@ -29,6 +29,7 @@
881b8e
 
881b8e
 #ifdef OBJ_ELF
881b8e
 #include "elf/ppc.h"
881b8e
+#include "elf/ppc64.h"
881b8e
 #include "dwarf2dbg.h"
881b8e
 #endif
881b8e
 
881b8e
@@ -112,7 +113,11 @@ static int set_target_endian = 0;
881b8e
    compensating for #lo being treated as a signed number.  */
881b8e
 #define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
881b8e
 
881b8e
-#define SEX16(val) ((((val) & 0xffff) ^ 0x8000) - 0x8000)
881b8e
+#define SEX16(val) (((val) ^ 0x8000) - 0x8000)
881b8e
+
881b8e
+/* For the time being on ppc64, don't report overflow on @h and @ha
881b8e
+   applied to constants.  */
881b8e
+#define REPORT_OVERFLOW_HI 0
881b8e
 
881b8e
 static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
881b8e
 
881b8e
@@ -155,6 +160,8 @@ static void ppc_vbyte (int);
881b8e
 static void ppc_elf_cons (int);
881b8e
 static void ppc_elf_rdata (int);
881b8e
 static void ppc_elf_lcomm (int);
881b8e
+static void ppc_elf_localentry (int);
881b8e
+static void ppc_elf_abiversion (int);
881b8e
 #endif
881b8e
 
881b8e
 #ifdef TE_PE
881b8e
@@ -225,6 +232,9 @@ unsigned long nop_limit = 4;
881b8e
 ppc_cpu_t ppc_cpu = 0;
881b8e
 ppc_cpu_t sticky = 0;
881b8e
 
881b8e
+/* Value for ELF e_flags EF_PPC64_ABI.  */
881b8e
+unsigned int ppc_abiversion = 0;
881b8e
+
881b8e
 /* Flags set on encountering toc relocs.  */
881b8e
 enum {
881b8e
   has_large_toc_reloc = 1,
881b8e
@@ -283,6 +293,8 @@ const pseudo_typeS md_pseudo_table[] =
881b8e
   { "rdata",	ppc_elf_rdata,	0 },
881b8e
   { "rodata",	ppc_elf_rdata,	0 },
881b8e
   { "lcomm",	ppc_elf_lcomm,	0 },
881b8e
+  { "localentry", ppc_elf_localentry,	0 },
881b8e
+  { "abiversion", ppc_elf_abiversion,	0 },
881b8e
 #endif
881b8e
 
881b8e
 #ifdef TE_PE
881b8e
@@ -1949,6 +1961,8 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
881b8e
     MAP32 ("bitfld",		BFD_RELOC_PPC_EMB_BIT_FLD),
881b8e
     MAP32 ("relsda",		BFD_RELOC_PPC_EMB_RELSDA),
881b8e
     MAP32 ("xgot",		BFD_RELOC_PPC_TOC16),
881b8e
+    MAP64 ("high",		BFD_RELOC_PPC64_ADDR16_HIGH),
881b8e
+    MAP64 ("higha",		BFD_RELOC_PPC64_ADDR16_HIGHA),
881b8e
     MAP64 ("higher",		BFD_RELOC_PPC64_HIGHER),
881b8e
     MAP64 ("highera",		BFD_RELOC_PPC64_HIGHER_S),
881b8e
     MAP64 ("highest",		BFD_RELOC_PPC64_HIGHEST),
881b8e
@@ -1958,10 +1972,14 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
881b8e
     MAP64 ("toc@l",		BFD_RELOC_PPC64_TOC16_LO),
881b8e
     MAP64 ("toc@h",		BFD_RELOC_PPC64_TOC16_HI),
881b8e
     MAP64 ("toc@ha",		BFD_RELOC_PPC64_TOC16_HA),
881b8e
+    MAP64 ("dtprel@high",	BFD_RELOC_PPC64_DTPREL16_HIGH),
881b8e
+    MAP64 ("dtprel@higha",	BFD_RELOC_PPC64_DTPREL16_HIGHA),
881b8e
     MAP64 ("dtprel@higher",	BFD_RELOC_PPC64_DTPREL16_HIGHER),
881b8e
     MAP64 ("dtprel@highera",	BFD_RELOC_PPC64_DTPREL16_HIGHERA),
881b8e
     MAP64 ("dtprel@highest",	BFD_RELOC_PPC64_DTPREL16_HIGHEST),
881b8e
     MAP64 ("dtprel@highesta",	BFD_RELOC_PPC64_DTPREL16_HIGHESTA),
881b8e
+    MAP64 ("tprel@high",	BFD_RELOC_PPC64_TPREL16_HIGH),
881b8e
+    MAP64 ("tprel@higha",	BFD_RELOC_PPC64_TPREL16_HIGHA),
881b8e
     MAP64 ("tprel@higher",	BFD_RELOC_PPC64_TPREL16_HIGHER),
881b8e
     MAP64 ("tprel@highera",	BFD_RELOC_PPC64_TPREL16_HIGHERA),
881b8e
     MAP64 ("tprel@highest",	BFD_RELOC_PPC64_TPREL16_HIGHEST),
881b8e
@@ -2237,6 +2255,101 @@ ppc_elf_lcomm (int xxx ATTRIBUTE_UNUSED)
881b8e
   demand_empty_rest_of_line ();
881b8e
 }
881b8e
 
881b8e
+/* Pseudo op to set symbol local entry point.  */
881b8e
+static void
881b8e
+ppc_elf_localentry (int ignore ATTRIBUTE_UNUSED)
881b8e
+{
881b8e
+  char *name = input_line_pointer;
881b8e
+  char c = get_symbol_end ();
881b8e
+  char *p;
881b8e
+  expressionS exp;
881b8e
+  symbolS *sym;
881b8e
+  asymbol *bfdsym;
881b8e
+  elf_symbol_type *elfsym;
881b8e
+
881b8e
+  p = input_line_pointer;
881b8e
+  *p = c;
881b8e
+  SKIP_WHITESPACE ();
881b8e
+  if (*input_line_pointer != ',')
881b8e
+    {
881b8e
+      *p = 0;
881b8e
+      as_bad (_("expected comma after name `%s' in .localentry directive"),
881b8e
+	      name);
881b8e
+      *p = c;
881b8e
+      ignore_rest_of_line ();
881b8e
+      return;
881b8e
+    }
881b8e
+  input_line_pointer++;
881b8e
+  expression (&exp);
881b8e
+  if (exp.X_op == O_absent)
881b8e
+    {
881b8e
+      as_bad (_("missing expression in .localentry directive"));
881b8e
+      exp.X_op = O_constant;
881b8e
+      exp.X_add_number = 0;
881b8e
+    }
881b8e
+  *p = 0;
881b8e
+  sym = symbol_find_or_make (name);
881b8e
+  *p = c;
881b8e
+
881b8e
+  if (resolve_expression (&exp)
881b8e
+      && exp.X_op == O_constant)
881b8e
+    {
881b8e
+      unsigned char encoded = PPC64_SET_LOCAL_ENTRY_OFFSET (exp.X_add_number);
881b8e
+
881b8e
+      if (exp.X_add_number != PPC64_LOCAL_ENTRY_OFFSET (encoded))
881b8e
+        as_bad (_(".localentry expression for `%s' "
881b8e
+		  "is not a valid power of 2"), S_GET_NAME (sym));
881b8e
+      else
881b8e
+	{
881b8e
+	  bfdsym = symbol_get_bfdsym (sym);
881b8e
+	  elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
881b8e
+	  gas_assert (elfsym);
881b8e
+	  elfsym->internal_elf_sym.st_other &= ~STO_PPC64_LOCAL_MASK;
881b8e
+	  elfsym->internal_elf_sym.st_other |= encoded;
881b8e
+	  if (ppc_abiversion == 0)
881b8e
+	    ppc_abiversion = 2;
881b8e
+	}
881b8e
+    }
881b8e
+  else
881b8e
+    as_bad (_(".localentry expression for `%s' "
881b8e
+	      "does not evaluate to a constant"), S_GET_NAME (sym));
881b8e
+
881b8e
+  demand_empty_rest_of_line ();
881b8e
+}
881b8e
+
881b8e
+/* Pseudo op to set ABI version.  */
881b8e
+static void
881b8e
+ppc_elf_abiversion (int ignore ATTRIBUTE_UNUSED)
881b8e
+{
881b8e
+  expressionS exp;
881b8e
+
881b8e
+  expression (&exp);
881b8e
+  if (exp.X_op == O_absent)
881b8e
+    {
881b8e
+      as_bad (_("missing expression in .abiversion directive"));
881b8e
+      exp.X_op = O_constant;
881b8e
+      exp.X_add_number = 0;
881b8e
+    }
881b8e
+
881b8e
+  if (resolve_expression (&exp)
881b8e
+      && exp.X_op == O_constant)
881b8e
+    ppc_abiversion = exp.X_add_number;
881b8e
+  else
881b8e
+    as_bad (_(".abiversion expression does not evaluate to a constant"));
881b8e
+  demand_empty_rest_of_line ();
881b8e
+}
881b8e
+
881b8e
+/* Set ABI version in output file.  */
881b8e
+void
881b8e
+ppc_elf_end (void)
881b8e
+{
881b8e
+  if (ppc_obj64 && ppc_abiversion != 0)
881b8e
+    {
881b8e
+      elf_elfheader (stdoutput)->e_flags &= ~EF_PPC64_ABI;
881b8e
+      elf_elfheader (stdoutput)->e_flags |= ppc_abiversion & EF_PPC64_ABI;
881b8e
+    }
881b8e
+}
881b8e
+
881b8e
 /* Validate any relocations emitted for -mrelocatable, possibly adding
881b8e
    fixups for word relocations in writable segments, so we can adjust
881b8e
    them at runtime.  */
881b8e
@@ -2838,55 +2951,76 @@ md_assemble (char *str)
881b8e
 		break;
881b8e
 
881b8e
 	      case BFD_RELOC_LO16:
881b8e
-		/* X_unsigned is the default, so if the user has done
881b8e
-		   something which cleared it, we always produce a
881b8e
-		   signed value.  */
881b8e
-		if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
881b8e
-		  ex.X_add_number &= 0xffff;
881b8e
-		else
881b8e
+		ex.X_add_number &= 0xffff;
881b8e
+		if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
 		  ex.X_add_number = SEX16 (ex.X_add_number);
881b8e
 		break;
881b8e
 
881b8e
 	      case BFD_RELOC_HI16:
881b8e
-		if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
881b8e
-		  ex.X_add_number = PPC_HI (ex.X_add_number);
881b8e
-		else
881b8e
-		  ex.X_add_number = SEX16 (PPC_HI (ex.X_add_number));
881b8e
+		if (REPORT_OVERFLOW_HI && ppc_obj64)
881b8e
+		  {
881b8e
+		    /* PowerPC64 @h is tested for overflow.  */
881b8e
+		    ex.X_add_number = (addressT) ex.X_add_number >> 16;
881b8e
+		    if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		      {
881b8e
+			addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
881b8e
+			ex.X_add_number
881b8e
+			  = ((addressT) ex.X_add_number ^ sign) - sign;
881b8e
+		      }
881b8e
+		    break;
881b8e
+		  }
881b8e
+		/* Fall thru */
881b8e
+
881b8e
+	      case BFD_RELOC_PPC64_ADDR16_HIGH:
881b8e
+		ex.X_add_number = PPC_HI (ex.X_add_number);
881b8e
+		if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		  ex.X_add_number = SEX16 (ex.X_add_number);
881b8e
 		break;
881b8e
 
881b8e
 	      case BFD_RELOC_HI16_S:
881b8e
-		if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
881b8e
-		  ex.X_add_number = PPC_HA (ex.X_add_number);
881b8e
-		else
881b8e
-		  ex.X_add_number = SEX16 (PPC_HA (ex.X_add_number));
881b8e
+		if (REPORT_OVERFLOW_HI && ppc_obj64)
881b8e
+		  {
881b8e
+		    /* PowerPC64 @ha is tested for overflow.  */
881b8e
+		    ex.X_add_number
881b8e
+		      = ((addressT) ex.X_add_number + 0x8000) >> 16;
881b8e
+		    if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		      {
881b8e
+			addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
881b8e
+			ex.X_add_number
881b8e
+			  = ((addressT) ex.X_add_number ^ sign) - sign;
881b8e
+		      }
881b8e
+		    break;
881b8e
+		  }
881b8e
+		/* Fall thru */
881b8e
+
881b8e
+	      case BFD_RELOC_PPC64_ADDR16_HIGHA:
881b8e
+		ex.X_add_number = PPC_HA (ex.X_add_number);
881b8e
+		if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		  ex.X_add_number = SEX16 (ex.X_add_number);
881b8e
 		break;
881b8e
 
881b8e
 	      case BFD_RELOC_PPC64_HIGHER:
881b8e
-		if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
881b8e
-		  ex.X_add_number = PPC_HIGHER (ex.X_add_number);
881b8e
-		else
881b8e
-		  ex.X_add_number = SEX16 (PPC_HIGHER (ex.X_add_number));
881b8e
+		ex.X_add_number = PPC_HIGHER (ex.X_add_number);
881b8e
+		if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		  ex.X_add_number = SEX16 (ex.X_add_number);
881b8e
 		break;
881b8e
 
881b8e
 	      case BFD_RELOC_PPC64_HIGHER_S:
881b8e
-		if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
881b8e
-		  ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
881b8e
-		else
881b8e
-		  ex.X_add_number = SEX16 (PPC_HIGHERA (ex.X_add_number));
881b8e
+		ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
881b8e
+		if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		  ex.X_add_number = SEX16 (ex.X_add_number);
881b8e
 		break;
881b8e
 
881b8e
 	      case BFD_RELOC_PPC64_HIGHEST:
881b8e
-		if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
881b8e
-		  ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
881b8e
-		else
881b8e
-		  ex.X_add_number = SEX16 (PPC_HIGHEST (ex.X_add_number));
881b8e
+		ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
881b8e
+		if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		  ex.X_add_number = SEX16 (ex.X_add_number);
881b8e
 		break;
881b8e
 
881b8e
 	      case BFD_RELOC_PPC64_HIGHEST_S:
881b8e
-		if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
881b8e
-		  ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
881b8e
-		else
881b8e
-		  ex.X_add_number = SEX16 (PPC_HIGHESTA (ex.X_add_number));
881b8e
+		ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
881b8e
+		if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
881b8e
+		  ex.X_add_number = SEX16 (ex.X_add_number);
881b8e
 		break;
881b8e
 	      }
881b8e
 #endif /* OBJ_ELF */
881b8e
@@ -6172,6 +6306,22 @@ ppc_force_relocation (fixS *fix)
881b8e
     case BFD_RELOC_24_PLT_PCREL:
881b8e
     case BFD_RELOC_PPC64_TOC:
881b8e
       return 1;
881b8e
+    case BFD_RELOC_PPC_B26:
881b8e
+    case BFD_RELOC_PPC_BA26:
881b8e
+    case BFD_RELOC_PPC_B16:
881b8e
+    case BFD_RELOC_PPC_BA16:
881b8e
+      /* All branch fixups targeting a localentry symbol must
881b8e
+         force a relocation.  */
881b8e
+      if (fix->fx_addsy)
881b8e
+	{
881b8e
+	  asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);
881b8e
+	  elf_symbol_type *elfsym
881b8e
+	    = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
881b8e
+	  gas_assert (elfsym);
881b8e
+	  if ((STO_PPC64_LOCAL_MASK & elfsym->internal_elf_sym.st_other) != 0)
881b8e
+	    return 1;
881b8e
+	}
881b8e
+      break;
881b8e
     default:
881b8e
       break;
881b8e
     }
881b8e
@@ -6186,6 +6336,32 @@ ppc_force_relocation (fixS *fix)
881b8e
 int
881b8e
 ppc_fix_adjustable (fixS *fix)
881b8e
 {
881b8e
+  switch (fix->fx_r_type)
881b8e
+    {
881b8e
+      /* All branch fixups targeting a localentry symbol must
881b8e
+         continue using the symbol.  */
881b8e
+    case BFD_RELOC_PPC_B26:
881b8e
+    case BFD_RELOC_PPC_BA26:
881b8e
+    case BFD_RELOC_PPC_B16:
881b8e
+    case BFD_RELOC_PPC_BA16:
881b8e
+    case BFD_RELOC_PPC_B16_BRTAKEN:
881b8e
+    case BFD_RELOC_PPC_B16_BRNTAKEN:
881b8e
+    case BFD_RELOC_PPC_BA16_BRTAKEN:
881b8e
+    case BFD_RELOC_PPC_BA16_BRNTAKEN:
881b8e
+      if (fix->fx_addsy)
881b8e
+	{
881b8e
+	  asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);
881b8e
+	  elf_symbol_type *elfsym
881b8e
+	    = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
881b8e
+	  gas_assert (elfsym);
881b8e
+	  if ((STO_PPC64_LOCAL_MASK & elfsym->internal_elf_sym.st_other) != 0)
881b8e
+	    return 0;
881b8e
+	}
881b8e
+      break;
881b8e
+    default:
881b8e
+      break;
881b8e
+    }
881b8e
+
881b8e
   return (fix->fx_r_type != BFD_RELOC_16_GOTOFF
881b8e
 	  && fix->fx_r_type != BFD_RELOC_LO16_GOTOFF
881b8e
 	  && fix->fx_r_type != BFD_RELOC_HI16_GOTOFF
881b8e
@@ -6465,10 +6641,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
881b8e
 	case BFD_RELOC_PPC_GOT_DTPREL16_HA:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_DS:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_LO_DS:
881b8e
+	case BFD_RELOC_PPC64_TPREL16_HIGH:
881b8e
+	case BFD_RELOC_PPC64_TPREL16_HIGHA:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_HIGHER:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_HIGHERA:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_HIGHEST:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
881b8e
+	case BFD_RELOC_PPC64_DTPREL16_HIGH:
881b8e
+	case BFD_RELOC_PPC64_DTPREL16_HIGHA:
881b8e
 	case BFD_RELOC_PPC64_DTPREL16_DS:
881b8e
 	case BFD_RELOC_PPC64_DTPREL16_LO_DS:
881b8e
 	case BFD_RELOC_PPC64_DTPREL16_HIGHER:
881b8e
@@ -6836,10 +7016,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
881b8e
 	case BFD_RELOC_PPC64_TOC16_LO:
881b8e
 	case BFD_RELOC_PPC64_TOC16_HI:
881b8e
 	case BFD_RELOC_PPC64_TOC16_HA:
881b8e
+	case BFD_RELOC_PPC64_DTPREL16_HIGH:
881b8e
+	case BFD_RELOC_PPC64_DTPREL16_HIGHA:
881b8e
 	case BFD_RELOC_PPC64_DTPREL16_HIGHER:
881b8e
 	case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
881b8e
 	case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
881b8e
 	case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
881b8e
+	case BFD_RELOC_PPC64_TPREL16_HIGH:
881b8e
+	case BFD_RELOC_PPC64_TPREL16_HIGHA:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_HIGHER:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_HIGHERA:
881b8e
 	case BFD_RELOC_PPC64_TPREL16_HIGHEST:
881b8e
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
881b8e
index 3dd3f81..6095416 100644
881b8e
--- a/gas/config/tc-ppc.h
881b8e
+++ b/gas/config/tc-ppc.h
881b8e
@@ -238,6 +238,9 @@ extern void ppc_frob_file_before_adjust (void);
881b8e
 #define tc_adjust_symtab() ppc_elf_adjust_symtab ()
881b8e
 extern void ppc_elf_adjust_symtab (void);
881b8e
 
881b8e
+extern void ppc_elf_end (void);
881b8e
+#define md_end ppc_elf_end
881b8e
+
881b8e
 #endif /* OBJ_ELF */
881b8e
 
881b8e
 #if defined (OBJ_ELF) || defined (OBJ_XCOFF)
881b8e
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
881b8e
index e192885..38a36ac 100644
881b8e
--- a/gold/powerpc.cc
881b8e
+++ b/gold/powerpc.cc
881b8e
@@ -72,12 +72,19 @@ public:
881b8e
 		 const typename elfcpp::Ehdr<size, big_endian>& ehdr)
881b8e
     : Sized_relobj_file<size, big_endian>(name, input_file, offset, ehdr),
881b8e
       special_(0), has_small_toc_reloc_(false), opd_valid_(false),
881b8e
-      opd_ent_(), access_from_map_(), has14_(), stub_table_()
881b8e
-  { }
881b8e
+      opd_ent_(), access_from_map_(), has14_(), stub_table_(),
881b8e
+      e_flags_(ehdr.get_e_flags()), st_other_()
881b8e
+  {
881b8e
+    this->set_abiversion(0);
881b8e
+  }
881b8e
 
881b8e
   ~Powerpc_relobj()
881b8e
   { }
881b8e
 
881b8e
+  // Read the symbols then set up st_other vector.
881b8e
+  void
881b8e
+  do_read_symbols(Read_symbols_data*);
881b8e
+
881b8e
   // The .got2 section shndx.
881b8e
   unsigned int
881b8e
   got2_shndx() const
881b8e
@@ -263,6 +270,22 @@ public:
881b8e
     return NULL;
881b8e
   }
881b8e
 
881b8e
+  int
881b8e
+  abiversion() const
881b8e
+  { return this->e_flags_ & elfcpp::EF_PPC64_ABI; }
881b8e
+
881b8e
+  // Set ABI version for input and output
881b8e
+  void
881b8e
+  set_abiversion(int ver);
881b8e
+
881b8e
+  unsigned int
881b8e
+  ppc64_local_entry_offset(const Symbol* sym) const
881b8e
+  { return elfcpp::ppc64_decode_local_entry(sym->nonvis() >> 3); }
881b8e
+
881b8e
+  unsigned int
881b8e
+  ppc64_local_entry_offset(unsigned int symndx) const
881b8e
+  { return elfcpp::ppc64_decode_local_entry(this->st_other_[symndx] >> 5); }
881b8e
+
881b8e
 private:
881b8e
   struct Opd_ent
881b8e
   {
881b8e
@@ -316,6 +339,12 @@ private:
881b8e
 
881b8e
   // The stub table to use for a given input section.
881b8e
   std::vector<Stub_table<size, big_endian>*> stub_table_;
881b8e
+
881b8e
+  // Header e_flags
881b8e
+  elfcpp::Elf_Word e_flags_;
881b8e
+
881b8e
+  // ELF st_other field for local symbols.
881b8e
+  std::vector<unsigned char> st_other_;
881b8e
 };
881b8e
 
881b8e
 template<int size, bool big_endian>
881b8e
@@ -1305,6 +1334,14 @@ public:
881b8e
     STATUS_OVERFLOW
881b8e
   };
881b8e
 
881b8e
+  int
881b8e
+  abiversion() const
881b8e
+  { return this->e_flags_ & elfcpp::EF_PPC64_ABI; }
881b8e
+
881b8e
+  // Set ABI version for input and output.
881b8e
+  void
881b8e
+  set_abiversion(int ver);
881b8e
+
881b8e
 private:
881b8e
   typedef Powerpc_relocate_functions<size, big_endian> This;
881b8e
   typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
881b8e
@@ -1930,6 +1967,24 @@ class Stub_control
881b8e
   output_section()
881b8e
   { return output_section_; }
881b8e
 
881b8e
+  int
881b8e
+  abiversion () const
881b8e
+  { return this->processor_specific_flags() & elfcpp::EF_PPC64_ABI; }
881b8e
+
881b8e
+  void
881b8e
+  set_abiversion (int ver)
881b8e
+  {
881b8e
+    elfcpp::Elf_Word flags = this->processor_specific_flags();
881b8e
+    flags &= ~elfcpp::EF_PPC64_ABI;
881b8e
+    flags |= ver & elfcpp::EF_PPC64_ABI;
881b8e
+    this->set_processor_specific_flags(flags);
881b8e
+  }
881b8e
+
881b8e
+  // Offset to to save stack slot
881b8e
+  int
881b8e
+  stk_toc () const
881b8e
+  { return this->abiversion() < 2 ? 40 : 24; }
881b8e
+
881b8e
  private:
881b8e
   typedef enum
881b8e
   {
881b8e
@@ -3605,6 +3660,26 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
881b8e
 	    }
881b8e
 	}
881b8e
     }
881b8e
+  else
881b8e
+    {
881b8e
+      // Define .TOC. as for 32-bit _GLOBAL_OFFSET_TABLE_
881b8e
+      Symbol *gotsym = symtab->lookup(".TOC.", NULL);
881b8e
+      if (gotsym != NULL && gotsym->is_undefined())
881b8e
+	{
881b8e
+	  Target_powerpc<size, big_endian>* target =
881b8e
+	    static_cast<Target_powerpc<size, big_endian>*>(
881b8e
+		parameters->sized_target<size, big_endian>());
881b8e
+	  Output_data_got_powerpc<size, big_endian>* got
881b8e
+	    = target->got_section(symtab, layout);
881b8e
+	  symtab->define_in_output_data(".TOC.", NULL,
881b8e
+					Symbol_table::PREDEFINED,
881b8e
+					got, 0x8000, 0,
881b8e
+					elfcpp::STT_OBJECT,
881b8e
+					elfcpp::STB_LOCAL,
881b8e
+					elfcpp::STV_HIDDEN, 0,
881b8e
+					false, false);
881b8e
+	}
881b8e
+    }
881b8e
 }
881b8e
 
881b8e
 // Write out .glink.
881b8e
@@ -3632,16 +3707,34 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
881b8e
 
881b8e
       elfcpp::Swap<64, big_endian>::writeval(p, pltoff),	p += 8;
881b8e
 
881b8e
-      write_insn<big_endian>(p, mflr_12),			p += 4;
881b8e
-      write_insn<big_endian>(p, bcl_20_31),			p += 4;
881b8e
-      write_insn<big_endian>(p, mflr_11),			p += 4;
881b8e
-      write_insn<big_endian>(p, ld_2_11 + l(-16)),		p += 4;
881b8e
-      write_insn<big_endian>(p, mtlr_12),			p += 4;
881b8e
-      write_insn<big_endian>(p, add_12_2_11),			p += 4;
881b8e
-      write_insn<big_endian>(p, ld_11_12 + 0),			p += 4;
881b8e
-      write_insn<big_endian>(p, ld_2_12 + 8),			p += 4;
881b8e
-      write_insn<big_endian>(p, mtctr_11),			p += 4;
881b8e
-      write_insn<big_endian>(p, ld_11_12 + 16),			p += 4;
881b8e
+      if (this->targ_->abiversion() < 2)
881b8e
+	{
881b8e
+	  write_insn<big_endian>(p, mflr_12),			p += 4;
881b8e
+	  write_insn<big_endian>(p, bcl_20_31),			p += 4;
881b8e
+	  write_insn<big_endian>(p, mflr_11),			p += 4;
881b8e
+	  write_insn<big_endian>(p, ld_2_11 + l(-16)),		p += 4;
881b8e
+	  write_insn<big_endian>(p, mtlr_12),			p += 4;
881b8e
+	  write_insn<big_endian>(p, add_11_2_11),		p += 4;
881b8e
+	  write_insn<big_endian>(p, ld_12_11 + 0),		p += 4;
881b8e
+	  write_insn<big_endian>(p, ld_2_11 + 8),		p += 4;
881b8e
+	  write_insn<big_endian>(p, mtctr_12),			p += 4;
881b8e
+	  write_insn<big_endian>(p, ld_11_11 + 16),		p += 4;
881b8e
+	}
881b8e
+      else
881b8e
+	{
881b8e
+	  write_insn<big_endian>(p, mflr_0),			p += 4;
881b8e
+	  write_insn<big_endian>(p, bcl_20_31),			p += 4;
881b8e
+	  write_insn<big_endian>(p, mflr_11),			p += 4;
881b8e
+	  write_insn<big_endian>(p, ld_2_11 + l(-16)),		p += 4;
881b8e
+	  write_insn<big_endian>(p, mtlr_0),			p += 4;
881b8e
+	  write_insn<big_endian>(p, sub_12_12_11),		p += 4;
881b8e
+	  write_insn<big_endian>(p, add_11_2_11),		p += 4;
881b8e
+	  write_insn<big_endian>(p, addi_0_12 + l(-48)),	p += 4;
881b8e
+	  write_insn<big_endian>(p, ld_12_11 + 0),		p += 4;
881b8e
+	  write_insn<big_endian>(p, srdi_0_0_2),		p += 4;
881b8e
+	  write_insn<big_endian>(p, mtctr_12),			p += 4;
881b8e
+	  write_insn<big_endian>(p, ld_11_11 + 8),		p += 4;
881b8e
+	}
881b8e
       write_insn<big_endian>(p, bctr),				p += 4;
881b8e
       while (p < oview + this->pltresolve_size)
881b8e
 	write_insn<big_endian>(p, nop), p += 4;
881b8e
@@ -3650,14 +3743,17 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
881b8e
       uint32_t indx = 0;
881b8e
       while (p < oview + oview_size)
881b8e
 	{
881b8e
-	  if (indx < 0x8000)
881b8e
-	    {
881b8e
-	      write_insn<big_endian>(p, li_0_0 + indx),			p += 4;
881b8e
-	    }
881b8e
-	  else
881b8e
+	  if (this->targ_->abiversion() < 2)
881b8e
 	    {
881b8e
-	      write_insn<big_endian>(p, lis_0_0 + hi(indx)),		p += 4;
881b8e
-	      write_insn<big_endian>(p, ori_0_0_0 + l(indx)),		p += 4;
881b8e
+	      if (indx < 0x8000)
881b8e
+		{
881b8e
+		  write_insn<big_endian>(p, li_0_0 + indx),		p += 4;
881b8e
+		}
881b8e
+	      else
881b8e
+		{
881b8e
+		  write_insn<big_endian>(p, lis_0_0 + hi(indx)),	p += 4;
881b8e
+		  write_insn<big_endian>(p, ori_0_0_0 + l(indx)),	p += 4;
881b8e
+		}
881b8e
 	    }
881b8e
 	  uint32_t branch_off = 8 - (p - oview);
881b8e
 	  write_insn<big_endian>(p, b + (branch_off & 0x3fffffc)),	p += 4;
881b8e
@@ -4144,24 +4240,6 @@ Target_powerpc<size, big_endian>::plt_entry_count() const
881b8e
   return count;
881b8e
 }
881b8e
 
881b8e
-// Return the offset of the first non-reserved PLT entry.
881b8e
-
881b8e
-template<int size, bool big_endian>
881b8e
-unsigned int
881b8e
-Target_powerpc<size, big_endian>::first_plt_entry_offset() const
881b8e
-{
881b8e
-  return this->plt_->first_plt_entry_offset();
881b8e
-}
881b8e
-
881b8e
-// Return the size of each PLT entry.
881b8e
-
881b8e
-template<int size, bool big_endian>
881b8e
-unsigned int
881b8e
-Target_powerpc<size, big_endian>::plt_entry_size() const
881b8e
-{
881b8e
-  return Output_data_plt_powerpc<size, big_endian>::get_plt_entry_size();
881b8e
-}
881b8e
-
881b8e
 // Create a GOT entry for local dynamic __tls_get_addr calls.
881b8e
 
881b8e
 template<int size, bool big_endian>
881b8e
@@ -4189,8 +4267,12 @@ Target_powerpc<size, big_endian>::tlsld_got_offset(
881b8e
 
881b8e
 template<int size, bool big_endian>
881b8e
 int
881b8e
-Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
881b8e
+Target_powerpc<size, big_endian>::Scan::get_reference_flags(
881b8e
+    unsigned int r_type,
881b8e
+    const Target_powerpc* target)
881b8e
 {
881b8e
+  int ref = 0;
881b8e
+
881b8e
   switch (r_type)
881b8e
     {
881b8e
     case elfcpp::R_POWERPC_NONE:
881b8e
@@ -4198,7 +4280,7 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
881b8e
     case elfcpp::R_POWERPC_GNU_VTENTRY:
881b8e
     case elfcpp::R_PPC64_TOC:
881b8e
       // No symbol reference.
881b8e
-      return 0;
881b8e
+      break;
881b8e
 
881b8e
     case elfcpp::R_PPC64_ADDR64:
881b8e
     case elfcpp::R_PPC64_UADDR64:
881b8e
@@ -4209,13 +4291,15 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
881b8e
     case elfcpp::R_POWERPC_ADDR16_LO:
881b8e
     case elfcpp::R_POWERPC_ADDR16_HI:
881b8e
     case elfcpp::R_POWERPC_ADDR16_HA:
881b8e
-      return Symbol::ABSOLUTE_REF;
881b8e
+      ref = Symbol::ABSOLUTE_REF;
881b8e
+      break;
881b8e
 
881b8e
     case elfcpp::R_POWERPC_ADDR24:
881b8e
     case elfcpp::R_POWERPC_ADDR14:
881b8e
     case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
881b8e
     case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
881b8e
-      return Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
881b8e
+      ref = Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
881b8e
+      break;
881b8e
 
881b8e
     case elfcpp::R_PPC64_REL64:
881b8e
     case elfcpp::R_POWERPC_REL32:
881b8e
@@ -4224,14 +4308,16 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
881b8e
     case elfcpp::R_POWERPC_REL16_LO:
881b8e
     case elfcpp::R_POWERPC_REL16_HI:
881b8e
     case elfcpp::R_POWERPC_REL16_HA:
881b8e
-      return Symbol::RELATIVE_REF;
881b8e
+      ref = Symbol::RELATIVE_REF;
881b8e
+      break;
881b8e
 
881b8e
     case elfcpp::R_POWERPC_REL24:
881b8e
     case elfcpp::R_PPC_PLTREL24:
881b8e
     case elfcpp::R_POWERPC_REL14:
881b8e
     case elfcpp::R_POWERPC_REL14_BRTAKEN:
881b8e
     case elfcpp::R_POWERPC_REL14_BRNTAKEN:
881b8e
-      return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
881b8e
+      ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
881b8e
+      break;
881b8e
 
881b8e
     case elfcpp::R_POWERPC_GOT16:
881b8e
     case elfcpp::R_POWERPC_GOT16_LO:
881b8e
@@ -4246,11 +4332,13 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
881b8e
     case elfcpp::R_PPC64_TOC16_DS:
881b8e
     case elfcpp::R_PPC64_TOC16_LO_DS:
881b8e
       // Absolute in GOT.
881b8e
-      return Symbol::ABSOLUTE_REF;
881b8e
+      ref = Symbol::ABSOLUTE_REF;
881b8e
+      break;
881b8e
 
881b8e
     case elfcpp::R_POWERPC_GOT_TPREL16:
881b8e
     case elfcpp::R_POWERPC_TLS:
881b8e
-      return Symbol::TLS_REF;
881b8e
+      ref = Symbol::TLS_REF;
881b8e
+      break;
881b8e
 
881b8e
     case elfcpp::R_POWERPC_COPY:
881b8e
     case elfcpp::R_POWERPC_GLOB_DAT:
881b8e
@@ -4259,8 +4347,12 @@ Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
881b8e
     case elfcpp::R_POWERPC_DTPMOD:
881b8e
     default:
881b8e
       // Not expected.  We will give an error later.
881b8e
-      return 0;
881b8e
+      break;
881b8e
     }
881b8e
+
881b8e
+  if (size == 64 && target->abiversion() < 2)
881b8e
+    ref |= Symbol::FUNC_DESC_ABI;
881b8e
+  return ref;
881b8e
 }
881b8e
 
881b8e
 // Report an unsupported relocation against a local symbol.
881b8e
@@ -4331,6 +4423,8 @@ Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
881b8e
 	case elfcpp::R_PPC64_JMP_IREL:
881b8e
 	case elfcpp::R_PPC64_ADDR16_DS:
881b8e
 	case elfcpp::R_PPC64_ADDR16_LO_DS:
881b8e
+	case elfcpp::R_PPC64_ADDR16_HIGH:
881b8e
+	case elfcpp::R_PPC64_ADDR16_HIGHA:
881b8e
 	case elfcpp::R_PPC64_ADDR16_HIGHER:
881b8e
 	case elfcpp::R_PPC64_ADDR16_HIGHEST:
881b8e
 	case elfcpp::R_PPC64_ADDR16_HIGHERA:
881b8e
@@ -4339,6 +4433,8 @@ Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
881b8e
 	case elfcpp::R_POWERPC_ADDR30:
881b8e
 	case elfcpp::R_PPC64_TPREL16_DS:
881b8e
 	case elfcpp::R_PPC64_TPREL16_LO_DS:
881b8e
+	case elfcpp::R_PPC64_TPREL16_HIGH:
881b8e
+	case elfcpp::R_PPC64_TPREL16_HIGHA:
881b8e
 	case elfcpp::R_PPC64_TPREL16_HIGHER:
881b8e
 	case elfcpp::R_PPC64_TPREL16_HIGHEST:
881b8e
 	case elfcpp::R_PPC64_TPREL16_HIGHERA:
881b8e
@@ -4509,7 +4605,6 @@ Target_powerpc<size, big_endian>::Scan::local(
881b8e
     case elfcpp::R_POWERPC_GNU_VTINHERIT:
881b8e
     case elfcpp::R_POWERPC_GNU_VTENTRY:
881b8e
     case elfcpp::R_PPC64_TOCSAVE:
881b8e
-    case elfcpp::R_PPC_EMB_MRKREF:
881b8e
     case elfcpp::R_POWERPC_TLS:
881b8e
       break;
881b8e
 
881b8e
@@ -4546,6 +4641,8 @@ Target_powerpc<size, big_endian>::Scan::local(
881b8e
     case elfcpp::R_POWERPC_ADDR16_HI:
881b8e
     case elfcpp::R_POWERPC_ADDR16_HA:
881b8e
     case elfcpp::R_POWERPC_UADDR16:
881b8e
+    case elfcpp::R_PPC64_ADDR16_HIGH:
881b8e
+    case elfcpp::R_PPC64_ADDR16_HIGHA:
881b8e
     case elfcpp::R_PPC64_ADDR16_HIGHER:
881b8e
     case elfcpp::R_PPC64_ADDR16_HIGHERA:
881b8e
     case elfcpp::R_PPC64_ADDR16_HIGHEST:
881b8e
@@ -4612,31 +4709,35 @@ Target_powerpc<size, big_endian>::Scan::local(
881b8e
     case elfcpp::R_POWERPC_REL16_HI:
881b8e
     case elfcpp::R_POWERPC_REL16_HA:
881b8e
     case elfcpp::R_POWERPC_SECTOFF:
881b8e
-    case elfcpp::R_POWERPC_TPREL16:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16:
881b8e
     case elfcpp::R_POWERPC_SECTOFF_LO:
881b8e
-    case elfcpp::R_POWERPC_TPREL16_LO:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16_LO:
881b8e
     case elfcpp::R_POWERPC_SECTOFF_HI:
881b8e
-    case elfcpp::R_POWERPC_TPREL16_HI:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16_HI:
881b8e
     case elfcpp::R_POWERPC_SECTOFF_HA:
881b8e
+    case elfcpp::R_PPC64_SECTOFF_DS:
881b8e
+    case elfcpp::R_PPC64_SECTOFF_LO_DS:
881b8e
+    case elfcpp::R_POWERPC_TPREL16:
881b8e
+    case elfcpp::R_POWERPC_TPREL16_LO:
881b8e
+    case elfcpp::R_POWERPC_TPREL16_HI:
881b8e
     case elfcpp::R_POWERPC_TPREL16_HA:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16_HA:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHER:
881b8e
+    case elfcpp::R_PPC64_TPREL16_DS:
881b8e
+    case elfcpp::R_PPC64_TPREL16_LO_DS:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGH:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGHA:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHER:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHERA:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHEST:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHESTA:
881b8e
-    case elfcpp::R_PPC64_TPREL16_DS:
881b8e
-    case elfcpp::R_PPC64_TPREL16_LO_DS:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_LO:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_HI:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_HA:
881b8e
     case elfcpp::R_PPC64_DTPREL16_DS:
881b8e
     case elfcpp::R_PPC64_DTPREL16_LO_DS:
881b8e
-    case elfcpp::R_PPC64_SECTOFF_DS:
881b8e
-    case elfcpp::R_PPC64_SECTOFF_LO_DS:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGH:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHA:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHER:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
881b8e
     case elfcpp::R_PPC64_TLSGD:
881b8e
     case elfcpp::R_PPC64_TLSLD:
881b8e
       break;
881b8e
@@ -4870,7 +4971,6 @@ Target_powerpc<size, big_endian>::Scan::global(
881b8e
     case elfcpp::R_POWERPC_GNU_VTINHERIT:
881b8e
     case elfcpp::R_POWERPC_GNU_VTENTRY:
881b8e
     case elfcpp::R_PPC_LOCAL24PC:
881b8e
-    case elfcpp::R_PPC_EMB_MRKREF:
881b8e
     case elfcpp::R_POWERPC_TLS:
881b8e
       break;
881b8e
 
881b8e
@@ -4919,6 +5019,8 @@ Target_powerpc<size, big_endian>::Scan::global(
881b8e
     case elfcpp::R_POWERPC_ADDR16_HI:
881b8e
     case elfcpp::R_POWERPC_ADDR16_HA:
881b8e
     case elfcpp::R_POWERPC_UADDR16:
881b8e
+    case elfcpp::R_PPC64_ADDR16_HIGH:
881b8e
+    case elfcpp::R_PPC64_ADDR16_HIGHA:
881b8e
     case elfcpp::R_PPC64_ADDR16_HIGHER:
881b8e
     case elfcpp::R_PPC64_ADDR16_HIGHERA:
881b8e
     case elfcpp::R_PPC64_ADDR16_HIGHEST:
881b8e
@@ -5005,7 +5107,7 @@ Target_powerpc<size, big_endian>::Scan::global(
881b8e
     case elfcpp::R_PPC64_REL64:
881b8e
     case elfcpp::R_POWERPC_REL32:
881b8e
       // Make a dynamic relocation if necessary.
881b8e
-      if (needs_dynamic_reloc<size>(gsym, Scan::get_reference_flags(r_type)))
881b8e
+      if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type, target)))
881b8e
 	{
881b8e
 	  if (gsym->may_need_copy_reloc())
881b8e
 	    {
881b8e
@@ -5037,31 +5139,35 @@ Target_powerpc<size, big_endian>::Scan::global(
881b8e
     case elfcpp::R_POWERPC_REL16_HI:
881b8e
     case elfcpp::R_POWERPC_REL16_HA:
881b8e
     case elfcpp::R_POWERPC_SECTOFF:
881b8e
-    case elfcpp::R_POWERPC_TPREL16:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16:
881b8e
     case elfcpp::R_POWERPC_SECTOFF_LO:
881b8e
-    case elfcpp::R_POWERPC_TPREL16_LO:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16_LO:
881b8e
     case elfcpp::R_POWERPC_SECTOFF_HI:
881b8e
-    case elfcpp::R_POWERPC_TPREL16_HI:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16_HI:
881b8e
     case elfcpp::R_POWERPC_SECTOFF_HA:
881b8e
+    case elfcpp::R_PPC64_SECTOFF_DS:
881b8e
+    case elfcpp::R_PPC64_SECTOFF_LO_DS:
881b8e
+    case elfcpp::R_POWERPC_TPREL16:
881b8e
+    case elfcpp::R_POWERPC_TPREL16_LO:
881b8e
+    case elfcpp::R_POWERPC_TPREL16_HI:
881b8e
     case elfcpp::R_POWERPC_TPREL16_HA:
881b8e
-    case elfcpp::R_POWERPC_DTPREL16_HA:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHER:
881b8e
+    case elfcpp::R_PPC64_TPREL16_DS:
881b8e
+    case elfcpp::R_PPC64_TPREL16_LO_DS:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGH:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGHA:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHER:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHERA:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHEST:
881b8e
-    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
881b8e
     case elfcpp::R_PPC64_TPREL16_HIGHESTA:
881b8e
-    case elfcpp::R_PPC64_TPREL16_DS:
881b8e
-    case elfcpp::R_PPC64_TPREL16_LO_DS:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_LO:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_HI:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_HA:
881b8e
     case elfcpp::R_PPC64_DTPREL16_DS:
881b8e
     case elfcpp::R_PPC64_DTPREL16_LO_DS:
881b8e
-    case elfcpp::R_PPC64_SECTOFF_DS:
881b8e
-    case elfcpp::R_PPC64_SECTOFF_LO_DS:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGH:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHA:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHER:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
881b8e
     case elfcpp::R_PPC64_TLSGD:
881b8e
     case elfcpp::R_PPC64_TLSLD:
881b8e
       break;
881b8e
@@ -5794,7 +5900,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
 		  && (insn2 == nop
881b8e
 		      || insn2 == cror_15_15_15 || insn2 == cror_31_31_31))
881b8e
 		{
881b8e
-		  elfcpp::Swap<32, big_endian>::writeval(wv + 1, ld_2_1 + 40);
881b8e
+		  elfcpp::Swap<32, big_endian>::
881b8e
+		    writeval(wv + 1, ld_2_1 + target->stk_toc());
881b8e
 		  can_plt_call = true;
881b8e
 		}
881b8e
 	    }
881b8e
@@ -6083,6 +6190,10 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
       if (r_type != elfcpp::R_PPC_PLTREL24)
881b8e
 	addend = rela.get_r_addend();
881b8e
       value = psymval->value(object, addend);
881b8e
+      if (gsym != NULL)
881b8e
+	value += object->ppc64_local_entry_offset(gsym);
881b8e
+      else
881b8e
+	value += object->ppc64_local_entry_offset(r_sym);
881b8e
       if (size == 64 && is_branch_reloc(r_type))
881b8e
 	value = target->symval_for_branch(value, gsym, object, &dest_shndx);
881b8e
       unsigned int max_branch_offset = 0;
881b8e
@@ -6146,8 +6257,10 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
 
881b8e
     case elfcpp::R_PPC64_TPREL16_DS:
881b8e
     case elfcpp::R_PPC64_TPREL16_LO_DS:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGH:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGHA:
881b8e
       if (size != 64)
881b8e
-	// R_PPC_TLSGD and R_PPC_TLSLD
881b8e
+	// R_PPC_TLSGD, R_PPC_TLSLD, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HI
881b8e
 	break;
881b8e
     case elfcpp::R_POWERPC_TPREL16:
881b8e
     case elfcpp::R_POWERPC_TPREL16_LO:
881b8e
@@ -6177,6 +6290,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
     case elfcpp::R_POWERPC_DTPREL16_HI:
881b8e
     case elfcpp::R_POWERPC_DTPREL16_HA:
881b8e
     case elfcpp::R_POWERPC_DTPREL:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGH:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHA:
881b8e
       // tls symbol values are relative to tls_segment()->vaddr()
881b8e
       value -= dtp_offset;
881b8e
       break;
881b8e
@@ -6317,6 +6432,34 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
       overflow = Reloc::CHECK_BITFIELD;
881b8e
       break;
881b8e
 
881b8e
+    case elfcpp::R_POWERPC_ADDR16_HI:
881b8e
+    case elfcpp::R_POWERPC_ADDR16_HA:
881b8e
+    case elfcpp::R_POWERPC_GOT16_HI:
881b8e
+    case elfcpp::R_POWERPC_GOT16_HA:
881b8e
+    case elfcpp::R_POWERPC_PLT16_HI:
881b8e
+    case elfcpp::R_POWERPC_PLT16_HA:
881b8e
+    case elfcpp::R_POWERPC_SECTOFF_HI:
881b8e
+    case elfcpp::R_POWERPC_SECTOFF_HA:
881b8e
+    case elfcpp::R_PPC64_TOC16_HI:
881b8e
+    case elfcpp::R_PPC64_TOC16_HA:
881b8e
+    case elfcpp::R_PPC64_PLTGOT16_HI:
881b8e
+    case elfcpp::R_PPC64_PLTGOT16_HA:
881b8e
+    case elfcpp::R_POWERPC_TPREL16_HI:
881b8e
+    case elfcpp::R_POWERPC_TPREL16_HA:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_HI:
881b8e
+    case elfcpp::R_POWERPC_DTPREL16_HA:
881b8e
+    case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
881b8e
+    case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
881b8e
+    case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
881b8e
+    case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
881b8e
+    case elfcpp::R_POWERPC_GOT_TPREL16_HI:
881b8e
+    case elfcpp::R_POWERPC_GOT_TPREL16_HA:
881b8e
+    case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
881b8e
+    case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
881b8e
+    case elfcpp::R_POWERPC_REL16_HI:
881b8e
+    case elfcpp::R_POWERPC_REL16_HA:
881b8e
+      if (size == 32)
881b8e
+	break;
881b8e
     case elfcpp::R_POWERPC_REL24:
881b8e
     case elfcpp::R_PPC_PLTREL24:
881b8e
     case elfcpp::R_PPC_LOCAL24PC:
881b8e
@@ -6350,7 +6493,6 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
     case elfcpp::R_POWERPC_TLS:
881b8e
     case elfcpp::R_POWERPC_GNU_VTINHERIT:
881b8e
     case elfcpp::R_POWERPC_GNU_VTENTRY:
881b8e
-    case elfcpp::R_PPC_EMB_MRKREF:
881b8e
       break;
881b8e
 
881b8e
     case elfcpp::R_PPC64_ADDR64:
881b8e
@@ -6421,6 +6563,12 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
       status = Reloc::addr16_u(view, value, overflow);
881b8e
       break;
881b8e
 
881b8e
+    case elfcpp::R_PPC64_ADDR16_HIGH:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGH:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGH:
881b8e
+      if (size == 32)
881b8e
+	// R_PPC_EMB_MRKREF, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HA
881b8e
+	goto unsupp;
881b8e
     case elfcpp::R_POWERPC_ADDR16_HI:
881b8e
     case elfcpp::R_POWERPC_REL16_HI:
881b8e
     case elfcpp::R_PPC64_TOC16_HI:
881b8e
@@ -6435,6 +6583,12 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
       Reloc::addr16_hi(view, value);
881b8e
       break;
881b8e
 
881b8e
+    case elfcpp::R_PPC64_ADDR16_HIGHA:
881b8e
+    case elfcpp::R_PPC64_TPREL16_HIGHA:
881b8e
+    case elfcpp::R_PPC64_DTPREL16_HIGHA:
881b8e
+      if (size == 32)
881b8e
+	// R_PPC_EMB_RELSEC16, R_PPC_EMB_RELST_HI, R_PPC_EMB_BIT_FLD
881b8e
+	goto unsupp;
881b8e
     case elfcpp::R_POWERPC_ADDR16_HA:
881b8e
     case elfcpp::R_POWERPC_REL16_HA:
881b8e
     case elfcpp::R_PPC64_TOC16_HA:
881b8e
@@ -6559,11 +6713,6 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
881b8e
     case elfcpp::R_PPC64_PLT16_LO_DS:
881b8e
     case elfcpp::R_PPC64_PLTGOT16_DS:
881b8e
     case elfcpp::R_PPC64_PLTGOT16_LO_DS:
881b8e
-    case elfcpp::R_PPC_EMB_RELSEC16:
881b8e
-    case elfcpp::R_PPC_EMB_RELST_LO:
881b8e
-    case elfcpp::R_PPC_EMB_RELST_HI:
881b8e
-    case elfcpp::R_PPC_EMB_RELST_HA:
881b8e
-    case elfcpp::R_PPC_EMB_BIT_FLD:
881b8e
     case elfcpp::R_PPC_EMB_RELSDA:
881b8e
     case elfcpp::R_PPC_TOC16:
881b8e
     default:
881b8e
diff --git a/gold/symtab.h b/gold/symtab.h
881b8e
index f26d4b9..457b8bd 100644
881b8e
--- a/gold/symtab.h
881b8e
+++ b/gold/symtab.h
881b8e
@@ -634,7 +634,10 @@ class Symbol
881b8e
     // A TLS-related reference.
881b8e
     TLS_REF = 4,
881b8e
     // A reference that can always be treated as a function call.
881b8e
-    FUNCTION_CALL = 8
881b8e
+    FUNCTION_CALL = 8,
881b8e
+    // When set, says that dynamic relocations are needed even if a
881b8e
+    // symbol has a plt entry.
881b8e
+    FUNC_DESC_ABI = 16,
881b8e
   };
881b8e
 
881b8e
   // Given a direct absolute or pc-relative static relocation against
881b8e
@@ -671,7 +674,8 @@ class Symbol
881b8e
 
881b8e
     // A reference to any PLT entry in a non-position-independent executable
881b8e
     // does not need a dynamic relocation.
881b8e
-    if (!parameters->options().output_is_position_independent()
881b8e
+    if (!(flags & FUNC_DESC_ABI)
881b8e
+	&& !parameters->options().output_is_position_independent()
881b8e
         && this->has_plt_offset())
881b8e
       return false;
881b8e
 
881b8e
diff --git a/include/elf/ppc.h b/include/elf/ppc.h
881b8e
index f80a1e8..da00df8 100644
881b8e
--- a/include/elf/ppc.h
881b8e
+++ b/include/elf/ppc.h
881b8e
@@ -176,7 +176,8 @@ END_RELOC_NUMBERS (R_PPC_max)
881b8e
 #define DT_PPC_GOT		(DT_LOPROC)
881b8e
 
881b8e
 /* Specify that tls descriptors should be optimized.  */
881b8e
-#define DT_PPC_TLSOPT		(DT_LOPROC + 1)
881b8e
+#define DT_PPC_OPT		(DT_LOPROC + 1)
881b8e
+#define PPC_OPT_TLS		1
881b8e
 
881b8e
 /* Processor specific flags for the ELF header e_flags field.  */
881b8e
 
881b8e
diff --git a/include/elf/ppc64.h b/include/elf/ppc64.h
881b8e
index f1c80f1..78d947b 100644
881b8e
--- a/include/elf/ppc64.h
881b8e
+++ b/include/elf/ppc64.h
881b8e
@@ -141,6 +141,14 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
881b8e
   RELOC_NUMBER (R_PPC64_TLSLD,		   108)
881b8e
   RELOC_NUMBER (R_PPC64_TOCSAVE,	   109)
881b8e
 
881b8e
+/* Added when HA and HI relocs were changed to report overflows.  */
881b8e
+  RELOC_NUMBER (R_PPC64_ADDR16_HIGH,	   110)
881b8e
+  RELOC_NUMBER (R_PPC64_ADDR16_HIGHA,	   111)
881b8e
+  RELOC_NUMBER (R_PPC64_TPREL16_HIGH,	   112)
881b8e
+  RELOC_NUMBER (R_PPC64_TPREL16_HIGHA,	   113)
881b8e
+  RELOC_NUMBER (R_PPC64_DTPREL16_HIGH,	   114)
881b8e
+  RELOC_NUMBER (R_PPC64_DTPREL16_HIGHA,	   115)
881b8e
+
881b8e
 #ifndef RELOC_MACROS_GEN_FUNC
881b8e
 /* Fake relocation only used internally by ld.  */
881b8e
   RELOC_NUMBER (R_PPC64_LO_DS_OPT,	   128)
881b8e
@@ -161,8 +169,63 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
881b8e
 
881b8e
 END_RELOC_NUMBERS (R_PPC64_max)
881b8e
 
881b8e
-#define IS_PPC64_TLS_RELOC(R) \
881b8e
-  ((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)
881b8e
+#define IS_PPC64_TLS_RELOC(R)						\
881b8e
+  (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)		\
881b8e
+   || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA))
881b8e
+
881b8e
+
881b8e
+/* e_flags bits specifying ABI.
881b8e
+   1 for original function descriptor using ABI,
881b8e
+   2 for revised ABI without function descriptors,
881b8e
+   0 for unspecified or not using any features affected by the differences.  */
881b8e
+#define EF_PPC64_ABI	3
881b8e
+
881b8e
+/* The ELFv2 ABI uses three bits in the symbol st_other field of a
881b8e
+   function definition to specify the number of instructions between a
881b8e
+   function's global entry point and local entry point.
881b8e
+   The global entry point is used when it is necessary to set up the
881b8e
+   toc pointer (r2) for the function.  Callers must enter the global
881b8e
+   entry point with r12 set to the global entry point address.  On
881b8e
+   return from the function, r2 may have a different value to that
881b8e
+   which it had on entry.
881b8e
+   The local entry point is used when r2 is known to already be valid
881b8e
+   for the function.  There is no requirement on r12 when using the
881b8e
+   local entry point, and on return r2 will contain the same value as
881b8e
+   at entry.
881b8e
+   A value of zero in these bits means that the function has a single
881b8e
+   entry point with no requirement on r12 or r2, and that on return r2
881b8e
+   will contain the same value as at entry.
881b8e
+   Values of one and seven are reserved.  */
881b8e
+#define STO_PPC64_LOCAL_BIT		5
881b8e
+#define STO_PPC64_LOCAL_MASK		(7 << STO_PPC64_LOCAL_BIT)
881b8e
+
881b8e
+// 3 bit other field to bytes.
881b8e
+static inline unsigned int
881b8e
+ppc64_decode_local_entry(unsigned int other)
881b8e
+{
881b8e
+  return ((1 << other) >> 2) << 2;
881b8e
+}
881b8e
+
881b8e
+// bytes to field value.
881b8e
+static inline unsigned int
881b8e
+ppc64_encode_local_entry(unsigned int val)
881b8e
+{
881b8e
+  return (val >= 4 * 4
881b8e
+	  ? (val >= 8 * 4
881b8e
+	     ? (val >= 16 * 4 ? 6 : 5)
881b8e
+	     : 4)
881b8e
+	  : (val >= 2 * 4
881b8e
+	     ? 3
881b8e
+	     : (val >= 1 * 4 ? 2 : 0)));
881b8e
+}
881b8e
+
881b8e
+/* st_other to number of bytes.  */
881b8e
+#define PPC64_LOCAL_ENTRY_OFFSET(other)				\
881b8e
+  ppc64_decode_local_entry (((other) & STO_PPC64_LOCAL_MASK)	\
881b8e
+			    >> STO_PPC64_LOCAL_BIT)
881b8e
+/* number of bytes to st_other.  */
881b8e
+#define PPC64_SET_LOCAL_ENTRY_OFFSET(val)		\
881b8e
+  ppc64_encode_local_entry (val) << STO_PPC64_LOCAL_BIT
881b8e
 
881b8e
 /* Specify the start of the .glink section.  */
881b8e
 #define DT_PPC64_GLINK		DT_LOPROC
881b8e
@@ -171,7 +234,9 @@ END_RELOC_NUMBERS (R_PPC64_max)
881b8e
 #define DT_PPC64_OPD		(DT_LOPROC + 1)
881b8e
 #define DT_PPC64_OPDSZ		(DT_LOPROC + 2)
881b8e
 
881b8e
-/* Specify that tls descriptors should be optimized.  */
881b8e
-#define DT_PPC64_TLSOPT		(DT_LOPROC + 3)
881b8e
+/* Specify whether various optimisations are possible.  */
881b8e
+#define DT_PPC64_OPT		(DT_LOPROC + 3)
881b8e
+#define PPC64_OPT_TLS		1
881b8e
+#define PPC64_OPT_MULTI_TOC	2
881b8e
 
881b8e
 #endif /* _ELF_PPC64_H */
881b8e
diff --git a/ld/testsuite/ld-elfvers/vers24.rd b/ld/testsuite/ld-elfvers/vers24.rd
881b8e
index 42e81e4..fb464f9 100644
881b8e
--- a/ld/testsuite/ld-elfvers/vers24.rd
881b8e
+++ b/ld/testsuite/ld-elfvers/vers24.rd
881b8e
@@ -7,9 +7,9 @@ Symbol table '.dynsym' contains [0-9]+ entries:
881b8e
 # And ensure the dynamic symbol table contains at least x@VERS.0
881b8e
 # and foo@@VERS.0 symbols
881b8e
 #...
881b8e
- +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ _?foo@)@VERS\.0
881b8e
+ +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT .* [0-9]+ _?foo@)@VERS\.0
881b8e
 #...
881b8e
- +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ _?foo@)@VERS\.0
881b8e
+ +[0-9]+: [0-9a-f]+ +(4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ _?x|[0-9]+ +FUNC +GLOBAL +DEFAULT .* [0-9]+ _?foo@)@VERS\.0
881b8e
 #...
881b8e
 Symbol table '.symtab' contains [0-9]+ entries:
881b8e
 #pass
881b8e
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
881b8e
index df913d8..d4c4035 100644
881b8e
--- a/ld/testsuite/ld-ifunc/ifunc.exp
881b8e
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
881b8e
@@ -97,8 +97,9 @@ proc contains_ifunc_symbol { binary_file } {
881b8e
 
881b8e
     # Look for a line like this:
881b8e
     #    58: 0000000000400600    30 IFUNC   GLOBAL DEFAULT   12 library_func2
881b8e
+    # with perhaps some other info between the visibility and section
881b8e
 
881b8e
-    if { ![regexp ".*\[ \]*IFUNC\[ \]+GLOBAL\[ \]+DEFAULT\[ \]+\[UND0-9\]+\[ \]+library_func2\n" [file_contents readelf.out]] } {
881b8e
+    if { ![regexp ".*\[ \]*IFUNC\[ \]+GLOBAL\[ \]+DEFAULT .* \[UND0-9\]+\[ \]+library_func2\n" [file_contents readelf.out]] } {
881b8e
 	return 0
881b8e
     }
881b8e
 
881b8e
diff --git a/ld/testsuite/ld-powerpc/elfv2.s b/ld/testsuite/ld-powerpc/elfv2.s
881b8e
new file mode 100644
881b8e
index 0000000..c2a4c3b
881b8e
--- /dev/null
881b8e
+++ b/ld/testsuite/ld-powerpc/elfv2.s
881b8e
@@ -0,0 +1,32 @@
881b8e
+ .section .toc,"aw",@progbits
881b8e
+.L0:
881b8e
+ .quad x
881b8e
+
881b8e
+ .data
881b8e
+x:
881b8e
+ .quad f1
881b8e
+
881b8e
+ .globl f1
881b8e
+ .type f1,@function
881b8e
+ .text
881b8e
+f1:
881b8e
+ addis 2,12,.TOC.-f1@ha
881b8e
+ addi 2,2,.TOC.-f1@l
881b8e
+ .localentry f1,.-f1
881b8e
+ mflr 0
881b8e
+ stdu 1,-32(1)
881b8e
+ std 0,48(1)
881b8e
+ bl f1
881b8e
+ ld 3,.L0@toc(2)
881b8e
+ bl f2
881b8e
+ nop
881b8e
+ ld 3,x@got(2)
881b8e
+ bl f3
881b8e
+ nop
881b8e
+ bl f4
881b8e
+ nop
881b8e
+ ld 0,48(1)
881b8e
+ addi 1,1,32
881b8e
+ mtlr 0
881b8e
+ blr
881b8e
+ .size f1,.-f1
881b8e
diff --git a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d
881b8e
new file mode 100644
881b8e
index 0000000..7ff9d38
881b8e
--- /dev/null
881b8e
+++ b/ld/testsuite/ld-powerpc/elfv2exe.d
881b8e
@@ -0,0 +1,40 @@
881b8e
+#source: elfv2.s
881b8e
+#as: -a64
881b8e
+#ld: -melf64ppc --defsym f2=0x1234 --defsym f3=0x10008888 --defsym f4=0x1200000 --defsym _start=f1
881b8e
+#objdump: -dr
881b8e
+
881b8e
+.*
881b8e
+
881b8e
+Disassembly of section \.text:
881b8e
+
881b8e
+0+100000c0 <.*\.plt_branch\.f2>:
881b8e
+.*:	(ff ff 62 3d|3d 62 ff ff) 	addis   r11,r2,-1
881b8e
+.*:	(f0 7f 8b e9|e9 8b 7f f0) 	ld      r12,32752\(r11\)
881b8e
+.*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
881b8e
+.*:	(20 04 80 4e|4e 80 04 20) 	bctr
881b8e
+
881b8e
+0+100000d0 <.*\.plt_branch\.f4>:
881b8e
+.*:	(ff ff 62 3d|3d 62 ff ff) 	addis   r11,r2,-1
881b8e
+.*:	(f8 7f 8b e9|e9 8b 7f f8) 	ld      r12,32760\(r11\)
881b8e
+.*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
881b8e
+.*:	(20 04 80 4e|4e 80 04 20) 	bctr
881b8e
+
881b8e
+0+100000e0 <_start>:
881b8e
+.*:	(02 10 40 3c|3c 40 10 02) 	lis     r2,4098
881b8e
+.*:	(40 81 42 38|38 42 81 40) 	addi    r2,r2,-32448
881b8e
+.*:	(a6 02 08 7c|7c 08 02 a6) 	mflr    r0
881b8e
+.*:	(e1 ff 21 f8|f8 21 ff e1) 	stdu    r1,-32\(r1\)
881b8e
+.*:	(30 00 01 f8|f8 01 00 30) 	std     r0,48\(r1\)
881b8e
+.*:	(f5 ff ff 4b|4b ff ff f5) 	bl      .* <_start\+0x8>
881b8e
+.*:	(08 80 62 e8|e8 62 80 08) 	ld      r3,-32760\(r2\)
881b8e
+.*:	(c5 ff ff 4b|4b ff ff c5) 	bl      .*\.plt_branch\.f2>
881b8e
+.*:	(00 00 00 60|60 00 00 00) 	nop
881b8e
+.*:	(10 80 62 e8|e8 62 80 10) 	ld      r3,-32752\(r2\)
881b8e
+.*:	(81 87 00 48|48 00 87 81) 	bl      10008888 <f3>
881b8e
+.*:	(00 00 00 60|60 00 00 00) 	nop
881b8e
+.*:	(c1 ff ff 4b|4b ff ff c1) 	bl      .*\.plt_branch\.f4>
881b8e
+.*:	(00 00 00 60|60 00 00 00) 	nop
881b8e
+.*:	(30 00 01 e8|e8 01 00 30) 	ld      r0,48\(r1\)
881b8e
+.*:	(20 00 21 38|38 21 00 20) 	addi    r1,r1,32
881b8e
+.*:	(a6 03 08 7c|7c 08 03 a6) 	mtlr    r0
881b8e
+.*:	(20 00 80 4e|4e 80 00 20) 	blr
881b8e
diff --git a/ld/testsuite/ld-powerpc/elfv2so.d b/ld/testsuite/ld-powerpc/elfv2so.d
881b8e
new file mode 100644
881b8e
index 0000000..963dbb6
881b8e
--- /dev/null
881b8e
+++ b/ld/testsuite/ld-powerpc/elfv2so.d
881b8e
@@ -0,0 +1,82 @@
881b8e
+#source: elfv2.s
881b8e
+#as: -a64
881b8e
+#ld: -melf64ppc -shared
881b8e
+#objdump: -dr
881b8e
+
881b8e
+.*
881b8e
+
881b8e
+Disassembly of section \.text:
881b8e
+
881b8e
+0+300 <.*\.plt_call\.f4>:
881b8e
+.*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
881b8e
+.*:	(38 80 82 e9|e9 82 80 38) 	ld      r12,-32712\(r2\)
881b8e
+.*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
881b8e
+.*:	(20 04 80 4e|4e 80 04 20) 	bctr
881b8e
+
881b8e
+0+310 <.*\.plt_call\.f3>:
881b8e
+.*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
881b8e
+.*:	(28 80 82 e9|e9 82 80 28) 	ld      r12,-32728\(r2\)
881b8e
+.*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
881b8e
+.*:	(20 04 80 4e|4e 80 04 20) 	bctr
881b8e
+
881b8e
+0+320 <.*\.plt_call\.f2>:
881b8e
+.*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
881b8e
+.*:	(30 80 82 e9|e9 82 80 30) 	ld      r12,-32720\(r2\)
881b8e
+.*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
881b8e
+.*:	(20 04 80 4e|4e 80 04 20) 	bctr
881b8e
+
881b8e
+0+330 <.*\.plt_call\.f1>:
881b8e
+.*:	(18 00 41 f8|f8 41 00 18) 	std     r2,24\(r1\)
881b8e
+.*:	(40 80 82 e9|e9 82 80 40) 	ld      r12,-32704\(r2\)
881b8e
+.*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
881b8e
+.*:	(20 04 80 4e|4e 80 04 20) 	bctr
881b8e
+
881b8e
+0+340 <f1>:
881b8e
+.*:	(02 00 4c 3c|3c 4c 00 02) 	addis   r2,r12,2
881b8e
+.*:	(e0 81 42 38|38 42 81 e0) 	addi    r2,r2,-32288
881b8e
+.*:	(a6 02 08 7c|7c 08 02 a6) 	mflr    r0
881b8e
+.*:	(e1 ff 21 f8|f8 21 ff e1) 	stdu    r1,-32\(r1\)
881b8e
+.*:	(30 00 01 f8|f8 01 00 30) 	std     r0,48\(r1\)
881b8e
+.*:	(dd ff ff 4b|4b ff ff dd) 	bl      .*\.plt_call\.f1>
881b8e
+.*:	(08 80 62 e8|e8 62 80 08) 	ld      r3,-32760\(r2\)
881b8e
+.*:	(c5 ff ff 4b|4b ff ff c5) 	bl      .*\.plt_call\.f2>
881b8e
+.*:	(18 00 41 e8|e8 41 00 18) 	ld      r2,24\(r1\)
881b8e
+.*:	(10 80 62 e8|e8 62 80 10) 	ld      r3,-32752\(r2\)
881b8e
+.*:	(a9 ff ff 4b|4b ff ff a9) 	bl      .*\.plt_call\.f3>
881b8e
+.*:	(18 00 41 e8|e8 41 00 18) 	ld      r2,24\(r1\)
881b8e
+.*:	(91 ff ff 4b|4b ff ff 91) 	bl      .*\.plt_call\.f4>
881b8e
+.*:	(18 00 41 e8|e8 41 00 18) 	ld      r2,24\(r1\)
881b8e
+.*:	(30 00 01 e8|e8 01 00 30) 	ld      r0,48\(r1\)
881b8e
+.*:	(20 00 21 38|38 21 00 20) 	addi    r1,r1,32
881b8e
+.*:	(a6 03 08 7c|7c 08 03 a6) 	mtlr    r0
881b8e
+.*:	(20 00 80 4e|4e 80 00 20) 	blr
881b8e
+.*:	(a0 01 01 00|00 00 00 00) 	.*
881b8e
+.*:	(00 00 00 00|00 01 01 a0) 	.*
881b8e
+
881b8e
+0+390 <__glink_PLTresolve>:
881b8e
+.*:	(a6 02 08 7c|7c 08 02 a6) 	mflr    r0
881b8e
+.*:	(05 00 9f 42|42 9f 00 05) 	bcl     .*
881b8e
+.*:	(a6 02 68 7d|7d 68 02 a6) 	mflr    r11
881b8e
+.*:	(f0 ff 4b e8|e8 4b ff f0) 	ld      r2,-16\(r11\)
881b8e
+.*:	(a6 03 08 7c|7c 08 03 a6) 	mtlr    r0
881b8e
+.*:	(50 60 8b 7d|7d 8b 60 50) 	subf    r12,r11,r12
881b8e
+.*:	(14 5a 62 7d|7d 62 5a 14) 	add     r11,r2,r11
881b8e
+.*:	(d0 ff 0c 38|38 0c ff d0) 	addi    r0,r12,-48
881b8e
+.*:	(00 00 8b e9|e9 8b 00 00) 	ld      r12,0\(r11\)
881b8e
+.*:	(82 f0 00 78|78 00 f0 82) 	rldicl  r0,r0,62,2
881b8e
+.*:	(a6 03 89 7d|7d 89 03 a6) 	mtctr   r12
881b8e
+.*:	(08 00 6b e9|e9 6b 00 08) 	ld      r11,8\(r11\)
881b8e
+.*:	(20 04 80 4e|4e 80 04 20) 	bctr
881b8e
+.*:	(00 00 00 60|60 00 00 00) 	nop
881b8e
+
881b8e
+.* <f3@plt>:
881b8e
+.*:	(c8 ff ff 4b|4b ff ff c8) 	b       .* <__glink_PLTresolve>
881b8e
+
881b8e
+.* <f2@plt>:
881b8e
+.*:	(c4 ff ff 4b|4b ff ff c4) 	b       .* <__glink_PLTresolve>
881b8e
+
881b8e
+.* <f4@plt>:
881b8e
+.*:	(c0 ff ff 4b|4b ff ff c0) 	b       .* <__glink_PLTresolve>
881b8e
+
881b8e
+.* <f1@plt>:
881b8e
+.*:	(bc ff ff 4b|4b ff ff bc) 	b       .* <__glink_PLTresolve>
881b8e
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
881b8e
index f022b95..837ad64 100644
881b8e
--- a/ld/testsuite/ld-powerpc/powerpc.exp
881b8e
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
881b8e
@@ -269,6 +269,8 @@ run_ld_link_tests $ppcelftests
881b8e
 if [ supports_ppc64 ] then {
881b8e
     run_ld_link_tests $ppc64elftests
881b8e
     run_dump_test "relbrlt"
881b8e
+    run_dump_test "elfv2so"
881b8e
+    run_dump_test "elfv2exe"
881b8e
 }
881b8e
 
881b8e
 if { [istarget "powerpc*-eabi*"] } {
881b8e
diff --git a/ld/testsuite/ld-powerpc/tls.d b/ld/testsuite/ld-powerpc/tls.d
881b8e
index 3c32980..eb4be24 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tls.d
881b8e
+++ b/ld/testsuite/ld-powerpc/tls.d
881b8e
@@ -9,7 +9,7 @@
881b8e
 
881b8e
 Disassembly of section \.text:
881b8e
 
881b8e
-0+100000e8 <_start>:
881b8e
+0+100000e8 <\._start>:
881b8e
 .*:	(3c 6d 00 00|00 00 6d 3c) 	addis   r3,r13,0
881b8e
 .*:	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*:	(38 63 90 78|78 90 63 38) 	addi    r3,r3,-28552
881b8e
diff --git a/ld/testsuite/ld-powerpc/tls.g b/ld/testsuite/ld-powerpc/tls.g
881b8e
index 83f8e06..2de9e3b 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tls.g
881b8e
+++ b/ld/testsuite/ld-powerpc/tls.g
881b8e
@@ -8,5 +8,5 @@
881b8e
 .*
881b8e
 
881b8e
 Contents of section \.got:
881b8e
- 100101e0 (00000000|e0810110) (100181e0|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff)  .*
881b8e
- 100101f0 (ffffffff|5880ffff) (ffff8058|ffffffff)                    .*
881b8e
+ 100101f8 (00000000|f8810110) (100181f8|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff)  .*
881b8e
+ 10010208 (ffffffff|5880ffff) (ffff8058|ffffffff)                    .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tls.s b/ld/testsuite/ld-powerpc/tls.s
881b8e
index 5ad9f3d..49828d0 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tls.s
881b8e
+++ b/ld/testsuite/ld-powerpc/tls.s
881b8e
@@ -19,8 +19,13 @@ ie4:	.quad 0x56789abcdef01234
881b8e
 le4:	.quad 0x6789abcdef012345
881b8e
 le5:	.quad 0x789abcdef0123456
881b8e
 
881b8e
-	.text
881b8e
+	.section ".opd","aw",@progbits
881b8e
+	.p2align 3
881b8e
 _start:
881b8e
+	.quad	.L_start,.TOC.@tocbase,0
881b8e
+
881b8e
+	.text
881b8e
+.L_start:
881b8e
 #extern syms
881b8e
 #GD
881b8e
  addi 3,2,gd@got@tlsgd		#R_PPC64_GOT_TLSGD16	gd
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsexe.d b/ld/testsuite/ld-powerpc/tlsexe.d
881b8e
index 8390551..0d5ee40 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsexe.d
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsexe.d
881b8e
@@ -19,8 +19,8 @@ Disassembly of section \.text:
881b8e
 .*	(7d 68 02 a6|a6 02 68 7d) 	mflr    r11
881b8e
 .*	(f9 61 00 20|20 00 61 f9) 	std     r11,32\(r1\)
881b8e
 .*	(f8 41 00 28|28 00 41 f8) 	std     r2,40\(r1\)
881b8e
-.*	(e9 62 80 48|48 80 62 e9) 	ld      r11,-32696\(r2\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
+.*	(e9 82 80 48|48 80 82 e9) 	ld      r12,-32696\(r2\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
 .*	(e8 42 80 50|50 80 42 e8) 	ld      r2,-32688\(r2\)
881b8e
 .*	(4e 80 04 21|21 04 80 4e) 	bctrl
881b8e
 .*	(e9 61 00 20|20 00 61 e9) 	ld      r11,32\(r1\)
881b8e
@@ -28,7 +28,7 @@ Disassembly of section \.text:
881b8e
 .*	(7d 68 03 a6|a6 03 68 7d) 	mtlr    r11
881b8e
 .*	(4e 80 00 20|20 00 80 4e) 	blr
881b8e
 
881b8e
-.* <_start>:
881b8e
+.* <._start>:
881b8e
 .*	(e8 62 80 10|10 80 62 e8) 	ld      r3,-32752\(r2\)
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(7c 63 6a 14|14 6a 63 7c) 	add     r3,r3,r13
881b8e
@@ -67,22 +67,23 @@ Disassembly of section \.text:
881b8e
 .*	(e9 4d 90 2a|2a 90 4d e9) 	lwa     r10,-28632\(r13\)
881b8e
 .*	(3d 2d 00 00|00 00 2d 3d) 	addis   r9,r13,0
881b8e
 .*	(a9 49 90 30|30 90 49 a9) 	lha     r10,-28624\(r9\)
881b8e
-.*	(00 00 00 00|00 02 01 00) .*
881b8e
-.*	(00 01 02 00|00 00 00 00) .*
881b8e
+.*	(00 00 00 00|18 02 01 00) .*
881b8e
+.*	(00 01 02 18|00 00 00 00) .*
881b8e
 .* <__glink_PLTresolve>:
881b8e
 .*	(7d 88 02 a6|a6 02 88 7d) 	mflr    r12
881b8e
 .*	(42 9f 00 05|05 00 9f 42) 	bcl     20,4\*cr7\+so,.*
881b8e
 .*	(7d 68 02 a6|a6 02 68 7d) 	mflr    r11
881b8e
 .*	(e8 4b ff f0|f0 ff 4b e8) 	ld      r2,-16\(r11\)
881b8e
 .*	(7d 88 03 a6|a6 03 88 7d) 	mtlr    r12
881b8e
-.*	(7d 82 5a 14|14 5a 82 7d) 	add     r12,r2,r11
881b8e
-.*	(e9 6c 00 00|00 00 6c e9) 	ld      r11,0\(r12\)
881b8e
-.*	(e8 4c 00 08|08 00 4c e8) 	ld      r2,8\(r12\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
-.*	(e9 6c 00 10|10 00 6c e9) 	ld      r11,16\(r12\)
881b8e
+.*	(7d 62 5a 14|14 5a 62 7d) 	add     r11,r2,r11
881b8e
+.*	(e9 8b 00 00|00 00 8b e9) 	ld      r12,0\(r11\)
881b8e
+.*	(e8 4b 00 08|08 00 4b e8) 	ld      r2,8\(r11\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
+.*	(e9 6b 00 10|10 00 6b e9) 	ld      r11,16\(r11\)
881b8e
 .*	(4e 80 04 20|20 04 80 4e) 	bctr
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
+.* <__tls_get_addr_opt@plt>:
881b8e
 .*	(38 00 00 00|00 00 00 38) 	li      r0,0
881b8e
 .*	(4b ff ff c4|c4 ff ff 4b) 	b       .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsexe.g b/ld/testsuite/ld-powerpc/tlsexe.g
881b8e
index 3420d20..fb8dbb3 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsexe.g
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsexe.g
881b8e
@@ -7,6 +7,6 @@
881b8e
 .*
881b8e
 
881b8e
 Contents of section \.got:
881b8e
-.* (00000000|20860110) (10018620|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff)  .*
881b8e
+.* (00000000|38860110) (10018638|00000000) (ffffffff|1880ffff) (ffff8018|ffffffff)  .*
881b8e
 .* 00000000 00000000 00000000 00000000  .*
881b8e
 .* 00000000 00000000 00000000 00000000  .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsexe.r b/ld/testsuite/ld-powerpc/tlsexe.r
881b8e
index 8d6ff30..72ef3f4 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsexe.r
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsexe.r
881b8e
@@ -20,6 +20,7 @@ Section Headers:
881b8e
  +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
881b8e
+ +\[[ 0-9]+\] \.opd .*
881b8e
  +\[[ 0-9]+\] \.got +PROGBITS .* 0+30 08 +WA +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.plt +.*
881b8e
  +\[[ 0-9]+\] \.shstrtab +.*
881b8e
@@ -46,7 +47,7 @@ Program Headers:
881b8e
  +0+ +
881b8e
  +01 +\.interp 
881b8e
  +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text 
881b8e
- +03 +\.tdata \.dynamic \.got \.plt 
881b8e
+ +03 +\.tdata \.dynamic \.opd \.got \.plt 
881b8e
  +04 +\.dynamic 
881b8e
  +05 +\.tdata \.tbss 
881b8e
 
881b8e
@@ -66,10 +67,10 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
881b8e
 .* TLS +GLOBAL +DEFAULT +UND gd
881b8e
 .* TLS +GLOBAL +DEFAULT +UND ld
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ld2
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
881b8e
 .* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
881b8e
 
881b8e
 Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
  +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
881b8e
@@ -86,6 +87,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* SECTION +LOCAL +DEFAULT +10 
881b8e
 .* SECTION +LOCAL +DEFAULT +11 
881b8e
 .* SECTION +LOCAL +DEFAULT +12 
881b8e
+.* SECTION +LOCAL +DEFAULT +13 
881b8e
 .* FILE +LOCAL +DEFAULT +ABS .*
881b8e
 .* TLS +LOCAL +DEFAULT +8 gd4
881b8e
 .* TLS +LOCAL +DEFAULT +8 ld4
881b8e
@@ -104,12 +106,12 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* GLOBAL +DEFAULT +9 ld0
881b8e
 .* GLOBAL +DEFAULT +9 le1
881b8e
 .* GLOBAL +DEFAULT +UND ld
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +7 _start
881b8e
+.* FUNC +GLOBAL +DEFAULT +11 _start
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ld2
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ld1
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
881b8e
 .* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
881b8e
 .* TLS +GLOBAL +DEFAULT +9 gd0
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ie0
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.d b/ld/testsuite/ld-powerpc/tlsexetoc.d
881b8e
index fc20992..ee0f3b2 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsexetoc.d
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.d
881b8e
@@ -19,8 +19,8 @@ Disassembly of section \.text:
881b8e
 .*	(7d 68 02 a6|a6 02 68 7d) 	mflr    r11
881b8e
 .*	(f9 61 00 20|20 00 61 f9) 	std     r11,32\(r1\)
881b8e
 .*	(f8 41 00 28|28 00 41 f8) 	std     r2,40\(r1\)
881b8e
-.*	(e9 62 80 70|70 80 62 e9) 	ld      r11,-32656\(r2\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
+.*	(e9 82 80 70|70 80 82 e9) 	ld      r12,-32656\(r2\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
 .*	(e8 42 80 78|78 80 42 e8) 	ld      r2,-32648\(r2\)
881b8e
 .*	(4e 80 04 21|21 04 80 4e) 	bctrl
881b8e
 .*	(e9 61 00 20|20 00 61 e9) 	ld      r11,32\(r1\)
881b8e
@@ -28,7 +28,7 @@ Disassembly of section \.text:
881b8e
 .*	(7d 68 03 a6|a6 03 68 7d) 	mtlr    r11
881b8e
 .*	(4e 80 00 20|20 00 80 4e) 	blr
881b8e
 
881b8e
-.* <_start>:
881b8e
+.* <\._start>:
881b8e
 .*	(38 62 80 08|08 80 62 38) 	addi    r3,r2,-32760
881b8e
 .*	(4b ff ff b5|b5 ff ff 4b) 	bl      .*
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
@@ -51,22 +51,23 @@ Disassembly of section \.text:
881b8e
 .*	(89 4d 90 60|60 90 4d 89) 	lbz     r10,-28576\(r13\)
881b8e
 .*	(3d 2d 00 00|00 00 2d 3d) 	addis   r9,r13,0
881b8e
 .*	(99 49 90 68|68 90 49 99) 	stb     r10,-28568\(r9\)
881b8e
-.*	(00 00 00 00|28 02 01 00) .*
881b8e
-.*	(00 01 02 28|00 00 00 00) .*
881b8e
+.*	(00 00 00 00|40 02 01 00) .*
881b8e
+.*	(00 01 02 40|00 00 00 00) .*
881b8e
 .* <__glink_PLTresolve>:
881b8e
 .*	(7d 88 02 a6|a6 02 88 7d) 	mflr    r12
881b8e
 .*	(42 9f 00 05|05 00 9f 42) 	bcl     20,4\*cr7\+so,.*
881b8e
 .*	(7d 68 02 a6|a6 02 68 7d) 	mflr    r11
881b8e
 .*	(e8 4b ff f0|f0 ff 4b e8) 	ld      r2,-16\(r11\)
881b8e
 .*	(7d 88 03 a6|a6 03 88 7d) 	mtlr    r12
881b8e
-.*	(7d 82 5a 14|14 5a 82 7d) 	add     r12,r2,r11
881b8e
-.*	(e9 6c 00 00|00 00 6c e9) 	ld      r11,0\(r12\)
881b8e
-.*	(e8 4c 00 08|08 00 4c e8) 	ld      r2,8\(r12\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
-.*	(e9 6c 00 10|10 00 6c e9) 	ld      r11,16\(r12\)
881b8e
+.*	(7d 62 5a 14|14 5a 62 7d) 	add     r11,r2,r11
881b8e
+.*	(e9 8b 00 00|00 00 8b e9) 	ld      r12,0\(r11\)
881b8e
+.*	(e8 4b 00 08|08 00 4b e8) 	ld      r2,8\(r11\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
+.*	(e9 6b 00 10|10 00 6b e9) 	ld      r11,16\(r11\)
881b8e
 .*	(4e 80 04 20|20 04 80 4e) 	bctr
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
+.* <__tls_get_addr_opt@plt>:
881b8e
 .*	(38 00 00 00|00 00 00 38) 	li      r0,0
881b8e
 .*	(4b ff ff c4|c4 ff ff 4b) 	b       .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.g b/ld/testsuite/ld-powerpc/tlsexetoc.g
881b8e
index e219f0e..dc563ad 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsexetoc.g
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.g
881b8e
@@ -7,7 +7,7 @@
881b8e
 .*: +file format elf64-powerpc
881b8e
 
881b8e
 Contents of section \.got:
881b8e
-.* (00000000|c0850110) (100185c0|00000000) 00000000 00000000  .*
881b8e
+.* (00000000|d8850110) (100185d8|00000000) 00000000 00000000  .*
881b8e
 .* 00000000 00000000 00000000 00000000  .*
881b8e
 .* 00000000 00000000 (00000000|01000000) (00000001|00000000)  .*
881b8e
 .* 00000000 00000000 (00000000|01000000) (00000001|00000000)  .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.r b/ld/testsuite/ld-powerpc/tlsexetoc.r
881b8e
index 71d6c9e..e6f606b 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsexetoc.r
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.r
881b8e
@@ -20,6 +20,7 @@ Section Headers:
881b8e
  +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
881b8e
+ +\[[ 0-9]+\] \.opd .*
881b8e
  +\[[ 0-9]+\] \.got +PROGBITS .* 0+58 08 +WA +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.plt +.*
881b8e
  +\[[ 0-9]+\] \.shstrtab +.*
881b8e
@@ -46,7 +47,7 @@ Program Headers:
881b8e
  +0+ +
881b8e
  +01 +\.interp 
881b8e
  +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text 
881b8e
- +03 +\.tdata \.dynamic \.got \.plt 
881b8e
+ +03 +\.tdata \.dynamic \.opd \.got \.plt 
881b8e
  +04 +\.dynamic 
881b8e
  +05 +\.tdata \.tbss 
881b8e
 
881b8e
@@ -65,10 +66,10 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
881b8e
 .* NOTYPE +LOCAL +DEFAULT +UND 
881b8e
 .* TLS +GLOBAL +DEFAULT +UND gd
881b8e
 .* TLS +GLOBAL +DEFAULT +UND ld
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
881b8e
 .* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
881b8e
 
881b8e
 Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
  +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
881b8e
@@ -85,6 +86,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* SECTION +LOCAL +DEFAULT +10 
881b8e
 .* SECTION +LOCAL +DEFAULT +11 
881b8e
 .* SECTION +LOCAL +DEFAULT +12 
881b8e
+.* SECTION +LOCAL +DEFAULT +13 
881b8e
 .* FILE +LOCAL +DEFAULT +ABS .*
881b8e
 .* TLS +LOCAL +DEFAULT +8 gd4
881b8e
 .* TLS +LOCAL +DEFAULT +8 ld4
881b8e
@@ -93,7 +95,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* TLS +LOCAL +DEFAULT +8 ie4
881b8e
 .* TLS +LOCAL +DEFAULT +8 le4
881b8e
 .* TLS +LOCAL +DEFAULT +8 le5
881b8e
-.* NOTYPE +LOCAL +DEFAULT +11 \.Lie0
881b8e
+.* NOTYPE +LOCAL +DEFAULT +12 \.Lie0
881b8e
 .* (FUNC|NOTYPE) +LOCAL +DEFAULT +UND \.__tls_get_addr(|_opt)
881b8e
 .* FILE +LOCAL +DEFAULT +ABS .*
881b8e
 .* NOTYPE +LOCAL +DEFAULT +7 00000010\.plt_call\.__tls_get_addr(|_opt)
881b8e
@@ -104,12 +106,12 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ld0
881b8e
 .* TLS +GLOBAL +DEFAULT +9 le1
881b8e
 .* TLS +GLOBAL +DEFAULT +UND ld
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +7 _start
881b8e
+.* FUNC +GLOBAL +DEFAULT +11 _start
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ld2
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ld1
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
881b8e
 .* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +13 _end
881b8e
 .* TLS +GLOBAL +DEFAULT +9 gd0
881b8e
 .* TLS +GLOBAL +DEFAULT +9 ie0
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsso.d b/ld/testsuite/ld-powerpc/tlsso.d
881b8e
index 00b00a0..e64184d 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsso.d
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsso.d
881b8e
@@ -10,14 +10,14 @@ Disassembly of section \.text:
881b8e
 
881b8e
 .* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
881b8e
 .*	(f8 41 00 28|28 00 41 f8) 	std     r2,40\(r1\)
881b8e
-.*	(e9 62 80 78|78 80 62 e9) 	ld      r11,-32648\(r2\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
+.*	(e9 82 80 78|78 80 82 e9) 	ld      r12,-32648\(r2\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
 .*	(e8 42 80 80|80 80 42 e8) 	ld      r2,-32640\(r2\)
881b8e
 .*	(28 22 00 00|00 00 22 28) 	cmpldi  r2,0
881b8e
 .*	(4c e2 04 20|20 04 e2 4c) 	bnectr\+ 
881b8e
-.*	(48 00 00 ..|.. 00 00 48) 	b       .* <__glink_PLTresolve\+0x38>
881b8e
+.*	(48 00 00 ..|.. 00 00 48) 	b       .* <__tls_get_addr@plt>
881b8e
 
881b8e
-.* <_start>:
881b8e
+.* <\._start>:
881b8e
 .*	(38 62 80 20|20 80 62 38) 	addi    r3,r2,-32736
881b8e
 .*	(4b ff ff ..|.. ff ff 4b) 	bl      .*plt_call.__tls_get_addr.*
881b8e
 .*	(e8 41 00 28|28 00 41 e8) 	ld      r2,40\(r1\)
881b8e
@@ -57,22 +57,23 @@ Disassembly of section \.text:
881b8e
 .*	(3d 2d 00 00|00 00 2d 3d) 	addis   r9,r13,0
881b8e
 .*	(a9 49 00 00|00 00 49 a9) 	lha     r10,0\(r9\)
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
-.*	(00 00 00 00|20 02 01 00) .*
881b8e
-.*	(00 01 02 20|00 00 00 00) .*
881b8e
+.*	(00 00 00 00|38 02 01 00) .*
881b8e
+.*	(00 01 02 38|00 00 00 00) .*
881b8e
 .* <__glink_PLTresolve>:
881b8e
 .*	(7d 88 02 a6|a6 02 88 7d) 	mflr    r12
881b8e
 .*	(42 9f 00 05|05 00 9f 42) 	bcl     20,4\*cr7\+so,.*
881b8e
 .*	(7d 68 02 a6|a6 02 68 7d) 	mflr    r11
881b8e
 .*	(e8 4b ff f0|f0 ff 4b e8) 	ld      r2,-16\(r11\)
881b8e
 .*	(7d 88 03 a6|a6 03 88 7d) 	mtlr    r12
881b8e
-.*	(7d 82 5a 14|14 5a 82 7d) 	add     r12,r2,r11
881b8e
-.*	(e9 6c 00 00|00 00 6c e9) 	ld      r11,0\(r12\)
881b8e
-.*	(e8 4c 00 08|08 00 4c e8) 	ld      r2,8\(r12\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
-.*	(e9 6c 00 10|10 00 6c e9) 	ld      r11,16\(r12\)
881b8e
+.*	(7d 62 5a 14|14 5a 62 7d) 	add     r11,r2,r11
881b8e
+.*	(e9 8b 00 00|00 00 8b e9) 	ld      r12,0\(r11\)
881b8e
+.*	(e8 4b 00 08|08 00 4b e8) 	ld      r2,8\(r11\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
+.*	(e9 6b 00 10|10 00 6b e9) 	ld      r11,16\(r11\)
881b8e
 .*	(4e 80 04 20|20 04 80 4e) 	bctr
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
+.* <__tls_get_addr@plt>:
881b8e
 .*	(38 00 00 00|00 00 00 38) 	li      r0,0
881b8e
 .*	(4b ff ff c4|c4 ff ff 4b) 	b       .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsso.g b/ld/testsuite/ld-powerpc/tlsso.g
881b8e
index 8536803..8fd3ce0 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsso.g
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsso.g
881b8e
@@ -7,7 +7,7 @@
881b8e
 .*: +file format elf64-powerpc
881b8e
 
881b8e
 Contents of section \.got:
881b8e
- 10788 (00000000|88870100) (00018788|00000000) 00000000 00000000  .*
881b8e
+ 107e0 (00000000|e0870100) (000187e0|00000000) 00000000 00000000  .*
881b8e
 .* 00000000 00000000 00000000 00000000  .*
881b8e
 .* 00000000 00000000 00000000 00000000  .*
881b8e
 .* 00000000 00000000 00000000 00000000  .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlsso.r b/ld/testsuite/ld-powerpc/tlsso.r
881b8e
index fab50e0..6464be0 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlsso.r
881b8e
+++ b/ld/testsuite/ld-powerpc/tlsso.r
881b8e
@@ -18,6 +18,7 @@ Section Headers:
881b8e
  +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.dynamic .*
881b8e
+ +\[[ 0-9]+\] \.opd .*
881b8e
  +\[[ 0-9]+\] \.got .*
881b8e
  +\[[ 0-9]+\] \.plt .*
881b8e
  +\[[ 0-9]+\] \.shstrtab .*
881b8e
@@ -39,12 +40,14 @@ Program Headers:
881b8e
  Section to Segment mapping:
881b8e
  +Segment Sections\.\.\.
881b8e
  +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text 
881b8e
- +01 +\.tdata \.dynamic .got \.plt 
881b8e
+ +01 +\.tdata \.dynamic \.opd \.got \.plt 
881b8e
  +02 +\.dynamic 
881b8e
  +03 +\.tdata \.tbss 
881b8e
 
881b8e
-Relocation section '\.rela\.dyn' at offset .* contains 16 entries:
881b8e
+Relocation section '\.rela\.dyn' at offset .* contains 18 entries:
881b8e
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
881b8e
+[0-9a-f ]+R_PPC64_RELATIVE +55c
881b8e
+[0-9a-f ]+R_PPC64_RELATIVE +187e0
881b8e
 [0-9a-f ]+R_PPC64_TPREL16 +0+60 le0 \+ 0
881b8e
 [0-9a-f ]+R_PPC64_TPREL16_HA +0+68 le1 \+ 0
881b8e
 [0-9a-f ]+R_PPC64_TPREL16_LO +0+68 le1 \+ 0
881b8e
@@ -77,12 +80,12 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 le1
881b8e
 .* TLS +GLOBAL +DEFAULT +UND ld
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
881b8e
+.* FUNC +GLOBAL +DEFAULT +10 _start
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld2
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld1
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
 .* TLS +GLOBAL +DEFAULT +8 gd0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ie0
881b8e
 
881b8e
@@ -100,6 +103,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* SECTION +LOCAL +DEFAULT +9 
881b8e
 .* SECTION +LOCAL +DEFAULT +10 
881b8e
 .* SECTION +LOCAL +DEFAULT +11 
881b8e
+.* SECTION +LOCAL +DEFAULT +12 
881b8e
 .* FILE +LOCAL +DEFAULT +ABS .*
881b8e
 .* TLS +LOCAL +DEFAULT +7 gd4
881b8e
 .* TLS +LOCAL +DEFAULT +7 ld4
881b8e
@@ -119,11 +123,11 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 le1
881b8e
 .* TLS +GLOBAL +DEFAULT +UND ld
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
881b8e
+.* FUNC +GLOBAL +DEFAULT +10 _start
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld2
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld1
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
 .* TLS +GLOBAL +DEFAULT +8 gd0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ie0
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlstoc.d b/ld/testsuite/ld-powerpc/tlstoc.d
881b8e
index faea1c4..05f61af 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlstoc.d
881b8e
+++ b/ld/testsuite/ld-powerpc/tlstoc.d
881b8e
@@ -12,7 +12,7 @@ Disassembly of section \.text:
881b8e
 .* <\.__tls_get_addr>:
881b8e
 .*	(4e 80 00 20|20 00 80 4e) 	blr
881b8e
 
881b8e
-.* <_start>:
881b8e
+.* <\._start>:
881b8e
 .*	(3c 6d 00 00|00 00 6d 3c) 	addis   r3,r13,0
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(38 63 90 40|40 90 63 38) 	addi    r3,r3,-28608
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlstoc.g b/ld/testsuite/ld-powerpc/tlstoc.g
881b8e
index 9ca4302..e3fe1d3 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlstoc.g
881b8e
+++ b/ld/testsuite/ld-powerpc/tlstoc.g
881b8e
@@ -8,8 +8,8 @@
881b8e
 .*
881b8e
 
881b8e
 Contents of section \.got:
881b8e
- 100101a0 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
- 100101b0 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
- 100101c0 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
- 100101d0 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
- 100101e0 (ffffffff|6080ffff) (ffff8060|ffffffff) 00000000 00000000  .*
881b8e
+ 100101b8 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
+ 100101c8 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
+ 100101d8 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
+ 100101e8 (00000000|01000000) (00000001|00000000) 00000000 00000000  .*
881b8e
+ 100101f8 (ffffffff|6080ffff) (ffff8060|ffffffff) 00000000 00000000  .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlstoc.s b/ld/testsuite/ld-powerpc/tlstoc.s
881b8e
index 5008d89..f5dbfdd 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlstoc.s
881b8e
+++ b/ld/testsuite/ld-powerpc/tlstoc.s
881b8e
@@ -19,8 +19,13 @@ ie4:	.quad 0x56789abcdef01234
881b8e
 le4:	.quad 0x6789abcdef012345
881b8e
 le5:	.quad 0x789abcdef0123456
881b8e
 
881b8e
-	.text
881b8e
+	.section ".opd","aw",@progbits
881b8e
+	.p2align 3
881b8e
 _start:
881b8e
+	.quad	.L_start,.TOC.@tocbase,0
881b8e
+
881b8e
+	.text
881b8e
+.L_start:
881b8e
 #extern syms
881b8e
 #GD
881b8e
  addi 3,2,.Lgd@toc
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlstocso.d b/ld/testsuite/ld-powerpc/tlstocso.d
881b8e
index a0cd08f..fa3b77a 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlstocso.d
881b8e
+++ b/ld/testsuite/ld-powerpc/tlstocso.d
881b8e
@@ -10,14 +10,14 @@ Disassembly of section \.text:
881b8e
 
881b8e
 .* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
881b8e
 .*	(f8 41 00 28|28 00 41 f8) 	std     r2,40\(r1\)
881b8e
-.*	(e9 62 80 70|70 80 62 e9) 	ld      r11,-32656\(r2\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
+.*	(e9 82 80 70|70 80 82 e9) 	ld      r12,-32656\(r2\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
 .*	(e8 42 80 78|78 80 42 e8) 	ld      r2,-32648\(r2\)
881b8e
 .*	(28 22 00 00|00 00 22 28) 	cmpldi  r2,0
881b8e
 .*	(4c e2 04 20|20 04 e2 4c) 	bnectr\+ 
881b8e
-.*	(48 00 00 ..|.. 00 00 48) 	b       .* <__glink_PLTresolve\+0x38>
881b8e
+.*	(48 00 00 ..|.. 00 00 48) 	b       .* <__tls_get_addr@plt>
881b8e
 
881b8e
-.* <_start>:
881b8e
+.* <\._start>:
881b8e
 .*	(38 62 80 08|08 80 62 38) 	addi    r3,r2,-32760
881b8e
 .*	(4b ff ff ..|.. ff ff 4b) 	bl      .*plt_call.__tls_get_addr.*
881b8e
 .*	(e8 41 00 28|28 00 41 e8) 	ld      r2,40\(r1\)
881b8e
@@ -41,22 +41,23 @@ Disassembly of section \.text:
881b8e
 .*	(3d 2d 00 00|00 00 2d 3d) 	addis   r9,r13,0
881b8e
 .*	(99 49 00 00|00 00 49 99) 	stb     r10,0\(r9\)
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
-.*	(00 00 00 00|18 02 01 00) .*
881b8e
-.*	(00 01 02 18|00 00 00 00) .*
881b8e
+.*	(00 00 00 00|30 02 01 00) .*
881b8e
+.*	(00 01 02 30|00 00 00 00) .*
881b8e
 .* <__glink_PLTresolve>:
881b8e
 .*	(7d 88 02 a6|a6 02 88 7d) 	mflr    r12
881b8e
 .*	(42 9f 00 05|05 00 9f 42) 	bcl     20,4\*cr7\+so,.*
881b8e
 .*	(7d 68 02 a6|a6 02 68 7d) 	mflr    r11
881b8e
 .*	(e8 4b ff f0|f0 ff 4b e8) 	ld      r2,-16\(r11\)
881b8e
 .*	(7d 88 03 a6|a6 03 88 7d) 	mtlr    r12
881b8e
-.*	(7d 82 5a 14|14 5a 82 7d) 	add     r12,r2,r11
881b8e
-.*	(e9 6c 00 00|00 00 6c e9) 	ld      r11,0\(r12\)
881b8e
-.*	(e8 4c 00 08|08 00 4c e8) 	ld      r2,8\(r12\)
881b8e
-.*	(7d 69 03 a6|a6 03 69 7d) 	mtctr   r11
881b8e
-.*	(e9 6c 00 10|10 00 6c e9) 	ld      r11,16\(r12\)
881b8e
+.*	(7d 62 5a 14|14 5a 62 7d) 	add     r11,r2,r11
881b8e
+.*	(e9 8b 00 00|00 00 8b e9) 	ld      r12,0\(r11\)
881b8e
+.*	(e8 4b 00 08|08 00 4b e8) 	ld      r2,8\(r11\)
881b8e
+.*	(7d 89 03 a6|a6 03 89 7d) 	mtctr   r12
881b8e
+.*	(e9 6b 00 10|10 00 6b e9) 	ld      r11,16\(r11\)
881b8e
 .*	(4e 80 04 20|20 04 80 4e) 	bctr
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
 .*	(60 00 00 00|00 00 00 60) 	nop
881b8e
+.* <__tls_get_addr@plt>:
881b8e
 .*	(38 00 00 00|00 00 00 38) 	li      r0,0
881b8e
 .*	(4b ff ff c4|c4 ff ff 4b) 	b       .*
881b8e
diff --git a/ld/testsuite/ld-powerpc/tlstocso.r b/ld/testsuite/ld-powerpc/tlstocso.r
881b8e
index 1ec8b63..f397915 100644
881b8e
--- a/ld/testsuite/ld-powerpc/tlstocso.r
881b8e
+++ b/ld/testsuite/ld-powerpc/tlstocso.r
881b8e
@@ -18,6 +18,7 @@ Section Headers:
881b8e
  +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
881b8e
  +\[[ 0-9]+\] \.dynamic .*
881b8e
+ +\[[ 0-9]+\] \.opd .*
881b8e
  +\[[ 0-9]+\] \.got .*
881b8e
  +\[[ 0-9]+\] \.plt .*
881b8e
  +\[[ 0-9]+\] \.shstrtab .*
881b8e
@@ -39,12 +40,14 @@ Program Headers:
881b8e
  Section to Segment mapping:
881b8e
  +Segment Sections\.\.\.
881b8e
  +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text 
881b8e
- +01 +\.tdata \.dynamic \.got \.plt 
881b8e
+ +01 +\.tdata \.dynamic \.opd \.got \.plt 
881b8e
  +02 +\.dynamic 
881b8e
  +03 +\.tdata \.tbss 
881b8e
 
881b8e
-Relocation section '\.rela\.dyn' at offset .* contains 11 entries:
881b8e
+Relocation section '\.rela\.dyn' at offset .* contains 13 entries:
881b8e
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
881b8e
+[0-9a-f ]+R_PPC64_RELATIVE +4dc
881b8e
+[0-9a-f ]+R_PPC64_RELATIVE +18720
881b8e
 [0-9a-f ]+R_PPC64_TPREL16 +0+60 le0 \+ 0
881b8e
 [0-9a-f ]+R_PPC64_TPREL16_HA +0+68 le1 \+ 0
881b8e
 [0-9a-f ]+R_PPC64_TPREL16_LO +0+68 le1 \+ 0
881b8e
@@ -72,12 +75,12 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 le1
881b8e
 .* TLS +GLOBAL +DEFAULT +UND ld
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
881b8e
+.* FUNC +GLOBAL +DEFAULT +10 _start
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld2
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld1
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
 .* TLS +GLOBAL +DEFAULT +8 gd0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ie0
881b8e
 
881b8e
@@ -95,6 +98,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* SECTION +LOCAL +DEFAULT +9 
881b8e
 .* SECTION +LOCAL +DEFAULT +10 
881b8e
 .* SECTION +LOCAL +DEFAULT +11 
881b8e
+.* SECTION +LOCAL +DEFAULT +12 
881b8e
 .* FILE +LOCAL +DEFAULT +ABS .*
881b8e
 .* TLS +LOCAL +DEFAULT +7 gd4
881b8e
 .* TLS +LOCAL +DEFAULT +7 ld4
881b8e
@@ -103,7 +107,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* TLS +LOCAL +DEFAULT +7 ie4
881b8e
 .* TLS +LOCAL +DEFAULT +7 le4
881b8e
 .* TLS +LOCAL +DEFAULT +7 le5
881b8e
-.* NOTYPE +LOCAL +DEFAULT +10 \.Lie0
881b8e
+.* NOTYPE +LOCAL +DEFAULT +11 \.Lie0
881b8e
 .* NOTYPE +LOCAL +DEFAULT +UND \.__tls_get_addr
881b8e
 .* FILE +LOCAL +DEFAULT +ABS .*
881b8e
 .* OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
881b8e
@@ -115,11 +119,11 @@ Symbol table '\.symtab' contains [0-9]+ entries:
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 le1
881b8e
 .* TLS +GLOBAL +DEFAULT +UND ld
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +6 _start
881b8e
+.* FUNC +GLOBAL +DEFAULT +10 _start
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld2
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ld1
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 __bss_start
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +10 _edata
881b8e
-.* NOTYPE +GLOBAL +DEFAULT +11 _end
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 __bss_start
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +11 _edata
881b8e
+.* NOTYPE +GLOBAL +DEFAULT +12 _end
881b8e
 .* TLS +GLOBAL +DEFAULT +8 gd0
881b8e
 .* TLS +GLOBAL +DEFAULT +8 ie0
881b8e
diff --git a/ld/testsuite/ld-scripts/crossref.exp b/ld/testsuite/ld-scripts/crossref.exp
881b8e
index 061b5aa..01fdeb4 100644
881b8e
--- a/ld/testsuite/ld-scripts/crossref.exp
881b8e
+++ b/ld/testsuite/ld-scripts/crossref.exp
881b8e
@@ -31,9 +31,11 @@ if { ![is_remote host] && [which $CC] == 0 } {
881b8e
     return
881b8e
 }
881b8e
 
881b8e
+global CFLAGS
881b8e
+set old_CFLAGS "$CFLAGS"
881b8e
+
881b8e
 # Xtensa targets currently default to putting literal values in a separate
881b8e
 # section and that requires linker script support, so put literals in text.
881b8e
-global CFLAGS
881b8e
 if [istarget xtensa*-*-*] {
881b8e
     set CFLAGS "$CFLAGS -mtext-section-literals"
881b8e
 }
881b8e
@@ -41,7 +43,7 @@ if [istarget xtensa*-*-*] {
881b8e
 # If we have a compiler that doesn't use/reference dot-symbols, then
881b8e
 # calls to functions reference the .opd section function descriptor.
881b8e
 # This makes NOCROSSREFS rather useless on powerpc64.
881b8e
-if [istarget powerpc64*-*-*] {
881b8e
+if [istarget powerpc64-*-*] {
881b8e
     set CFLAGS "$CFLAGS -mcall-aixdesc"
881b8e
 }
881b8e
 
881b8e
@@ -61,6 +63,7 @@ if { ![ld_compile $CC "$srcdir/$subdir/cross1.c" tmpdir/cross1.o] \
881b8e
      || ![ld_compile $CC "$srcdir/$subdir/cross2.c" tmpdir/cross2.o] } {
881b8e
     unresolved $test1
881b8e
     unresolved $test2
881b8e
+    set CFLAGS "$old_CFLAGS"
881b8e
     return
881b8e
 }
881b8e
 
881b8e
@@ -95,6 +98,7 @@ if [string match "" $exec_output] then {
881b8e
 
881b8e
 if { ![ld_compile $CC "$srcdir/$subdir/cross3.c" tmpdir/cross3.o] } {
881b8e
     unresolved $test2
881b8e
+    set CFLAGS "$old_CFLAGS"
881b8e
     return
881b8e
 }
881b8e
 
881b8e
@@ -118,11 +122,13 @@ if [string match "" $exec_output] then {
881b8e
 
881b8e
 if { ![ld_compile $CC "$srcdir/$subdir/cross4.c" tmpdir/cross4.o] } {
881b8e
     unresolved $test3
881b8e
+    set CFLAGS "$old_CFLAGS"
881b8e
     return
881b8e
 }
881b8e
 
881b8e
 if ![ld_relocate $ld tmpdir/cross3-partial.o "tmpdir/cross1.o tmpdir/cross4.o"] {
881b8e
     unresolved $test3
881b8e
+    set CFLAGS "$old_CFLAGS"
881b8e
     return
881b8e
 }
881b8e
 
881b8e
@@ -138,3 +144,5 @@ if [string match "" $exec_output] then {
881b8e
     verbose -log "$exec_output"
881b8e
     fail $test3
881b8e
 }
881b8e
+
881b8e
+set CFLAGS "$old_CFLAGS"