[Patch, AARCH64] gc-section support
Venkataramanan Kumar
venkataramanan.kumar@linaro.org
Fri Feb 22 17:25:00 GMT 2013
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 relocs.
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.
-------------- next part --------------
Index: bfd/elf64-aarch64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-aarch64.c,v
retrieving revision 1.9
diff -r1.9 elf64-aarch64.c
4869d4868
< /* Update the got entry reference counts for the section being removed. */
4870a4870
> /* Update the got entry reference counts for the section being removed. */
4877a4878,5010
> 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;
>
> }
>
> }
>
7052c7185
< #define elf_backend_can_gc_sections 0
---
> #define elf_backend_can_gc_sections 1
Index: ld/testsuite/lib/ld-lib.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/lib/ld-lib.exp,v
retrieving revision 1.103
diff -r1.103 ld-lib.exp
1521,1522c1521
< if {[istarget aarch64*-*-*]
< || [istarget arc-*-*]
---
> if {[istarget arc-*-*]
More information about the Binutils
mailing list