[binutils-gdb] Have the linker report an error if the same script is used twice.

Nick Clifton nickc@sourceware.org
Wed May 22 14:59:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6ec6968b1b259948ba42f0a47a3da048377058bc

commit 6ec6968b1b259948ba42f0a47a3da048377058bc
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed May 22 15:58:57 2019 +0100

    Have the linker report an error if the same script is used twice.
    
    	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.

Diff:
---
 ld/ChangeLog | 15 +++++++++++++++
 ld/ldfile.c  | 42 ++++++++++++++++++++++++++++++++++++++----
 ld/ldfile.h  |  2 ++
 ld/ldmain.c  |  2 +-
 ld/lexsup.c  |  2 +-
 5 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index eb0dd9b..7f7fef6 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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
diff --git a/ld/ldfile.c b/ld/ldfile.c
index fcadc08..5bb08f7 100644
--- a/ld/ldfile.c
+++ b/ld/ldfile.c
@@ -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
diff --git a/ld/ldfile.h b/ld/ldfile.h
index 6da3fee..3d6ddf1 100644
--- a/ld/ldfile.h
+++ b/ld/ldfile.h
@@ -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
diff --git a/ld/ldmain.c b/ld/ldmain.c
index da1c6a7..a7ca4f4 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -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 ();
     }
diff --git a/ld/lexsup.c b/ld/lexsup.c
index dacb962..2539356 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -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;



More information about the Binutils-cvs mailing list