[PATCH] ld: Prohibit input name of have the same name as one of its inputs

Alan Modra amodra@gmail.com
Tue Dec 7 03:20:28 GMT 2021


On Mon, Dec 06, 2021 at 09:50:30AM -0300, Renato Alencar via Binutils wrote:
> When doing partial linking, one of the inputs may have the same name as the
> output, which generates an incorrect object file because it overwrites the file
> before actually reading it. This patch proposes prohibiting that, just gcc does
> for compile only cases.
> 
> That's the case of this issue on the OCaml compiler (link below),
> which generates
> an invalid object file with several undefined entries, when they
> should be defined.
> Although OCaml may have their ways of handling it (there's PR
> submitted for that)
> this should also be handled by ld in some way. Either by reading the whole file
> before starting to writing it or prohibiting that, which is the
> current behavior for gcc,
> and so I'm adopting it.
> 
> * https://discuss.ocaml.org/t/bad-object-file-from-ocamlopt-output-obj-o-foo-o-foo-ml/8753
> 
> ---
>  ld/lexsup.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/ld/lexsup.c b/ld/lexsup.c
> index a626d7ff6d4..127a3a67201 100644
> --- a/ld/lexsup.c
> +++ b/ld/lexsup.c
> @@ -1798,6 +1798,20 @@ parse_args (unsigned argc, char **argv)
>      }
>      }
> 
> +  for (lang_input_statement_type *statement =
> &input_file_chain.head->input_statement;
> +       statement != NULL;
> +       statement = statement->next_real_file)
> +    {
> +      if (statement->filename != NULL
> +          && output_filename != NULL
> +          && strcmp(statement->filename, output_filename) == 0)
> +        {
> +          einfo (_("%P: input file '%s' is the same as output file\n"),
> +                 statement->filename);
> +          break;
> +        }
> +    }
> +
>    if (command_line.soname && command_line.soname[0] == '\0')
>      {
>        einfo (_("%P: SONAME must not be empty string; ignored\n"));
> -- 
> 2.33.1

Code such as this should be in ldlang.c:open_output.  Linker scripts
can add files.  I'll commit the following after a test run completes,
assuming no regressions.

It's not foolproof, for example we don't catch output to a linker
script, to a library specified with -l, or to an element of a thin
archive.

	* ldlang.c (open_output): Exit with error on output file matching
	an input file.
	* testsuite/ld-misc/just-symbols.exp: Adjust ld -r test to suit.

diff --git a/ld/ldlang.c b/ld/ldlang.c
index acd90fa8f42..64a8f602093 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3392,6 +3392,22 @@ lang_get_output_target (void)
 static void
 open_output (const char *name)
 {
+  lang_input_statement_type *f;
+  char *out = lrealpath (name);
+
+  for (f = (void *) input_file_chain.head;
+       f != NULL;
+       f = f->next_real_file)
+    if (f->flags.real)
+      {
+	char *in = lrealpath (f->filename);
+	if (filename_cmp (in, out) == 0)
+	  einfo (_("%F%P: input file '%s' is the same as output file\n"),
+		 f->filename);
+	free (in);
+      }
+  free (out);
+
   output_target = lang_get_output_target ();
 
   /* Has the user requested a particular endianness on the command
diff --git a/ld/testsuite/ld-misc/just-symbols.exp b/ld/testsuite/ld-misc/just-symbols.exp
index 510291473ca..6cfbd34eda9 100644
--- a/ld/testsuite/ld-misc/just-symbols.exp
+++ b/ld/testsuite/ld-misc/just-symbols.exp
@@ -44,7 +44,7 @@ run_ld_link_tests [list \
      "" \
      {just-symbols-0.s} \
      {} \
-     "just-symbols-0.o"] \
+     "just-symbols-r"] \
     [list "Executable for --just-symbols test" \
      "$LDFLAGS -e 0 -T just-symbols.ld" "" \
      "" \


-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list