bfd_boolean ldfile_open_file_search (const char *arch, lang_input_statement_type *entry, const char *lib, const char *suffix) { search_dirs_type *search; /* If this is not an archive, try to open it in the current directory first. */ if (! entry->flags.maybe_archive) { if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) { char *name = concat (ld_sysroot, entry->filename, (const char *) NULL); if (ldfile_try_open_bfd (name, entry)) { entry->filename = name; return TRUE; } free (name); } else if (ldfile_try_open_bfd (entry->filename, entry)) return TRUE; if (IS_ABSOLUTE_PATH (entry->filename)) return FALSE; } for (search = search_head; search != NULL; search = search->next) { char *string; if (entry->flags.dynamic && !bfd_link_relocatable (&link_info)) { if (ldemul_open_dynamic_archive (arch, search, entry)) return TRUE; } if (entry->flags.maybe_archive && !entry->flags.full_name_provided) string = concat (search->name, slash, lib, entry->filename, arch, suffix, (const char *) NULL); else string = concat (search->name, slash, entry->filename, (const char *) 0); if (ldfile_try_open_bfd (string, entry)) { entry->filename = string; return TRUE; } free (string); } return FALSE; }
void ldfile_open_file (lang_input_statement_type *entry) { if (entry->the_bfd != NULL) return; if (! entry->flags.search_dirs) { if (ldfile_try_open_bfd (entry->filename, entry)) return; if (filename_cmp (entry->filename, entry->local_sym_name) != 0) einfo (_("%P: cannot find %s (%s): %E\n"), entry->filename, entry->local_sym_name); else einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name); entry->flags.missing_file = TRUE; input_flags.missing_file = TRUE; } else { search_arch_type *arch; bfd_boolean found = FALSE; /* Try to open <filename><suffix> or lib<filename><suffix>.a */ for (arch = search_arch_head; arch != NULL; arch = arch->next) { found = ldfile_open_file_search (arch->name, entry, "lib", ".a"); if (found) break; #ifdef VMS found = ldfile_open_file_search (arch->name, entry, ":lib", ".a"); if (found) break; #endif found = ldemul_find_potential_libraries (arch->name, entry); if (found) break; } /* If we have found the file, we don't need to search directories again. */ if (found) entry->flags.search_dirs = FALSE; else { if (entry->flags.sysrooted && ld_sysroot && IS_ABSOLUTE_PATH (entry->local_sym_name)) einfo (_("%P: cannot find %s inside %s\n"), entry->local_sym_name, ld_sysroot); else einfo (_("%P: cannot find %s\n"), entry->local_sym_name); entry->flags.missing_file = TRUE; input_flags.missing_file = TRUE; } } }
static bfd_boolean gldelf64ltsmip_open_dynamic_archive (const char *arch, search_dirs_type *search, lang_input_statement_type *entry) { const char *filename; char *string; if (! entry->is_archive) return FALSE; filename = entry->filename; /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION is defined, but it does not seem worth the headache to optimize away those two bytes of space. */ string = (char *) xmalloc (strlen (search->name) + strlen (filename) + strlen (arch) #ifdef EXTRA_SHLIB_EXTENSION + strlen (EXTRA_SHLIB_EXTENSION) #endif + sizeof "/lib.so"); sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); #ifdef EXTRA_SHLIB_EXTENSION /* Try the .so extension first. If that fails build a new filename using EXTRA_SHLIB_EXTENSION. */ if (! ldfile_try_open_bfd (string, entry)) sprintf (string, "%s/lib%s%s%s", search->name, filename, arch, EXTRA_SHLIB_EXTENSION); #endif if (! ldfile_try_open_bfd (string, entry)) { free (string); return FALSE; } entry->filename = string; /* We have found a dynamic object to include in the link. The ELF backend linker will create a DT_NEEDED entry in the .dynamic section naming this file. If this file includes a DT_SONAME entry, it will be used. Otherwise, the ELF linker will just use the name of the file. For an archive found by searching, like this one, the DT_NEEDED entry should consist of just the name of the file, without the path information used to find it. Note that we only need to do this if we have a dynamic object; an archive will never be referenced by a DT_NEEDED entry. FIXME: This approach--using bfd_elf_set_dt_needed_name--is not very pretty. I haven't been able to think of anything that is pretty, though. */ if (bfd_check_format (entry->the_bfd, bfd_object) && (entry->the_bfd->flags & DYNAMIC) != 0) { ASSERT (entry->is_archive && entry->search_dirs_flag); /* Rather than duplicating the logic above. Just use the filename we recorded earlier. */ filename = lbasename (entry->filename); bfd_elf_set_dt_needed_name (entry->the_bfd, filename); } return TRUE; }