aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2025-01-17 07:22:04 +0800
committerH.J. Lu <hjl.tools@gmail.com>2025-01-17 14:25:28 +0800
commitd7a3c9e650240e9e1c8e66e9099dc2880840a919 (patch)
tree935eb57555ef95d6c7c3ec0af76a240dcf3975bc
parentb565ac119bdf8ed857cfa1352ddc732ccdac7b66 (diff)
downloadbinutils-d7a3c9e650240e9e1c8e66e9099dc2880840a919.zip
binutils-d7a3c9e650240e9e1c8e66e9099dc2880840a919.tar.gz
binutils-d7a3c9e650240e9e1c8e66e9099dc2880840a919.tar.bz2
ld: Load the object only section when opening the mixed object file
Load the object only section when opening the mixed object file, instead of loading it after all other input files have been loaded. This fixed .../ld/collect-ld: /tmp/ccZAoUIW.obj-only.o: in function `main': .../ld/testsuite/ld-plugin/lto-10a.c:4: multiple definition of `main'; /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libmingw32.a(lib64_libmingw32_a-crtexewin.o):(.text.startup+0x0): first defined here .../ld/collect-ld: /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libmingw32.a(lib64_libmingw32_a-crtexewin.o):(.text.startup+0xc5): undefined reference to `WinMain' collect2: error: ld returned 1 exit status ... FAIL: LTO 10 for x86_64-w64-mingw32 so that mixing LTO and non-LTO relocatable files for "ld -r" works for both ELF and non-ELF platforms. * ld.texi: Remove "On ELF platforms" from documentation of mixing LTO and non-LTO relocatable files for "ld -r". * ldlang.c (cmdline_load_object_only_section): New. (cmdline_check_object_only_section): Call it. * testsuite/ld-plugin/lto.exp: Enable mixed LTO and non-LTO relocatable output tests for all. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
-rw-r--r--ld/ld.texi14
-rw-r--r--ld/ldlang.c31
-rw-r--r--ld/testsuite/ld-plugin/lto.exp78
3 files changed, 74 insertions, 49 deletions
diff --git a/ld/ld.texi b/ld/ld.texi
index d087743..f6384ad 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1126,13 +1126,13 @@ relocations. Different output formats can have further restrictions; for
example some @code{a.out}-based formats do not support partial linking
with input files in other formats at all.
-On ELF platforms, when the relocatable output contains both contents
-which require link-time optimization (LTO) and contents which don't
-require LTO, a .gnu_object_only section will be created to contain a
-relocatable object file, as if @samp{-r} is applied to all relocatable
-inputs which don't require LTO. When processing a relocatable input
-with a .gnu_object_only section, the linker will extract the
-.gnu_object_only section as a separate input.
+When the relocatable output contains both contents which require
+link-time optimization (LTO) and contents which don't require LTO,
+a .gnu_object_only section will be created to contain a relocatable
+object file, as if @samp{-r} is applied to all relocatable inputs
+which don't require LTO. When processing a relocatable input with
+a .gnu_object_only section, the linker will extract the .gnu_object_only
+section as a separate input.
Note that since @samp{-r} groups some sections from different input files
together, there may be negative impacts on code size and locality in
diff --git a/ld/ldlang.c b/ld/ldlang.c
index b59a079..cf4294d 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -10966,6 +10966,34 @@ cmdline_extract_object_only_section (bfd *abfd)
return name;
}
+/* Load the object-only section. */
+
+static void
+cmdline_load_object_only_section (const char *name)
+{
+ lang_input_statement_type *entry
+ = new_afile (name, lang_input_file_is_file_enum, NULL, NULL);
+
+ if (!entry)
+ abort ();
+
+ ldfile_open_file (entry);
+
+ if (trace_files || verbose)
+ info_msg ("%pI\n", entry);
+
+ if (entry->flags.missing_file
+ || bfd_get_format (entry->the_bfd) != bfd_object)
+ abort ();
+
+ ldlang_add_file (entry);
+
+ if (bfd_link_add_symbols (entry->the_bfd, &link_info))
+ entry->flags.loaded = true;
+ else
+ einfo (_("%F%P: %pB: error adding symbols: %E\n"), entry->the_bfd);
+}
+
/* Check and handle the object-only section. */
void
@@ -10987,8 +11015,7 @@ cmdline_check_object_only_section (bfd *abfd, bool lto)
abort ();
case lto_mixed_object:
filename = cmdline_extract_object_only_section (abfd);
- lang_add_input_file (filename,
- lang_input_file_is_file_enum, NULL);
+ cmdline_load_object_only_section (filename);
break;
case lto_non_ir_object:
case lto_slim_ir_object:
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 2c722b3..556bbe9 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -726,9 +726,29 @@ set lto_run_tests [list \
[list "LTO 3c" \
"-O2 -flto -fuse-linker-plugin tmpdir/lto-3a.o tmpdir/lto-3c.o -Wl,--whole-archive tmpdir/liblto-3.a -Wl,--no-whole-archive tmpdir/liblto-3.a" "" \
{dummy.c} "lto-3d.exe" "lto-3.out" "" "c"] \
+ [list "LTO 4a" \
+ "-O2 -flto -fuse-linker-plugin \
+ -Wl,--no-warn-execstack,--no-error-execstack \
+ tmpdir/lto-4r-a.o" "" \
+ {dummy.c} "lto-4a.exe" "lto-4.out" "" "c"] \
+ [list "LTO 4c" \
+ "-O2 -flto -fuse-linker-plugin \
+ -Wl,--no-warn-execstack,--no-error-execstack \
+ tmpdir/lto-4r-c.o" "" \
+ {dummy.c} "lto-4c.exe" "lto-4.out" "" "c"] \
+ [list "LTO 4d" \
+ "-O2 -flto -fuse-linker-plugin \
+ -Wl,--no-warn-execstack,--no-error-execstack \
+ tmpdir/lto-4r-d.o" "" \
+ {dummy.c} "lto-4d.exe" "lto-4.out" "" "c"] \
[list "LTO 5" \
"-O2 -flto -fuse-linker-plugin tmpdir/lto-5.o" "" \
{dummy.c} "lto-5.exe" "lto-5.out" "" "c"] \
+ [list "LTO 10" \
+ "-O2 -flto -fuse-linker-plugin \
+ -Wl,--no-warn-execstack,--no-error-execstack \
+ tmpdir/lto-10.o" "" \
+ {dummy.c} "lto-10.exe" "lto-10.out" "" "c"] \
[list "LTO 11" \
"-O -flto -fuse-linker-plugin tmpdir/liblto-11.a" "" \
{dummy.c} "lto-11.exe" "lto-11.out" "" "c"] \
@@ -898,29 +918,9 @@ set lto_run_elf_shared_tests [list \
# LTO run-time tests for ELF
set lto_run_elf_tests [list \
- [list "LTO 4a" \
- "-O2 -flto -fuse-linker-plugin \
- -Wl,--no-warn-execstack,--no-error-execstack \
- tmpdir/lto-4r-a.o" "" \
- {dummy.c} "lto-4a.exe" "lto-4.out" "" "c"] \
- [list "LTO 4c" \
- "-O2 -flto -fuse-linker-plugin \
- -Wl,--no-warn-execstack,--no-error-execstack \
- tmpdir/lto-4r-c.o" "" \
- {dummy.c} "lto-4c.exe" "lto-4.out" "" "c"] \
- [list "LTO 4d" \
- "-O2 -flto -fuse-linker-plugin \
- -Wl,--no-warn-execstack,--no-error-execstack \
- tmpdir/lto-4r-d.o" "" \
- {dummy.c} "lto-4d.exe" "lto-4.out" "" "c"] \
[list "LTO 8" \
"-O2 -flto -fuse-linker-plugin tmpdir/lto-8b.o tmpdir/lto-8a.o" "" \
{dummy.c} "lto-8.exe" "lto-8.out" "" "c"] \
- [list "LTO 10" \
- "-O2 -flto -fuse-linker-plugin \
- -Wl,--no-warn-execstack,--no-error-execstack \
- tmpdir/lto-10.o" "" \
- {dummy.c} "lto-10.exe" "lto-10.out" "" "c"] \
[list "LTO TLS IE" \
"-O2 -flto -fuse-linker-plugin" "" \
{run-ie.c} "run-ie.exe" "run-ie.out" "" "c"] \
@@ -1135,31 +1135,29 @@ if { [at_least_gcc_version 4 7] } {
# Run "ld -r" to generate inputs for complex LTO tests.
run_dump_test "lto-3r"
remote_exec host "mv" "tmpdir/dump tmpdir/lto-3.o"
+run_dump_test "lto-4r-a"
+remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-a.o"
+run_dump_test "lto-4r-b"
+remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-b.o"
+run_dump_test "lto-4r-c"
+remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-c.o"
+run_dump_test "lto-4r-d"
+remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-d.o"
run_dump_test "lto-5r"
remote_exec host "mv" "tmpdir/dump tmpdir/lto-5.o"
-if { [is_elf_format] } {
- run_dump_test "lto-4r-a"
- remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-a.o"
- run_dump_test "lto-4r-b"
- remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-b.o"
- run_dump_test "lto-4r-c"
- remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-c.o"
- run_dump_test "lto-4r-d"
- remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-d.o"
- run_dump_test "lto-10r"
- remote_exec host "mv" "tmpdir/dump tmpdir/lto-10.o"
- set testname "nm mixed object"
- set lto_plugin [string trim [run_host_cmd "$CC_FOR_TARGET" "-print-prog-name=liblto_plugin.so"]]
- if { [ regexp "liblto_plugin.so" $lto_plugin ] } {
- set exec_output [run_host_cmd "$NM" "--plugin $lto_plugin tmpdir/lto-10.o"]
- if { [ regexp "(D|T) main" $exec_output ] } {
- pass $testname
- } else {
- fail $testname
- }
+run_dump_test "lto-10r"
+remote_exec host "mv" "tmpdir/dump tmpdir/lto-10.o"
+set testname "nm mixed object"
+set lto_plugin [string trim [run_host_cmd "$CC_FOR_TARGET" "-print-prog-name=liblto_plugin.so"]]
+if { [ regexp "liblto_plugin.so" $lto_plugin ] } {
+ set exec_output [run_host_cmd "$NM" "--plugin $lto_plugin tmpdir/lto-10.o"]
+ if { [ regexp "(D|T) main" $exec_output ] } {
+ pass $testname
} else {
fail $testname
}
+} else {
+ fail $testname
}
run_cc_link_tests $lto_link_symbol_tests