]> git.ipfire.org Git - ipfire-3.x.git/blobdiff - binutils/patches/binutils-2.24-aarch64-fix-static-ifunc.patch
binutils: Update to 2.24
[ipfire-3.x.git] / binutils / patches / binutils-2.24-aarch64-fix-static-ifunc.patch
diff --git a/binutils/patches/binutils-2.24-aarch64-fix-static-ifunc.patch b/binutils/patches/binutils-2.24-aarch64-fix-static-ifunc.patch
new file mode 100644 (file)
index 0000000..296f162
--- /dev/null
@@ -0,0 +1,118 @@
+commit 14d96265dd8fd934d868c0b8e1991e2fefbe9fc8
+Author: Will Newton <will.newton@linaro.org>
+Date:   Mon Nov 25 14:44:59 2013 +0000
+
+    bfd/elfnn-aarch64.c: Handle static links with ifunc correctly.
+    
+    The code for handling GOT references to ifunc symbols in static links
+    was missing.
+    
+    bfd/ChangeLog:
+    
+    2013-11-26  Will Newton  <will.newton@linaro.org>
+    
+       * elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol):
+       Handle STT_GNU_IFUNC symbols correctly in static links.
+    
+    ld/testsuite/ChangeLog:
+    
+    2013-11-26  Will Newton  <will.newton@linaro.org>
+    
+       * ld-aarch64/aarch64-elf.exp: Add ifunc-22.
+       * ld-aarch64/ifunc-22.d: New file.
+       * ld-aarch64/ifunc-22.s: Likewise.
+
+diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
+index 3cd3a18..9053635 100644
+--- a/bfd/elfnn-aarch64.c
++++ b/bfd/elfnn-aarch64.c
+@@ -6824,7 +6824,34 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
+                      + 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;
+@@ -6837,6 +6864,7 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
+       }
+       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);
+diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+index a6b3ea2..692bf34 100644
+--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
++++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+@@ -156,3 +156,4 @@ run_dump_test "ifunc-19a"
+ run_dump_test "ifunc-19b"
+ run_dump_test "ifunc-20"
+ run_dump_test "ifunc-21"
++run_dump_test "ifunc-22"
+diff --git a/ld/testsuite/ld-aarch64/ifunc-22.d b/ld/testsuite/ld-aarch64/ifunc-22.d
+new file mode 100644
+index 0000000..f28b039
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-22.d
+@@ -0,0 +1,11 @@
++#source: ifunc-22.s
++#objdump: -s -j .got
++#ld: -static
++#target: aarch64*-*-*
++
++# Ensure GOT is populated correctly in static link
++
++.*:     file format elf64-(little|big)aarch64
++
++Contents of section \.got:
++ 4100f0 00000000 00000000 d0004000 00000000  ..........@.....
+diff --git a/ld/testsuite/ld-aarch64/ifunc-22.s b/ld/testsuite/ld-aarch64/ifunc-22.s
+new file mode 100644
+index 0000000..69a87bb
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-22.s
+@@ -0,0 +1,14 @@
++      .text
++      .type ifunc, @gnu_indirect_function
++      .global ifunc
++ifunc:
++      ret
++      .size   ifunc, .-ifunc
++      .type _start, @function
++      .globl _start
++_start:
++        adrp    x0, :got:ifunc
++        ldr     x0, [x0, #:got_lo12:ifunc]
++      .size   _start, .-_start
++      .data
++      .xword  ifunc