diff options
Diffstat (limited to 'contrib/binutils/ld/ldfile.c')
-rw-r--r-- | contrib/binutils/ld/ldfile.c | 279 |
1 files changed, 160 insertions, 119 deletions
diff --git a/contrib/binutils/ld/ldfile.c b/contrib/binutils/ld/ldfile.c index d706eec..a6f0d60 100644 --- a/contrib/binutils/ld/ldfile.c +++ b/contrib/binutils/ld/ldfile.c @@ -1,23 +1,23 @@ /* Linker file opening and searching. - Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, + 2003, 2004 Free Software Foundation, Inc. -This file is part of GLD, the Gnu Linker. + 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 2, or (at your option) -any later version. + 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 2, or (at your option) + any later version. -GLD 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. + GLD 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. */ + 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. */ /* ldfile.c: look after all the file stuff. */ @@ -35,67 +35,106 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ldlex.h" #include "ldemul.h" #include "libiberty.h" +#include "filenames.h" -const char *ldfile_input_filename; -boolean ldfile_assumed_script = false; -const char *ldfile_output_machine_name = ""; +const char * ldfile_input_filename; +bfd_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; +search_dirs_type * search_head; #ifndef MPW #ifdef VMS -char *slash = ""; +char * slash = ""; #else #if defined (_WIN32) && ! defined (__CYGWIN32__) -char *slash = "\\"; +char * slash = "\\"; #else -char *slash = "/"; +char * slash = "/"; #endif #endif #else /* MPW */ /* The MPW path char is a colon. */ -char *slash = ":"; +char * slash = ":"; #endif /* MPW */ -/* LOCAL */ - -static search_dirs_type **search_tail_ptr = &search_head; - -typedef struct search_arch { +typedef struct search_arch +{ char *name; struct search_arch *next; } search_arch_type; +static search_dirs_type **search_tail_ptr = &search_head; 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)); +/* Test whether a pathname, after canonicalization, is the same or a + sub-directory of the sysroot directory. */ + +static bfd_boolean +is_sysrooted_pathname (const char *name, bfd_boolean notsame) +{ + char * realname = ld_canon_sysroot ? lrealpath (name) : NULL; + int len; + bfd_boolean result; + + if (! realname) + return FALSE; + + len = strlen (realname); + + if (((! notsame && len == ld_canon_sysroot_len) + || (len >= ld_canon_sysroot_len + && IS_DIR_SEPARATOR (realname[ld_canon_sysroot_len]) + && (realname[ld_canon_sysroot_len] = '\0') == '\0')) + && FILENAME_CMP (ld_canon_sysroot, realname) == 0) + result = TRUE; + else + result = FALSE; + + if (realname) + free (realname); + + return result; +} + +/* Adds NAME to the library search path. + Makes a copy of NAME using xmalloc(). */ void -ldfile_add_library_path (name, cmdline) - const char *name; - boolean cmdline; +ldfile_add_library_path (const char *name, bfd_boolean cmdline) { search_dirs_type *new; if (!cmdline && config.only_cmd_line_lib_dirs) return; - new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type)); + new = xmalloc (sizeof (search_dirs_type)); new->next = NULL; - new->name = name; new->cmdline = cmdline; *search_tail_ptr = new; search_tail_ptr = &new->next; + + /* If a directory is marked as honoring sysroot, prepend the sysroot path + now. */ + if (name[0] == '=') + { + new->name = concat (ld_sysroot, name + 1, NULL); + new->sysrooted = TRUE; + } + else + { + new->name = xstrdup (name); + new->sysrooted = is_sysrooted_pathname (name, FALSE); + } } /* Try to open a BFD for a lang_input_statement. */ -boolean -ldfile_try_open_bfd (attempt, entry) - const char *attempt; - lang_input_statement_type *entry; +bfd_boolean +ldfile_try_open_bfd (const char *attempt, + lang_input_statement_type *entry) { entry->the_bfd = bfd_openr (attempt, entry->target); @@ -111,7 +150,7 @@ ldfile_try_open_bfd (attempt, entry) { if (bfd_get_error () == bfd_error_invalid_target) einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target); - return false; + return FALSE; } /* If we are searching for this file, see if the architecture is @@ -142,8 +181,8 @@ ldfile_try_open_bfd (attempt, entry) /* Try to interpret the file as a linker script. */ ldfile_open_command_file (attempt); - - ldfile_assumed_script = true; + + ldfile_assumed_script = TRUE; parser_input = input_selected; ldlex_both (); token = INPUT_SCRIPT; @@ -207,10 +246,11 @@ ldfile_try_open_bfd (attempt, entry) if (yylval.bigint.str) free (yylval.bigint.str); break; - } + } token = yylex (); } - ldfile_assumed_script = false; + ldlex_popstate (); + ldfile_assumed_script = FALSE; fclose (yyin); yyin = NULL; if (skip) @@ -219,14 +259,15 @@ ldfile_try_open_bfd (attempt, entry) attempt, entry->local_sym_name); bfd_close (entry->the_bfd); entry->the_bfd = NULL; - return false; + return FALSE; } } - return true; + return TRUE; } - if ((bfd_arch_get_compatible (check, output_bfd) == NULL) - /* XCOFF archives can have 32 and 64 bit objects */ + if ((bfd_arch_get_compatible (check, output_bfd, + command_line.accept_unknown_input_arch) == NULL) + /* 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_check_format (entry->the_bfd, bfd_archive))) @@ -235,23 +276,22 @@ ldfile_try_open_bfd (attempt, entry) attempt, entry->local_sym_name); bfd_close (entry->the_bfd); entry->the_bfd = NULL; - return false; + return FALSE; } } } - return true; + return TRUE; } /* 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_boolean +ldfile_open_file_search (const char *arch, + lang_input_statement_type *entry, + const char *lib, + const char *suffix) { search_dirs_type *search; @@ -259,61 +299,72 @@ ldfile_open_file_search (arch, entry, lib, suffix) directory first. */ if (! entry->is_archive) { - if (ldfile_try_open_bfd (entry->filename, entry)) - return true; + if (entry->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)) + { + entry->sysrooted = IS_ABSOLUTE_PATH (entry->filename) + && is_sysrooted_pathname (entry->filename, TRUE); + return TRUE; + } + + if (IS_ABSOLUTE_PATH (entry->filename)) + return FALSE; } - for (search = search_head; - search != (search_dirs_type *) NULL; - search = search->next) + for (search = search_head; search != NULL; search = search->next) { char *string; - if (entry->dynamic && ! link_info.relocateable) + if (entry->dynamic && ! link_info.relocatable) { if (ldemul_open_dynamic_archive (arch, search, entry)) - return true; + { + entry->sysrooted = search->sysrooted; + return TRUE; + } } - string = (char *) xmalloc (strlen (search->name) - + strlen (slash) - + strlen (lib) - + strlen (entry->filename) - + strlen (arch) - + strlen (suffix) - + 1); + 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); - 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; - return true; + entry->sysrooted = search->sysrooted; + return TRUE; } free (string); } - return false; + return FALSE; } /* Open the input file specified by ENTRY. */ void -ldfile_open_file (entry) - lang_input_statement_type *entry; +ldfile_open_file (lang_input_statement_type *entry) { if (entry->the_bfd != NULL) return; @@ -323,20 +374,18 @@ ldfile_open_file (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"), + einfo (_("%F%P: %s (%s): No such file: %E\n"), entry->filename, entry->local_sym_name); else - einfo (_("%F%P: cannot open %s: %E\n"), entry->local_sym_name); + einfo (_("%F%P: %s: No such file: %E\n"), entry->local_sym_name); } else { search_arch_type *arch; - boolean found = false; + bfd_boolean found = FALSE; /* Try to open <filename><suffix> or lib<filename><suffix>.a */ - for (arch = search_arch_head; - arch != (search_arch_type *) NULL; - arch = arch->next) + for (arch = search_arch_head; arch != NULL; arch = arch->next) { found = ldfile_open_file_search (arch->name, entry, "lib", ".a"); if (found) @@ -354,7 +403,12 @@ ldfile_open_file (entry) /* If we have found the file, we don't need to search directories again. */ if (found) - entry->search_dirs_flag = false; + entry->search_dirs_flag = FALSE; + else if (entry->sysrooted + && ld_sysroot + && IS_ABSOLUTE_PATH (entry->local_sym_name)) + einfo (_("%F%P: cannot find %s inside %s\n"), + entry->local_sym_name, ld_sysroot); else einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name); } @@ -363,9 +417,7 @@ ldfile_open_file (entry) /* Try to open NAME; if that fails, try NAME with EXTEN appended to it. */ static FILE * -try_open (name, exten) - const char *name; - const char *exten; +try_open (const char *name, const char *exten) { FILE *result; char buff[1000]; @@ -401,12 +453,10 @@ try_open (name, exten) } /* Try to open NAME; if that fails, look for it in any directories - specified with -L, without and with EXTEND apppended. */ + specified with -L, without and with EXTEND appended. */ FILE * -ldfile_find_command_file (name, extend) - const char *name; - const char *extend; +ldfile_find_command_file (const char *name, const char *extend) { search_dirs_type *search; FILE *result; @@ -414,12 +464,10 @@ ldfile_find_command_file (name, extend) /* First try raw name. */ result = try_open (name, ""); - if (result == (FILE *) NULL) + if (result == NULL) { /* Try now prefixes. */ - for (search = search_head; - search != (search_dirs_type *) NULL; - search = search->next) + for (search = search_head; search != NULL; search = search->next) { sprintf (buffer, "%s%s%s", search->name, slash, name); @@ -433,13 +481,12 @@ ldfile_find_command_file (name, extend) } void -ldfile_open_command_file (name) - const char *name; +ldfile_open_command_file (const char *name) { FILE *ldlex_input_stack; ldlex_input_stack = ldfile_find_command_file (name, ""); - if (ldlex_input_stack == (FILE *) NULL) + if (ldlex_input_stack == NULL) { bfd_set_error (bfd_error_system_call); einfo (_("%P%F: cannot open linker script file %s: %E\n"), name); @@ -455,8 +502,7 @@ ldfile_open_command_file (name) #ifdef GNU960 static char * -gnu960_map_archname (name) - char *name; +gnu960_map_archname (char *name) { struct tabentry { char *cmd_switch; char *arch; }; static struct tabentry arch_tab[] = @@ -486,11 +532,9 @@ gnu960_map_archname (name) } void -ldfile_add_arch (name) - char *name; +ldfile_add_arch (char *name) { - search_arch_type *new = - (search_arch_type *) xmalloc ((bfd_size_type) (sizeof (search_arch_type))); + search_arch_type *new = xmalloc (sizeof (search_arch_type)); if (*name != '\0') { @@ -503,7 +547,7 @@ ldfile_add_arch (name) ldfile_output_machine_name = name; } - new->next = (search_arch_type *) NULL; + new->next = NULL; new->name = gnu960_map_archname (name); *search_arch_tail_ptr = new; search_arch_tail_ptr = &new->next; @@ -512,17 +556,15 @@ ldfile_add_arch (name) #else /* not GNU960 */ void -ldfile_add_arch (in_name) - const char *in_name; +ldfile_add_arch (const char *in_name) { char *name = xstrdup (in_name); - search_arch_type *new = - (search_arch_type *) xmalloc (sizeof (search_arch_type)); + search_arch_type *new = xmalloc (sizeof (search_arch_type)); ldfile_output_machine_name = in_name; new->name = name; - new->next = (search_arch_type *) NULL; + new->next = NULL; while (*name) { *name = TOLOWER (*name); @@ -537,8 +579,7 @@ ldfile_add_arch (in_name) /* Set the output architecture. */ void -ldfile_set_output_arch (string) - const char *string; +ldfile_set_output_arch (const char *string, enum bfd_architecture defarch) { const bfd_arch_info_type *arch = bfd_scan_arch (string); @@ -548,8 +589,8 @@ ldfile_set_output_arch (string) ldfile_output_machine = arch->mach; ldfile_output_machine_name = arch->printable_name; } + else if (defarch != bfd_arch_unknown) + ldfile_output_architecture = defarch; else - { - einfo (_("%P%F: cannot represent machine `%s'\n"), string); - } + einfo (_("%P%F: cannot represent machine `%s'\n"), string); } |