/* AArch64-specific support for NN-bit ELF.
- Copyright 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of BFD, the Binary File Descriptor library.
return NULL;
}
-#define TARGET_LITTLE_SYM bfd_elfNN_littleaarch64_vec
+#define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
#define TARGET_LITTLE_NAME "elfNN-littleaarch64"
-#define TARGET_BIG_SYM bfd_elfNN_bigaarch64_vec
+#define TARGET_BIG_SYM aarch64_elfNN_be_vec
#define TARGET_BIG_NAME "elfNN-bigaarch64"
/* The linker script knows the section names for placement.
value = (symbol_got_offset (input_bfd, h, r_symndx)
+ globals->root.sgot->output_section->vma
- + globals->root.sgot->output_section->output_offset);
+ + globals->root.sgot->output_offset);
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
0, weak_undef_p);
case BFD_RELOC_AARCH64_TLSDESC_LDR:
if (globals->root.sgot == NULL)
return bfd_reloc_notsupported;
-
value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
+ globals->root.sgotplt->output_section->vma
- + globals->root.sgotplt->output_section->output_offset
+ + globals->root.sgotplt->output_offset
+ globals->sgotplt_jump_table_size);
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
*/
insn = bfd_getl32 (contents + rel->r_offset);
- insn &= 0xfffffff0;
+ insn &= 0xffffffe0;
bfd_putl32 (insn, contents + rel->r_offset);
return bfd_reloc_continue;
}
return TRUE;
}
-/* Copy backend specific data from one object module to another. */
-
-static bfd_boolean
-elfNN_aarch64_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
-{
- flagword in_flags;
-
- if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
- return TRUE;
-
- in_flags = elf_elfheader (ibfd)->e_flags;
-
- elf_elfheader (obfd)->e_flags = in_flags;
- elf_flags_init (obfd) = TRUE;
-
- /* Also copy the EI_OSABI field. */
- elf_elfheader (obfd)->e_ident[EI_OSABI] =
- elf_elfheader (ibfd)->e_ident[EI_OSABI];
-
- /* Copy object attributes. */
- _bfd_elf_copy_obj_attributes (ibfd, obfd);
-
- return TRUE;
-}
-
/* Merge backend specific data from an object file to the output
object file when linking. */
i_ehdrp = elf_elfheader (abfd);
i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
- _bfd_elf_set_osabi (abfd, link_info);
+ _bfd_elf_post_process_headers (abfd, link_info);
}
static enum elf_reloc_type_class
}
}
-/* Set the right machine number for an AArch64 ELF file. */
-
-static bfd_boolean
-elfNN_aarch64_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
-{
- if (hdr->sh_type == SHT_NOTE)
- *flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS;
-
- return TRUE;
-}
-
/* Handle an AArch64 specific section when reading an object file. This is
called when bfd_section_from_shdr finds a section with an unknown
type. */
plt_entry = plt->contents + h->plt.offset;
plt_entry_address = plt->output_section->vma
- + plt->output_section->output_offset + h->plt.offset;
+ + plt->output_offset + h->plt.offset;
gotplt_entry_address = gotplt->output_section->vma +
gotplt->output_offset + got_offset;
+ htab->root.sgot->output_offset
+ (h->got.offset & ~(bfd_vma) 1));
- if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
+ if (h->def_regular
+ && h->type == STT_GNU_IFUNC)
+ {
+ if (info->shared)
+ {
+ /* Generate R_AARCH64_GLOB_DAT. */
+ goto do_glob_dat;
+ }
+ else
+ {
+ asection *plt;
+
+ if (!h->pointer_equality_needed)
+ abort ();
+
+ /* For non-shared object, we can't use .got.plt, which
+ contains the real function address if we need pointer
+ equality. We load the GOT entry with the PLT entry. */
+ plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
+ bfd_put_NN (output_bfd, (plt->output_section->vma
+ + plt->output_offset
+ + h->plt.offset),
+ htab->root.sgot->contents
+ + (h->got.offset & ~(bfd_vma) 1));
+ return TRUE;
+ }
+ }
+ else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
{
if (!h->def_regular)
return FALSE;
}
else
{
+do_glob_dat:
BFD_ASSERT ((h->got.offset & 1) == 0);
bfd_put_NN (output_bfd, (bfd_vma) 0,
htab->root.sgot->contents + h->got.offset);
+ GOT_ENTRY_SIZE * 2);
plt_base = htab->root.splt->output_section->vma +
- htab->root.splt->output_section->output_offset;
+ htab->root.splt->output_offset;
/* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
break;
case DT_PLTRELSZ:
- s = htab->root.srelplt->output_section;
+ s = htab->root.srelplt;
dyn.d_un.d_val = s->size;
break;
about changing the DT_RELA entry. */
if (htab->root.srelplt != NULL)
{
- s = htab->root.srelplt->output_section;
+ s = htab->root.srelplt;
dyn.d_un.d_val -= s->size;
}
break;
#define bfd_elfNN_close_and_cleanup \
elfNN_aarch64_close_and_cleanup
-#define bfd_elfNN_bfd_copy_private_bfd_data \
- elfNN_aarch64_copy_private_bfd_data
-
#define bfd_elfNN_bfd_free_cached_info \
elfNN_aarch64_bfd_free_cached_info
#define elf_backend_reloc_type_class \
elfNN_aarch64_reloc_type_class
-#define elf_backend_section_flags \
- elfNN_aarch64_section_flags
-
#define elf_backend_section_from_shdr \
elfNN_aarch64_section_from_shdr