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

git commit 6ec6968b1b2 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> 2019-05-22 Julius Werner <jwerner@chromium.org>
Nick Clifton <nickc@redhat.com> Nick Clifton <nickc@redhat.com>

View File

@ -186,7 +186,7 @@ ldfile_try_open_bfd (const char *attempt,
extern FILE *yyin; extern FILE *yyin;
/* Try to interpret the file as a linker script. */ /* Try to interpret the file as a linker script. */
ldfile_open_script_file (attempt); ldfile_open_command_file (attempt);
ldfile_assumed_script = TRUE; ldfile_assumed_script = TRUE;
parser_input = input_selected; parser_input = input_selected;
@ -585,29 +585,39 @@ ldfile_find_command_file (const char *name,
return result; 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. */ /* Open command file NAME. */
static void static void
ldfile_open_command_file_1 (const char *name, ldfile_open_command_file_1 (const char *name, enum script_open_style open_how)
bfd_boolean default_only,
bfd_boolean is_script)
{ {
FILE *ldlex_input_stack; FILE *ldlex_input_stack;
bfd_boolean sysrooted; bfd_boolean sysrooted;
static struct script_name_list *processed_scripts = NULL;
if (is_script) struct script_name_list *script;
{ size_t len;
static struct name_list *processed_scripts = NULL;
struct name_list *script;
/* PR 24576: Catch the case where the user has accidentally included /* PR 24576: Catch the case where the user has accidentally included
the same linker script twice. */ the same linker script twice. */
for (script = processed_scripts; script != NULL; script = script->next) for (script = processed_scripts; script != NULL; script = script->next)
{ {
if (strcmp (name, script->name) == 0) 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"), einfo (_("%F%P: error: linker script file '%s'"
name); " appears multiple times\n"), name);
return; return;
} }
} }
@ -615,14 +625,16 @@ ldfile_open_command_file_1 (const char *name,
/* FIXME: This memory is never freed, but that should not really matter. /* 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 It will be released when the linker exits, and it is unlikely to ever
be more than a few tens of bytes. */ be more than a few tens of bytes. */
script = xmalloc (sizeof (name_list)); len = strlen (name);
script->name = strdup (name); script = xmalloc (sizeof (*script) + len);
script->next = processed_scripts; script->next = processed_scripts;
script->open_how = open_how;
memcpy (script->name, name, len + 1);
processed_scripts = script; processed_scripts = script;
}
ldlex_input_stack = ldfile_find_command_file (name, default_only, &sysrooted);
ldlex_input_stack = ldfile_find_command_file (name,
open_how == script_defaultT,
&sysrooted);
if (ldlex_input_stack == NULL) if (ldlex_input_stack == NULL)
{ {
bfd_set_error (bfd_error_system_call); bfd_set_error (bfd_error_system_call);
@ -643,13 +655,13 @@ ldfile_open_command_file_1 (const char *name,
void void
ldfile_open_command_file (const char *name) ldfile_open_command_file (const char *name)
{ {
ldfile_open_command_file_1 (name, FALSE, FALSE); ldfile_open_command_file_1 (name, script_nonT);
} }
void void
ldfile_open_script_file (const char *name) 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. */ /* Open command file NAME at the default script location. */
@ -657,7 +669,7 @@ ldfile_open_script_file (const char *name)
void void
ldfile_open_default_command_file (const char *name) 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 void