* emultempl/elf32.em (global_found): Make it a pointer.
authorAlan Modra <amodra@gmail.com>
Sat, 3 Jun 2006 02:45:26 +0000 (02:45 +0000)
committerAlan Modra <amodra@gmail.com>
Sat, 3 Jun 2006 02:45:26 +0000 (02:45 +0000)
(stat_needed, try_needed): Adjust.
(check_needed): Don't skip non-loaded as-needed entries.  Only
consider entries with both filename and the_bfd non-null.
(after_open): Try loading non-loaded as-needed libs to satisfy
DT_NEEDED libs.

ld/ChangeLog
ld/emultempl/elf32.em

index 4088569175838a4444bd167e15a228cf8fb3efb6..cacf8fa5950758ed52ee23035b01dc5b41a4e02e 100644 (file)
@@ -1,3 +1,12 @@
+2006-06-03  Alan Modra  <amodra@bigpond.net.au>
+
+       * emultempl/elf32.em (global_found): Make it a pointer.
+       (stat_needed, try_needed): Adjust.
+       (check_needed): Don't skip non-loaded as-needed entries.  Only
+       consider entries with both filename and the_bfd non-null.
+       (after_open): Try loading non-loaded as-needed libs to satisfy
+       DT_NEEDED libs.
+
 2006-06-02  Joseph S. Myers  <joseph@codesourcery.com>
 
        * Makefile.am (TEXI2DVI): Add -I $(top_srcdir)/../libiberty.
index cafb6c5b46cba5dc78640d00bd34a7869a9b659b..19d98fedbd06dcb5ad18156aa5a63ab6994c90da 100644 (file)
@@ -148,7 +148,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
 
 static struct bfd_link_needed_list *global_needed;
 static struct stat global_stat;
-static bfd_boolean global_found;
+static lang_input_statement_type *global_found;
 static struct bfd_link_needed_list *global_vercheck_needed;
 static bfd_boolean global_vercheck_failed;
 
@@ -229,12 +229,14 @@ gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
   const char *suffix;
   const char *soname;
 
-  if (global_found)
+  if (global_found != NULL)
     return;
   if (s->the_bfd == NULL)
     return;
-  if (s->as_needed
-      && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
+
+  /* If this input file was an as-needed entry, and wasn't found to be
+     needed at the stage it was linked, then don't say we have loaded it.  */
+  if ((bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
     return;
 
   if (bfd_stat (s->the_bfd, &st) != 0)
@@ -254,7 +256,7 @@ gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
       && st.st_ino == global_stat.st_ino
       && st.st_ino != 0)
     {
-      global_found = TRUE;
+      global_found = s;
       return;
     }
 
@@ -398,9 +400,9 @@ cat >>e${EMULATION_NAME}.c <<EOF
   if (trace_file_tries)
     info_msg (_("found %s at %s\n"), soname, name);
 
-  global_found = FALSE;
+  global_found = NULL;
   lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
-  if (global_found)
+  if (global_found != NULL)
     {
       /* Return TRUE to indicate that we found the file, even though
         we aren't going to do anything with it.  */
@@ -569,7 +571,7 @@ gld${EMULATION_NAME}_check_ld_elf_hints (const char *name, int force)
                  if (fread (b, 1, hdr.dirlistlen + 1, f) ==
                      hdr.dirlistlen + 1)
                    ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b);
-               
+
                  free (b);
                }
            }
@@ -585,7 +587,7 @@ gld${EMULATION_NAME}_check_ld_elf_hints (const char *name, int force)
   needed.by = NULL;
   needed.name = name;
   return gld${EMULATION_NAME}_search_needed (ld_elf_hints, & needed,
-                                            force);
+                                            force);
 }
 EOF
     # FreeBSD
@@ -809,49 +811,45 @@ cat >>e${EMULATION_NAME}.c <<EOF
 static void
 gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
 {
-  if (global_found)
+  const char *soname;
+
+  /* Stop looking if we've found a loaded lib.  */
+  if (global_found != NULL
+      && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
+         & DYN_AS_NEEDED) == 0)
     return;
 
-  /* If this input file was an as-needed entry, and wasn't found to be
-     needed at the stage it was linked, then don't say we have loaded it.  */
-  if (s->as_needed
-      && (s->the_bfd == NULL
-         || (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0))
+  if (s->filename == NULL || s->the_bfd == NULL)
+    return;
+
+  /* Don't look for a second non-loaded as-needed lib.  */
+  if (global_found != NULL
+      && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
     return;
 
-  if (s->filename != NULL)
+  if (strcmp (s->filename, global_needed->name) == 0)
     {
-      const char *f;
+      global_found = s;
+      return;
+    }
 
-      if (strcmp (s->filename, global_needed->name) == 0)
+  if (s->search_dirs_flag)
+    {
+      const char *f = strrchr (s->filename, '/');
+      if (f != NULL
+         && strcmp (f + 1, global_needed->name) == 0)
        {
-         global_found = TRUE;
+         global_found = s;
          return;
        }
-
-      if (s->search_dirs_flag)
-       {
-         f = strrchr (s->filename, '/');
-         if (f != NULL
-             && strcmp (f + 1, global_needed->name) == 0)
-           {
-             global_found = TRUE;
-             return;
-           }
-       }
     }
 
-  if (s->the_bfd != NULL)
+  soname = bfd_elf_get_dt_soname (s->the_bfd);
+  if (soname != NULL
+      && strcmp (soname, global_needed->name) == 0)
     {
-      const char *soname;
-
-      soname = bfd_elf_get_dt_soname (s->the_bfd);
-      if (soname != NULL
-         && strcmp (soname, global_needed->name) == 0)
-       {
-         global_found = TRUE;
-         return;
-       }
+      global_found = s;
+      return;
     }
 }
 
@@ -904,9 +902,11 @@ gld${EMULATION_NAME}_after_open (void)
 
       /* See if this file was included in the link explicitly.  */
       global_needed = l;
-      global_found = FALSE;
+      global_found = NULL;
       lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
-      if (global_found)
+      if (global_found != NULL
+         && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
+             & DYN_AS_NEEDED) == 0)
        continue;
 
       n.by = l->by;
@@ -915,6 +915,15 @@ gld${EMULATION_NAME}_after_open (void)
       if (trace_file_tries)
        info_msg (_("%s needed by %B\n"), l->name, l->by);
 
+      /* As-needed libs specified on the command line (or linker script)
+        take priority over libs found in search dirs.  */
+      if (global_found != NULL)
+       {
+         nn.name = global_found->filename;
+         if (gld${EMULATION_NAME}_try_needed (&nn, TRUE))
+           continue;
+       }
+
       /* We need to find this file and include the symbol table.  We
         want to search for the file in the same way that the dynamic
         linker will search.  That means that we want to use
@@ -1725,7 +1734,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
 #define OPTION_GROUP                   (OPTION_ENABLE_NEW_DTAGS + 1)
 #define OPTION_EH_FRAME_HDR            (OPTION_GROUP + 1)
 #define OPTION_EXCLUDE_LIBS            (OPTION_EH_FRAME_HDR + 1)
-  
+
 static void
 gld${EMULATION_NAME}_add_options
   (int ns, char **shortopts, int nl, struct option **longopts,