aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog6
-rw-r--r--ld/emultempl/elf32.em70
2 files changed, 54 insertions, 22 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 76772e3..9941f3b 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,11 @@
Mon Feb 19 11:16:44 1996 Ian Lance Taylor <ian@cygnus.com>
+ * emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Check
+ the SONAME if it is available.
+ (gld${EMULATION_NAME}_stat_needed): Use the SONAME, not the
+ filename, when checking for conflicting library versions. Don't
+ assume that the suffix is only numbers and dots.
+
* ld.texinfo: Mention that -R can be used for -rpath.
Sun Feb 18 15:05:17 1996 Ian Lance Taylor <ian@cygnus.com>
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index ebb391e..728b8d3 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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