bfd/elfnn-aarch64.c: Handle static links with ifunc correctly.
authorWill Newton <will.newton@linaro.org>
Mon, 25 Nov 2013 14:44:59 +0000 (14:44 +0000)
committerWill Newton <will.newton@linaro.org>
Tue, 26 Nov 2013 15:25:11 +0000 (15:25 +0000)
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.

bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/testsuite/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/ifunc-22.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/ifunc-22.s [new file with mode: 0644]

index 4bcbba8..17e1fab 100644 (file)
@@ -1,5 +1,10 @@
 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.
+
+2013-11-26  Will Newton  <will.newton@linaro.org>
+
        * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Ensure
        PLT_INDEX is calculated using correct header size.
 
index 7cce6f4..6a42bc5 100644 (file)
@@ -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);
index 22a062d..bbd8eb3 100644 (file)
@@ -1,5 +1,11 @@
 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.
+
+2013-11-26  Will Newton  <will.newton@linaro.org>
+
        * ld-aarch64/aarch64-elf.exp: Add ifunc-21 test.
        * ld-aarch64/ifunc-21.d: New file.
        * ld-aarch64/ifunc-21.s: Likewise.
index a6b3ea2..692bf34 100644 (file)
@@ -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 (file)
index 0000000..f28b039
--- /dev/null
@@ -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 (file)
index 0000000..69a87bb
--- /dev/null
@@ -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