Blame binutils-2.24-elfnn-aarch64.patch

e4cc6a5
*** ../binutils-2.24.orig/bfd/elfnn-aarch64.c	2013-12-17 11:16:28.723807381 +0000
e4cc6a5
--- bfd/elfnn-aarch64.c	2013-12-17 11:18:13.517804067 +0000
e4cc6a5
*************** _aarch64_elf_section_data;
e4cc6a5
*** 1679,1686 ****
e4cc6a5
  #define elf_aarch64_section_data(sec) \
e4cc6a5
    ((_aarch64_elf_section_data *) elf_section_data (sec))
e4cc6a5
  
e4cc6a5
! /* The size of the thread control block.  */
e4cc6a5
! #define TCB_SIZE	16
e4cc6a5
  
e4cc6a5
  struct elf_aarch64_local_symbol
e4cc6a5
  {
e4cc6a5
--- 1679,1686 ----
e4cc6a5
  #define elf_aarch64_section_data(sec) \
e4cc6a5
    ((_aarch64_elf_section_data *) elf_section_data (sec))
e4cc6a5
  
e4cc6a5
! /* The size of the thread control block which is defined to be two pointers.  */
e4cc6a5
! #define TCB_SIZE	(ARCH_SIZE/8)*2
e4cc6a5
  
e4cc6a5
  struct elf_aarch64_local_symbol
e4cc6a5
  {
e4cc6a5
*************** elfNN_aarch64_final_link_relocate (reloc
e4cc6a5
*** 3589,3595 ****
e4cc6a5
  
e4cc6a5
  	      if (globals->root.splt != NULL)
e4cc6a5
  		{
e4cc6a5
! 		  plt_index = h->plt.offset / globals->plt_entry_size - 1;
e4cc6a5
  		  off = (plt_index + 3) * GOT_ENTRY_SIZE;
e4cc6a5
  		  base_got = globals->root.sgotplt;
e4cc6a5
  		}
e4cc6a5
--- 3589,3596 ----
e4cc6a5
  
e4cc6a5
  	      if (globals->root.splt != NULL)
e4cc6a5
  		{
e4cc6a5
! 		  plt_index = ((h->plt.offset - globals->plt_header_size) /
e4cc6a5
! 			       globals->plt_entry_size);
e4cc6a5
  		  off = (plt_index + 3) * GOT_ENTRY_SIZE;
e4cc6a5
  		  base_got = globals->root.sgotplt;
e4cc6a5
  		}
e4cc6a5
*************** elfNN_aarch64_finish_dynamic_symbol (bfd
e4cc6a5
*** 6823,6829 ****
e4cc6a5
  		       + htab->root.sgot->output_offset
e4cc6a5
  		       + (h->got.offset & ~(bfd_vma) 1));
e4cc6a5
  
e4cc6a5
!       if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
e4cc6a5
  	{
e4cc6a5
  	  if (!h->def_regular)
e4cc6a5
  	    return FALSE;
e4cc6a5
--- 6824,6857 ----
e4cc6a5
  		       + htab->root.sgot->output_offset
e4cc6a5
  		       + (h->got.offset & ~(bfd_vma) 1));
e4cc6a5
  
e4cc6a5
!       if (h->def_regular
e4cc6a5
! 	  && h->type == STT_GNU_IFUNC)
e4cc6a5
! 	{
e4cc6a5
! 	  if (info->shared)
e4cc6a5
! 	    {
e4cc6a5
! 	      /* Generate R_AARCH64_GLOB_DAT.  */
e4cc6a5
! 	      goto do_glob_dat;
e4cc6a5
! 	    }
e4cc6a5
! 	  else
e4cc6a5
! 	    {
e4cc6a5
! 	      asection *plt;
e4cc6a5
! 
e4cc6a5
! 	      if (!h->pointer_equality_needed)
e4cc6a5
! 		abort ();
e4cc6a5
! 
e4cc6a5
! 	      /* For non-shared object, we can't use .got.plt, which
e4cc6a5
! 		 contains the real function address if we need pointer
e4cc6a5
! 		 equality.  We load the GOT entry with the PLT entry.  */
e4cc6a5
! 	      plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
e4cc6a5
! 	      bfd_put_NN (output_bfd, (plt->output_section->vma
e4cc6a5
! 				       + plt->output_offset
e4cc6a5
! 				       + h->plt.offset),
e4cc6a5
! 			  htab->root.sgot->contents
e4cc6a5
! 			  + (h->got.offset & ~(bfd_vma) 1));
e4cc6a5
! 	      return TRUE;
e4cc6a5
! 	    }
e4cc6a5
! 	}
e4cc6a5
!       else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
e4cc6a5
  	{
e4cc6a5
  	  if (!h->def_regular)
e4cc6a5
  	    return FALSE;
e4cc6a5
*************** elfNN_aarch64_finish_dynamic_symbol (bfd
e4cc6a5
*** 6836,6841 ****
e4cc6a5
--- 6864,6870 ----
e4cc6a5
  	}
e4cc6a5
        else
e4cc6a5
  	{
e4cc6a5
+ do_glob_dat:
e4cc6a5
  	  BFD_ASSERT ((h->got.offset & 1) == 0);
e4cc6a5
  	  bfd_put_NN (output_bfd, (bfd_vma) 0,
e4cc6a5
  		      htab->root.sgot->contents + h->got.offset);