From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) by sourceware.org (Postfix) with ESMTPS id 393F33894C0F for ; Mon, 7 Sep 2020 16:07:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 393F33894C0F Received: by mail-pj1-x1041.google.com with SMTP id kk9so4305259pjb.2 for ; Mon, 07 Sep 2020 09:07:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=8x7Vk//tCCJ0hFr05XUjMUzaLnOb4wckaKhmNNFKOH0=; b=drQKLpk+BH4lzRc1Yix0wgqgG2CeWU5QDCoh2yKZpFrO1sLXwil6PO7dMy6Eo/4XdH WkpC5x5uIUohQ5hnxswkoSvMHbrVWYP5mqHt620UMHWMmAooE6cvMJEhofUMDmUo601/ HDU38psvamci/6NfXu9yZFGNWlfjrzGXHDX8JacTbuUQlYLUCCrJgYgSaiwtLDhdsSAM OsITGBP9ZuAUSrOVfiiAbr22M8oiWA/HFpaA7F0QWSyxLAIdrpPfyIjEhIYhvxBWCPX/ ijgy0pgiLA9LfF3q0hvqC+GSWN+68OHktBgTVQVscAgPQt0nhdMQBPlg8GBV7BnArK3W ujhQ== X-Gm-Message-State: AOAM53019T1FQ8p4aisFbVnOOEjeL//DPxHin86WXkGsshZnhtIDvsWm 3XDzcuNBmTc3lPsflWsn15pm3gqVy2M= X-Google-Smtp-Source: ABdhPJxKWDVmEUHDZUOvkRWD0sIPmCj2VaolyT/CFVoMeKSrtD7RWM4D+frl95tJYe8rCK6dVM0uIQ== X-Received: by 2002:a17:90a:aa89:: with SMTP id l9mr42554pjq.226.1599494819964; Mon, 07 Sep 2020 09:06:59 -0700 (PDT) Received: from gnu-cfl-2.localdomain (c-69-181-90-243.hsd1.ca.comcast.net. [69.181.90.243]) by smtp.gmail.com with ESMTPSA id w6sm12324941pgr.82.2020.09.07.09.06.59 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2020 09:06:59 -0700 (PDT) Received: from gnu-cfl-2.localdomain (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id B174A1A0225 for ; Mon, 7 Sep 2020 09:06:58 -0700 (PDT) From: "H.J. Lu" To: binutils@sourceware.org Subject: [PATCH] elf: Don't load archive element after DT_NEEDED dynamic definition Date: Mon, 7 Sep 2020 09:06:58 -0700 Message-Id: <20200907160658.3236624-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Sep 2020 16:07:02 -0000 Don't load the archive element after seeing a definition in a DT_NEEDED shared object. bfd/ PR ld/26530 * elflink.c (elf_link_add_object_symbols): Also preserve the as_needed_def_dynamic bit for --as-needed. (elf_link_add_archive_symbols): Don't load the archive element after seeing a definition in a DT_NEEDED shared object. include/ PR ld/26530 * bfdlink.h (bfd_link_hash_entry): Add as_needed_def_dynamic. ld/ PR ld/26530 * plugin.c (get_symbols): Check as_needed_def_dynamic for undefined IR symbol. * testsuite/ld-plugin/lto.exp: Run PR ld/26530 tests. * testsuite/ld-plugin/pr26530a.c: New file. * testsuite/ld-plugin/pr26530b.c: Likewise. * testsuite/ld-plugin/pr26530c.c: Likewise. --- bfd/elflink.c | 20 ++++++++++++++------ include/bfdlink.h | 3 +++ ld/plugin.c | 3 ++- ld/testsuite/ld-plugin/lto.exp | 22 ++++++++++++++++++++++ ld/testsuite/ld-plugin/pr26530a.c | 5 +++++ ld/testsuite/ld-plugin/pr26530b.c | 7 +++++++ ld/testsuite/ld-plugin/pr26530c.c | 12 ++++++++++++ 7 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 ld/testsuite/ld-plugin/pr26530a.c create mode 100644 ld/testsuite/ld-plugin/pr26530b.c create mode 100644 ld/testsuite/ld-plugin/pr26530c.c diff --git a/bfd/elflink.c b/bfd/elflink.c index 5c085b14b7..562a3f9924 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -5347,7 +5347,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) struct elf_link_hash_entry *h; bfd_size_type size; unsigned int alignment_power; - unsigned int non_ir_ref_dynamic; + struct elf_link_hash_entry preserved_h; for (p = htab->root.table.table[i]; p != NULL; p = p->next) { @@ -5369,10 +5369,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) size = 0; alignment_power = 0; } - /* Preserve non_ir_ref_dynamic so that this symbol - will be exported when the dynamic lib becomes needed - in the second pass. */ - non_ir_ref_dynamic = h->root.non_ir_ref_dynamic; + /* Preserve some bits so that this symbol will be exported + when the dynamic lib becomes needed in the second pass. + and to avoid linking in an archive after the dynamic + lib. */ + preserved_h = *h; memcpy (p, old_ent, htab->root.table.entsize); old_ent = (char *) old_ent + htab->root.table.entsize; h = (struct elf_link_hash_entry *) p; @@ -5389,7 +5390,9 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) if (alignment_power > h->root.u.c.p->alignment_power) h->root.u.c.p->alignment_power = alignment_power; } - h->root.non_ir_ref_dynamic = non_ir_ref_dynamic; + h->root.non_ir_ref_dynamic + = preserved_h.root.non_ir_ref_dynamic; + h->root.as_needed_def_dynamic |= preserved_h.dynamic_def; } } @@ -5826,6 +5829,11 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) if (h == NULL) continue; + /* Don't load the archive element after seeing a definition + in a DT_NEEDED shared object. */ + if (h->root.as_needed_def_dynamic) + continue; + if (h->root.type == bfd_link_hash_undefined) { /* If the archive element has already been loaded then one diff --git a/include/bfdlink.h b/include/bfdlink.h index 3badfbdb19..f5517ee5dd 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -114,6 +114,9 @@ struct bfd_link_hash_entry as distinct from a LTO IR object file. */ unsigned int non_ir_ref_dynamic : 1; + /* Symbol is defined in a DT_NEEDED dynamic object file. */ + unsigned int as_needed_def_dynamic : 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 d709ee10fe..ee8948e40c 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -794,7 +794,8 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms, if (blhe->type == bfd_link_hash_undefined || blhe->type == bfd_link_hash_undefweak) { - res = LDPR_UNDEF; + res = (blhe->as_needed_def_dynamic + ? LDPR_RESOLVED_DYN : LDPR_UNDEF); goto report_symbol; } if (blhe->type != bfd_link_hash_defined diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp index adad1e4895..8ccf4b8deb 100644 --- a/ld/testsuite/ld-plugin/lto.exp +++ b/ld/testsuite/ld-plugin/lto.exp @@ -419,6 +419,18 @@ set lto_link_elf_tests [list \ "-shared -Wl,--exclude-libs,ALL tmpdir/pr25618a.o tmpdir/pr25618.a" \ "-fpic" \ {dummy.c} {{readelf {--dyn-syms --wide} pr25618.d}} "pr25618.so" "c++"] \ + [list "Build pr26530a.so" \ + "-shared" "-O2 -fpic $no_lto" \ + {pr26530a.c} {} "pr26530a.so" "c"] \ + [list "Build pr26530b.so" \ + "-shared" "-O2 -fpic $no_lto" \ + {pr26530b.c} {} "pr26530b.so" "c"] \ + [list "Build pr26530a.a" \ + "" "-O2 $no_lto" \ + {pr26530a.c} {} "pr26530a.a" "c"] \ + [list "Build pr26530b.a" \ + "" "-O2 $no_lto" \ + {pr26530b.c} {} "pr26530b.a" "c"] \ ] # PR 14918 checks that libgcc is not spuriously included in a shared link of @@ -584,6 +596,16 @@ set lto_run_elf_shared_tests [list \ [list {pr22220b} \ {-flto -fuse-linker-plugin -Wl,--no-as-needed tmpdir/pr22220lib.so tmpdir/pr22220main.o} {} \ {dummy.c} {pr22220b.exe} {pass.out} {} {c++}] \ + [list "pr26530a" \ + "-O2 -flto -fuse-linker-plugin -Wl,--verbose=2" "" \ + {pr26530c.c} "pr26530a.exe" "pass.out" "-O2 -flto" "c" \ + {.*: symbol `lrealpath' definition: UNDEF, visibility: DEFAULT, resolution: RESOLVED_DYN.*} \ + "-Wl,--as-needed tmpdir/pr26530a.so tmpdir/pr26530b.a"] \ + [list "pr26530b" \ + "-O2 -flto -fuse-linker-plugin -Wl,--verbose=2" "" \ + {pr26530c.c} "pr26530b.exe" "pass.out" "-O2 -flto" "c" \ + {.*: symbol `lrealpath' definition: UNDEF, visibility: DEFAULT, resolution: RESOLVED_EXEC.*} \ + "-Wl,--as-needed tmpdir/pr26530a.a tmpdir/pr26530b.so"] \ ] # LTO run-time tests for ELF diff --git a/ld/testsuite/ld-plugin/pr26530a.c b/ld/testsuite/ld-plugin/pr26530a.c new file mode 100644 index 0000000000..08e746911e --- /dev/null +++ b/ld/testsuite/ld-plugin/pr26530a.c @@ -0,0 +1,5 @@ +const char * +lrealpath (const char *a) +{ + return a; +} diff --git a/ld/testsuite/ld-plugin/pr26530b.c b/ld/testsuite/ld-plugin/pr26530b.c new file mode 100644 index 0000000000..0eb003f470 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr26530b.c @@ -0,0 +1,7 @@ +#include + +void +lrealpath (void) +{ + abort (); +} diff --git a/ld/testsuite/ld-plugin/pr26530c.c b/ld/testsuite/ld-plugin/pr26530c.c new file mode 100644 index 0000000000..c8ef23675e --- /dev/null +++ b/ld/testsuite/ld-plugin/pr26530c.c @@ -0,0 +1,12 @@ +#include + +const char *lrealpath(const char *a); + +int +main(int argc, char **argv) +{ + const char *path = lrealpath (argv[0]); + if (path[0] != '\0') + printf ("PASS\n"); + return 0; +} -- 2.26.2