* [PATCH] elf: Don't load archive element after DT_NEEDED dynamic definition
@ 2020-09-07 16:06 H.J. Lu
0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 2020-09-07 16:06 UTC (permalink / raw)
To: binutils
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 <stdlib.h>
+
+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 <stdio.h>
+
+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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-09-07 16:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-07 16:06 [PATCH] elf: Don't load archive element after DT_NEEDED dynamic definition H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).