X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Fldfile.c;h=3c59a20819695d728cd84cd48db0582abc5577d5;hb=e09875d41026beb03eae1a65510ca40ed3a5d6c1;hp=a073e884636103b0248efd04fe7a88e8214c64b5;hpb=0ef622cbcfcadaf9484a6e4e06ea8757dce510e3;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldfile.c b/ld/ldfile.c index a073e88463..3c59a20819 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -1,28 +1,26 @@ /* Linker file opening and searching. Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, - 2003, 2004 Free Software Foundation, Inc. + 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. - This file is part of GLD, the Gnu Linker. + This file is part of the GNU Binutils. - GLD is free software; you can redistribute it and/or modify + This program 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 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. - GLD is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 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, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -/* ldfile.c: look after all the file stuff. */ - -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "bfdlink.h" #include "safe-ctype.h" #include "ld.h" @@ -45,12 +43,12 @@ enum bfd_architecture ldfile_output_architecture; search_dirs_type * search_head; #ifdef VMS -char * slash = ""; +static char * slash = ""; #else #if defined (_WIN32) && ! defined (__CYGWIN32__) -char * slash = "\\"; +static char * slash = "\\"; #else -char * slash = "/"; +static char * slash = "/"; #endif #endif @@ -115,7 +113,7 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) now. */ if (name[0] == '=') { - new->name = concat (ld_sysroot, name + 1, NULL); + new->name = concat (ld_sysroot, name + 1, (const char *) NULL); new->sysrooted = TRUE; } else @@ -252,8 +250,10 @@ ldfile_try_open_bfd (const char *attempt, yyin = NULL; if (skip) { - einfo (_("%P: skipping incompatible %s when searching for %s\n"), - attempt, entry->local_sym_name); + if (command_line.warn_search_mismatch) + 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; @@ -272,15 +272,17 @@ ldfile_try_open_bfd (const char *attempt, } if (entry->search_dirs_flag - && !bfd_arch_get_compatible (check, output_bfd, + && !bfd_arch_get_compatible (check, link_info.output_bfd, command_line.accept_unknown_input_arch) /* XCOFF archives can have 32 and 64 bit objects. */ && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour - && bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour + && bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour && bfd_check_format (entry->the_bfd, bfd_archive))) { - einfo (_("%P: skipping incompatible %s when searching for %s\n"), - attempt, entry->local_sym_name); + if (command_line.warn_search_mismatch) + 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; @@ -341,19 +343,12 @@ ldfile_open_file_search (const char *arch, } } - string = 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); + string = concat (search->name, slash, lib, entry->filename, + arch, suffix, (const char *) NULL); else - sprintf (string, "%s%s%s", search->name, slash, entry->filename); + string = concat (search->name, slash, entry->filename, + (const char *) 0); if (ldfile_try_open_bfd (string, entry)) { @@ -427,7 +422,6 @@ static FILE * try_open (const char *name, const char *exten) { FILE *result; - char buff[1000]; result = fopen (name, "r"); @@ -444,7 +438,9 @@ try_open (const char *name, const char *exten) if (*exten) { - sprintf (buff, "%s%s", name, exten); + char *buff; + + buff = concat (name, exten, (const char *) NULL); result = fopen (buff, "r"); if (trace_file_tries) @@ -454,44 +450,135 @@ try_open (const char *name, const char *exten) else info_msg (_("opened script file %s\n"), buff); } + free (buff); } return result; } -/* Try to open NAME; if that fails, look for it in any directories - specified with -L, without and with EXTEND appended. */ +/* Return TRUE iff directory DIR contains an "ldscripts" subdirectory. */ + +static bfd_boolean +check_for_scripts_dir (char *dir) +{ + char *buf; + struct stat s; + bfd_boolean res; + + buf = concat (dir, "/ldscripts", (const char *) NULL); + res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); + free (buf); + return res; +} + +/* Return the default directory for finding script files. + We look for the "ldscripts" directory in: + + SCRIPTDIR (passed from Makefile) + (adjusted according to the current location of the binary) + SCRIPTDIR (passed from Makefile) + the dir where this program is (for using it from the build tree). */ + +static char * +find_scripts_dir (void) +{ + char *dir; + + dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR); + if (dir) + { + if (check_for_scripts_dir (dir)) + return dir; + free (dir); + } + + dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR); + if (dir) + { + if (check_for_scripts_dir (dir)) + return dir; + free (dir); + } + + if (check_for_scripts_dir (SCRIPTDIR)) + /* We've been installed normally. */ + return SCRIPTDIR; + + /* Look for "ldscripts" in the dir where our binary is. */ + dir = make_relative_prefix (program_name, ".", "."); + if (dir) + { + if (check_for_scripts_dir (dir)) + return dir; + free (dir); + } + + return NULL; +} + +/* If DEFAULT_ONLY is false, try to open NAME; if that fails, look for + it in directories specified with -L, then in the default script + directory, without and with EXTEND appended. If DEFAULT_ONLY is + true, the search is restricted to the default script location. */ -FILE * -ldfile_find_command_file (const char *name, const char *extend) +static FILE * +ldfile_find_command_file (const char *name, const char *extend, + bfd_boolean default_only) { search_dirs_type *search; - FILE *result; - char buffer[1000]; + FILE *result = NULL; + char *buffer; + static search_dirs_type *script_search; - /* First try raw name. */ - result = try_open (name, ""); - if (result == NULL) + if (!default_only) { - /* Try now prefixes. */ - for (search = search_head; search != NULL; search = search->next) - { - sprintf (buffer, "%s%s%s", search->name, slash, name); + /* First try raw name. */ + result = try_open (name, ""); + if (result != NULL) + return result; + } - result = try_open (buffer, extend); - if (result) - break; + if (!script_search) + { + char *script_dir = find_scripts_dir (); + if (script_dir) + { + search_dirs_type **save_tail_ptr = search_tail_ptr; + search_tail_ptr = &script_search; + ldfile_add_library_path (script_dir, TRUE); + search_tail_ptr = save_tail_ptr; } } + /* Temporarily append script_search to the path list so that the + paths specified with -L will be searched first. */ + *search_tail_ptr = script_search; + + /* Try now prefixes. */ + for (search = default_only ? script_search : search_head; + search != NULL; + search = search->next) + { + buffer = concat (search->name, slash, name, (const char *) NULL); + result = try_open (buffer, extend); + free (buffer); + if (result) + break; + } + + /* Restore the original path list. */ + *search_tail_ptr = NULL; + return result; } -void -ldfile_open_command_file (const char *name) +/* Open command file NAME. */ + +static void +ldfile_open_command_file_1 (const char *name, bfd_boolean default_only) { FILE *ldlex_input_stack; - ldlex_input_stack = ldfile_find_command_file (name, ""); + ldlex_input_stack = ldfile_find_command_file (name, "", default_only); if (ldlex_input_stack == NULL) { @@ -507,6 +594,23 @@ ldfile_open_command_file (const char *name) saved_script_handle = ldlex_input_stack; } +/* Open command file NAME in the current directory, -L directories, + the default script location, in that order. */ + +void +ldfile_open_command_file (const char *name) +{ + ldfile_open_command_file_1 (name, FALSE); +} + +/* Open command file NAME at the default script location. */ + +void +ldfile_open_default_command_file (const char *name) +{ + ldfile_open_command_file_1 (name, TRUE); +} + void ldfile_add_arch (const char *in_name) {