X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=ld%2Fldfile.c;h=9613c078384202a61d0afe07330e02fafa1346db;hb=302ab118e191d58d6d143dfa81661520e2e8134c;hp=4c4af01212a166d66a7be9abd844d8408cf47ff7;hpb=fcf276c4958f7cc906ec389f003aa2a713c98528;p=binutils-gdb.git diff --git a/ld/ldfile.c b/ld/ldfile.c index 4c4af01212a..9613c078384 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -1,11 +1,12 @@ - -/* Copyright (C) 1991 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, @@ -14,8 +15,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, 675 Mass Ave, Cambridge, MA 02139, 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 @@ -26,39 +28,43 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "sysdep.h" +#include "bfdlink.h" #include "ld.h" #include "ldmisc.h" #include "ldexp.h" #include "ldlang.h" #include "ldfile.h" -#include "ldsym.h" #include "ldmain.h" +#include "ldgram.h" #include "ldlex.h" +#include "ldemul.h" #include -char *ldfile_input_filename; -CONST char * ldfile_output_machine_name =""; +const char *ldfile_input_filename; +boolean ldfile_assumed_script = false; +const char *ldfile_output_machine_name = ""; unsigned long ldfile_output_machine; enum bfd_architecture ldfile_output_architecture; +search_dirs_type *search_head; +#ifndef MPW #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. */ +char *slash = ":"; +#endif /* MPW */ /* LOCAL */ -typedef struct search_dirs -{ - char *name; - struct search_dirs *next; -} search_dirs_type; -static search_dirs_type *search_head; static search_dirs_type **search_tail_ptr = &search_head; typedef struct search_arch @@ -70,150 +76,221 @@ typedef struct search_arch static search_arch_type *search_arch_head; static search_arch_type **search_arch_tail_ptr = &search_arch_head; - +static FILE *try_open PARAMS ((const char *name, const char *exten)); void -ldfile_add_library_path(name) -char *name; +ldfile_add_library_path (name, cmdline) + const char *name; + boolean cmdline; { - search_dirs_type *new = - (search_dirs_type *)ldmalloc((bfd_size_type)(sizeof(search_dirs_type))); + search_dirs_type *new; + + new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type)); + new->next = NULL; new->name = name; - new->next = (search_dirs_type*)NULL; + new->cmdline = cmdline; *search_tail_ptr = new; search_tail_ptr = &new->next; } +/* Try to open a BFD for a lang_input_statement. */ -static bfd* -cached_bfd_openr(attempt,entry) -char *attempt; -lang_input_statement_type *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 == true ) { - info_msg ("attempt to open %s %s\n", attempt, - (entry->the_bfd == (bfd *)NULL) ? "failed" : "succeeded" ); - } - return entry->the_bfd; + entry->the_bfd = bfd_openr (attempt, entry->target); + + if (trace_file_tries) + { + 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) + { + 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"), + attempt, entry->local_sym_name); + bfd_close (entry->the_bfd); + entry->the_bfd = NULL; + return false; + } + } + } + + return true; } -static bfd * -open_a(arch, entry, lib, suffix) -char *arch; -lang_input_statement_type *entry; -char *lib; -char *suffix; +/* Search for and open the file specified by ENTRY. If it is an + archive, use ARCH, LIB and SUFFIX to modify the file name. */ + +boolean +ldfile_open_file_search (arch, entry, lib, suffix) + const char *arch; + lang_input_statement_type *entry; + const char *lib; + const char *suffix; { - bfd*desc; - search_dirs_type *search ; + search_dirs_type *search; + + /* If this is not an archive, try to open it in the current + directory first. */ + if (! entry->is_archive) + { + if (ldfile_try_open_bfd (entry->filename, entry)) + return true; + } + for (search = search_head; search != (search_dirs_type *)NULL; search = search->next) { - char buffer[1000]; char *string; - if (entry->is_archive == true) { - sprintf(buffer, - "%s%s%s%s%s%s", - search->name, - slash, - lib, - entry->filename, arch, suffix); - } - else { - if (entry->filename[0] == '/' || entry->filename[0] == '.') { - strcpy(buffer, entry->filename); - } else { - sprintf(buffer,"%s%s%s",search->name, slash, entry->filename); - } - } - string = buystring(buffer); - desc = cached_bfd_openr (string, entry); - if (desc) + + 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) + + strlen (entry->filename) + + strlen (arch) + + strlen (suffix) + + 1); + + 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] == '.' +#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 (ldfile_try_open_bfd (string, entry)) { entry->filename = string; - entry->search_dirs_flag = false; - entry->the_bfd = desc; - return desc; + return true; } - free(string); + + free (string); } - return (bfd *)NULL; + + return false; } -/* Open the input file specified by 'entry', and return a descriptor. - The open file is remembered; if the same file is opened twice in a row, - a new open is not actually done. */ +/* Open the input file specified by ENTRY. */ void ldfile_open_file (entry) -lang_input_statement_type *entry; + lang_input_statement_type *entry; { + if (entry->the_bfd != NULL) + return; - if (entry->superfile) - ldfile_open_file (entry->superfile); - - if (entry->search_dirs_flag) + if (! entry->search_dirs_flag) + { + 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 { search_arch_type *arch; + /* Try to open or lib.a */ - for (arch = search_arch_head; - arch != (search_arch_type *)NULL; - arch = arch->next) { - if (open_a(arch->name,entry,"lib",".a") != (bfd *)NULL) { - return; - } + arch != (search_arch_type *) NULL; + arch = arch->next) + { + if (ldfile_open_file_search (arch->name, entry, "lib", ".a")) + return; #ifdef VMS - if (open_a(arch->name,entry,":lib",".a") != (bfd *)NULL) { - return; - } + 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); } - else { - entry->the_bfd = cached_bfd_openr (entry->filename, entry); - } - - if (!entry->the_bfd) - 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. */ static FILE * -try_open(name, exten) -char *name; -char *exten; +try_open (name, exten) + const char *name; + const char *exten; { FILE *result; char buff[1000]; - result = fopen(name, "r"); - if (trace_file_tries == true) { - if (result == (FILE *)NULL) { - info_msg ("cannot find "); + result = fopen (name, "r"); + if (trace_file_tries) + { + if (result == NULL) + info_msg (_("cannot find script file %s\n"), name); + else + info_msg (_("opened script file %s\n"), name); } - info_msg ("%s\n",name); - } - if (result != (FILE *)NULL) { + + if (result != NULL) return result; - } - if (*exten) { - sprintf(buff, "%s%s", name, exten); - result = fopen(buff, "r"); - if (trace_file_tries == true) { - if (result == (FILE *)NULL) { - info_msg ("cannot find "); - } - info_msg ("%s\n", buff); + if (*exten) + { + sprintf (buff, "%s%s", name, exten); + result = fopen (buff, "r"); + if (trace_file_tries) + { + if (result == NULL) + info_msg (_("cannot find script file %s\n"), buff); + else + info_msg (_("opened script file %s\n"), buff); + } } - } + return result; } @@ -221,9 +298,9 @@ char *exten; specified with -L, without and with EXTEND apppended. */ FILE * -ldfile_find_command_file(name, extend) -char *name; -char *extend; +ldfile_find_command_file (name, extend) + const char *name; + const char *extend; { search_dirs_type *search; FILE *result; @@ -236,7 +313,7 @@ char *extend; for (search = search_head; search != (search_dirs_type *)NULL; search = search->next) { - sprintf(buffer,"%s/%s", search->name, name); + sprintf(buffer,"%s%s%s", search->name, slash, name); result = try_open(buffer, extend); if (result)break; } @@ -245,18 +322,20 @@ char *extend; } void -ldfile_open_command_file(name) -char *name; +ldfile_open_command_file (name) + const char *name; { FILE *ldlex_input_stack; ldlex_input_stack = ldfile_find_command_file(name, ""); if (ldlex_input_stack == (FILE *)NULL) { - einfo("%P%F: cannot open linker script file %s: %E\n",name); + 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; } @@ -292,7 +371,7 @@ char *name; } if ( tp->cmd_switch == NULL ){ - einfo("%P%F: unknown architecture: %s\n",name); + einfo(_("%P%F: unknown architecture: %s\n"),name); } return tp->arch; } @@ -304,12 +383,12 @@ ldfile_add_arch(name) char *name; { search_arch_type *new = - (search_arch_type *)ldmalloc((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"); + einfo(_("%P%F: target architecture respecified\n")); return; } ldfile_output_machine_name = name; @@ -331,16 +410,18 @@ ldfile_add_arch (in_name) { char *name = buystring(in_name); search_arch_type *new = - (search_arch_type *)ldmalloc((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; @@ -352,7 +433,7 @@ void ldfile_set_output_arch (string) CONST char *string; { - bfd_arch_info_type *arch = bfd_scan_arch(string); + const bfd_arch_info_type *arch = bfd_scan_arch(string); if (arch) { ldfile_output_architecture = arch->arch; @@ -360,6 +441,6 @@ ldfile_set_output_arch (string) ldfile_output_machine_name = arch->printable_name; } else { - einfo("%P%F: cannot represent machine `%s'\n", string); + einfo(_("%P%F: cannot represent machine `%s'\n"), string); } }