From 625489271da5a6e44cad4d8f501e07512b661a10 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 13 Feb 1996 19:05:38 +0000 Subject: [PATCH] * 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 . --- ld/ChangeLog | 6 +++ ld/emultempl/elf32.em | 92 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 19 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 3d354dd8688..1a2371611cb 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +Tue Feb 13 14:04:19 1996 Ian Lance Taylor + + * 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 . + Thu Feb 8 19:25:54 1996 Ian Lance Taylor * ldlang.c (lang_size_sections): Increment the section size when a diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index affd72539a6..16a96affe0c 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -4,7 +4,7 @@ cat >e${EMULATION_NAME}.c < ELF support by Ian Lance Taylor @@ -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 <name)) continue; +EOF +fi +cat >>e${EMULATION_NAME}.c <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)) -- 2.30.2