/* Linker file opening and searching.
- Copyright (C) 1991-2019 Free Software Foundation, Inc.
+ Copyright (C) 1991-2020 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
+#include "ctf-api.h"
#include "safe-ctype.h"
#include "ld.h"
#include "ldmisc.h"
skip = 1;
}
free (arg1);
- if (arg2) free (arg2);
- if (arg3) free (arg3);
+ free (arg2);
+ free (arg3);
break;
case NAME:
case LNAME:
free (yylval.name);
break;
case INT:
- if (yylval.bigint.str)
- free (yylval.bigint.str);
+ free (yylval.bigint.str);
break;
}
token = yylex ();
}
}
}
-success:
+ success:
#ifdef ENABLE_PLUGINS
/* If plugins are active, they get first chance to claim
any successfully-opened input file. We skip archives
search_arch_type *arch;
bfd_boolean found = FALSE;
- /* Try to open <filename><suffix> or lib<filename><suffix>.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 <filename><suffix> or lib<filename><suffix>.a. */
for (arch = search_arch_head; arch != NULL; arch = arch->next)
{
found = ldfile_open_file_search (arch->name, entry, "lib", ".a");
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;
}
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);
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. */
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