X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Fldfile.c;h=53112c86947fdf222e9517f5b3db4a36a56ff5ad;hb=02eba61aa6cad683e96cf13f483adc04982c0c2b;hp=21bdbf404710ab57e735cd805daf4f9fc9de04d1;hpb=ce875075f9c8acc57bb0ec516ae3ba50064e52b7;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldfile.c b/ld/ldfile.c index 21bdbf4047..53112c8694 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -1,5 +1,5 @@ /* Linker file opening and searching. - Copyright (C) 1991-2015 Free Software Foundation, Inc. + Copyright (C) 1991-2020 Free Software Foundation, Inc. This file is part of the GNU Binutils. @@ -21,6 +21,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "safe-ctype.h" #include "ld.h" #include "ldmisc.h" @@ -38,19 +39,19 @@ #include "plugin.h" #endif /* ENABLE_PLUGINS */ -bfd_boolean ldfile_assumed_script = FALSE; -const char * ldfile_output_machine_name = ""; +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; #ifdef VMS -static char * slash = ""; +static char *slash = ""; #else -#if defined (_WIN32) && ! defined (__CYGWIN32__) -static char * slash = "\\"; +#if defined (_WIN32) && !defined (__CYGWIN32__) +static char *slash = "\\"; #else -static char * slash = "/"; +static char *slash = "/"; #endif #endif @@ -112,6 +113,8 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) now. */ if (name[0] == '=') new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); + else if (CONST_STRNEQ (name, "$SYSROOT")) + new_dirs->name = concat (ld_sysroot, name + strlen ("$SYSROOT"), (const char *) NULL); else new_dirs->name = xstrdup (name); } @@ -142,6 +145,9 @@ ldfile_try_open_bfd (const char *attempt, /* Linker needs to decompress sections. */ entry->the_bfd->flags |= BFD_DECOMPRESS; + /* This is a linker input BFD. */ + entry->the_bfd->is_linker_input = 1; + #ifdef ENABLE_PLUGINS if (entry->flags.lto_output) entry->the_bfd->lto_output = 1; @@ -169,12 +175,12 @@ ldfile_try_open_bfd (const char *attempt, if (check != NULL) { - if (! bfd_check_format (check, bfd_object)) + if (!bfd_check_format (check, bfd_object)) { if (check == entry->the_bfd && entry->flags.search_dirs && bfd_get_error () == bfd_error_file_not_recognized - && ! ldemul_unrecognized_file (entry)) + && !ldemul_unrecognized_file (entry)) { int token, skip = 0; char *arg, *arg1, *arg2, *arg3; @@ -281,9 +287,10 @@ ldfile_try_open_bfd (const char *attempt, && !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 (link_info.output_bfd) == bfd_target_xcoff_flavour - && bfd_check_format (entry->the_bfd, bfd_archive))) + && !(bfd_get_flavour (check) == bfd_target_xcoff_flavour + && (bfd_get_flavour (link_info.output_bfd) + == bfd_target_xcoff_flavour) + && bfd_check_format (entry->the_bfd, bfd_archive))) { if (command_line.warn_search_mismatch) einfo (_("%P: skipping incompatible %s " @@ -295,7 +302,7 @@ ldfile_try_open_bfd (const char *attempt, } } } -success: + success: #ifdef ENABLE_PLUGINS /* If plugins are active, they get first chance to claim any successfully-opened input file. We skip archives @@ -330,7 +337,7 @@ ldfile_open_file_search (const char *arch, /* If this is not an archive, try to open it in the current directory first. */ - if (! entry->flags.maybe_archive) + if (!entry->flags.maybe_archive) { if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) { @@ -354,7 +361,7 @@ ldfile_open_file_search (const char *arch, { char *string; - if (entry->flags.dynamic && ! link_info.relocatable) + if (entry->flags.dynamic && !bfd_link_relocatable (&link_info)) { if (ldemul_open_dynamic_archive (arch, search, entry)) return TRUE; @@ -390,7 +397,7 @@ ldfile_open_file (lang_input_statement_type *entry) if (entry->the_bfd != NULL) return; - if (! entry->flags.search_dirs) + if (!entry->flags.search_dirs) { if (ldfile_try_open_bfd (entry->filename, entry)) return; @@ -409,7 +416,24 @@ ldfile_open_file (lang_input_statement_type *entry) search_arch_type *arch; bfd_boolean found = FALSE; - /* Try to open or lib.a */ + /* If extra_search_path is set, entry->filename is a relative path. + Search the directory of the current linker script before searching + other paths. */ + if (entry->extra_search_path) + { + char *path = concat (entry->extra_search_path, slash, entry->filename, + (const char *)0); + if (ldfile_try_open_bfd (path, entry)) + { + entry->filename = path; + entry->flags.search_dirs = FALSE; + return; + } + + free (path); + } + + /* Try to open or lib.a. */ for (arch = search_arch_head; arch != NULL; arch = arch->next) { found = ldfile_open_file_search (arch->name, entry, "lib", ".a"); @@ -438,6 +462,22 @@ ldfile_open_file (lang_input_statement_type *entry) entry->local_sym_name, ld_sysroot); else einfo (_("%P: cannot find %s\n"), entry->local_sym_name); + + /* PR 25747: Be kind to users who forgot to add the + "lib" prefix to their library when it was created. */ + for (arch = search_arch_head; arch != NULL; arch = arch->next) + { + if (ldfile_open_file_search (arch->name, entry, "", ".a")) + { + const char * base = lbasename (entry->filename); + + einfo (_("%P: note to link with %s use -l:%s or rename it to lib%s\n"), + entry->filename, base, base); + bfd_close (entry->the_bfd); + entry->the_bfd = NULL; + break; + } + } entry->flags.missing_file = TRUE; input_flags.missing_file = TRUE; } @@ -579,20 +619,60 @@ ldfile_find_command_file (const char *name, return result; } +enum script_open_style { + script_nonT, + script_T, + script_defaultT +}; + +struct script_name_list +{ + struct script_name_list *next; + enum script_open_style open_how; + char name[1]; +}; + /* Open command file NAME. */ static void -ldfile_open_command_file_1 (const char *name, bfd_boolean default_only) +ldfile_open_command_file_1 (const char *name, enum script_open_style open_how) { FILE *ldlex_input_stack; bfd_boolean sysrooted; + static struct script_name_list *processed_scripts = NULL; + struct script_name_list *script; + size_t len; - ldlex_input_stack = ldfile_find_command_file (name, default_only, &sysrooted); + /* PR 24576: Catch the case where the user has accidentally included + the same linker script twice. */ + for (script = processed_scripts; script != NULL; script = script->next) + { + if ((open_how != script_nonT || script->open_how != script_nonT) + && strcmp (name, script->name) == 0) + { + einfo (_("%F%P: error: linker script file '%s'" + " appears multiple times\n"), name); + return; + } + } + /* FIXME: This memory is never freed, but that should not really matter. + It will be released when the linker exits, and it is unlikely to ever + be more than a few tens of bytes. */ + len = strlen (name); + script = xmalloc (sizeof (*script) + len); + script->next = processed_scripts; + script->open_how = open_how; + memcpy (script->name, name, len + 1); + processed_scripts = script; + + ldlex_input_stack = ldfile_find_command_file (name, + open_how == script_defaultT, + &sysrooted); if (ldlex_input_stack == NULL) { bfd_set_error (bfd_error_system_call); - einfo (_("%P%F: cannot open linker script file %s: %E\n"), name); + einfo (_("%F%P: cannot open linker script file %s: %E\n"), name); return; } @@ -609,7 +689,13 @@ ldfile_open_command_file_1 (const char *name, bfd_boolean default_only) void ldfile_open_command_file (const char *name) { - ldfile_open_command_file_1 (name, FALSE); + ldfile_open_command_file_1 (name, script_nonT); +} + +void +ldfile_open_script_file (const char *name) +{ + ldfile_open_command_file_1 (name, script_T); } /* Open command file NAME at the default script location. */ @@ -617,15 +703,15 @@ ldfile_open_command_file (const char *name) void ldfile_open_default_command_file (const char *name) { - ldfile_open_command_file_1 (name, TRUE); + ldfile_open_command_file_1 (name, script_defaultT); } void ldfile_add_arch (const char *in_name) { char *name = xstrdup (in_name); - search_arch_type *new_arch = (search_arch_type *) - xmalloc (sizeof (search_arch_type)); + search_arch_type *new_arch + = (search_arch_type *) xmalloc (sizeof (search_arch_type)); ldfile_output_machine_name = in_name; @@ -657,5 +743,5 @@ ldfile_set_output_arch (const char *string, enum bfd_architecture defarch) else if (defarch != bfd_arch_unknown) ldfile_output_architecture = defarch; else - einfo (_("%P%F: cannot represent machine `%s'\n"), string); + einfo (_("%F%P: cannot represent machine `%s'\n"), string); }