Have the linker report an error if the same script is used twice.
authorNick Clifton <nickc@redhat.com>
Wed, 22 May 2019 14:58:57 +0000 (15:58 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 22 May 2019 14:58:57 +0000 (15:58 +0100)
PR 24576
* ld/ldfile.c: (ldfile_open_command_file_1): Add new parameter -
is_script.  If true check that the file has not already been
parsed as a linker script.
(ldfile_open_script_file): New function.
(ldfile_try_open_bfd): Use the new function in place of
ldfile_open_command_line.
* ldmain.c (main): Likewise.
* lexsup.c (parse_args): Use the new function for opening linker
scripts with the -T option.
* ldfile.h (ldfile_open_script_file): Add prototype.

ld/ChangeLog
ld/ldfile.c
ld/ldfile.h
ld/ldmain.c
ld/lexsup.c

index eb0dd9bb8fe3e006efbd590fa238de9ce6a18a6f..7f7fef6be58853603cb8d515dca9a3af71c33bdf 100644 (file)
@@ -1,3 +1,18 @@
+2019-05-22  Julius Werner  <jwerner@chromium.org>
+           Nick Clifton  <nickc@redhat.com>
+
+       PR 24576
+       * ld/ldfile.c: (ldfile_open_command_file_1): Add new parameter -
+       is_script.  If true check that the file has not already been
+       parsed as a linker script.
+       (ldfile_open_script_file): New function.
+       (ldfile_try_open_bfd): Use the new function in place of
+       ldfile_open_command_line.
+       * ldmain.c (main): Likewise.
+       * lexsup.c (parse_args): Use the new function for opening linker
+       scripts with the -T option.
+       * ldfile.h (ldfile_open_script_file): Add prototype.
+
 2019-05-21  Faraz Shahbazker  <fshahbazker@wavecomp.com>
 
        * testsuite/ld-mips-elf/pic-reloc-5.s: Add tests for
index fcadc08c73ff637be0ad0ebb99ddd9dbfc8eb621..5bb08f7b2e46f1072efc92de6b5a1c7bb109f6c1 100644 (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_command_file (attempt);
+                 ldfile_open_script_file (attempt);
 
                  ldfile_assumed_script = TRUE;
                  parser_input = input_selected;
@@ -588,11 +588,39 @@ ldfile_find_command_file (const char *name,
 /* 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,
+                           bfd_boolean default_only,
+                           bfd_boolean is_script)
 {
   FILE *ldlex_input_stack;
   bfd_boolean sysrooted;
 
+  if (is_script)
+    {
+      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 (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.  */
+      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);
 
   if (ldlex_input_stack == NULL)
@@ -615,7 +643,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, FALSE, FALSE);
+}
+
+void
+ldfile_open_script_file (const char *name)
+{
+  ldfile_open_command_file_1 (name, FALSE, TRUE);
 }
 
 /* Open command file NAME at the default script location.  */
@@ -623,7 +657,7 @@ 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, TRUE, TRUE);
 }
 
 void
index 6da3fee6d584401b872b885a889b9e5cf93ff3f6..3d6ddf12fdffcf5aeed47cfcd68936e12bf3462f 100644 (file)
@@ -46,6 +46,8 @@ extern void ldfile_add_library_path
   (const char *, bfd_boolean cmdline);
 extern void ldfile_open_command_file
   (const char *name);
+extern void ldfile_open_script_file
+  (const char *name);
 extern void ldfile_open_default_command_file
   (const char *name);
 extern void ldfile_open_file
index da1c6a7658f1c41fed33c98f314d8d996f2aab0d..a7ca4f487db11cacaf2b755b43dd7ac0e580baf5 100644 (file)
@@ -329,7 +329,7 @@ main (int argc, char **argv)
   if (saved_script_handle == NULL
       && command_line.default_script != NULL)
     {
-      ldfile_open_command_file (command_line.default_script);
+      ldfile_open_script_file (command_line.default_script);
       parser_input = input_script;
       yyparse ();
     }
index dacb9623b404a766b8ac65e35eb538b999fa6446..2539356baa7b930d9eb19cd52cd4fa0ca7010327 100644 (file)
@@ -1243,7 +1243,7 @@ parse_args (unsigned argc, char **argv)
          break;
        case 'T':
          previous_script_handle = saved_script_handle;
-         ldfile_open_command_file (optarg);
+         ldfile_open_script_file (optarg);
          parser_input = input_script;
          yyparse ();
          previous_script_handle = NULL;