Bug 23930 - Problems linking objectfiles optimized for size (-Os)
Summary: Problems linking objectfiles optimized for size (-Os)
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.29
: P2 normal
Target Milestone: 2.32
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-28 16:06 UTC by Artem Savkov
Modified: 2018-12-01 14:41 UTC (History)
1 user (show)

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


Attachments
Reproducer (568 bytes, application/gzip)
2018-11-28 16:06 UTC, Artem Savkov
Details
A workaround (1.90 KB, patch)
2018-11-28 23:38 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Artem Savkov 2018-11-28 16:06:25 UTC
Created attachment 11416 [details]
Reproducer

The issue was found while building linux kernel with CONFIG_CC_OPTIMIZE_FOR_SIZE (adds -Os to cflags) and KCFLAGS="-ffunction-sections", while linking vmlinux I get the fillowing warnings and error:

  ld: warning: dot moved backwards before `.text.__startup_secondary_64'
  ld: warning: dot moved backwards before `.text.__startup_secondary_64'
  ld: final link failed: File truncated
  make: *** [Makefile:1032: vmlinux] Error 1                                       

.iplt section seem to cause issues during linking. This is only reproducible when vmas and lmas are different, failing section sh_addralign is 1(caused by -Os) and .iplt is before failing section and the section offset needs to be just right. I am attaching a small reproducer that I managed to put together based on linux kernel linker script [1].

This is what I see happening:
.iplt does not have ignored flag set on first pass of one_lang_size_sections_pass() but has it set on subsequent passes, this results in dot of the following section moving backwards, resulting in a warning and section lma not being set properly which later results in s_start being set to a negative value in assign_file_positions_for_load_sections() yielding a "File truncated" error.

I have bisected this issue to the following commit: 38b123494b "x86-64: Improve PLT generation and synthetic PLT symbols"

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/vmlinux.lds.S
Comment 1 H.J. Lu 2018-11-28 23:38:45 UTC
Created attachment 11418 [details]
A workaround

The bug is in ldlang.c.  In the meantime, please try this workaround in
x86 backend.
Comment 2 Artem Savkov 2018-11-29 08:51:31 UTC
The workaround fixes both the reproducer and original kernel build for me.
Comment 3 H.J. Lu 2018-11-30 13:57:39 UTC
This is the patch:

https://sourceware.org/ml/binutils/2018-11/msg00279.html

I will check in.
Comment 4 Sourceware Commits 2018-12-01 14:39:31 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=b44ee3a8cf21294eeb079ffbada7eeb559a9c6b4

commit b44ee3a8cf21294eeb079ffbada7eeb559a9c6b4
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Dec 1 05:42:33 2018 -0800

    x86: Delay setting the iplt section alignment
    
    Delay setting its alignment until we know it is non-empty.  Otherwise an
    empty iplt section may change vma and lma of the following sections, which
    triggers moving dot of the following section backwards, resulting in a
    warning and section lma not being set properly.  It later leads to a
    "File truncated" error.
    
    bfd/
    
    	PR ld/23930
    	* elfxx-x86.c (_bfd_x86_elf_size_dynamic_sections): Update
    	the iplt section alignment if it is non-empty.
    	(_bfd_x86_elf_link_setup_gnu_properties): Set plt.iplt_alignment
    	and delay setting the iplt section alignment.
    	* elfxx-x86.h (elf_x86_plt_layout): Add iplt_alignment.
    
    ld/
    
    	PR ld/23930
    	* testsuite/ld-i386/i386.exp: Run pr23930.
    	* testsuite/ld-i386/pr23930.d: New file.
    	* testsuite/ld-x86-64/pr23930-32.t: Likewise.
    	* testsuite/ld-x86-64/pr23930-x32.d: Likewise.
    	* testsuite/ld-x86-64/pr23930.d: Likewise.
    	* testsuite/ld-x86-64/pr23930.t: Likewise.
    	* testsuite/ld-x86-64/pr23930a.s: Likewise.
    	* testsuite/ld-x86-64/pr23930b.s: Likewise.
    	* testsuite/ld-x86-64/x86-64.exp: Run pr23930 and pr23930-x32.
Comment 5 H.J. Lu 2018-12-01 14:41:55 UTC
Fixed for 2.32.