diff options
author | Ian Lance Taylor <ian@airs.com> | 1996-02-13 19:05:38 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1996-02-13 19:05:38 +0000 |
commit | 625489271da5a6e44cad4d8f501e07512b661a10 (patch) | |
tree | e0de23434b2fcc22d28eee2aa7c5bc156c59c026 /ld | |
parent | baa833b9e26adf4a921db79b3bec0718874d3b79 (diff) | |
download | gdb-625489271da5a6e44cad4d8f501e07512b661a10.zip gdb-625489271da5a6e44cad4d8f501e07512b661a10.tar.gz gdb-625489271da5a6e44cad4d8f501e07512b661a10.tar.bz2 |
* 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>.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 6 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 92 |
2 files changed, 79 insertions, 19 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 3d354dd..1a23716 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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 diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index affd725..16a96af 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -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) + 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); + return; + } + + if (st.st_dev == global_stat.st_dev + && st.st_ino == global_stat.st_ino) { - struct stat st; + global_found = true; + 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; - } + /* 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)) |