From patchwork Wed May 27 21:38:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 6949 Received: (qmail 8933 invoked by alias); 27 May 2015 21:38:29 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 8901 invoked by uid 89); 27 May 2015 21:38:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.1 required=5.0 tests=AWL, BAYES_20, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-oi0-f44.google.com MIME-Version: 1.0 X-Received: by 10.202.208.66 with SMTP id h63mr9699018oig.74.1432762705084; Wed, 27 May 2015 14:38:25 -0700 (PDT) In-Reply-To: <5566232B.4080904@redhat.com> References: <5566232B.4080904@redhat.com> Date: Wed, 27 May 2015 14:38:24 -0700 Message-ID: Subject: Re: Relocations to use when eliding plts From: "H.J. Lu" To: Richard Henderson Cc: "gcc@gcc.gnu.org" , Binutils , libc-alpha On Wed, May 27, 2015 at 1:03 PM, Richard Henderson wrote: > There's one problem with the couple of patches that I've seen go by wrt eliding > PLTs with -z now, and relaxing inlined PLTs (aka -fno-plt): > > They're currently using the same relocations used by data, and thus the linker > and dynamic linker must ensure that pointer equality is maintained. Which > results in branch-to-branch-(to-branch) situations. > Your test exposed a linker bug: https://sourceware.org/bugzilla/show_bug.cgi?id=18458 I checked in this patch to fix it. From 8ded2ddc8bac501c1ee0706cb3d3ef3fb1c10b85 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 27 May 2015 14:32:24 -0700 Subject: [PATCH] Convert PLT reloc only if pointer equality isn't needed When pointer equality needed, we can't replace PLT relocations with GOT relocations for -z now. This patch checks if pointer equality is needed before converting PLT relocations to GOT relocations. bfd/ PR binutils/18458 * elf32-i386.c (elf_i386_check_relocs): Create .plt.got section for now binding only if pointer equality isn't needed. (elf_i386_allocate_dynrelocs): Use .plt.got section for now binding only if pointer equality isn't needed. * elf64-x86-64.c (elf_x86_64_check_relocs): Create .plt.got section for now binding only if pointer equality isn't needed. (elf_x86_64_allocate_dynrelocs): Use .plt.got section for now binding only if pointer equality isn't needed. ld/testsuite/ PR binutils/18458 * ld-elf/shared.exp (build_tests): Build libpr18458a.so and libpr18458b.so. (run_tests): Run pr18458 test. * ld-elf/pr18458a.c: New file. * ld-elf/pr18458b.c: Likewise. * ld-elf/pr18458c.c: Likewise. --- bfd/ChangeLog | 12 ++++++++++++ bfd/elf32-i386.c | 5 +++-- bfd/elf64-x86-64.c | 5 +++-- ld/testsuite/ChangeLog | 10 ++++++++++ ld/testsuite/ld-elf/pr18458a.c | 6 ++++++ ld/testsuite/ld-elf/pr18458b.c | 6 ++++++ ld/testsuite/ld-elf/pr18458c.c | 18 ++++++++++++++++++ ld/testsuite/ld-elf/shared.exp | 9 +++++++++ 8 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 ld/testsuite/ld-elf/pr18458a.c create mode 100644 ld/testsuite/ld-elf/pr18458b.c create mode 100644 ld/testsuite/ld-elf/pr18458c.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 87a0bff..a8a0ad9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2015-05-27 H.J. Lu + + PR binutils/18458 + * elf32-i386.c (elf_i386_check_relocs): Create .plt.got section + for now binding only if pointer equality isn't needed. + (elf_i386_allocate_dynrelocs): Use .plt.got section for now + binding only if pointer equality isn't needed. + * elf64-x86-64.c (elf_x86_64_check_relocs): Create .plt.got + section for now binding only if pointer equality isn't needed. + (elf_x86_64_allocate_dynrelocs): Use .plt.got section for now + binding only if pointer equality isn't needed. + 2015-05-26 H.J. Lu PR binutils/18437 diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 23d50e1..f3aee96 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1885,7 +1885,8 @@ do_size: if (use_plt_got && h != NULL && h->plt.refcount > 0 - && ((info->flags & DF_BIND_NOW) || h->got.refcount > 0) + && (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed) + || h->got.refcount > 0) && htab->plt_got == NULL) { /* Create the GOT procedure linkage table. */ @@ -2323,7 +2324,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) { bfd_boolean use_plt_got; - if ((info->flags & DF_BIND_NOW)) + if ((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed) { /* Don't use the regular PLT for DF_BIND_NOW. */ h->plt.offset = (bfd_vma) -1; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 4428f97..072c00b 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2080,7 +2080,8 @@ do_size: if (use_plt_got && h != NULL && h->plt.refcount > 0 - && ((info->flags & DF_BIND_NOW) || h->got.refcount > 0) + && (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed) + || h->got.refcount > 0) && htab->plt_got == NULL) { /* Create the GOT procedure linkage table. */ @@ -2542,7 +2543,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) { bfd_boolean use_plt_got; - if ((info->flags & DF_BIND_NOW)) + if ((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed) { /* Don't use the regular PLT for DF_BIND_NOW. */ h->plt.offset = (bfd_vma) -1; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index e6a551c..779fc03 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2015-05-27 H.J. Lu + + PR binutils/18458 + * ld-elf/shared.exp (build_tests): Build libpr18458a.so and + libpr18458b.so. + (run_tests): Run pr18458 test. + * ld-elf/pr18458a.c: New file. + * ld-elf/pr18458b.c: Likewise. + * ld-elf/pr18458c.c: Likewise. + 2015-05-16 H.J. Lu * ld-i386/i386.exp: Run PR ld/17689 tests with -z now. diff --git a/ld/testsuite/ld-elf/pr18458a.c b/ld/testsuite/ld-elf/pr18458a.c new file mode 100644 index 0000000..d6aa49f --- /dev/null +++ b/ld/testsuite/ld-elf/pr18458a.c @@ -0,0 +1,6 @@ +#include +void +a (void) +{ + printf("PASS\n"); +} diff --git a/ld/testsuite/ld-elf/pr18458b.c b/ld/testsuite/ld-elf/pr18458b.c new file mode 100644 index 0000000..33c1cb6 --- /dev/null +++ b/ld/testsuite/ld-elf/pr18458b.c @@ -0,0 +1,6 @@ +extern void a (void); +void +b (void) +{ + a(); +} diff --git a/ld/testsuite/ld-elf/pr18458c.c b/ld/testsuite/ld-elf/pr18458c.c new file mode 100644 index 0000000..d40f98c --- /dev/null +++ b/ld/testsuite/ld-elf/pr18458c.c @@ -0,0 +1,18 @@ +extern void a(void); +extern void b(void); + +void dummy (void) +{ + a(); +} +int +compare (void (*f)(void)) +{ + return a == f; +} +int +main (void) +{ + b (); + return 0; +} diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp index 8aa7a32..bcbe8e2 100644 --- a/ld/testsuite/ld-elf/shared.exp +++ b/ld/testsuite/ld-elf/shared.exp @@ -267,6 +267,12 @@ set build_tests { {"Build pr16457" "tmpdir/libpr16452b.so -Wl,-rpath=tmpdir" "" {pr16452b.c} {{objdump {-p} pr16457.od}} "pr16457"} + {"Build libpr18458a.so" + "-shared -Wl,-z,now" "-fPIC" + {pr18458a.c} {} "libpr18458a.so"} + {"Build libpr18458b.so" + "-shared -Wl,-z,now tmpdir/libpr18458a.so" "-fPIC" + {pr18458b.c} {} "libpr18458b.so"} } run_cc_link_tests $build_tests @@ -417,6 +423,9 @@ set run_tests { {"Run pr2404" "tmpdir/pr2404b.o tmpdir/libpr2404a.so" "" {dummy.c} "pr2404" "pr2404.out"} + {"Run pr18458" + "tmpdir/libpr18458a.so tmpdir/libpr18458b.so -z now" "" + {pr18458c.c} "pr18458" "pass.out"} } # NetBSD ELF systems do not currently support the .*_array sections. -- 1.9.3