+2016-04-01 Alan Modra <amodra@gmail.com>
+
+ PR 19886
+ * elflink.c (on_needed_list): Recursively check needed status.
+ (elf_link_add_object_symbols): Adjust.
+
2016-03-30 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
* elf32-avr.c (avr_elf32_load_records_from_section): Free
return 0;
}
+/* Return true if SONAME is on the needed list between NEEDED and STOP
+ (or the end of list if STOP is NULL), and needed by a library that
+ will be loaded. */
+
static bfd_boolean
-on_needed_list (const char *soname, struct bfd_link_needed_list *needed)
-{
- for (; needed != NULL; needed = needed->next)
- if ((elf_dyn_lib_class (needed->by) & DYN_AS_NEEDED) == 0
- && strcmp (soname, needed->name) == 0)
+on_needed_list (const char *soname,
+ struct bfd_link_needed_list *needed,
+ struct bfd_link_needed_list *stop)
+{
+ struct bfd_link_needed_list *look;
+ for (look = needed; look != stop; look = look->next)
+ if (strcmp (soname, look->name) == 0
+ && ((elf_dyn_lib_class (look->by) & DYN_AS_NEEDED) == 0
+ /* If needed by a library that itself is not directly
+ needed, recursively check whether that library is
+ indirectly needed. Since we add DT_NEEDED entries to
+ the end of the list, library dependencies appear after
+ the library. Therefore search prior to the current
+ LOOK, preventing possible infinite recursion. */
+ || on_needed_list (elf_dt_name (look->by), needed, look)))
return TRUE;
return FALSE;
|| (old_bfd->flags & BFD_PLUGIN) == 0))
|| (h->ref_dynamic_nonweak
&& (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0
- && !on_needed_list (elf_dt_name (abfd), htab->needed))))
+ && !on_needed_list (elf_dt_name (abfd),
+ htab->needed, NULL))))
{
int ret;
const char *soname = elf_dt_name (abfd);