Browse Source

* elf64-aarch64.c (elf_backend_can_gc_sections): Enable

gc-section support.
        (elf64_aarch64_gc_sweep_hook): Handle GOT, TLS and PLT related relocs.

        * lib/ld-lib.exp (check_gc_sections_available): Remove aarch64
from list of
        targets that don't support gc-section.
gdb_7_6-branch
Nick Clifton 14 years ago
parent
commit
59c108f731
  1. 7
      bfd/ChangeLog
  2. 135
      bfd/elf64-aarch64.c
  3. 5
      ld/testsuite/ChangeLog
  4. 35
      ld/testsuite/lib/ld-lib.exp

7
bfd/ChangeLog

@ -1,3 +1,10 @@
2013-03-08 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.
2013-03-08 Andreas Arnez <arnez@linux.vnet.ibm.com>
* elf-bfd.h (elfcore_write_s390_tdb): Add prototype.

135
bfd/elf64-aarch64.c

@ -1,5 +1,5 @@
/* ELF support for AArch64.
Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
Copyright 2009-2013 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of BFD, the Binary File Descriptor library.
@ -4875,6 +4875,137 @@ elf64_aarch64_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
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 +7180,7 @@ const struct elf_size_info elf64_aarch64_size_info =
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

5
ld/testsuite/ChangeLog

@ -1,3 +1,8 @@
2013-03-08 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.
2013-03-05 Alan Modra <amodra@gmail.com>
* ld-scripts/rgn-at6.s, * ld-scripts/rgn-at6.t, * ld-scripts/rgn-at6.d,

35
ld/testsuite/lib/ld-lib.exp

@ -1,7 +1,5 @@
# Support routines for LD testsuite.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
# Free Software Foundation, Inc.
# Copyright 1994-2013 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
@ -1518,22 +1516,21 @@ 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-*-*]
|| [istarget d30v-*-*]
|| [istarget dlx-*-*]
|| [istarget i960-*-*]
|| [istarget or32-*-*]
|| [istarget pj*-*-*]
|| [istarget alpha-*-*]
|| [istarget hppa*64-*-*]
|| [istarget i370-*-*]
|| [istarget i860-*-*]
|| [istarget ia64-*-*]
|| [istarget mep-*-*]
|| [istarget mn10200-*-*]
|| [istarget *-*-cygwin]
|| [istarget *-*-mingw*] } {
if { [istarget arc-*-*]
|| [istarget d30v-*-*]
|| [istarget dlx-*-*]
|| [istarget i960-*-*]
|| [istarget or32-*-*]
|| [istarget pj*-*-*]
|| [istarget alpha-*-*]
|| [istarget hppa*64-*-*]
|| [istarget i370-*-*]
|| [istarget i860-*-*]
|| [istarget ia64-*-*]
|| [istarget mep-*-*]
|| [istarget mn10200-*-*]
|| [istarget *-*-cygwin]
|| [istarget *-*-mingw*] } {
set gc_sections_available_saved 0
return 0
}

Loading…
Cancel
Save