* emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Check
[deliverable/binutils-gdb.git] / ld / emultempl / elf32.em
index ebb391e98da3ac48a8f91d631c30860d0e20e6e9..728b8d394ac8e4cd4b28258dad99d04b160d3cec 100644 (file)
@@ -334,19 +334,42 @@ static void
 gld${EMULATION_NAME}_check_needed (s)
      lang_input_statement_type *s;
 {
+  if (global_found)
+    return;
+
   if (s->filename != NULL
       && strcmp (s->filename, global_needed->name) == 0)
-    global_found = true;
-  else if (s->search_dirs_flag
-          && s->filename != NULL
-          && strchr (global_needed->name, '/') == NULL)
+    {
+      global_found = true;
+      return;
+    }
+
+  if (s->the_bfd != NULL)
+    {
+      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;
+       }
+    }
+         
+  if (s->search_dirs_flag
+      && s->filename != NULL
+      && strchr (global_needed->name, '/') == NULL)
     {
       const char *f;
 
       f = strrchr (s->filename, '/');
       if (f != NULL
          && strcmp (f + 1, global_needed->name) == 0)
-       global_found = true;
+       {
+         global_found = true;
+         return;
+       }
     }
 }
 
@@ -358,7 +381,9 @@ gld${EMULATION_NAME}_stat_needed (s)
      lang_input_statement_type *s;
 {
   struct stat st;
-  const char *f, *g;
+  const char *suffix;
+  const char *soname;
+  const char *f;
 
   if (global_found)
     return;
@@ -381,31 +406,32 @@ gld${EMULATION_NAME}_stat_needed (s)
   /* We issue a warning if it looks like we are including two
      different versions of the same shared library.  For example,
      there may be a problem if -lc picks up libc.so.6 but some other
-     shared library has a DT_NEEDED entry of libc.so.5.  */
+     shared library has a DT_NEEDED entry of libc.so.5.  This is a
+     hueristic test, and it will only work if the name looks like
+     NAME.so.VERSION.  FIXME: Depending on file names is error-prone.
+     If we really want to issue warnings about mixing version numbers
+     of shared libraries, we need to find a better way.  */
 
   if (strchr (global_needed->name, '/') != NULL)
     return;
+  suffix = strstr (global_needed->name, ".so.");
+  if (suffix == NULL)
+    return;
+  suffix += sizeof ".so." - 1;
+
+  soname = bfd_elf_get_dt_soname (s->the_bfd);
+  if (soname == NULL)
+    soname = s->filename;
 
-  f = strrchr (s->filename, '/');
+  f = strrchr (soname, '/');
   if (f != NULL)
     ++f;
   else
-    f = s->filename;
-  g = global_needed->name;
-
-  while (*f != '\0' && *f == *g)
-    {
-      ++f;
-      ++g;
-    }
+    f = soname;
 
-  /* We have now skipped past the identical prefixes.  If the
-     remainder of both names is nothing but numbers and dots, we issue
-     a warning.  */
-  if (f[strspn (f, "0123456789.")] == '\0'
-      && g[strspn (g, "0123456789.")] == '\0')
+  if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
     einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
-          global_needed->name, global_needed->by, s->filename);
+          global_needed->name, global_needed->by, f);
 }
 
 /* This is called after the sections have been attached to output
This page took 0.023602 seconds and 4 git commands to generate.