Blame SOURCES/binutils-aa64-elf_backend_can_gc_sections.patch

881b8e
commit 59c108f731e32b4292c4c31c072a9c11f3ca1404
881b8e
Author: Nick Clifton <nickc@redhat.com>
881b8e
Date:   Fri Mar 8 17:37:30 2013 +0000
881b8e
881b8e
            * elf64-aarch64.c (elf_backend_can_gc_sections): Enable
881b8e
    gc-section support.
881b8e
            (elf64_aarch64_gc_sweep_hook): Handle GOT, TLS and PLT related relocs.
881b8e
    
881b8e
            * lib/ld-lib.exp (check_gc_sections_available): Remove aarch64
881b8e
    from list of
881b8e
            targets that don't support gc-section.
881b8e
881b8e
diff --git a/bfd/elf64-aarch64.c b/bfd/elf64-aarch64.c
881b8e
index 61909b9..94d90c5 100644
881b8e
--- a/bfd/elf64-aarch64.c
881b8e
+++ b/bfd/elf64-aarch64.c
881b8e
@@ -1,5 +1,5 @@
881b8e
 /* ELF support for AArch64.
881b8e
-   Copyright 2009, 2010, 2011, 2012  Free Software Foundation, Inc.
881b8e
+   Copyright 2009-2013 Free Software Foundation, Inc.
881b8e
    Contributed by ARM Ltd.
881b8e
 
881b8e
    This file is part of BFD, the Binary File Descriptor library.
881b8e
@@ -4875,6 +4875,137 @@ elf64_aarch64_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
881b8e
 			     const Elf_Internal_Rela *
881b8e
 			     relocs ATTRIBUTE_UNUSED)
881b8e
 {
881b8e
+  struct elf64_aarch64_link_hash_table *htab;
881b8e
+  Elf_Internal_Shdr *symtab_hdr;
881b8e
+  struct elf_link_hash_entry **sym_hashes;
881b8e
+  bfd_signed_vma *local_got_refcounts;
881b8e
+  const Elf_Internal_Rela *rel, *relend;
881b8e
+
881b8e
+  if (info->relocatable)
881b8e
+    return TRUE;
881b8e
+
881b8e
+  htab = elf64_aarch64_hash_table (info);
881b8e
+
881b8e
+  if (htab == NULL)
881b8e
+    return FALSE;
881b8e
+
881b8e
+  elf_section_data (sec)->local_dynrel = NULL;
881b8e
+
881b8e
+  symtab_hdr = &elf_symtab_hdr (abfd);
881b8e
+  sym_hashes = elf_sym_hashes (abfd);
881b8e
+
881b8e
+  local_got_refcounts = elf_local_got_refcounts (abfd);
881b8e
+
881b8e
+  relend = relocs + sec->reloc_count;
881b8e
+  for (rel = relocs; rel < relend; rel++)
881b8e
+    {
881b8e
+      unsigned long r_symndx;
881b8e
+      unsigned int r_type;
881b8e
+      struct elf_link_hash_entry *h = NULL;
881b8e
+
881b8e
+      r_symndx = ELF64_R_SYM (rel->r_info);
881b8e
+
881b8e
+      if (r_symndx >= symtab_hdr->sh_info)
881b8e
+	{
881b8e
+	  struct elf64_aarch64_link_hash_entry *eh;
881b8e
+	  struct elf_dyn_relocs **pp;
881b8e
+	  struct elf_dyn_relocs *p;
881b8e
+
881b8e
+	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
881b8e
+	  while (h->root.type == bfd_link_hash_indirect
881b8e
+		 || h->root.type == bfd_link_hash_warning)
881b8e
+	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
881b8e
+	  eh = (struct elf64_aarch64_link_hash_entry *) h;
881b8e
+
881b8e
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
881b8e
+	    {
881b8e
+	      if (p->sec == sec)
881b8e
+		{
881b8e
+		  /* Everything must go for SEC.  */
881b8e
+		  *pp = p->next;
881b8e
+		  break;
881b8e
+		}
881b8e
+	    }
881b8e
+        }
881b8e
+      else
881b8e
+	{
881b8e
+	  Elf_Internal_Sym *isym;
881b8e
+
881b8e
+	  /* A local symbol.  */
881b8e
+	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
881b8e
+					abfd, r_symndx);
881b8e
+	  if (isym == NULL)
881b8e
+	    return FALSE;
881b8e
+	}
881b8e
+
881b8e
+      r_type = ELF64_R_TYPE (rel->r_info);
881b8e
+      r_type = aarch64_tls_transition (abfd,info, r_type, h ,r_symndx);
881b8e
+      switch (r_type)
881b8e
+	{
881b8e
+	case R_AARCH64_LD64_GOT_LO12_NC:
881b8e
+	case R_AARCH64_GOT_LD_PREL19:
881b8e
+	case R_AARCH64_ADR_GOT_PAGE:
881b8e
+	case R_AARCH64_TLSGD_ADR_PAGE21:
881b8e
+	case R_AARCH64_TLSGD_ADD_LO12_NC:
881b8e
+	case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
881b8e
+	case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
881b8e
+	case R_AARCH64_TLSLE_ADD_TPREL_LO12:
881b8e
+	case R_AARCH64_TLSLE_ADD_TPREL_HI12:
881b8e
+	case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
881b8e
+	case R_AARCH64_TLSLE_MOVW_TPREL_G2:
881b8e
+	case R_AARCH64_TLSLE_MOVW_TPREL_G1:
881b8e
+	case R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
881b8e
+	case R_AARCH64_TLSLE_MOVW_TPREL_G0:
881b8e
+	case R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
881b8e
+	case R_AARCH64_TLSDESC_ADR_PAGE:
881b8e
+	case R_AARCH64_TLSDESC_ADD_LO12_NC:
881b8e
+	case R_AARCH64_TLSDESC_LD64_LO12_NC:
881b8e
+          if (h != NULL)
881b8e
+	    {
881b8e
+	      if (h->got.refcount > 0)
881b8e
+		h->got.refcount -= 1;
881b8e
+	    }
881b8e
+	  else if (local_got_refcounts != NULL)
881b8e
+	    {
881b8e
+	      if (local_got_refcounts[r_symndx] > 0)
881b8e
+		local_got_refcounts[r_symndx] -= 1;
881b8e
+	    }
881b8e
+	  break;
881b8e
+
881b8e
+	case R_AARCH64_ADR_PREL_PG_HI21_NC:
881b8e
+	case R_AARCH64_ADR_PREL_PG_HI21:
881b8e
+	case R_AARCH64_ADR_PREL_LO21:
881b8e
+	  if (h != NULL && info->executable)
881b8e
+	    {
881b8e
+	      if (h->plt.refcount > 0)
881b8e
+		h->plt.refcount -= 1;
881b8e
+	    }
881b8e
+	  break;
881b8e
+
881b8e
+	case R_AARCH64_CALL26:
881b8e
+	case R_AARCH64_JUMP26:
881b8e
+          /* If this is a local symbol then we resolve it
881b8e
+             directly without creating a PLT entry.  */
881b8e
+	  if (h == NULL)
881b8e
+	    continue;
881b8e
+
881b8e
+	  if (h->plt.refcount > 0)
881b8e
+	    h->plt.refcount -= 1;
881b8e
+	  break;
881b8e
+
881b8e
+	case R_AARCH64_ABS64:
881b8e
+	  if (h != NULL && info->executable)
881b8e
+	    {
881b8e
+	      if (h->plt.refcount > 0)
881b8e
+		h->plt.refcount -= 1;
881b8e
+	    }
881b8e
+	  break;
881b8e
+        
881b8e
+	default:
881b8e
+	  break;
881b8e
+	}
881b8e
+    }
881b8e
+
881b8e
   return TRUE;
881b8e
 }
881b8e
 
881b8e
@@ -7049,7 +7180,7 @@ const struct elf_size_info elf64_aarch64_size_info =
881b8e
   elf64_aarch64_size_info
881b8e
 
881b8e
 #define elf_backend_can_refcount       1
881b8e
-#define elf_backend_can_gc_sections    0
881b8e
+#define elf_backend_can_gc_sections    1
881b8e
 #define elf_backend_plt_readonly       1
881b8e
 #define elf_backend_want_got_plt       1
881b8e
 #define elf_backend_want_plt_sym       0
881b8e
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
881b8e
index 4cd671d..4b88093 100644
881b8e
--- a/ld/testsuite/lib/ld-lib.exp
881b8e
+++ b/ld/testsuite/lib/ld-lib.exp
881b8e
@@ -1,7 +1,5 @@
881b8e
 # Support routines for LD testsuite.
881b8e
-#   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
881b8e
-#    2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
881b8e
-#    Free Software Foundation, Inc.
881b8e
+#   Copyright 1994-2013 Free Software Foundation, Inc.
881b8e
 #
881b8e
 # This file is part of the GNU Binutils.
881b8e
 #
881b8e
@@ -1518,22 +1516,21 @@ proc check_gc_sections_available { } {
881b8e
     if {![info exists gc_sections_available_saved]} {
881b8e
 	# Some targets don't support gc-sections despite whatever's
881b8e
 	# advertised by ld's options.
881b8e
-	if {[istarget aarch64*-*-*]
881b8e
-	     || [istarget arc-*-*]
881b8e
-	     || [istarget d30v-*-*]
881b8e
-	     || [istarget dlx-*-*]
881b8e
-	     || [istarget i960-*-*]
881b8e
-	     || [istarget or32-*-*]
881b8e
-	     || [istarget pj*-*-*]
881b8e
-	     || [istarget alpha-*-*]
881b8e
-	     || [istarget hppa*64-*-*]
881b8e
-	     || [istarget i370-*-*]
881b8e
-	     || [istarget i860-*-*]
881b8e
-	     || [istarget ia64-*-*]
881b8e
-	     || [istarget mep-*-*]
881b8e
-	     || [istarget mn10200-*-*]
881b8e
-	     || [istarget *-*-cygwin]
881b8e
-	     || [istarget *-*-mingw*] } {
881b8e
+	if {   [istarget arc-*-*]
881b8e
+	    || [istarget d30v-*-*]
881b8e
+	    || [istarget dlx-*-*]
881b8e
+	    || [istarget i960-*-*]
881b8e
+	    || [istarget or32-*-*]
881b8e
+	    || [istarget pj*-*-*]
881b8e
+	    || [istarget alpha-*-*]
881b8e
+	    || [istarget hppa*64-*-*]
881b8e
+	    || [istarget i370-*-*]
881b8e
+	    || [istarget i860-*-*]
881b8e
+	    || [istarget ia64-*-*]
881b8e
+	    || [istarget mep-*-*]
881b8e
+	    || [istarget mn10200-*-*]
881b8e
+	    || [istarget *-*-cygwin]
881b8e
+	    || [istarget *-*-mingw*] } {
881b8e
 	    set gc_sections_available_saved 0
881b8e
 	    return 0
881b8e
 	}