* coffread.c (process_coff_symbol, coff_read_enum_type): Call
[deliverable/binutils-gdb.git] / bfd / elf64-aarch64.c
index 708b3628a3d70c2c01d1a16820b985313f27a42a..540b275353f2c59e00e1195c94057f71f5e48e7d 100644 (file)
@@ -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.
@@ -1531,16 +1531,16 @@ elf64_aarch64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
       case 408:                /* sizeof(struct elf_prstatus) on Linux/arm64.  */
        /* pr_cursig */
-       elf_tdata (abfd)->core_signal
+       elf_tdata (abfd)->core->signal
          = bfd_get_16 (abfd, note->descdata + 12);
 
        /* pr_pid */
-       elf_tdata (abfd)->core_lwpid
+       elf_tdata (abfd)->core->lwpid
          = bfd_get_32 (abfd, note->descdata + 32);
 
        /* pr_reg */
        offset = 112;
-       size = 288;
+       size = 272;
 
        break;
     }
@@ -2093,7 +2093,7 @@ elf64_aarch64_link_hash_table_create (bfd *abfd)
   struct elf64_aarch64_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct elf64_aarch64_link_hash_table);
 
-  ret = bfd_malloc (amt);
+  ret = bfd_zmalloc (amt);
   if (ret == NULL)
     return NULL;
 
@@ -2105,23 +2105,9 @@ elf64_aarch64_link_hash_table_create (bfd *abfd)
       return NULL;
     }
 
-  ret->sdynbss = NULL;
-  ret->srelbss = NULL;
-
   ret->plt_header_size = PLT_ENTRY_SIZE;
   ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
-
-  ret->sym_cache.abfd = NULL;
   ret->obfd = abfd;
-
-  ret->stub_bfd = NULL;
-  ret->add_stub_section = NULL;
-  ret->layout_sections_again = NULL;
-  ret->stub_group = NULL;
-  ret->bfd_count = 0;
-  ret->top_index = 0;
-  ret->input_list = NULL;
-  ret->tlsdesc_plt = 0;
   ret->dt_tlsdesc_got = (bfd_vma) - 1;
 
   if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
@@ -2143,7 +2129,7 @@ elf64_aarch64_hash_table_free (struct bfd_link_hash_table *hash)
     = (struct elf64_aarch64_link_hash_table *) hash;
 
   bfd_hash_table_free (&ret->stub_hash_table);
-  _bfd_generic_link_hash_table_free (hash);
+  _bfd_elf_link_hash_table_free (hash);
 }
 
 static bfd_vma
@@ -4883,12 +4869,142 @@ elf64_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
 /* 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,
-                            asection *sec ATTRIBUTE_UNUSED,
-                            const Elf_Internal_Rela *
-                            relocs ATTRIBUTE_UNUSED)
+elf64_aarch64_gc_sweep_hook (bfd *abfd,
+                            struct bfd_link_info *info,
+                            asection *sec,
+                            const Elf_Internal_Rela * relocs)
 {
+  struct elf64_aarch64_link_hash_table *htab;
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_aarch64_local_symbol *locals;
+  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);
+
+  locals = elf64_aarch64_locals (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 (locals != NULL)
+           {
+             if (locals[r_symndx].got_refcount > 0)
+               locals[r_symndx].got_refcount -= 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;
 }
 
@@ -5075,6 +5191,10 @@ elf64_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *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;
+
+         /* PR15323, ref flags aren't set for references in the same
+            object.  */
+         h->root.non_ir_ref = 1;
        }
 
       /* Could be done earlier, if h were already available.  */
@@ -5443,7 +5563,9 @@ elf64_aarch64_post_process_headers (bfd *abfd,
 }
 
 static enum elf_reloc_type_class
-elf64_aarch64_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                               const asection *rel_sec ATTRIBUTE_UNUSED,
+                               const Elf_Internal_Rela *rela)
 {
   switch ((int) ELF64_R_TYPE (rela->r_info))
     {
@@ -7063,7 +7185,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
This page took 0.027123 seconds and 4 git commands to generate.