From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 40053 invoked by alias); 14 Apr 2017 15:44:59 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 40036 invoked by uid 89); 14 Apr 2017 15:44:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.6 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,NO_DNS_FOR_FROM,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= X-HELO: mga14.intel.com Received: from mga14.intel.com (HELO mga14.intel.com) (192.55.52.115) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 14 Apr 2017 15:44:56 +0000 Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Apr 2017 08:44:56 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([172.25.70.218]) by orsmga004.jf.intel.com with ESMTP; 14 Apr 2017 08:44:56 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 1000) id 8269A202445; Fri, 14 Apr 2017 08:44:56 -0700 (PDT) Date: Fri, 14 Apr 2017 15:44:00 -0000 From: "H.J. Lu" To: binutils@sourceware.org Subject: [PATCH] PR ld/21382: Handle symbol defined in IR and referenced in DSO Message-ID: <20170414154456.GA22259@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.8.0 (2017-02-23) X-SW-Source: 2017-04/txt/msg00144.txt.bz2 We need to make an IR symbol visible if it is defined in an IR object and referenced in a dynamic object. When --as-needed is used, since linker removes the IR symbol reference of the dynamic object if the dynamic object isn't needed in the first pass, the IR definition isn't visible to the dynamic object even if the dynamic object becomes needed in the second pass. Add ir_def_dynamic_ref to bfd_link_hash_entry to track IR symbol which is defined in an IR object and referenced in a dynamic object. ir_def_dynamic_ref is preserved when restoring the symbol table for unneeded dynamic object. OK for master? H.J. --- bfd/ PR ld/21382 * elflink.c (elf_link_add_object_symbols): Preserve re_def_dynamic_ref when restoring the symbol table for unneeded dynamic object. include/ PR ld/21382 * bfdlink.h (bfd_link_hash_entry): Add ir_def_dynamic_ref. ld/ PR ld/21382 * plugin.c (is_visible_from_outside): Symbol may be visible from outside if ir_def_dynamic_ref is set. (plugin_notice): Set ir_def_dynamic_ref if the symbol is defined in an IR object and referenced in a dynamic object. * testsuite/ld-plugin/lto.exp: Run PR ld/21382 tests. * testsuite/ld-plugin/pr21382a.c: New file. * testsuite/ld-plugin/pr21382b.c: Likewise. --- bfd/elflink.c | 6 ++++++ include/bfdlink.h | 4 ++++ ld/plugin.c | 23 +++++++++++++++++------ ld/testsuite/ld-plugin/lto.exp | 9 +++++++++ ld/testsuite/ld-plugin/pr21382a.c | 17 +++++++++++++++++ ld/testsuite/ld-plugin/pr21382b.c | 7 +++++++ 6 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 ld/testsuite/ld-plugin/pr21382a.c create mode 100644 ld/testsuite/ld-plugin/pr21382b.c diff --git a/bfd/elflink.c b/bfd/elflink.c index dfcc51e..14c4a52 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4887,6 +4887,7 @@ error_free_dyn: struct elf_link_hash_entry *h; bfd_size_type size; unsigned int alignment_power; + unsigned int ir_def_dynamic_ref; for (p = htab->root.table.table[i]; p != NULL; p = p->next) { @@ -4908,6 +4909,10 @@ error_free_dyn: size = 0; alignment_power = 0; } + /* Preserve re_def_dynamic_ref so that this symbol will + be exported when the dynamic lib becomes needed in the + second pass. */ + ir_def_dynamic_ref = h->root.ir_def_dynamic_ref; memcpy (p, old_ent, htab->root.table.entsize); old_ent = (char *) old_ent + htab->root.table.entsize; h = (struct elf_link_hash_entry *) p; @@ -4924,6 +4929,7 @@ error_free_dyn: if (alignment_power > h->root.u.c.p->alignment_power) h->root.u.c.p->alignment_power = alignment_power; } + h->root.ir_def_dynamic_ref = ir_def_dynamic_ref; } } diff --git a/include/bfdlink.h b/include/bfdlink.h index 3835fcb..5dc1377 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -104,6 +104,10 @@ struct bfd_link_hash_entry IR object file. */ unsigned int non_ir_ref : 1; + /* Symbol is defined in an IR object and referenced in a dynamic + object. */ + unsigned int ir_def_dynamic_ref : 1; + /* Symbol is a built-in define. These will be overridden by PROVIDE in a linker script. */ unsigned int linker_def : 1; diff --git a/ld/plugin.c b/ld/plugin.c index 03e2e69..3a44eb2 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -629,7 +629,9 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym, if (bfd_link_relocatable (&link_info)) return TRUE; - if (link_info.export_dynamic || bfd_link_dll (&link_info)) + if (blhe->ir_def_dynamic_ref + || link_info.export_dynamic + || bfd_link_dll (&link_info)) { /* Check if symbol is hidden by version script. */ if (bfd_hide_sym_by_version (link_info.version_info, @@ -1316,12 +1318,21 @@ plugin_notice (struct bfd_link_info *info, /* If this is a ref, set non_ir_ref. */ else if (bfd_is_und_section (section)) { + if (h->type == bfd_link_hash_defweak + || h->type == bfd_link_hash_defined) + { + /* Check if the symbol is defined in an IR object and + referenced in a dynamic object. */ + if ((abfd->flags & DYNAMIC) != 0 + && is_ir_dummy_bfd (h->u.def.section->owner)) + h->ir_def_dynamic_ref = TRUE; + } /* Replace the undefined dummy bfd with the real one. */ - if ((h->type == bfd_link_hash_undefined - || h->type == bfd_link_hash_undefweak) - && (h->u.undef.abfd == NULL - || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0)) - h->u.undef.abfd = abfd; + else if ((h->type == bfd_link_hash_undefined + || h->type == bfd_link_hash_undefweak) + && (h->u.undef.abfd == NULL + || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0)) + h->u.undef.abfd = abfd; h->non_ir_ref = TRUE; } diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp index 80c084b..f0bc345 100644 --- a/ld/testsuite/ld-plugin/lto.exp +++ b/ld/testsuite/ld-plugin/lto.exp @@ -289,6 +289,12 @@ set lto_link_elf_tests [list \ [list "PR ld/14918" \ "-flto" "-flto" \ {pr14918.c} {{"readelf" {-d --wide} "pr14918.d"}} "pr14918.exe" "c"] \ + [list "Build pr21382a.o" \ + "" "-O2 -flto" \ + {pr21382a.c} {} "" "c"] \ + [list "Build pr21382.so" \ + "-shared" "-O2 -fpic" \ + {pr21382b.c} {} "pr21382.so" "c"] \ ] # Check final symbols in executables. @@ -387,6 +393,9 @@ set lto_run_elf_shared_tests [list \ [list "LTO 7" \ "-O2 -flto -fuse-linker-plugin tmpdir/lto-7b.o tmpdir/lto-7c.o tmpdir/lto-7a.o -Wl,--no-as-needed tmpdir/liblto-7.so" "" \ {dummy.c} "lto-7.exe" "lto-7.out" "" "c"] \ + [list "Run pr21382" \ + "-O2 -flto -fuse-linker-plugin -Wl,--as-needed tmpdir/pr21382a.o tmpdir/pr21382.so" "" \ + {dummy.c} "pr21382.exe" "pass.out" "" "c"] \ ] # LTO run-time tests for ELF diff --git a/ld/testsuite/ld-plugin/pr21382a.c b/ld/testsuite/ld-plugin/pr21382a.c new file mode 100644 index 0000000..09b9d75 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr21382a.c @@ -0,0 +1,17 @@ +#include + +extern void y (void); + +void +x (void) +{ + printf ("PASS\n"); +} + + +int +main (void) +{ + y (); + return 0; +} diff --git a/ld/testsuite/ld-plugin/pr21382b.c b/ld/testsuite/ld-plugin/pr21382b.c new file mode 100644 index 0000000..c5b74a9 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr21382b.c @@ -0,0 +1,7 @@ +extern void x (void); + +void +y (void) +{ + x (); +} -- 2.9.3