Blame SOURCES/glibc-aarch64-ifunc.patch

147e83
diff --git glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h
147e83
index 8686fd5..2b10581 100644
147e83
--- glibc-2.17-c758a686/elf/elf.h
147e83
+++ glibc-2.17-c758a686/elf/elf.h
147e83
@@ -2327,6 +2327,117 @@ typedef Elf32_Addr Elf32_Conflict;
147e83
 #define R_AARCH64_NONE            0	/* No relocation.  */
147e83
 #define R_AARCH64_ABS64         257	/* Direct 64 bit. */
147e83
 #define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
147e83
+#define R_AARCH64_ABS16         259	/* Direct 16-bit.  */
147e83
+#define R_AARCH64_PREL64        260	/* PC-relative 64-bit.  */
147e83
+#define R_AARCH64_PREL32        261	/* PC-relative 32-bit.  */
147e83
+#define R_AARCH64_PREL16        262	/* PC-relative 16-bit.  */
147e83
+#define R_AARCH64_MOVW_UABS_G0  263	/* Dir. MOVZ imm. from bits 15:0.  */
147e83
+#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_UABS_G1  265	/* Dir. MOVZ imm. from bits 31:16.  */
147e83
+#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_UABS_G2  267	/* Dir. MOVZ imm. from bits 47:32.  */
147e83
+#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_UABS_G3  269	/* Dir. MOV{K,Z} imm. from 63:48.  */
147e83
+#define R_AARCH64_MOVW_SABS_G0  270	/* Dir. MOV{N,Z} imm. from 15:0.  */
147e83
+#define R_AARCH64_MOVW_SABS_G1  271	/* Dir. MOV{N,Z} imm. from 31:16.  */
147e83
+#define R_AARCH64_MOVW_SABS_G2  272	/* Dir. MOV{N,Z} imm. from 47:32.  */
147e83
+#define R_AARCH64_LD_PREL_LO19  273	/* PC-rel. LD imm. from bits 20:2.  */
147e83
+#define R_AARCH64_ADR_PREL_LO21 274	/* PC-rel. ADR imm. from bits 20:0.  */
147e83
+#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
147e83
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check.  */
147e83
+#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
147e83
+#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
147e83
+#define R_AARCH64_TSTBR14       279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
147e83
+#define R_AARCH64_CONDBR19      280	/* PC-rel. cond. br. imm. from 20:2. */
147e83
+#define R_AARCH64_JUMP26        282	/* PC-rel. B imm. from bits 27:2.  */
147e83
+#define R_AARCH64_CALL26        283	/* Likewise for CALL.  */
147e83
+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1.  */
147e83
+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2.  */
147e83
+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3.  */
147e83
+#define R_AARCH64_MOVW_PREL_G0  287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
147e83
+#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_PREL_G1  289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
147e83
+#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_PREL_G2  291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
147e83
+#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_PREL_G3  293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
147e83
+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4.  */
147e83
+#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
147e83
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
147e83
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
147e83
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
147e83
+#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
147e83
+#define R_AARCH64_GOTREL64      307	/* GOT-relative 64-bit.  */
147e83
+#define R_AARCH64_GOTREL32      308	/* GOT-relative 32-bit.  */
147e83
+#define R_AARCH64_GOT_LD_PREL19 309	/* PC-rel. GOT off. load imm. 20:2.  */
147e83
+#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
147e83
+#define R_AARCH64_ADR_GOT_PAGE  311	/* P-page-rel. GOT off. ADRP 32:12.  */
147e83
+#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
147e83
+#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
147e83
+#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
147e83
+#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
147e83
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
147e83
+#define R_AARCH64_TLSGD_MOVW_G1 515	/* GOT-rel. MOV{N,Z} 31:16.  */
147e83
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
147e83
+#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
147e83
+#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
147e83
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
147e83
+#define R_AARCH64_TLSLD_MOVW_G1 520	/* Like 515; local dynamic model.  */
147e83
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
147e83
+#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
147e83
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32.  */
147e83
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16.  */
147e83
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check.  */
147e83
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0.  */
147e83
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check.  */
147e83
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
147e83
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0.  */
147e83
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check.  */
147e83
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0.  */
147e83
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1.  */
147e83
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2.  */
147e83
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3.  */
147e83
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16.  */
147e83
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0.  */
147e83
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12.  */
147e83
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3.  */
147e83
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2.  */
147e83
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32.  */
147e83
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16.  */
147e83
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check.  */
147e83
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0.  */
147e83
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check.  */
147e83
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12.  */
147e83
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0.  */
147e83
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check.  */
147e83
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0.  */
147e83
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
147e83
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1.  */
147e83
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2.  */
147e83
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3.  */
147e83
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
147e83
+#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0.  */
147e83
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12.  */
147e83
+#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
147e83
+#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
147e83
+#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
147e83
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
147e83
+#define R_AARCH64_TLSDESC_LDR   567	/* Relax LDR.  */
147e83
+#define R_AARCH64_TLSDESC_ADD   568	/* Relax ADD.  */
147e83
+#define R_AARCH64_TLSDESC_CALL  569	/* Relax BLR.  */
147e83
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4.  */
147e83
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check.  */
147e83
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
147e83
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check.  */
147e83
 #define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
147e83
 #define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
147e83
 #define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
147e83
@@ -2335,6 +2446,7 @@ typedef Elf32_Addr Elf32_Conflict;
147e83
 #define R_AARCH64_TLS_DTPREL64 1029	/* Module-relative offset, 64 bit.  */
147e83
 #define R_AARCH64_TLS_TPREL64  1030	/* TP-relative offset, 64 bit.  */
147e83
 #define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
147e83
+#define R_AARCH64_IRELATIVE    1032	/* STT_GNU_IFUNC relocation.  */
147e83
 
147e83
 /* ARM relocs.  */
147e83
 
147e83
diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h
147e83
index 32dee0f..9a48dc2 100644
147e83
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h
147e83
+++ glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h
147e83
@@ -1,6 +1,6 @@
147e83
 /* Machine-dependent ELF indirect relocation inline functions.
147e83
    AArch64 version.
147e83
-   Copyright (C) 2012 Free Software Foundation, Inc.
147e83
+   Copyright (C) 2012-2014 Free Software Foundation, Inc.
147e83
    This file is part of the GNU C Library.
147e83
 
147e83
    The GNU C Library is free software; you can redistribute it and/or
147e83
@@ -22,15 +22,31 @@
147e83
 
147e83
 #include <stdio.h>
147e83
 #include <unistd.h>
147e83
+#include <ldsodefs.h>
147e83
 
147e83
-/* AArch64 does not yet implement IFUNC support.  However since
147e83
-   2011-06-20 provision of a elf_ifunc_invoke has been mandatory.  */
147e83
+#define ELF_MACHINE_IRELA       1
147e83
 
147e83
 static inline ElfW(Addr)
147e83
 __attribute ((always_inline))
147e83
 elf_ifunc_invoke (ElfW(Addr) addr)
147e83
 {
147e83
-  return ((ElfW(Addr) (*) (void)) (addr)) ();
147e83
+  return ((ElfW(Addr) (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap));
147e83
+}
147e83
+
147e83
+static inline void
147e83
+__attribute ((always_inline))
147e83
+elf_irela (const ElfW(Rela) *reloc)
147e83
+{
147e83
+  ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset;
147e83
+  const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
147e83
+
147e83
+  if (__glibc_likely (r_type == R_AARCH64_IRELATIVE))
147e83
+    {
147e83
+      ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend);
147e83
+      *reloc_addr = value;
147e83
+    }
147e83
+  else
147e83
+    __libc_fatal ("unexpected reloc type in static binary");
147e83
 }
147e83
 
147e83
 #endif
147e83
diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h
147e83
index b1878a7..1db5a5b 100644
147e83
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h
147e83
+++ glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h
147e83
@@ -23,6 +23,7 @@
147e83
 
147e83
 #include <tls.h>
147e83
 #include <dl-tlsdesc.h>
147e83
+#include <dl-irel.h>
147e83
 
147e83
 /* Return nonzero iff ELF header is compatible with the running host.  */
147e83
 static inline int __attribute__ ((unused))
147e83
@@ -336,6 +337,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
147e83
 	    }
147e83
 	  break;
147e83
 
147e83
+	case R_AARCH64_IRELATIVE:
147e83
+	  value = map->l_addr + reloc->r_addend;
147e83
+	  value = elf_ifunc_invoke (value);
147e83
+	  *reloc_addr = value;
147e83
+	  break;
147e83
+
147e83
 	default:
147e83
 	  _dl_reloc_bad_type (map, r_type, 0);
147e83
 	  break;
147e83
@@ -379,6 +386,13 @@ elf_machine_lazy_rel (struct link_map *map,
147e83
       td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
147e83
 			  + map->l_addr);
147e83
     }
147e83
+  else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE))
147e83
+    {
147e83
+      ElfW(Addr) value = map->l_addr + reloc->r_addend;
147e83
+      if (__glibc_likely (!skip_ifunc))
147e83
+	value = elf_ifunc_invoke (value);
147e83
+      *reloc_addr = value;
147e83
+    }
147e83
   else
147e83
     _dl_reloc_bad_type (map, r_type, 1);
147e83
 }