This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] PR19886, --as-needed regression


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7b15fa7ac802f430f7fb7c2b77f40ab78c2e4018

commit 7b15fa7ac802f430f7fb7c2b77f40ab78c2e4018
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Apr 1 17:08:45 2016 +1030

    PR19886, --as-needed regression
    
    This isn't perfect in checking whether libraries will be loaded since
    elf_link_add_object_symbols doesn't recurse down DT_NEEDED links.
    (That happens later in ld/emultempl/elf32.em after_open.)  So in
    effect this recursive check really only looks one level down the
    DT_NEEDED tree.  Which is enough for the most common case, and
    libc.so/ld.so in particular.
    
    	PR 19886
    	* elflink.c (on_needed_list): Recursively check needed status.
    	(elf_link_add_object_symbols): Adjust.

Diff:
---
 bfd/ChangeLog |  6 ++++++
 bfd/elflink.c | 27 +++++++++++++++++++++------
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b1b053b..9b87780 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+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
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c2ad11b..445fb01 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3245,12 +3245,26 @@ elf_add_dt_needed_tag (bfd *abfd,
   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;
@@ -4593,7 +4607,8 @@ error_free_dyn:
 		       || (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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]