This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR ld/20515: i386: Issue an error on non-PIC call to IFUNC in PIC object


On Fri, Aug 26, 2016 at 12:23 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> On i386, IFUNC function must be called via PLT.  Since PLT in PIC
> object uses EBX register, R_386_PLT32 relocation must be used to
> call IFUNC function even when IFUNC function is defined locally.
> Linker should issue an error when R_386_PC32 relocation is used
> to call IFUNC function.
>
> Since PR ld/19784 tests doesn't use PLT relocation to local IFUNC
> function, they are moved to the x86-64 test directory.
>
> Tested on i386.  I will check it in.
>
> H.J.
> ---
> bfd/
>
>         PR ld/14961
>         PR ld/20515
>         * elf32-i386.c (elf_i386_check_relocs): Issue an error when
>         R_386_PC32 relocation is used to call IFUNC function in PIC
>         object.
>
> ld/
>
>         PR ld/14961
>         PR ld/20515
>         * testsuite/ld-i386/i386.exp: Run pr20515.
>         * testsuite/ld-i386/pr20515.d: New file.
>         * testsuite/ld-i386/pr20515.s: Likewise.
>         * testsuite/ld-ifunc/ifunc-14a.s: Use R_386_PLT32 to call IFUNC
>         function.
>         * testsuite/ld-ifunc/ifunc-14c.s: Likewise.
>         * testsuite/ld-ifunc/ifunc-2-i386.s: Likewise.
>         * testsuite/ld-ifunc/ifunc-2-local-i386.s: Likewise.
>         * testsuite/ld-ifunc/ifunc.exp: Move PR ld/19784 tests to ...
>         * testsuite/ld-x86-64/x86-64.exp: Here.
>         * testsuite/ld-ifunc/pr19784a.c: Moved to ...
>         * testsuite/ld-x86-64/pr19784a.c: Here.
>         * testsuite/ld-ifunc/pr19784b.c: Moved to ...
>         * testsuite/ld-x86-64/pr19784b.c: Here.
>         * testsuite/ld-ifunc/pr19784c.c: Moved to ...
>         * testsuite/ld-x86-64/pr19784c.c: Here.
> ---
>  bfd/elf32-i386.c                           | 14 +++++++++++
>  ld/testsuite/ld-i386/i386.exp              |  1 +
>  ld/testsuite/ld-i386/pr20515.d             |  3 +++
>  ld/testsuite/ld-i386/pr20515.s             | 12 +++++++++
>  ld/testsuite/ld-ifunc/ifunc-14a.s          |  2 +-
>  ld/testsuite/ld-ifunc/ifunc-14c.s          |  2 +-
>  ld/testsuite/ld-ifunc/ifunc-2-i386.s       |  2 +-
>  ld/testsuite/ld-ifunc/ifunc-2-local-i386.s |  2 +-
>  ld/testsuite/ld-ifunc/ifunc.exp            | 40 ------------------------------
>  ld/testsuite/ld-ifunc/pr19784a.c           |  6 -----
>  ld/testsuite/ld-ifunc/pr19784b.c           | 11 --------
>  ld/testsuite/ld-ifunc/pr19784c.c           | 11 --------
>  ld/testsuite/ld-x86-64/pr19784a.c          |  6 +++++
>  ld/testsuite/ld-x86-64/pr19784b.c          | 11 ++++++++
>  ld/testsuite/ld-x86-64/pr19784c.c          | 11 ++++++++
>  ld/testsuite/ld-x86-64/x86-64.exp          | 38 ++++++++++++++++++++++++++++
>  16 files changed, 100 insertions(+), 72 deletions(-)
>  create mode 100644 ld/testsuite/ld-i386/pr20515.d
>  create mode 100644 ld/testsuite/ld-i386/pr20515.s
>  delete mode 100644 ld/testsuite/ld-ifunc/pr19784a.c
>  delete mode 100644 ld/testsuite/ld-ifunc/pr19784b.c
>  delete mode 100644 ld/testsuite/ld-ifunc/pr19784c.c
>  create mode 100644 ld/testsuite/ld-x86-64/pr19784a.c
>  create mode 100644 ld/testsuite/ld-x86-64/pr19784b.c
>  create mode 100644 ld/testsuite/ld-x86-64/pr19784c.c
>
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index 4179572..17f86e8 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -2178,6 +2178,20 @@ do_relocation:
>                      a function defined in a shared library.  */
>                   if ((sec->flags & SEC_CODE) == 0)
>                     h->pointer_equality_needed = 1;
> +                 else if (h->type == STT_GNU_IFUNC
> +                          && bfd_link_pic (info))
> +                   {
> +                   if (isym == NULL)
> +                     name = h->root.root.string;
> +                   else
> +                     name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
> +                                              NULL);
> +                   (*_bfd_error_handler)
> +                     (_("%B: unsupported non-PIC call to IFUNC `%s'"),
> +                      abfd, name);
> +                     bfd_set_error (bfd_error_bad_value);
> +                     goto error_return;
> +                   }
>                 }
>               else
>                 {
> diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
> index 2ba0f05..aedec41 100644
> --- a/ld/testsuite/ld-i386/i386.exp
> +++ b/ld/testsuite/ld-i386/i386.exp
> @@ -413,6 +413,7 @@ run_dump_test "pr20253-4a"
>  run_dump_test "pr20253-4b"
>  run_dump_test "pr20253-4c"
>  run_dump_test "pr20253-5"
> +run_dump_test "pr20515"
>
>  if { !([istarget "i?86-*-linux*"]
>         || [istarget "i?86-*-gnu*"]
> diff --git a/ld/testsuite/ld-i386/pr20515.d b/ld/testsuite/ld-i386/pr20515.d
> new file mode 100644
> index 0000000..f3f5fec
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/pr20515.d
> @@ -0,0 +1,3 @@
> +#as: --32
> +#ld: -m elf_i386 -shared
> +#error: unsupported non-PIC call to IFUNC `foo'
> diff --git a/ld/testsuite/ld-i386/pr20515.s b/ld/testsuite/ld-i386/pr20515.s
> new file mode 100644
> index 0000000..eb86cbc
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/pr20515.s
> @@ -0,0 +1,12 @@
> +       .text
> +       .globl bar
> +       .type   bar, @function
> +bar:
> +       jmp     foo
> +       .size   bar, .-bar
> +       .hidden foo
> +       .type foo, %gnu_indirect_function
> +       .globl foo
> +foo:
> +       ret
> +       .size   foo, .-foo
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14a.s b/ld/testsuite/ld-ifunc/ifunc-14a.s
> index 9f20604..87bc0ef 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-14a.s
> +++ b/ld/testsuite/ld-ifunc/ifunc-14a.s
> @@ -2,6 +2,6 @@
>         .globl bar
>         .type   bar, @function
>  bar:
> -       jmp     foo
> +       jmp     foo@PLT
>         .size   bar, .-bar
>         .hidden foo
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14c.s b/ld/testsuite/ld-ifunc/ifunc-14c.s
> index 3cde56e..1a714cb 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-14c.s
> +++ b/ld/testsuite/ld-ifunc/ifunc-14c.s
> @@ -2,6 +2,6 @@
>         .globl xxx
>         .type   xxx, @function
>  xxx:
> -       jmp     foo
> +       jmp     foo@PLT
>         .size   xxx, .-xxx
>         .hidden foo
> diff --git a/ld/testsuite/ld-ifunc/ifunc-2-i386.s b/ld/testsuite/ld-ifunc/ifunc-2-i386.s
> index 32d8812..e84d6b7 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-2-i386.s
> +++ b/ld/testsuite/ld-ifunc/ifunc-2-i386.s
> @@ -15,7 +15,7 @@ bar:
>  .L6:
>         popl    %ebx
>         addl    $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
> -       call    __GI_foo
> +       call    __GI_foo@PLT
>         leal    __GI_foo@GOTOFF(%ebx), %eax
>         ret
>         .size   bar, .-bar
> diff --git a/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s b/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s
> index 4e0b6ae..a69e060 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s
> +++ b/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s
> @@ -12,7 +12,7 @@ bar:
>  .L6:
>         popl    %ebx
>         addl    $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
> -       call    __GI_foo
> +       call    __GI_foo@PLT
>         leal    __GI_foo@GOTOFF(%ebx), %eax
>         ret
>         .size   bar, .-bar
> diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
> index c3c9379..504007a 100644
> --- a/ld/testsuite/ld-ifunc/ifunc.exp
> +++ b/ld/testsuite/ld-ifunc/ifunc.exp
> @@ -505,30 +505,6 @@ run_cc_link_tests [list \
>         {} \
>         "libpr18841c.so" \
>      ] \
> -    [list \
> -       "Build libpr19784a.so" \
> -       "-shared -Wl,-Bsymbolic-functions" \
> -       "-fPIC -O2 -g" \
> -       { pr19784b.c pr19784c.c } \
> -       {} \
> -       "libpr19784a.so" \
> -    ] \
> -    [list \
> -       "Build libpr19784b.so" \
> -       "-shared -Wl,-Bsymbolic-functions" \
> -       "-fPIC -O2 -g" \
> -       { pr19784c.c pr19784b.c } \
> -       {} \
> -       "libpr19784b.so" \
> -    ] \
> -    [list \
> -       "Build pr19784a.o" \
> -       "" \
> -       "" \
> -       { pr19784a.c } \
> -       "" \
> -       "" \
> -    ] \
>  ]
>
>  run_ld_link_exec_tests [list \
> @@ -556,20 +532,4 @@ run_ld_link_exec_tests [list \
>         "pr18841c" \
>         "pr18841.out" \
>      ] \
> -    [list \
> -       "Run pr19784a" \
> -       "tmpdir/pr19784a.o tmpdir/libpr19784a.so" \
> -       "" \
> -       { dummy.c } \
> -       "pr19784a" \
> -       "pass.out" \
> -    ] \
> -    [list \
> -       "Run pr19784b" \
> -       "--as-needed tmpdir/pr19784a.o tmpdir/libpr19784b.so" \
> -       "" \
> -       { dummy.c } \
> -       "pr19784b" \
> -       "pass.out" \
> -    ] \
>  ]
> diff --git a/ld/testsuite/ld-ifunc/pr19784a.c b/ld/testsuite/ld-ifunc/pr19784a.c
> deleted file mode 100644
> index c922cb9..0000000
> --- a/ld/testsuite/ld-ifunc/pr19784a.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -void bar(void);
> -int main(void)
> -{
> -  bar();
> -  return 0;
> -}
> diff --git a/ld/testsuite/ld-ifunc/pr19784b.c b/ld/testsuite/ld-ifunc/pr19784b.c
> deleted file mode 100644
> index 8ea7ce2..0000000
> --- a/ld/testsuite/ld-ifunc/pr19784b.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -int foo (int x) __attribute__ ((ifunc ("resolve_foo")));
> -
> -static int foo_impl(int x)
> -{
> -  return x;
> -}
> -
> -void *resolve_foo (void)
> -{
> -  return (void *) foo_impl;
> -}
> diff --git a/ld/testsuite/ld-ifunc/pr19784c.c b/ld/testsuite/ld-ifunc/pr19784c.c
> deleted file mode 100644
> index 117dfec..0000000
> --- a/ld/testsuite/ld-ifunc/pr19784c.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -#include <stdio.h>
> -
> -extern void abort (void);
> -extern int foo (int) __attribute__ ((visibility("hidden")));
> -
> -int bar()
> -{
> -  if (foo (5) != 5)
> -    abort ();
> -  printf("PASS\n");
> -}
> diff --git a/ld/testsuite/ld-x86-64/pr19784a.c b/ld/testsuite/ld-x86-64/pr19784a.c
> new file mode 100644
> index 0000000..c922cb9
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/pr19784a.c
> @@ -0,0 +1,6 @@
> +void bar(void);
> +int main(void)
> +{
> +  bar();
> +  return 0;
> +}
> diff --git a/ld/testsuite/ld-x86-64/pr19784b.c b/ld/testsuite/ld-x86-64/pr19784b.c
> new file mode 100644
> index 0000000..8ea7ce2
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/pr19784b.c
> @@ -0,0 +1,11 @@
> +int foo (int x) __attribute__ ((ifunc ("resolve_foo")));
> +
> +static int foo_impl(int x)
> +{
> +  return x;
> +}
> +
> +void *resolve_foo (void)
> +{
> +  return (void *) foo_impl;
> +}
> diff --git a/ld/testsuite/ld-x86-64/pr19784c.c b/ld/testsuite/ld-x86-64/pr19784c.c
> new file mode 100644
> index 0000000..117dfec
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/pr19784c.c
> @@ -0,0 +1,11 @@
> +#include <stdio.h>
> +
> +extern void abort (void);
> +extern int foo (int) __attribute__ ((visibility("hidden")));
> +
> +int bar()
> +{
> +  if (foo (5) != 5)
> +    abort ();
> +  printf("PASS\n");
> +}
> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> index 5fa4c9f..01b6a49 100644
> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> @@ -822,6 +822,28 @@ if { [isnative] && [which $CC] != 0 } {
>             {{objdump {-dw} pr19319.dd}} \
>             "pr19319" \
>         ] \
> +       [list \
> +           "Build libpr19784a.so" \
> +           "-shared -Wl,-Bsymbolic-functions" \
> +           "-fPIC -O2 -g" \
> +           { pr19784b.c pr19784c.c } \
> +           {} \
> +           "libpr19784a.so" \
> +       ] \
> +       [list \
> +           "Build libpr19784b.so" \
> +           "-shared -Wl,-Bsymbolic-functions" \
> +           "-fPIC -O2 -g" \
> +           { pr19784c.c pr19784b.c } \
> +           {} \
> +           "libpr19784b.so" \
> +       ] \
> +       [list \
> +          "Build pr19784a.o" \
> +          "" \
> +          "" \
> +          { pr19784a.c } \
> +       ] \
>      ]
>
>      run_ld_link_exec_tests [list \
> @@ -892,6 +914,22 @@ if { [isnative] && [which $CC] != 0 } {
>             "gotpcrel1" \
>             "gotpcrel1.out" \
>         ] \
> +       [list \
> +           "Run pr19784a" \
> +           "tmpdir/pr19784a.o tmpdir/libpr19784a.so" \
> +           "" \
> +           { dummy.s } \
> +           "pr19784a" \
> +           "pass.out" \
> +       ] \
> +       [list \
> +           "Run pr19784b" \
> +           "--as-needed tmpdir/pr19784a.o tmpdir/libpr19784b.so" \
> +           "" \
> +           { dummy.s } \
> +           "pr19784b" \
> +           "pass.out" \
> +       ] \
>      ]
>
>      if { [istarget "x86_64-*-linux*"] \
> --
> 2.7.4
>

We should run PR ld/19784 tests only if ifunc attribute works.
Checked into master.

-- 
H.J.
From 3c4f32287f2271ee46cf57669f867b39f716fe46 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 29 Aug 2016 09:09:14 -0700
Subject: [PATCH] Run PR ld/19784 tests only if ifunc attribute works

	* testsuite/ld-x86-64/x86-64.exp: Run PR ld/19784 tests only
	if ifunc attribute works.
---
 ld/ChangeLog                      |  5 +++
 ld/testsuite/ld-x86-64/x86-64.exp | 85 ++++++++++++++++++++++-----------------
 2 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 69e018c..654605b 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,10 @@
 2016-08-29  H.J. Lu  <hongjiu.lu@intel.com>
 
+	* testsuite/ld-x86-64/x86-64.exp: Run PR ld/19784 tests only
+	if ifunc attribute works.
+
+2016-08-29  H.J. Lu  <hongjiu.lu@intel.com>
+
 	PR ld/14961
 	PR ld/20515
 	* testsuite/ld-i386/i386.exp: Run pr20515.
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 01b6a49..c24eeea 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -822,28 +822,6 @@ if { [isnative] && [which $CC] != 0 } {
 	    {{objdump {-dw} pr19319.dd}} \
 	    "pr19319" \
 	] \
-	[list \
-	    "Build libpr19784a.so" \
-	    "-shared -Wl,-Bsymbolic-functions" \
-	    "-fPIC -O2 -g" \
-	    { pr19784b.c pr19784c.c } \
-	    {} \
-	    "libpr19784a.so" \
-	] \
-	[list \
-	    "Build libpr19784b.so" \
-	    "-shared -Wl,-Bsymbolic-functions" \
-	    "-fPIC -O2 -g" \
-	    { pr19784c.c pr19784b.c } \
-	    {} \
-	    "libpr19784b.so" \
-	] \
-	[list \
-	   "Build pr19784a.o" \
-	   "" \
-	   "" \
-	   { pr19784a.c } \
-	] \
     ]
 
     run_ld_link_exec_tests [list \
@@ -914,24 +892,55 @@ if { [isnative] && [which $CC] != 0 } {
 	    "gotpcrel1" \
 	    "gotpcrel1.out" \
 	] \
-	[list \
-	    "Run pr19784a" \
-	    "tmpdir/pr19784a.o tmpdir/libpr19784a.so" \
-	    "" \
-	    { dummy.s } \
-	    "pr19784a" \
-	    "pass.out" \
-	] \
-	[list \
-	    "Run pr19784b" \
-	    "--as-needed tmpdir/pr19784a.o tmpdir/libpr19784b.so" \
-	    "" \
-	    { dummy.s } \
-	    "pr19784b" \
-	    "pass.out" \
-	] \
     ]
 
+    # Run-time tests which require working ifunc attribute support.
+    if { [check_ifunc_attribute_available] } {
+	run_cc_link_tests [list \
+	    [list \
+		"Build libpr19784a.so" \
+		"-shared -Wl,-Bsymbolic-functions" \
+		"-fPIC -O2 -g" \
+		{ pr19784b.c pr19784c.c } \
+		{} \
+		"libpr19784a.so" \
+	    ] \
+	    [list \
+		"Build libpr19784b.so" \
+		"-shared -Wl,-Bsymbolic-functions" \
+		"-fPIC -O2 -g" \
+		{ pr19784c.c pr19784b.c } \
+		{} \
+		"libpr19784b.so" \
+	    ] \
+	    [list \
+		"Build pr19784a.o" \
+		"" \
+		"" \
+		{ pr19784a.c } \
+	    ] \
+	]
+
+	run_ld_link_exec_tests [list \
+	    [list \
+		"Run pr19784a" \
+		"tmpdir/pr19784a.o tmpdir/libpr19784a.so" \
+		"" \
+		{ dummy.s } \
+		"pr19784a" \
+		"pass.out" \
+	    ] \
+	    [list \
+		"Run pr19784b" \
+		"--as-needed tmpdir/pr19784a.o tmpdir/libpr19784b.so" \
+		"" \
+		{ dummy.s } \
+		"pr19784b" \
+		"pass.out" \
+	    ] \
+	]
+    }
+
     if { [istarget "x86_64-*-linux*"] \
 	 && ![istarget "x86_64-*-linux*-gnux32"]} {
 
-- 
2.7.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]