-/* Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
+/* Linker file opening and searching.
+ Copyright (C) 1991, 92, 93, 94, 95, 98, 99, 2000
+ Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GLD; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+along with GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
-/*
- ldfile.c
-
- look after all the file stuff
-
- */
+/* ldfile.c: look after all the file stuff. */
#include "bfd.h"
#include "sysdep.h"
+#include "bfdlink.h"
#include "ld.h"
#include "ldmisc.h"
#include "ldexp.h"
#ifdef VMS
char *slash = "";
#else
+#if defined (_WIN32) && ! defined (__CYGWIN32__)
+char *slash = "\\";
+#else
char *slash = "/";
#endif
+#endif
#else /* MPW */
-/* The MPW path char is a colon. */
+/* The MPW path char is a colon. */
char *slash = ":";
#endif /* MPW */
static search_arch_type *search_arch_head;
static search_arch_type **search_arch_tail_ptr = &search_arch_head;
-static boolean try_open_bfd PARAMS ((const char *attempt,
- lang_input_statement_type *entry));
static FILE *try_open PARAMS ((const char *name, const char *exten));
void
/* Try to open a BFD for a lang_input_statement. */
-static boolean
-try_open_bfd (attempt, entry)
+boolean
+ldfile_try_open_bfd (attempt, entry)
const char *attempt;
lang_input_statement_type *entry;
{
entry->the_bfd = bfd_openr (attempt, entry->target);
if (trace_file_tries)
- info_msg ("attempt to open %s %s\n", attempt,
- entry->the_bfd == NULL ? "failed" : "succeeded");
+ {
+ if (entry->the_bfd == NULL)
+ info_msg (_("attempt to open %s failed\n"), attempt);
+ else
+ info_msg (_("attempt to open %s succeeded\n"), attempt);
+ }
- if (entry->the_bfd != NULL)
- return true;
- else
- return false;
+ if (entry->the_bfd == NULL)
+ {
+ if (bfd_get_error () == bfd_error_invalid_target)
+ einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
+ return false;
+ }
+
+ /* If we are searching for this file, see if the architecture is
+ compatible with the output file. If it isn't, keep searching.
+ If we can't open the file as an object file, stop the search
+ here. */
+
+ if (entry->search_dirs_flag)
+ {
+ bfd *check;
+
+ if (bfd_check_format (entry->the_bfd, bfd_archive))
+ check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
+ else
+ check = entry->the_bfd;
+
+ if (check != NULL)
+ {
+ if (! bfd_check_format (check, bfd_object))
+ return true;
+ if (bfd_arch_get_compatible (check, output_bfd) == NULL)
+ {
+ einfo (_("%P: skipping incompatible %s when searching for %s\n"),
+ attempt, entry->local_sym_name);
+ bfd_close (entry->the_bfd);
+ entry->the_bfd = NULL;
+ return false;
+ }
+ }
+ }
+
+ return true;
}
/* Search for and open the file specified by ENTRY. If it is an
directory first. */
if (! entry->is_archive)
{
- if (try_open_bfd (entry->filename, entry))
+ if (ldfile_try_open_bfd (entry->filename, entry))
return true;
}
{
char *string;
+ if (entry->dynamic && ! link_info.relocateable)
+ {
+ if (ldemul_open_dynamic_archive (arch, search, entry))
+ return true;
+ }
+
string = (char *) xmalloc (strlen (search->name)
+ strlen (slash)
+ strlen (lib)
if (entry->is_archive)
sprintf (string, "%s%s%s%s%s%s", search->name, slash,
lib, entry->filename, arch, suffix);
- else if (entry->filename[0] == '/' || entry->filename[0] == '.')
+ else if (entry->filename[0] == '/' || entry->filename[0] == '.'
+#if defined (__MSDOS__) || defined (_WIN32)
+ || entry->filename[0] == '\\'
+ || (isalpha (entry->filename[0])
+ && entry->filename[1] == ':')
+#endif
+ )
strcpy (string, entry->filename);
else
sprintf (string, "%s%s%s", search->name, slash, entry->filename);
- if (try_open_bfd (string, entry))
+ if (ldfile_try_open_bfd (string, entry))
{
entry->filename = string;
return true;
if (! entry->search_dirs_flag)
{
- if (try_open_bfd (entry->filename, entry))
+ if (ldfile_try_open_bfd (entry->filename, entry))
return;
+ if (strcmp (entry->filename, entry->local_sym_name) != 0)
+ einfo (_("%F%P: cannot open %s for %s: %E\n"),
+ entry->filename, entry->local_sym_name);
+ else
+ einfo (_("%F%P: cannot open %s: %E\n"), entry->local_sym_name);
}
else
{
arch != (search_arch_type *) NULL;
arch = arch->next)
{
- if (config.dynamic_link)
- {
- if (ldemul_open_dynamic_archive (arch->name, entry))
- return;
- }
if (ldfile_open_file_search (arch->name, entry, "lib", ".a"))
return;
#ifdef VMS
if (ldfile_open_file_search (arch->name, entry, ":lib", ".a"))
return;
#endif
+ if (ldemul_find_potential_libraries (arch->name, entry))
+ return;
}
+
+ einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
}
-
- einfo("%F%P: cannot open %s: %E\n", entry->local_sym_name);
}
/* Try to open NAME; if that fails, try NAME with EXTEN appended to it. */
char buff[1000];
result = fopen (name, "r");
+
if (trace_file_tries)
{
if (result == NULL)
- info_msg ("cannot find script file ");
+ info_msg (_("cannot find script file %s\n"), name);
else
- info_msg ("opened script file ");
- info_msg ("%s\n",name);
+ info_msg (_("opened script file %s\n"), name);
}
if (result != NULL)
{
sprintf (buff, "%s%s", name, exten);
result = fopen (buff, "r");
+
if (trace_file_tries)
{
if (result == NULL)
- info_msg ("cannot find script file ");
+ info_msg (_("cannot find script file %s\n"), buff);
else
- info_msg ("opened script file ");
- info_msg ("%s\n", buff);
+ info_msg (_("opened script file %s\n"), buff);
}
}
char buffer[1000];
/* First try raw name */
- result = try_open(name,"");
- if (result == (FILE *)NULL) {
- /* Try now prefixes */
- for (search = search_head;
- search != (search_dirs_type *)NULL;
- search = search->next) {
- sprintf(buffer,"%s/%s", search->name, name);
- result = try_open(buffer, extend);
- if (result)break;
+ result = try_open (name, "");
+ if (result == (FILE *)NULL)
+ {
+ /* Try now prefixes */
+ for (search = search_head;
+ search != (search_dirs_type *)NULL;
+ search = search->next)
+ {
+ sprintf (buffer,"%s%s%s", search->name, slash, name);
+
+ result = try_open (buffer, extend);
+ if (result)
+ break;
+ }
}
- }
+
return result;
}
const char *name;
{
FILE *ldlex_input_stack;
- ldlex_input_stack = ldfile_find_command_file(name, "");
+ ldlex_input_stack = ldfile_find_command_file (name, "");
- if (ldlex_input_stack == (FILE *)NULL) {
- bfd_set_error (bfd_error_system_call);
- einfo("%P%F: cannot open linker script file %s: %E\n",name);
- }
- lex_push_file(ldlex_input_stack, name);
+ if (ldlex_input_stack == (FILE *)NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ einfo (_("%P%F: cannot open linker script file %s: %E\n"), name);
+ }
+
+ lex_push_file (ldlex_input_stack, name);
ldfile_input_filename = name;
lineno = 1;
had_script = true;
}
-
-
-
-
#ifdef GNU960
-static
-char *
-gnu960_map_archname( name )
-char *name;
+static char *
+gnu960_map_archname (name)
+ char *name;
{
struct tabentry { char *cmd_switch; char *arch; };
- static struct tabentry arch_tab[] = {
+ static struct tabentry arch_tab[] =
+ {
"", "",
"KA", "ka",
"KB", "kb",
struct tabentry *tp;
- for ( tp = arch_tab; tp->cmd_switch != NULL; tp++ ){
- if ( !strcmp(name,tp->cmd_switch) ){
- break;
+ for (tp = arch_tab; tp->cmd_switch != NULL; tp++)
+ {
+ if (! strcmp (name,tp->cmd_switch))
+ break;
}
- }
- if ( tp->cmd_switch == NULL ){
- einfo("%P%F: unknown architecture: %s\n",name);
- }
+ if (tp->cmd_switch == NULL)
+ einfo (_("%P%F: unknown architecture: %s\n"),name);
+
return tp->arch;
}
-
-
void
-ldfile_add_arch(name)
-char *name;
+ldfile_add_arch (name)
+ char *name;
{
search_arch_type *new =
- (search_arch_type *)xmalloc((bfd_size_type)(sizeof(search_arch_type)));
+ (search_arch_type *)xmalloc ((bfd_size_type)(sizeof (search_arch_type)));
- if (*name != '\0') {
- if (ldfile_output_machine_name[0] != '\0') {
- einfo("%P%F: target architecture respecified\n");
- return;
+ if (*name != '\0')
+ {
+ if (ldfile_output_machine_name[0] != '\0')
+ {
+ einfo (_("%P%F: target architecture respecified\n"));
+ return;
+ }
+
+ ldfile_output_machine_name = name;
}
- ldfile_output_machine_name = name;
- }
new->next = (search_arch_type*)NULL;
- new->name = gnu960_map_archname( name );
+ new->name = gnu960_map_archname (name);
*search_arch_tail_ptr = new;
search_arch_tail_ptr = &new->next;
-
}
#else /* not GNU960 */
ldfile_add_arch (in_name)
CONST char * in_name;
{
- char *name = buystring(in_name);
+ char *name = buystring (in_name);
search_arch_type *new =
- (search_arch_type *)xmalloc((bfd_size_type)(sizeof(search_arch_type)));
+ (search_arch_type *) xmalloc (sizeof (search_arch_type));
ldfile_output_machine_name = in_name;
new->name = name;
new->next = (search_arch_type*)NULL;
- while (*name) {
- if (isupper(*name)) *name = tolower(*name);
- name++;
- }
+ while (*name)
+ {
+ if (isupper ((unsigned char) *name))
+ *name = tolower ((unsigned char) *name);
+ name++;
+ }
*search_arch_tail_ptr = new;
search_arch_tail_ptr = &new->next;
ldfile_set_output_arch (string)
CONST char *string;
{
- bfd_arch_info_type *arch = bfd_scan_arch(string);
-
- if (arch) {
- ldfile_output_architecture = arch->arch;
- ldfile_output_machine = arch->mach;
- ldfile_output_machine_name = arch->printable_name;
- }
- else {
- einfo("%P%F: cannot represent machine `%s'\n", string);
- }
+ const bfd_arch_info_type *arch = bfd_scan_arch (string);
+
+ if (arch)
+ {
+ ldfile_output_architecture = arch->arch;
+ ldfile_output_machine = arch->mach;
+ ldfile_output_machine_name = arch->printable_name;
+ }
+ else
+ {
+ einfo (_("%P%F: cannot represent machine `%s'\n"), string);
+ }
}