/* Linker file opening and searching.
- Copyright (C) 1991-2020 Free Software Foundation, Inc.
+ Copyright (C) 1991-2022 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
#include "ldemul.h"
#include "libiberty.h"
#include "filenames.h"
-#ifdef ENABLE_PLUGINS
+#if BFD_SUPPORTS_PLUGINS
#include "plugin-api.h"
#include "plugin.h"
-#endif /* ENABLE_PLUGINS */
+#endif /* BFD_SUPPORTS_PLUGINS */
-bfd_boolean ldfile_assumed_script = FALSE;
+bool ldfile_assumed_script = false;
const char *ldfile_output_machine_name = "";
unsigned long ldfile_output_machine;
enum bfd_architecture ldfile_output_architecture;
/* Test whether a pathname, after canonicalization, is the same or a
sub-directory of the sysroot directory. */
-static bfd_boolean
+static bool
is_sysrooted_pathname (const char *name)
{
char *realname;
int len;
- bfd_boolean result;
+ bool result;
if (ld_canon_sysroot == NULL)
- return FALSE;
+ return false;
realname = lrealpath (name);
len = strlen (realname);
- result = FALSE;
+ result = false;
if (len > ld_canon_sysroot_len
&& IS_DIR_SEPARATOR (realname[ld_canon_sysroot_len]))
{
Makes a copy of NAME using xmalloc(). */
void
-ldfile_add_library_path (const char *name, bfd_boolean cmdline)
+ldfile_add_library_path (const char *name, bool cmdline)
{
search_dirs_type *new_dirs;
now. */
if (name[0] == '=')
new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL);
- else if (CONST_STRNEQ (name, "$SYSROOT"))
+ else if (startswith (name, "$SYSROOT"))
new_dirs->name = concat (ld_sysroot, name + strlen ("$SYSROOT"), (const char *) NULL);
else
new_dirs->name = xstrdup (name);
/* Try to open a BFD for a lang_input_statement. */
-bfd_boolean
+bool
ldfile_try_open_bfd (const char *attempt,
lang_input_statement_type *entry)
{
{
if (bfd_get_error () == bfd_error_invalid_target)
einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
- return FALSE;
+ return false;
}
+ track_dependency_files (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 BFD_SUPPORTS_PLUGINS
if (entry->flags.lto_output)
entry->the_bfd->lto_output = 1;
#endif
a dynamic object.
In the code below, it's OK to exit early if the check fails,
- closing the checked BFD and returning FALSE, but if the BFD
- checks out compatible, do not exit early returning TRUE, or
+ closing the checked BFD and returning false, but if the BFD
+ checks out compatible, do not exit early returning true, or
the plugins will not get a chance to claim the file. */
if (entry->flags.search_dirs || !entry->flags.dynamic)
/* 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 ();
+ ldlex_script ();
token = INPUT_SCRIPT;
while (token != 0)
{
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 ();
}
ldlex_popstate ();
- ldfile_assumed_script = FALSE;
+ ldfile_assumed_script = false;
fclose (yyin);
yyin = NULL;
if (skip)
attempt, entry->local_sym_name);
bfd_close (entry->the_bfd);
entry->the_bfd = NULL;
- return FALSE;
+ return false;
}
}
goto success;
attempt);
bfd_close (entry->the_bfd);
entry->the_bfd = NULL;
- return FALSE;
+ return false;
}
if (entry->flags.search_dirs
attempt, entry->local_sym_name);
bfd_close (entry->the_bfd);
entry->the_bfd = NULL;
- return FALSE;
+ return false;
}
}
}
success:
-#ifdef ENABLE_PLUGINS
+#if BFD_SUPPORTS_PLUGINS
/* If plugins are active, they get first chance to claim
any successfully-opened input file. We skip archives
here; the plugin wants us to offer it the individual
&& !no_more_claiming
&& bfd_check_format (entry->the_bfd, bfd_object))
plugin_maybe_claim (entry);
-#endif /* ENABLE_PLUGINS */
+#endif /* BFD_SUPPORTS_PLUGINS */
/* It opened OK, the format checked out, and the plugins have had
their chance to claim it, so this is success. */
- 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. */
-bfd_boolean
+bool
ldfile_open_file_search (const char *arch,
lang_input_statement_type *entry,
const char *lib,
if (ldfile_try_open_bfd (name, entry))
{
entry->filename = name;
- return TRUE;
+ return true;
}
free (name);
}
else if (ldfile_try_open_bfd (entry->filename, entry))
- return TRUE;
+ return true;
if (IS_ABSOLUTE_PATH (entry->filename))
- return FALSE;
+ return false;
}
for (search = search_head; search != NULL; search = search->next)
if (entry->flags.dynamic && !bfd_link_relocatable (&link_info))
{
if (ldemul_open_dynamic_archive (arch, search, entry))
- return TRUE;
+ return true;
}
if (entry->flags.maybe_archive && !entry->flags.full_name_provided)
if (ldfile_try_open_bfd (string, entry))
{
entry->filename = string;
- return TRUE;
+ return true;
}
free (string);
}
- return FALSE;
+ return false;
}
/* Open the input file specified by ENTRY.
else
einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name);
- entry->flags.missing_file = TRUE;
- input_flags.missing_file = TRUE;
+ entry->flags.missing_file = true;
+ input_flags.missing_file = true;
}
else
{
search_arch_type *arch;
- bfd_boolean found = FALSE;
+ bool found = false;
+
+ /* 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;
+ }
- /* Try to open <filename><suffix> or lib<filename><suffix>.a */
+ 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");
/* If we have found the file, we don't need to search directories
again. */
if (found)
- entry->flags.search_dirs = FALSE;
+ entry->flags.search_dirs = false;
else
{
if (entry->flags.sysrooted
&& IS_ABSOLUTE_PATH (entry->local_sym_name))
einfo (_("%P: cannot find %s inside %s\n"),
entry->local_sym_name, ld_sysroot);
+#if SUPPORT_ERROR_HANDLING_SCRIPT
+ else if (error_handling_script != NULL)
+ {
+ char * argv[4];
+ const char * res;
+ int status, err;
+
+ argv[0] = error_handling_script;
+ argv[1] = "missing-lib";
+ argv[2] = (char *) entry->local_sym_name;
+ argv[3] = NULL;
+
+ if (verbose)
+ einfo (_("%P: About to run error handling script '%s' with arguments: '%s' '%s'\n"),
+ argv[0], argv[1], argv[2]);
+
+ res = pex_one (PEX_SEARCH, error_handling_script, argv,
+ N_("error handling script"),
+ NULL /* Send stdout to random, temp file. */,
+ NULL /* Write to stderr. */,
+ &status, &err);
+ if (res != NULL)
+ {
+ einfo (_("%P: Failed to run error handling script '%s', reason: "),
+ error_handling_script);
+ /* FIXME: We assume here that errrno == err. */
+ perror (res);
+ }
+ else /* We ignore the return status of the script
+ and always print the error message. */
+ einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name);
+ }
+#endif
else
- einfo (_("%P: cannot find %s\n"), entry->local_sym_name);
- entry->flags.missing_file = TRUE;
- input_flags.missing_file = TRUE;
+ einfo (_("%P: cannot find %s: %E\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;
}
}
}
/* Try to open NAME. */
static FILE *
-try_open (const char *name, bfd_boolean *sysrooted)
+try_open (const char *name, bool *sysrooted)
{
FILE *result;
/* Return TRUE iff directory DIR contains an "ldscripts" subdirectory. */
-static bfd_boolean
+static bool
check_for_scripts_dir (char *dir)
{
char *buf;
struct stat s;
- bfd_boolean res;
+ bool res;
buf = concat (dir, "/ldscripts", (const char *) NULL);
res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode);
static FILE *
ldfile_find_command_file (const char *name,
- bfd_boolean default_only,
- bfd_boolean *sysrooted)
+ bool default_only,
+ bool *sysrooted)
{
search_dirs_type *search;
FILE *result = NULL;
{
search_dirs_type **save_tail_ptr = search_tail_ptr;
search_tail_ptr = &script_search;
- ldfile_add_library_path (script_dir, TRUE);
+ ldfile_add_library_path (script_dir, true);
search_tail_ptr = save_tail_ptr;
}
}
ldfile_open_command_file_1 (const char *name, enum script_open_style open_how)
{
FILE *ldlex_input_stack;
- bfd_boolean sysrooted;
+ bool sysrooted;
static struct script_name_list *processed_scripts = NULL;
struct script_name_list *script;
size_t len;
return;
}
+ track_dependency_files (name);
+
lex_push_file (ldlex_input_stack, name, sysrooted);
lineno = 1;