-
- /* We've found a dynamic object matching the DT_NEEDED entry. */
-
- /* We have already checked that there is no other input file of the
- same name. We must now check again that we are not including the
- same file twice. We need to do this because on many systems
- libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will
- reference libc.so.1. If we have already included libc.so, we
- don't want to include libc.so.1 if they are the same file, and we
- can only check that using stat. */
-
- if (bfd_stat (abfd, &global_stat) != 0)
- einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
- global_found = false;
- lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
- if (global_found)
- {
- /* Return true to indicate that we found the file, even though
- we aren't going to do anything with it. */
- return true;
- }
-
- /* Tell the ELF backend that don't want the output file to have a
- DT_NEEDED entry for this file. */
- bfd_elf_set_dt_needed_name (abfd, "");
-
- /* Add this file into the symbol table. */
- if (! bfd_link_add_symbols (abfd, &link_info))
- einfo ("%F%B: could not read symbols: %E\n", abfd);
-
- return true;
-}
-
-/* See if an input file matches a DT_NEEDED entry by name. */
-
-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;
- 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;
- return;
- }
- }
-}
-
-/* See if an input file matches a DT_NEEDED entry by running stat on
- the file. */
-
-static void
-gld${EMULATION_NAME}_stat_needed (s)
- lang_input_statement_type *s;
-{
- struct stat st;
- const char *suffix;
- const char *soname;
- const char *f;
-
- if (global_found)
- return;
- 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)
- {
- 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. 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 (soname, '/');
- if (f != NULL)
- ++f;
- else
- f = soname;
-
- 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, f);