Re: Have the linker report an error if the same script is used twice

git commit 6ec6968b1b results in
... error: linker script file '/usr/local/lib64/libgcc_s.so' appears multiple times
collect2: error: ld returned 1 exit status
FAIL: bootstrap

This patch changes things so that an error is given only when a -T
script or the default script is invoked more than once.  I'm still a
little nervous that we match script file names, not the entire path.

	PR 24576
	* ldfile.c (enum script_open_style): New.
	(struct script_name_list): New.
	(ldfile_open_command_file_1): Take a script_open_style param
	rather than booleans.  Adjust callers.  Only fail when -T or
	default -T script is invoked twice.
	(ldfile_try_open_bfd): Revert last change.
This commit is contained in:
Alan Modra 2019-05-23 10:22:56 +09:30
parent 016181423b
commit 82d7a6f4e3
2 changed files with 51 additions and 29 deletions

View File

@ -1,3 +1,13 @@
2019-05-23 Alan Modra <amodra@gmail.com>
PR 24576
* ldfile.c (enum script_open_style): New.
(struct script_name_list): New.
(ldfile_open_command_file_1): Take a script_open_style param
rather than booleans. Adjust callers. Only fail when -T or
default -T script is invoked twice.
(ldfile_try_open_bfd): Revert last change.
2019-05-22 Julius Werner <jwerner@chromium.org>
Nick Clifton <nickc@redhat.com>

View File

@ -186,7 +186,7 @@ ldfile_try_open_bfd (const char *attempt,
extern FILE *yyin;
/* Try to interpret the file as a linker script. */
ldfile_open_script_file (attempt);
ldfile_open_command_file (attempt);
ldfile_assumed_script = TRUE;
parser_input = input_selected;
@ -585,44 +585,56 @@ 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,
bfd_boolean is_script)
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;
if (is_script)
/* 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)
{
static struct name_list *processed_scripts = NULL;
struct name_list *script;
/* 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)
{
if (strcmp (name, script->name) == 0)
{
einfo (_("%F%P: error: linker script file '%s' appears multiple times\n"),
name);
return;
}
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. */
script = xmalloc (sizeof (name_list));
script->name = strdup (name);
script->next = processed_scripts;
processed_scripts = script;
}
ldlex_input_stack = ldfile_find_command_file (name, default_only, &sysrooted);
/* 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);
@ -643,13 +655,13 @@ ldfile_open_command_file_1 (const char *name,
void
ldfile_open_command_file (const char *name)
{
ldfile_open_command_file_1 (name, FALSE, FALSE);
ldfile_open_command_file_1 (name, script_nonT);
}
void
ldfile_open_script_file (const char *name)
{
ldfile_open_command_file_1 (name, FALSE, TRUE);
ldfile_open_command_file_1 (name, script_T);
}
/* Open command file NAME at the default script location. */
@ -657,7 +669,7 @@ ldfile_open_script_file (const char *name)
void
ldfile_open_default_command_file (const char *name)
{
ldfile_open_command_file_1 (name, TRUE, TRUE);
ldfile_open_command_file_1 (name, script_defaultT);
}
void