[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