*** ../binutils-2.24.orig/bfd/elfnn-aarch64.c 2013-12-17 11:16:28.723807381 +0000
--- bfd/elfnn-aarch64.c 2013-12-17 11:18:13.517804067 +0000
*************** _aarch64_elf_section_data;
*** 1679,1686 ****
#define elf_aarch64_section_data(sec) \
((_aarch64_elf_section_data *) elf_section_data (sec))
! /* The size of the thread control block. */
! #define TCB_SIZE 16
struct elf_aarch64_local_symbol
{
--- 1679,1686 ----
#define elf_aarch64_section_data(sec) \
((_aarch64_elf_section_data *) elf_section_data (sec))
! /* The size of the thread control block which is defined to be two pointers. */
! #define TCB_SIZE (ARCH_SIZE/8)*2
struct elf_aarch64_local_symbol
{
*************** elfNN_aarch64_final_link_relocate (reloc
*** 3589,3595 ****
if (globals->root.splt != NULL)
{
! plt_index = h->plt.offset / globals->plt_entry_size - 1;
off = (plt_index + 3) * GOT_ENTRY_SIZE;
base_got = globals->root.sgotplt;
}
--- 3589,3596 ----
if (globals->root.splt != NULL)
{
! plt_index = ((h->plt.offset - globals->plt_header_size) /
! globals->plt_entry_size);
off = (plt_index + 3) * GOT_ENTRY_SIZE;
base_got = globals->root.sgotplt;
}
*************** elfNN_aarch64_finish_dynamic_symbol (bfd
*** 6823,6829 ****
+ htab->root.sgot->output_offset
+ (h->got.offset & ~(bfd_vma) 1));
! if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
{
if (!h->def_regular)
return FALSE;
--- 6824,6857 ----
+ htab->root.sgot->output_offset
+ (h->got.offset & ~(bfd_vma) 1));
! 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;
*************** elfNN_aarch64_finish_dynamic_symbol (bfd
*** 6836,6841 ****
--- 6864,6870 ----
}
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);