Add 2 i386 tests to call IFUNC functions via GOT
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 13 Jun 2016 16:27:12 +0000 (09:27 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 13 Jun 2016 16:27:12 +0000 (09:27 -0700)
bfd/

* elf32-i386.c (elf_i386_relocate_section): Simplify IFUNC
GOT32 adjustment for static executables.

ld/

2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>

* testsuite/ld-i386/i386.exp: Run ifunc-1a and ifunc-1b.
* testsuite/ld-i386/ifunc-1a.c: New file.
* testsuite/ld-i386/ifunc-1b.S: Likewise.
* testsuite/ld-i386/ifunc-1c.S: Likewise.
* testsuite/ld-i386/ifunc-1d.S: Likewise.

bfd/ChangeLog
bfd/elf32-i386.c
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/ifunc-1a.c [new file with mode: 0644]
ld/testsuite/ld-i386/ifunc-1b.S [new file with mode: 0644]
ld/testsuite/ld-i386/ifunc-1c.S [new file with mode: 0644]
ld/testsuite/ld-i386/ifunc-1d.S [new file with mode: 0644]

index 8e9ad822bd35b28de7c7fd18e7082057a6716ce7..2a1ae1313305892f8442045f2136c4497d371859 100644 (file)
@@ -1,3 +1,8 @@
+2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf32-i386.c (elf_i386_relocate_section): Simplify IFUNC
+       GOT32 adjustment for static executables.
+
 2016-06-13  Maciej W. Rozycki  <macro@imgtec.com>
 
        * elf32-mips.c (elf_mips_gnu_pcrel32): Update comment.
index 7e2b2cba0e412f8ea7351fd004decdf91a1d32a5..fbbf4ab8f70dc9dc07bad39c5e01b56a3dfc15fc 100644 (file)
@@ -4032,21 +4032,16 @@ elf_i386_relocate_section (bfd *output_bfd,
                    }
 
                  relocation = off;
-
-                 /* Adjust for static executables.  */
-                 if (htab->elf.splt == NULL)
-                   relocation += gotplt->output_offset;
                }
              else
-               {
-                 relocation = (base_got->output_section->vma
-                               + base_got->output_offset + off
-                               - gotplt->output_section->vma
-                               - gotplt->output_offset);
-                 /* Adjust for static executables.  */
-                 if (htab->elf.splt == NULL)
-                   relocation += gotplt->output_offset;
-               }
+               relocation = (base_got->output_section->vma
+                             + base_got->output_offset + off
+                             - gotplt->output_section->vma
+                             - gotplt->output_offset);
+
+             /* Adjust for static executables.  */
+             if (htab->elf.splt == NULL)
+               relocation += gotplt->output_offset;
 
              goto do_relocation;
 
index dff7ba8c25b9c15c0fdad010acbb0e21dea5f49a..a8cceb86eec5af4c2612a37b485a4b6d93d4ad60 100644 (file)
@@ -1,3 +1,11 @@
+2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * testsuite/ld-i386/i386.exp: Run ifunc-1a and ifunc-1b.
+       * testsuite/ld-i386/ifunc-1a.c: New file.
+       * testsuite/ld-i386/ifunc-1b.S: Likewise.
+       * testsuite/ld-i386/ifunc-1c.S: Likewise.
+       * testsuite/ld-i386/ifunc-1d.S: Likewise.
+
 2016-06-13  Cupertino Miranda  <cmiranda@synospsy.com>
 
        * testsuite/ld-srec/srec.exp: Changed to XFAIL on both little and
index a6efa53e6afee306f8628d6f0cf2cf1890934329..93f11efc1afd0e97fcb80a176df9a7483c6a611c 100644 (file)
@@ -809,6 +809,42 @@ if { [isnative]
     undefined_weak "-fPIE" "-pie -z nodynamic-undefined-weak"
 }
 
+# Must be native with the C compiler and working IFUNC support,
+if { [isnative]
+     && [check_ifunc_available]
+     && [istarget "i?86-*-*"]
+     && [which $CC] != 0 } {
+    run_cc_link_tests [list \
+       [list \
+           "Build ifunc-1a.o ifunc-1b.o ifunc-1c.o ifunc-1d.o" \
+           "" \
+           "-fPIC -O2 -g" \
+           { ifunc-1a.c ifunc-1b.S ifunc-1c.S ifunc-1d.S } \
+       ] \
+    ]
+
+    run_ld_link_exec_tests [] [list \
+       [list \
+           "Run ifunc-1a" \
+           "tmpdir/ifunc-1a.o tmpdir/ifunc-1b.o \
+            tmpdir/ifunc-1c.o tmpdir/ifunc-1d.o" \
+           "" \
+           { dummy.c } \
+           "ifunc-1a" \
+           "pass.out" \
+       ] \
+       [list \
+           "Run ifunc-1b" \
+           "--static tmpdir/ifunc-1a.o tmpdir/ifunc-1b.o \
+           tmpdir/ifunc-1c.o tmpdir/ifunc-1d.o" \
+           "" \
+           { dummy.c } \
+           "ifunc-1b" \
+           "pass.out" \
+       ] \
+    ]
+}
+
 if { !([istarget "i?86-*-linux*"]
        || [istarget "x86_64-*-linux*"]) } {
     return
diff --git a/ld/testsuite/ld-i386/ifunc-1a.c b/ld/testsuite/ld-i386/ifunc-1a.c
new file mode 100644 (file)
index 0000000..370275a
--- /dev/null
@@ -0,0 +1,8 @@
+extern void check (void);
+
+int
+main ()
+{
+  check ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/ifunc-1b.S b/ld/testsuite/ld-i386/ifunc-1b.S
new file mode 100644 (file)
index 0000000..802a36d
--- /dev/null
@@ -0,0 +1,42 @@
+       .section        .rodata.str1.1,"aMS",@progbits,1
+.LC0:
+       .string "PASS"
+       .text
+       .p2align 4,,15
+       .globl  check
+       .type   check, @function
+check:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       call    *get_func1@GOT(%ebx)
+       cmpl    func1@GOT(%ebx), %eax
+       jne     .L3
+       call    *func1@GOT(%ebx)
+       cmpl    $1, %eax
+       jne     .L3
+       call    *call_func1@GOT(%ebx)
+       cmpl    $1, %eax
+       jne     .L3
+       call    *call_func2@GOT(%ebx)
+       cmpl    $2, %eax
+       jne     .L3
+       leal    .LC0@GOTOFF(%ebx), %eax
+       subl    $12, %esp
+       pushl   %eax
+       call    *puts@GOT(%ebx)
+       addl    $24, %esp
+       popl    %ebx
+       ret
+.L3:
+       call    *abort@GOT(%ebx)
+       .size   check, .-check
+       .section        .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+       .globl  __x86.get_pc_thunk.bx
+       .hidden __x86.get_pc_thunk.bx
+       .type   __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+       movl    (%esp), %ebx
+       ret
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/ifunc-1c.S b/ld/testsuite/ld-i386/ifunc-1c.S
new file mode 100644 (file)
index 0000000..b00f128
--- /dev/null
@@ -0,0 +1,26 @@
+       .text
+       .p2align 4,,15
+       .globl  get_func1
+       .type   get_func1, @function
+get_func1:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       movl    func1@GOT(%eax), %eax
+       ret
+       .size   get_func1, .-get_func1
+       .p2align 4,,15
+       .globl  call_func1
+       .type   call_func1, @function
+call_func1:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       jmp     *func1@GOT(%eax)
+       .size   call_func1, .-call_func1
+       .section        .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
+       .globl  __x86.get_pc_thunk.ax
+       .hidden __x86.get_pc_thunk.ax
+       .type   __x86.get_pc_thunk.ax, @function
+__x86.get_pc_thunk.ax:
+       movl    (%esp), %eax
+       ret
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/ifunc-1d.S b/ld/testsuite/ld-i386/ifunc-1d.S
new file mode 100644 (file)
index 0000000..28f262e
--- /dev/null
@@ -0,0 +1,76 @@
+       .text
+       .p2align 4,,15
+       .type   implementation1, @function
+implementation1:
+       movl    $1, %eax
+       ret
+       .size   implementation1, .-implementation1
+       .p2align 4,,15
+       .type   implementation2, @function
+implementation2:
+       movl    $2, %eax
+       ret
+       .size   implementation2, .-implementation2
+       .p2align 4,,15
+       .type   resolver2, @function
+resolver2:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       leal    implementation2@GOTOFF(%eax), %eax
+       ret
+       .size   resolver2, .-resolver2
+       .type   func2, @gnu_indirect_function
+       .set    func2,resolver2
+       .p2align 4,,15
+       .type   resolver1, @function
+resolver1:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       leal    implementation1@GOTOFF(%eax), %eax
+       ret
+       .size   resolver1, .-resolver1
+       .globl  func1
+       .type   func1, @gnu_indirect_function
+       .set    func1,resolver1
+       .p2align 4,,15
+       .globl  get_func2
+       .type   get_func2, @function
+get_func2:
+       call    __x86.get_pc_thunk.ax
+       addl    $_GLOBAL_OFFSET_TABLE_, %eax
+       movl    func2@GOT(%eax), %eax
+       ret
+       .size   get_func2, .-get_func2
+       .p2align 4,,15
+       .globl  call_func2
+       .type   call_func2, @function
+call_func2:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       call    *get_func2@GOT(%ebx)
+       cmpl    func2@GOT(%ebx), %eax
+       jne     .L10
+       addl    $8, %esp
+       movl    %ebx, %eax
+       popl    %ebx
+       jmp     *func2@GOT(%eax)
+.L10:
+       call    *abort@GOT(%ebx)
+       .size   call_func2, .-call_func2
+       .section        .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
+       .globl  __x86.get_pc_thunk.ax
+       .hidden __x86.get_pc_thunk.ax
+       .type   __x86.get_pc_thunk.ax, @function
+__x86.get_pc_thunk.ax:
+       movl    (%esp), %eax
+       ret
+       .section        .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+       .globl  __x86.get_pc_thunk.bx
+       .hidden __x86.get_pc_thunk.bx
+       .type   __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+       movl    (%esp), %ebx
+       ret
+       .section        .note.GNU-stack,"",@progbits