Bug 12291 - "ld -r" doesn't work with mixed IR/non-IR objects
Summary: "ld -r" doesn't work with mixed IR/non-IR objects
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: H.J. Lu
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-06 22:28 UTC by H.J. Lu
Modified: 2025-01-13 21:27 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2010-12-06 22:28:36 UTC
[hjl@gnu-6 pr-1]$ cat foo.c
#include <stdio.h>

void foo(void)
{
  printf ("hello foo\n");
}
[hjl@gnu-6 pr-1]$ cat main.c
extern void foo(void);

int main(void)
{
  foo();
  return 0;
}
[hjl@gnu-6 pr-1]$ make
/usr/gcc-4.6/bin/gcc -B./ -c -O -flto -fuse-linker-plugin main.c -o main.o
/usr/gcc-4.6/bin/gcc -B./ -c -O foo.c -o foo.o
./ld -r -o prog.o main.o foo.o
/usr/gcc-4.6/bin/gcc -B./ -flto -fuse-linker-plugin prog.o -o prog
/tmp/ccAWLRVh.ltrans0.ltrans.o: In function `main':
ccAWLRVh.ltrans0.o:(.text.startup+0x5): undefined reference to `foo'
collect2: ld returned 1 exit status
make: *** [prog] Error 1
[hjl@gnu-6 pr-1]$
Comment 1 H.J. Lu 2010-12-06 23:01:17 UTC
One approach

--
We generate a prog.o that contains an object that is the relocation of real foo.o and main.o (used if prog.o is linked without IR support), that also contains IR for main.o, and within the IR the object code for main.o.  So the interesting case is when the relocatable object is again compiled in such a way that the IR is read out from prog.o.  The Intel compiler will take the IR from prog.o, and compile it with any other IR present in archives or other objects (none in this particular case), and will create a real object from the IR, this is then added to a list of objects that the driver will pass to the linker along with the object code for main.o which the compiler extracts to a new temporary object that is added to the list of objects.
--
Comment 2 H.J. Lu 2010-12-15 19:17:03 UTC
The proposal is at

http://www.kernel.org/pub/linux/devel/gcc/lto/mixed-IR/mixed-IR.pdf

It is implemented on hjl/lto-mixed branch at

http://git.kernel.org/?p=devel/binutils/hjl/x86.git;a=summary
Comment 3 Dmitry Gorbachev 2011-01-21 21:55:59 UTC
ld.ian (gold with patch <http://sourceware.org/ml/binutils/2011-01/msg00270.html>) silently uses non-IR part of prog.o
Comment 4 H.J. Lu 2011-01-21 22:27:45 UTC
(In reply to comment #3)
> ld.ian (gold with patch
> <http://sourceware.org/ml/binutils/2011-01/msg00270.html>) silently uses non-IR
> part of prog.o

What does gold generate for

/usr/gcc-4.6/bin/gcc -B./ -c -O -flto -fuse-linker-plugin main.c -o main.o
/usr/gcc-4.6/bin/gcc -B./ -c -O foo.c -o foo.o
./ld -r -o prog.o main.o foo.o

Does prog.o contain both IR and non-IR sections?
Comment 5 Dmitry Gorbachev 2011-01-22 00:43:24 UTC
> Does prog.o contain both IR and non-IR sections?

No. I think a new bug report should be opened for gold.

When I use ld.bfd (or ld.hjl) for partial link step and ld.ian for final link, everything works.
Comment 6 H.J. Lu 2020-10-13 14:07:15 UTC
(In reply to H.J. Lu from comment #2)
> The proposal is at
> 
> http://www.kernel.org/pub/linux/devel/gcc/lto/mixed-IR/mixed-IR.pdf

Here is the proposal:

Link with mixed IR/non-IR objects

* 2 kinds of object files
  o non-IR object file has
    * non-IR sections
  o IR object file has
    * IR sections
    * non-IR sections
    * The output of "ld -r" with mixed IR/non-IR objects should work with:
        o Compilers/linkers with IR support.
	o Compilers/linkers without IR support.
* Add the mixed object file which has
  o IR sections
  o non-IR sections:
    * Object codes from IR sections.
    * Object codes from non-IR object files.
  o Object-only section:
    * With section name ".gnu_object_only" and SHT_GNU_OBJECT_ONLY type
    on ELF:
    #define SHT_GNU_OBJECT_ONLY 0x6ffffff8	/* Object only */
    * Contain non-IR object file.
    * Input is discarded after link.
* Linker action:
  o Classify each input object file:
    * If there is a ".gnu_object_only" section, it is a mixed object file.
    * If there is a IR section, it is an IR object file.
    * Otherwise, it is a non-IR object file.
  o Relocatable non-IR link:
    * Prepare for an object-only output.
    * Prepare for a regular output.
    * For each mixed object file:
      * Add IR and non-IR sections to the regular output.
      * For object-only section:
	* Extract object only file.
	* Add it to the object-only output.
	* Discard object-only section.
    * For each IR object file:
      * Add IR and non-IR sections to the regular output.
    * For each non-IR object file:
      * Add non-IR sections to the regular output.
      * Add non-IR sections to the object-only output.
    * Final output:
      * If there are IR objects, non-IR objects and the object-only
      output isn't empty:
	* Put the object-only output into the object-only section.
	* Add the object-only section to the regular output.
	* Remove the object-only output.
  o Normal link and relocatable IR link:
    * Prepare for output.
    * IR link:
      * For each mixed object file:
	* Compile and add IR sections to the output.
	* Discard non-IR sections.
	* Object-only section:
	  * Extract object only file.
	  * Add it to the output.
	  * Discard object-only section.
      * For each IR object file:
        * Compile and add IR sections to the output.
	* Discard non-IR sections.
      * For each non-IR object file:
	* Add non-IR sections to the output.
    * Non-IR link:
      * For each mixed object file:
	* Add non-IR sections to the output.
	* Discard IR sections and object-only section.
      * For each IR object file:
	* Add non-IR sections to the output.
	* Discard IR sections.
      * For each non-IR object file:
	* Add non-IR sections to the output.

> 
> It is implemented on hjl/lto-mixed branch at
> 
> http://git.kernel.org/?p=devel/binutils/hjl/x86.git;a=summary

It has been moved at:

https://gitlab.com/x86-binutils/binutils-gdb/-/tree/users/hjl/lto-mixed/master
Comment 7 Nick Clifton 2020-10-20 16:23:46 UTC
Hi H.J.

(In reply to H.J. Lu from comment #6)

> Here is the proposal:

> It has been moved at:
> 
> https://gitlab.com/x86-binutils/binutils-gdb/-/tree/users/hjl/lto-mixed/
> master

I like the proposal.

Do you think that the branch sources are ready for review and 
merging/pulling into mainline ?

Cheers
  Nick
Comment 8 H.J. Lu 2020-10-20 17:15:00 UTC
(In reply to Nick Clifton from comment #7)
> Hi H.J.
> 
> (In reply to H.J. Lu from comment #6)
> 
> > Here is the proposal:
> 
> > It has been moved at:
> > 
> > https://gitlab.com/x86-binutils/binutils-gdb/-/tree/users/hjl/lto-mixed/
> > master
> 
> I like the proposal.
> 
> Do you think that the branch sources are ready for review and 
> merging/pulling into mainline ?
> 

Yes, I will submit a patch set.
Comment 9 Sam James 2022-07-22 22:28:46 UTC
(In reply to H.J. Lu from comment #8)
> (In reply to Nick Clifton from comment #7)
> > Hi H.J.
> > 
> > (In reply to H.J. Lu from comment #6)
> > 
> > > Here is the proposal:
> > 
> > > It has been moved at:
> > > 
> > > https://gitlab.com/x86-binutils/binutils-gdb/-/tree/users/hjl/lto-mixed/
> > > master
> > 
> > I like the proposal.
> > 
> > Do you think that the branch sources are ready for review and 
> > merging/pulling into mainline ?
> > 
> 
> Yes, I will submit a patch set.

Did anything happen w/ this? Thanks!
Comment 11 Sourceware Commits 2025-01-13 21:27:13 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 9b854f169df9b9853dc7284114beca8d8ab4f99f
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Nov 4 09:17:45 2013 -0800

    ld: Add LTO and none-LTO output support for ld -r
    
    Link with mixed IR/non-IR objects
    
    * 2 kinds of object files
      o non-IR object file has
        * non-IR sections
      o IR object file has
        * IR sections
        * non-IR sections
        * The output of "ld -r" with mixed IR/non-IR objects should work with:
            o Compilers/linkers with IR support.
            o Compilers/linkers without IR support.
    * Add the mixed object file which has
      o IR sections
      o non-IR sections:
        * Object codes from IR sections.
        * Object codes from non-IR object files.
      o Object-only section:
        * With section name ".gnu_object_only" and SHT_GNU_OBJECT_ONLY type
        on ELF:
        https://gitlab.com/x86-psABIs/Linux-ABI
        #define SHT_GNU_OBJECT_ONLY 0x6ffffff8      /* Object only */
        * Contain non-IR object file.
        * Input is discarded after link.
    * Linker action:
      o Classify each input object file:
        * If there is a ".gnu_object_only" section, it is a mixed object file.
        * If there is a IR section, it is an IR object file.
        * Otherwise, it is a non-IR object file.
      o Relocatable non-IR link:
        * Prepare for an object-only output.
        * Prepare for a regular output.
        * For each mixed object file:
          * Add IR and non-IR sections to the regular output.
          * For object-only section:
            * Extract object only file.
            * Add it to the object-only output.
            * Discard object-only section.
        * For each IR object file:
          * Add IR and non-IR sections to the regular output.
        * For each non-IR object file:
          * Add non-IR sections to the regular output.
          * Add non-IR sections to the object-only output.
        * Final output:
          * If there are IR objects, non-IR objects and the object-only
          output isn't empty:
            * Put the object-only output into the object-only section.
            * Add the object-only section to the regular output.
            * Remove the object-only output.
      o Normal link and relocatable IR link:
        * Prepare for output.
        * IR link:
          * For each mixed object file:
            * Compile and add IR sections to the output.
            * Discard non-IR sections.
            * Object-only section:
              * Extract object only file.
              * Add it to the output.
              * Discard object-only section.
          * For each IR object file:
            * Compile and add IR sections to the output.
            * Discard non-IR sections.
          * For each non-IR object file:
            * Add non-IR sections to the output.
        * Non-IR link:
          * For each mixed object file:
            * Add non-IR sections to the output.
            * Discard IR sections and object-only section.
          * For each IR object file:
            * Add non-IR sections to the output.
            * Discard IR sections.
          * For each non-IR object file:
            * Add non-IR sections to the output.
    
    This is useful for Linux kernel build with LTO.
    
    bfd/
    
            PR ld/12291
            PR ld/12430
            PR ld/13298
            * bfd.c (bfd_lto_object_type): Add lto_mixed_object.
            (bfd): Add object_only_section.
            (bfd_group_signature): New.
            * elf.c (special_sections_g): Add .gnu_object_only.
            * format.c: Include "plugin-api.h" and "plugin.h" if
            BFD_SUPPORTS_PLUGINS is defined.
            (bfd_set_lto_type): Set type to lto_mixed_object for
            GNU_OBJECT_ONLY_SECTION_NAME section.
            (bfd_check_format_matches): Don't check the plugin target twice
            if the plugin target is explicitly specified.
            * opncls.c (bfd_extract_object_only_section): New.
            * plugin.c (bfd_plugin_fake_text_section): New.
            (bfd_plugin_fake_data_section): Likewise.
            (bfd_plugin_fake_bss_section): Likewise.
            (bfd_plugin_fake_common_section): Likewise.
            (bfd_plugin_get_symbols_in_object_only): Likewise.
            * plugin.c (add_symbols): Call
            bfd_plugin_get_symbols_in_object_only and count
            plugin_data->object_only_nsyms.
            (bfd_plugin_get_symtab_upper_bound): Count
            plugin_data->object_only_nsyms.
            bfd_plugin_get_symbols_in_object_only and add symbols from
            object only section.
            (bfd_plugin_canonicalize_symtab): Remove fake_section,
            fake_data_section, fake_bss_section and fake_common_section.
            Set udata.p to NULL.  Use bfd_plugin_fake_text_section,
            bfd_plugin_fake_data_section, bfd_plugin_fake_bss_section and
            bfd_plugin_fake_common_section.
            Set udata.p to NULL.
            * plugin.h (plugin_data_struct): Add object_only_nsyms and
            object_only_syms.
            * section.c (GNU_OBJECT_ONLY_SECTION_NAME): New.
            * bfd-in2.h: Regenerated.
    
    binutils/
    
            PR ld/12291
            PR ld/12430
            PR ld/13298
            * objcopy.c (group_signature): Removed.
            (is_strip_section): Replace group_signature with
            bfd_group_signature.
            (setup_section): Likewise.
            * readelf.c (get_os_specific_section_type_name): Handle
            SHT_GNU_OBJECT_ONLY.
    
    gas/
    
            PR ld/12291
            PR ld/12430
            PR ld/13298
            * testsuite/gas/elf/section9.s: Add the .gnu_object_only test.
            * testsuite/gas/elf/section9.d: Updated.
    
    include/
    
            PR ld/12291
            PR ld/12430
            PR ld/13298
            * elf/common.h (SHT_GNU_OBJECT_ONLY): New.
    
    ld/
    
            PR ld/12291
            PR ld/12430
            PR ld/13298
            * ld.h (ld_config_type): Add emit_gnu_object_only and
            emitting_gnu_object_only.
            * ldelf.c (orphan_init_done): Make it file scope.
            (ldelf_place_orphan): Rename hold to orig_hold.  Initialize hold
            from orig_hold at run-time.
            (ldelf_finish): New.
            * ldelf.h (ldelf_finish): New.
            * ldexp.c (ldexp_init): Take a bfd_boolean argument to supprt
            object-only output.
            (ldexp_finish): Likewise.
            * ldexp.h (ldexp_init): Take a bfd_boolean argument.
            (ldexp_finish): Likewise.
            * ldfile.c (ldfile_try_open_bfd): Call
            cmdline_check_object_only_section.
            * ldlang.c: Include "ldwrite.h" and elf-bfd.h.
            * ldlang.c (cmdline_object_only_file_list): New.
            (cmdline_object_only_archive_list): Likewise.
            (cmdline_temp_object_only_list): Likewise.
            (cmdline_lists_init): Likewise.
            (cmdline_list_new): Likewise.
            (cmdline_list_append): Likewise.
            (print_cmdline_list): Likewise.
            (cmdline_on_object_only_archive_list_p): Likewise.
            (cmdline_object_only_list_append): Likewise.
            (cmdline_get_object_only_input_files): Likewise.
            (cmdline_arg): Likewise.
            (setup_section): Likewise.
            (copy_section): Likewise.
            (cmdline_fopen_temp): Likewise.
            (cmdline_add_object_only_section): Likewise.
            (cmdline_emit_object_only_section): Likewise.
            (cmdline_extract_object_only_section): Likewise.
            (cmdline_check_object_only_section): Likewise.
            (cmdline_remove_object_only_files): Likewise.
            (lang_init): Take a bfd_boolean argument to supprt object-only
            output.  Call cmdline_lists_init.
            (load_symbols): Call cmdline_on_object_only_archive_list_p
            to check if an archive member should be loaded.
            (lang_process): Handle object-only link.
            * ldlang.h (lang_init): Take a bfd_boolean argument.
            (cmdline_enum_type): New.
            (cmdline_header_type): Likewise.
            (cmdline_file_type): Likewise.
            (cmdline_bfd_type): Likewise.
            (cmdline_union_type): Likewise.
            (cmdline_list_type): Likewise.
            (cmdline_emit_object_only_section): Likewise.
            (cmdline_check_object_only_section): Likewise.
            (cmdline_remove_object_only_files): Likewise.
            * ldmain.c (main): Call xatexit with
            cmdline_remove_object_only_files.  Pass FALSE to lang_init,
            ldexp_init and ldexp_finish.  Use ld_parse_linker_script.
            Set link_info.output_bfd to NULL after close.  Call
            cmdline_emit_object_only_section if needed.
            (add_archive_element): Call cmdline_check_object_only_section.
            (ld_parse_linker_script): New.
            * ldmain.h (ld_parse_linker_script): New.
            * plugin.c (plugin_maybe_claim): Call
            cmdline_check_object_only_section on claimed IR files.
            * scripttempl/elf.sc: Also discard .gnu_object_only sections.
            * scripttempl/elf64hppa.sc: Likewise.
            * scripttempl/elfxtensa.sc: Likewise.
            * scripttempl/mep.sc: Likewise.
            * scripttempl/pe.sc: Likewise.
            * scripttempl/pep.sc: Likewise.
            * emultempl/aarch64elf.em (gld${EMULATION_NAME}_finish): Replace
            finish_default with ldelf_finish.
            * emultempl/alphaelf.em (alpha_finish): Likewise.
            * emultempl/avrelf.em (avr_finish): Likewise.
            * emultempl/elf.em (ld_${EMULATION_NAME}_emulation): Likewise.
            * emultempl/ppc32elf.em (ppc_finish): Likewise.
            * emultempl/ppc64elf.em (gld${EMULATION_NAME}_finish): Likewise.
            * emultempl/spuelf.em (gld${EMULATION_NAME}_finish): Likewise.
            * testsuite/ld-plugin/lto-10.out: New file.
            * testsuite/ld-plugin/lto-10a.c: Likewise.
            * testsuite/ld-plugin/lto-10b.c: Likewise.
            * testsuite/ld-plugin/lto-10r.d: Likewise.
            * testsuite/ld-plugin/lto-4.out: Likewise.
            * testsuite/ld-plugin/lto-4a.c: Likewise.
            * testsuite/ld-plugin/lto-4b.c: Likewise.
            * testsuite/ld-plugin/lto-4c.c: Likewise.
            * testsuite/ld-plugin/lto-4r-a.d: Likewise.
            * testsuite/ld-plugin/lto-4r-b.d: Likewise.
            * testsuite/ld-plugin/lto-4r-c.d: Likewise.
            * testsuite/ld-plugin/lto-4r-d.d: Likewise.
            * testsuite/ld-plugin/lto.exp (lto_link_tests): Prepare for
            "LTO 4[acd]", "lto-4r-[abcd]" and "LTO 10" tests.
            (lto_run_tests): Add "LTO 4[acd]" and "LTO 10" tests.
            Build liblto-4.a.  Run "lto-4r-[abcd]" tests.
            Run lto-10r and create tmpdir/lto-10.o.
            Add test for nm on mixed LTO/non-LTO object.
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Comment 12 Sourceware Commits 2025-01-13 21:27:23 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 04cd256685fae4bf54beec1a461298e8fc574890
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Oct 27 06:39:59 2020 -0700

    h8300: Handle .gnu_object_only section
    
            PR ld/12291
            PR ld/12430
            PR ld/13298
            * config/tc-h8300.c (h8300_elf_section): Handle .gnu_object_only
            section.