diff -rup binutils.orig/bfd/elflink.c binutils-2.35.1/bfd/elflink.c --- binutils.orig/bfd/elflink.c 2020-10-29 12:46:32.228618844 +0000 +++ binutils-2.35.1/bfd/elflink.c 2020-10-29 13:07:58.786847312 +0000 @@ -5340,7 +5340,7 @@ elf_link_add_object_symbols (bfd *abfd, 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) { @@ -5365,7 +5365,8 @@ elf_link_add_object_symbols (bfd *abfd, /* 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; + 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; @@ -5382,7 +5383,10 @@ elf_link_add_object_symbols (bfd *abfd, 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; } } @@ -5819,6 +5823,11 @@ elf_link_add_archive_symbols (bfd *abfd, 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 Only in binutils.orig/: binutils-2.35.1 diff -rup binutils.orig/include/bfdlink.h binutils-2.35.1/include/bfdlink.h --- binutils.orig/include/bfdlink.h 2020-10-29 12:46:31.611621137 +0000 +++ binutils-2.35.1/include/bfdlink.h 2020-10-29 13:07:36.833927443 +0000 @@ -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 -rup binutils.orig/ld/plugin.c binutils-2.35.1/ld/plugin.c --- binutils.orig/ld/plugin.c 2020-10-29 12:46:31.878620145 +0000 +++ binutils-2.35.1/ld/plugin.c 2020-10-29 13:07:19.951989072 +0000 @@ -794,7 +794,8 @@ get_symbols (const void *handle, int nsy 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