Blame SOURCES/binutils-ppc64le-7.patch

881b8e
git f6c7c3e8b from upstream:
881b8e
881b8e
    Referencing a function's address on PowerPC64 ELFv2
881b8e
    
881b8e
    ELFv2 needs to create plt entries in a non-PIC executable for an
881b8e
    address reference to a function defined in a shared object.  It's
881b8e
    possible that an object file has no features that distinguish it as
881b8e
    ELFv1 or ELFv2, eg. an object only containing data.  Such files need
881b8e
    to be handled like those that are known to be ELFv2.
881b8e
    However, this unnecessarily creates plt entries for the analogous
881b8e
    ELFv1 case, so arrange to set output abi version earlier, and use the
881b8e
    output abi version to further distinguish ambiguous input files.
881b8e
881b8e
diff -urpN binutils-alan2/bfd/elf64-ppc.c binutils-alan3/bfd/elf64-ppc.c
881b8e
--- binutils-alan2/bfd/elf64-ppc.c	2014-07-31 14:18:08.549977196 +0930
881b8e
+++ binutils-alan3/bfd/elf64-ppc.c	2014-07-31 14:31:16.298120492 +0930
881b8e
@@ -96,7 +96,7 @@ static bfd_vma opd_entry_value
881b8e
 #define elf_backend_create_dynamic_sections   ppc64_elf_create_dynamic_sections
881b8e
 #define elf_backend_copy_indirect_symbol      ppc64_elf_copy_indirect_symbol
881b8e
 #define elf_backend_add_symbol_hook	      ppc64_elf_add_symbol_hook
881b8e
-#define elf_backend_check_directives	      ppc64_elf_process_dot_syms
881b8e
+#define elf_backend_check_directives	      ppc64_elf_before_check_relocs
881b8e
 #define elf_backend_as_needed_cleanup	      ppc64_elf_as_needed_cleanup
881b8e
 #define elf_backend_archive_symbol_lookup     ppc64_elf_archive_symbol_lookup
881b8e
 #define elf_backend_check_relocs	      ppc64_elf_check_relocs
881b8e
@@ -3958,7 +3958,7 @@ struct ppc_link_hash_table
881b8e
   /* Set on error.  */
881b8e
   unsigned int stub_error:1;
881b8e
 
881b8e
-  /* Temp used by ppc64_elf_process_dot_syms.  */
881b8e
+  /* Temp used by ppc64_elf_before_check_relocs.  */
881b8e
   unsigned int twiddled_syms:1;
881b8e
 
881b8e
   /* Incremented every time we size stubs.  */
881b8e
@@ -4922,10 +4922,11 @@ add_symbol_adjust (struct ppc_link_hash_
881b8e
   return TRUE;
881b8e
 }
881b8e
 
881b8e
-/* Process list of dot-symbols we made in link_hash_newfunc.  */
881b8e
+/* Set up opd section info and abiversion for IBFD, and process list
881b8e
+   of dot-symbols we made in link_hash_newfunc.  */
881b8e
 
881b8e
 static bfd_boolean
881b8e
-ppc64_elf_process_dot_syms (bfd *ibfd, struct bfd_link_info *info)
881b8e
+ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
881b8e
 {
881b8e
   struct ppc_link_hash_table *htab;
881b8e
   struct ppc_link_hash_entry **p, *eh;
881b8e
@@ -4938,6 +4939,57 @@ ppc64_elf_process_dot_syms (bfd *ibfd, s
881b8e
 
881b8e
   if (is_ppc64_elf (ibfd))
881b8e
     {
881b8e
+      asection *opd = bfd_get_section_by_name (ibfd, ".opd");
881b8e
+
881b8e
+      if (opd != NULL && opd->size != 0)
881b8e
+	{
881b8e
+	  if (abiversion (ibfd) == 0)
881b8e
+	    set_abiversion (ibfd, 1);
881b8e
+	  else if (abiversion (ibfd) == 2)
881b8e
+	    {
881b8e
+	      info->callbacks->einfo (_("%P: %B .opd not allowed in ABI"
881b8e
+					" version %d\n"),
881b8e
+				      ibfd, abiversion (ibfd));
881b8e
+	      bfd_set_error (bfd_error_bad_value);
881b8e
+	      return FALSE;
881b8e
+	    }
881b8e
+
881b8e
+	  if ((ibfd->flags & DYNAMIC) == 0
881b8e
+	      && (opd->flags & SEC_RELOC) != 0
881b8e
+	      && opd->reloc_count != 0
881b8e
+	      && !bfd_is_abs_section (opd->output_section))
881b8e
+	    {
881b8e
+	      /* Garbage collection needs some extra help with .opd sections.
881b8e
+		 We don't want to necessarily keep everything referenced by
881b8e
+		 relocs in .opd, as that would keep all functions.  Instead,
881b8e
+		 if we reference an .opd symbol (a function descriptor), we
881b8e
+		 want to keep the function code symbol's section.  This is
881b8e
+		 easy for global symbols, but for local syms we need to keep
881b8e
+		 information about the associated function section.  */
881b8e
+	      bfd_size_type amt;
881b8e
+	      asection **opd_sym_map;
881b8e
+
881b8e
+	      amt = opd->size * sizeof (*opd_sym_map) / 8;
881b8e
+	      opd_sym_map = bfd_zalloc (ibfd, amt);
881b8e
+	      if (opd_sym_map == NULL)
881b8e
+		return FALSE;
881b8e
+	      ppc64_elf_section_data (opd)->u.opd.func_sec = opd_sym_map;
881b8e
+	      BFD_ASSERT (ppc64_elf_section_data (opd)->sec_type == sec_normal);
881b8e
+	      ppc64_elf_section_data (opd)->sec_type = sec_opd;
881b8e
+	    }
881b8e
+	}
881b8e
+
881b8e
+      /* For input files without an explicit abiversion in e_flags
881b8e
+	 we should have flagged any with symbol st_other bits set
881b8e
+	 as ELFv1 and above flagged those with .opd as ELFv2.
881b8e
+	 Set the output abiversion if not yet set, and for any input
881b8e
+	 still ambiguous, take its abiversion from the output.
881b8e
+	 Differences in ABI are reported later.  */
881b8e
+      if (abiversion (info->output_bfd) == 0)
881b8e
+	set_abiversion (info->output_bfd, abiversion (ibfd));
881b8e
+      else if (abiversion (ibfd) == 0)
881b8e
+	set_abiversion (ibfd, abiversion (info->output_bfd));
881b8e
+
881b8e
       p = &htab->dot_syms;
881b8e
       while ((eh = *p) != NULL)
881b8e
 	{
881b8e
@@ -5137,34 +5189,9 @@ ppc64_elf_check_relocs (bfd *abfd, struc
881b8e
   sym_hashes = elf_sym_hashes (abfd);
881b8e
   sreloc = NULL;
881b8e
   opd_sym_map = NULL;
881b8e
-  if (strcmp (sec->name, ".opd") == 0)
881b8e
-    {
881b8e
-      /* Garbage collection needs some extra help with .opd sections.
881b8e
-	 We don't want to necessarily keep everything referenced by
881b8e
-	 relocs in .opd, as that would keep all functions.  Instead,
881b8e
-	 if we reference an .opd symbol (a function descriptor), we
881b8e
-	 want to keep the function code symbol's section.  This is
881b8e
-	 easy for global symbols, but for local syms we need to keep
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
-	return FALSE;
881b8e
-      ppc64_elf_section_data (sec)->u.opd.func_sec = opd_sym_map;
881b8e
-      BFD_ASSERT (ppc64_elf_section_data (sec)->sec_type == sec_normal);
881b8e
-      ppc64_elf_section_data (sec)->sec_type = sec_opd;
881b8e
-    }
881b8e
+  if (ppc64_elf_section_data (sec) != NULL
881b8e
+      && ppc64_elf_section_data (sec)->sec_type == sec_opd)
881b8e
+    opd_sym_map = ppc64_elf_section_data (sec)->u.opd.func_sec;
881b8e
 
881b8e
   rel_end = relocs + sec->reloc_count;
881b8e
   for (rel = relocs; rel < rel_end; rel++)
881b8e
@@ -5338,7 +5365,7 @@ ppc64_elf_check_relocs (bfd *abfd, struc
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
+	  if (h != NULL && !info->shared && abiversion (abfd) != 1)
881b8e
 	    {
881b8e
 	      if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
881b8e
 		return FALSE;
881b8e
@@ -5607,7 +5634,7 @@ ppc64_elf_check_relocs (bfd *abfd, struc
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
+	  if (h != NULL && !info->shared && abiversion (abfd) != 1
881b8e
 	      && rel->r_addend == 0)
881b8e
 	    {
881b8e
 	      /* We may need a .plt entry if this reloc refers to a
881b8e
@@ -5781,21 +5808,14 @@ ppc64_elf_merge_private_bfd_data (bfd *i
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
+  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
+  else if (iflags != oflags && iflags != 0)
881b8e
     {
881b8e
       (*_bfd_error_handler)
881b8e
 	(_("%B: ABI version %ld is not compatible with ABI version %ld output"),
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/ambiguousv1.d binutils-alan3/ld/testsuite/ld-powerpc/ambiguousv1.d
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/ambiguousv1.d	1970-01-01 09:30:00.000000000 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/ambiguousv1.d	2014-07-31 14:30:15.816565692 +0930
881b8e
@@ -0,0 +1,12 @@
881b8e
+#source: startv1.s
881b8e
+#source: funref.s
881b8e
+#as: -a64
881b8e
+#ld: -melf64ppc
881b8e
+#ld_after_inputfiles: tmpdir/funv1.so
881b8e
+#readelf: -r --wide
881b8e
+# check that we do the right thing with funref.s that doesn't have
881b8e
+# anything to mark it as ELFv1 or ELFv2
881b8e
+
881b8e
+Relocation section .* contains 1 entries:
881b8e
+.*
881b8e
+.* R_PPC64_ADDR64 +0+ my_func \+ 0
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/ambiguousv2.d binutils-alan3/ld/testsuite/ld-powerpc/ambiguousv2.d
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/ambiguousv2.d	1970-01-01 09:30:00.000000000 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/ambiguousv2.d	2014-07-31 14:30:15.816565692 +0930
881b8e
@@ -0,0 +1,12 @@
881b8e
+#source: startv2.s
881b8e
+#source: funref.s
881b8e
+#as: -a64
881b8e
+#ld: -melf64ppc
881b8e
+#ld_after_inputfiles: tmpdir/funv2.so
881b8e
+#readelf: -r --wide
881b8e
+# check that we do the right thing with funref.s that doesn't have
881b8e
+# anything to mark it as ELFv1 or ELFv2
881b8e
+
881b8e
+Relocation section .*contains 1 entries:
881b8e
+.*
881b8e
+.* R_PPC64_JMP_SLOT .* my_func \+ 0
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/funref.s binutils-alan3/ld/testsuite/ld-powerpc/funref.s
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/funref.s	1970-01-01 09:30:00.000000000 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/funref.s	2014-07-31 14:30:15.816565692 +0930
881b8e
@@ -0,0 +1,4 @@
881b8e
+ .data
881b8e
+ .globl func_tab
881b8e
+func_tab:
881b8e
+ .dc.a my_func
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/funv1.s binutils-alan3/ld/testsuite/ld-powerpc/funv1.s
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/funv1.s	1970-01-01 09:30:00.000000000 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/funv1.s	2014-07-31 14:30:15.816565692 +0930
881b8e
@@ -0,0 +1,10 @@
881b8e
+ .globl my_func
881b8e
+ .type my_func,@function
881b8e
+ .section .opd,"aw",@progbits
881b8e
+my_func:
881b8e
+ .quad .Lmy_func, .TOC.@tocbase
881b8e
+
881b8e
+ .text
881b8e
+.Lmy_func:
881b8e
+ blr
881b8e
+ .size my_func,.-.Lmy_func
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/funv2.s binutils-alan3/ld/testsuite/ld-powerpc/funv2.s
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/funv2.s	1970-01-01 09:30:00.000000000 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/funv2.s	2014-07-31 14:30:15.816565692 +0930
881b8e
@@ -0,0 +1,6 @@
881b8e
+ .abiversion 2
881b8e
+ .globl my_func
881b8e
+ .type my_func,@function
881b8e
+my_func:
881b8e
+ blr
881b8e
+ .size my_func,.-my_func
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/powerpc.exp binutils-alan3/ld/testsuite/ld-powerpc/powerpc.exp
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/powerpc.exp	2014-07-31 10:57:23.830363894 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/powerpc.exp	2014-07-31 14:32:08.843996200 +0930
881b8e
@@ -213,6 +213,8 @@ set ppc64elftests {
881b8e
         {tocopt4a.s tocopt4b.s} {{objdump -s tocopt4.d}} "tocopt4"}
881b8e
     {"TOC opt5" "-melf64ppc" "" "-a64"  {tocopt5.s}
881b8e
 	{{objdump -s tocopt5.d}} "tocopt5"}
881b8e
+    {"ambig shared v1" "-shared -melf64ppc" "" "-a64" {funv1.s} {} "funv1.so"}
881b8e
+    {"ambig shared v2" "-shared -melf64ppc" "" "-a64" {funv2.s} {} "funv2.so"}
881b8e
 }
881b8e
 
881b8e
 set ppceabitests {
881b8e
@@ -271,6 +273,8 @@ if [ supports_ppc64 ] then {
881b8e
     run_dump_test "relbrlt"
881b8e
     run_dump_test "elfv2so"
881b8e
     run_dump_test "elfv2exe"
881b8e
+    run_dump_test "ambiguousv1"
881b8e
+    run_dump_test "ambiguousv2"
881b8e
 }
881b8e
 
881b8e
 if { [istarget "powerpc*-eabi*"] } {
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/startv1.s binutils-alan3/ld/testsuite/ld-powerpc/startv1.s
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/startv1.s	1970-01-01 09:30:00.000000000 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/startv1.s	2014-07-31 14:30:15.820565530 +0930
881b8e
@@ -0,0 +1,8 @@
881b8e
+ .globl _start
881b8e
+ .section .opd,"aw",@progbits
881b8e
+_start:
881b8e
+ .quad .L_start, .TOC.@tocbase
881b8e
+
881b8e
+ .text
881b8e
+.L_start:
881b8e
+ b _start
881b8e
diff -urpN binutils-alan2/ld/testsuite/ld-powerpc/startv2.s binutils-alan3/ld/testsuite/ld-powerpc/startv2.s
881b8e
--- binutils-alan2/ld/testsuite/ld-powerpc/startv2.s	1970-01-01 09:30:00.000000000 +0930
881b8e
+++ binutils-alan3/ld/testsuite/ld-powerpc/startv2.s	2014-07-31 14:30:15.820565530 +0930
881b8e
@@ -0,0 +1,5 @@
881b8e
+ .abiversion 2
881b8e
+ .text
881b8e
+ .globl _start
881b8e
+_start:
881b8e
+ b _start