[AARCH64] gc-section support

Message ID CAJK_mQ245pGQGpwuwQhMMQereSpg0NG1DGD6WDykO6fGN4idgg@mail.gmail.com
State New
Headers show

Commit Message

Venkataramanan Kumar Feb. 25, 2013, 4:37 p.m.
Hi Yufeng,

I have done the formating changes and used normal diff instaed of cvs diff now.

Attached is the updated patch.

regards,
Venkat.

>
> Hi Venkat,
>
> Thanks for the patch.
>
> Can you please generate the patch using "diff -u -p"?  This will make
> the patch easier to review.  Also the indent is not consistent with the
> existing style, which is hard tab(s) plus spaces.  Can you please
> correct it as well.
>
> Thanks,
> Yufeng
>
> On 02/22/13 17:25, Venkataramanan Kumar wrote:
>> Hi Maintainers,
>>
>> Attached is a small patch that enables gc-section support for AARCH64.
>>
>> In the sweep hook I have handled TLS and GOT related relocs that were
>> already supported in that file.
>>
>> Make check passes along with the gc-section tests.
>>
>> I used the patched binutils to build gcc for aarch64-none-elf target
>> and tested the gcc testsuite in v8 foundation model.
>>
>> Ok for trunk?
>>
>> regards,
>> Venkat,
>>
>>
>> ChangeLog:
>>
>> BFD
>>
>> 2013-02-21  Venkataramanan Kumar<venkataramanan.kumar@linaro.org>
>>
>>          * elf64-aarch64.c (elf_backend_can_gc_sections): Enable
>> gc-section support.
>>          (elf64_aarch64_gc_sweep_hook): Handle GOT, TLS and PLT related r
> elocs.
>>
>> LD
>>
>> 2013-02-21  Venkataramanan Kumar<venkataramanan.kumar@linaro.org>
>>
>>          * lib/ld-lib.exp (check_gc_sections_available): Remove aarch64
>> from list of
>>          targets that don't support gc-section.
>>

Patch hide | download patch | download mbox

diff -x '*CVS*' -u -p -r src/bfd/elf64-aarch64.c src-patch/bfd/elf64-aarch64.c
--- src/bfd/elf64-aarch64.c	2013-02-21 08:32:30.000000000 +0530
+++ src-patch/bfd/elf64-aarch64.c	2013-02-25 20:34:58.137044054 +0530
@@ -4866,8 +4866,8 @@  elf64_aarch64_print_private_bfd_data (bf
   return TRUE;
 }
 
-/* Update the got entry reference counts for the section being removed.  */
 
+/* Update the got entry reference counts for the section being removed.  */
 static bfd_boolean
 elf64_aarch64_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
 			     struct bfd_link_info *info ATTRIBUTE_UNUSED,
@@ -4875,6 +4875,139 @@  elf64_aarch64_gc_sweep_hook (bfd *abfd A
 			     const Elf_Internal_Rela *
 			     relocs ATTRIBUTE_UNUSED)
 {
+  struct elf64_aarch64_link_hash_table *htab;
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  bfd_signed_vma *local_got_refcounts;
+  const Elf_Internal_Rela *rel, *relend;
+
+  if (info->relocatable)
+	return TRUE;
+
+  htab = elf64_aarch64_hash_table (info);
+
+  if (htab == NULL)
+	return FALSE;
+
+  elf_section_data (sec)->local_dynrel = NULL;
+
+  symtab_hdr = &elf_symtab_hdr (abfd);
+  sym_hashes = elf_sym_hashes (abfd);
+
+  local_got_refcounts = elf_local_got_refcounts (abfd);
+
+  relend = relocs + sec->reloc_count;
+  for (rel = relocs; rel < relend; rel++)
+    {
+      unsigned long r_symndx;
+      unsigned int r_type;
+      struct elf_link_hash_entry *h = NULL;
+
+      r_symndx = ELF64_R_SYM (rel->r_info);
+     
+      if (r_symndx >= symtab_hdr->sh_info)
+	{
+	  struct elf64_aarch64_link_hash_entry *eh;
+	  struct elf_dyn_relocs **pp;
+	  struct elf_dyn_relocs *p;
+
+	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  while (h->root.type == bfd_link_hash_indirect
+		 || h->root.type == bfd_link_hash_warning)
+	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+	  eh = (struct elf64_aarch64_link_hash_entry *) h;
+
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    {
+	      if (p->sec == sec)
+		{
+		  /* Everything must go for SEC.  */
+		  *pp = p->next;
+		  break;
+		}
+	    }
+        }
+      else
+	{
+	  Elf_Internal_Sym *isym;
+
+	  /* A local symbol.  */
+	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+					abfd, r_symndx);
+	  if (isym == NULL)
+	    return FALSE;
+	}
+
+      r_type = ELF64_R_TYPE (rel->r_info);
+      r_type = aarch64_tls_transition (abfd,info, r_type, h ,r_symndx);
+      switch (r_type)
+	{
+	case R_AARCH64_LD64_GOT_LO12_NC:
+	case R_AARCH64_GOT_LD_PREL19:
+	case R_AARCH64_ADR_GOT_PAGE:
+	case R_AARCH64_TLSGD_ADR_PAGE21:
+	case R_AARCH64_TLSGD_ADD_LO12_NC:
+	case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+	case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+	case R_AARCH64_TLSLE_ADD_TPREL_LO12:
+	case R_AARCH64_TLSLE_ADD_TPREL_HI12:
+	case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+	case R_AARCH64_TLSLE_MOVW_TPREL_G2:
+	case R_AARCH64_TLSLE_MOVW_TPREL_G1:
+	case R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+	case R_AARCH64_TLSLE_MOVW_TPREL_G0:
+	case R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+	case R_AARCH64_TLSDESC_ADR_PAGE:
+	case R_AARCH64_TLSDESC_ADD_LO12_NC:
+	case R_AARCH64_TLSDESC_LD64_LO12_NC:
+          if (h != NULL)
+	    {
+	      if (h->got.refcount > 0)
+		h->got.refcount -= 1;
+	    }
+	  else if (local_got_refcounts != NULL)
+	    {
+	      if (local_got_refcounts[r_symndx] > 0)
+		local_got_refcounts[r_symndx] -= 1;
+	    }
+	  break;
+
+	case R_AARCH64_ADR_PREL_PG_HI21_NC:
+	case R_AARCH64_ADR_PREL_PG_HI21:
+	case R_AARCH64_ADR_PREL_LO21:
+	  if (h != NULL && info->executable)
+	    {
+	      if (h->plt.refcount > 0)
+		h->plt.refcount -= 1;
+	    }
+	  break;
+
+	case R_AARCH64_CALL26:
+	case R_AARCH64_JUMP26:
+          /* If this is a local symbol then we resolve it
+             directly without creating a PLT entry.  */
+	  if (h == NULL)
+	    continue;
+
+	  if (h->plt.refcount > 0)
+	    h->plt.refcount -= 1;
+	  break;
+
+	case R_AARCH64_ABS64:
+	  if (h != NULL && info->executable)
+	    {
+	      if (h->plt.refcount > 0)
+		h->plt.refcount -= 1;
+	    }
+	    break;
+        
+	default:
+	  break;
+
+	}
+
+    }
+
   return TRUE;
 }
 
@@ -7049,7 +7182,7 @@  const struct elf_size_info elf64_aarch64
   elf64_aarch64_size_info
 
 #define elf_backend_can_refcount       1
-#define elf_backend_can_gc_sections    0
+#define elf_backend_can_gc_sections    1 
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_got_plt       1
 #define elf_backend_want_plt_sym       0
diff -x '*CVS*' -u -p -r src/ld/testsuite/lib/ld-lib.exp src-patch/ld/testsuite/lib/ld-lib.exp
--- src/ld/testsuite/lib/ld-lib.exp	2013-02-19 06:40:06.000000000 +0530
+++ src-patch/ld/testsuite/lib/ld-lib.exp	2013-02-25 20:34:46.737044219 +0530
@@ -1518,8 +1518,7 @@  proc check_gc_sections_available { } {
     if {![info exists gc_sections_available_saved]} {
 	# Some targets don't support gc-sections despite whatever's
 	# advertised by ld's options.
-	if {[istarget aarch64*-*-*]
-	     || [istarget arc-*-*]
+	if {[istarget arc-*-*]
 	     || [istarget d30v-*-*]
 	     || [istarget dlx-*-*]
 	     || [istarget i960-*-*]