* emultempl/elf32.em (gld${EMULATION_NAME}_stat_needed): Warn if

it looks like we might be linking in two different versions of the
	same shared library.  Based on a patch from H J Lu <hjl@zoom.com>.
This commit is contained in:
Ian Lance Taylor 1996-02-13 19:05:38 +00:00
parent baa833b9e2
commit 625489271d
2 changed files with 80 additions and 20 deletions

View File

@ -1,3 +1,9 @@
Tue Feb 13 14:04:19 1996 Ian Lance Taylor <ian@cygnus.com>
* emultempl/elf32.em (gld${EMULATION_NAME}_stat_needed): Warn if
it looks like we might be linking in two different versions of the
same shared library. Based on a patch from H J Lu <hjl@zoom.com>.
Thu Feb 8 19:25:54 1996 Ian Lance Taylor <ian@cygnus.com>
* ldlang.c (lang_size_sections): Increment the section size when a

View File

@ -4,7 +4,7 @@ cat >e${EMULATION_NAME}.c <<EOF
/* This file is is generated by a shell script. DO NOT EDIT! */
/* 32 bit ELF emulation code for ${EMULATION_NAME}
Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1991, 93, 94, 95, 1996 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
@ -134,7 +134,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
/* These variables are required to pass information back and forth
between after_open and check_needed and stat_needed. */
static struct bfd_elf_link_needed_list *global_needed;
static struct bfd_link_needed_list *global_needed;
static struct stat global_stat;
static boolean global_found;
@ -143,7 +143,7 @@ static boolean global_found;
static void
gld${EMULATION_NAME}_after_open ()
{
struct bfd_elf_link_needed_list *needed, *l;
struct bfd_link_needed_list *needed, *l;
/* We only need to worry about this when doing a final link. */
if (link_info.relocateable || link_info.shared)
@ -161,7 +161,7 @@ gld${EMULATION_NAME}_after_open ()
needed = bfd_elf_get_needed_list (output_bfd, &link_info);
for (l = needed; l != NULL; l = l->next)
{
struct bfd_elf_link_needed_list *ll;
struct bfd_link_needed_list *ll;
const char *lib_path;
size_t len;
search_dirs_type *search;
@ -182,15 +182,31 @@ gld${EMULATION_NAME}_after_open ()
/* 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 rpath,
then the environment variable LD_LIBRARY_PATH, then the
linker script LIB_SEARCH_DIRS. We do not search using the -L
arguments. */
linker will search. That means that we want to use
rpath_link, rpath, then the environment variable
LD_LIBRARY_PATH (native only), then the linker script
LIB_SEARCH_DIRS. We do not search using the -L arguments. */
if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
l->name))
continue;
if (gld${EMULATION_NAME}_search_needed (command_line.rpath, l->name))
continue;
if (command_line.rpath_link == NULL
&& command_line.rpath == NULL)
{
lib_path = (const char *) getenv ("LD_RUN_PATH");
if (gld${EMULATION_NAME}_search_needed (lib_path, l->name))
continue;
}
EOF
if [ "x${host}" = "x${target}" ] ; then
cat >>e${EMULATION_NAME}.c <<EOF
lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
if (gld${EMULATION_NAME}_search_needed (lib_path, l->name))
continue;
EOF
fi
cat >>e${EMULATION_NAME}.c <<EOF
len = strlen (l->name);
for (search = search_head; search != NULL; search = search->next)
{
@ -341,21 +357,55 @@ static void
gld${EMULATION_NAME}_stat_needed (s)
lang_input_statement_type *s;
{
struct stat st;
const char *f, *g;
if (global_found)
return;
if (s->the_bfd != NULL)
{
struct stat st;
if (s->the_bfd == NULL)
return;
if (bfd_stat (s->the_bfd, &st) != 0)
einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
else
{
if (st.st_dev == global_stat.st_dev
&& st.st_ino == global_stat.st_ino)
global_found = true;
}
if (bfd_stat (s->the_bfd, &st) != 0)
{
einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
return;
}
if (st.st_dev == global_stat.st_dev
&& st.st_ino == global_stat.st_ino)
{
global_found = true;
return;
}
/* 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. */
if (strchr (global_needed->name, '/') != NULL)
return;
f = strrchr (s->filename, '/');
if (f != NULL)
++f;
else
f = s->filename;
g = global_needed->name;
while (*f != '\0' && *f == *g)
{
++f;
++g;
}
/* 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')
einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
global_needed->name, global_needed->by, s->filename);
}
/* This is called after the sections have been attached to output
@ -364,6 +414,7 @@ gld${EMULATION_NAME}_stat_needed (s)
static void
gld${EMULATION_NAME}_before_allocation ()
{
const char *rpath;
asection *sinterp;
/* If we are going to make any variable assignments, we need to let
@ -373,9 +424,12 @@ gld${EMULATION_NAME}_before_allocation ()
/* Let the ELF backend work out the sizes of any sections required
by dynamic linking. */
rpath = command_line.rpath;
if (rpath == NULL)
rpath = (const char *) getenv ("LD_RUN_PATH");
if (! bfd_elf32_size_dynamic_sections (output_bfd,
command_line.soname,
command_line.rpath,
rpath,
command_line.export_dynamic,
&link_info,
&sinterp))