Bug 19254 - "too many sections" when linking COFF executables
Summary: "too many sections" when linking COFF executables
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-11-17 10:48 UTC by Simon Brenner
Modified: 2016-12-13 17:06 UTC (History)
2 users (show)

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


Attachments
Fix (?) 32-bit handling (447 bytes, patch)
2016-12-02 10:44 UTC, awson
Details | Diff
Section merging for GHC (611 bytes, patch)
2016-12-02 10:46 UTC, awson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Brenner 2015-11-17 10:48:47 UTC
When linking an executable out of many object files with many sections, it seems that if the total number of input sections is larger than COFF/PE's maximum the linking fails.

I would expect those sections to get merged together into a single .text section (and .data etc), and so the final executable should have much less than 32k sections and not risk hitting the limit. I'm guessing the section number limit is checked when loading everything in, before the linker script gets to merge sections?

The objective was to use --gc-sections (e.g. with -ffunction-sections, though in this case actually https://ghc.haskell.org/trac/ghc/ticket/8405), but I don't think that is actually relevant to the problem. Even if you don't GC sections, they should get merged when linking executables as I understand it.

This was using binutils 2.25.1 on mingw/x86_64.
Comment 1 awson 2016-12-02 10:44:57 UTC
Created attachment 9683 [details]
Fix (?) 32-bit handling

Pure technical (and not essential for this ticket) patch, which simply synchronizes 32-bit (pei-i386) scripts with 64-bit (pei-x86-64) ones. I suspect (but am not sure) that 32-bit scripts are currently broken if "gc-sections" is used.
Comment 2 awson 2016-12-02 10:46:36 UTC
Created attachment 9684 [details]
Section merging for GHC

This patch solves the problem for me. It adds sections merging for the sections generated by GHC. I consider this patch as mostly non-intrusive except the one notable case: we no more guard .text.* sections merging case with RELOCATING macro because we need it also for `ld -r` invocation.
Comment 3 Simon Brenner 2016-12-02 12:30:52 UTC
Looked a bit at the pe.sc script in git[1] earlier and there is actually section merging being done there, but for sections named like ".data$*" rather than the ELF convention of ".data.*" - so this could actually be a bug on the GHC side failing to use the platform convention for subsection names.

[1] https://sourceware.org/git/?p=binutils.git;a=blob;f=ld/scripttempl/pe.sc;h=59ce0420d58803b6b7154f6c31b0b016448c4d11;hb=master


It also seems to be intentional on ld's side to not do any section merging for `ld -r` invocations. If the linker is supposed to do that, I think it should be added for ELF too. (GHC currently has to use a custom linker script to get ld -r with section merging.)
Comment 4 awson 2016-12-02 12:58:29 UTC
Good catch of ".data$*" thing, indeed `gcc` on Windows generates `$` instead of `.`, and this, perhaps, would be correct to make GHC do the same thing, but we already have separate handling of `.text.*` sections on Windows. I suspect that this is because there exist another tools from GNU/Unix land, ported to Windows which also use `.` for namespace hierarchy handling.

Regarding `ln -r` I don't think `ELF` case is indicative because `PE-COFF` linking is *very* different.
Comment 5 awson 2016-12-02 13:17:26 UTC
I looked further into it. Sections with '$' separator also not only should be merged into the prefix section, but also should be sorted according to their suffix names. I'm not sure if we need this for GHC-generated case. Moreover, in `ELF` case we have *no* sorting for such sections.
Comment 6 Nick Clifton 2016-12-06 17:34:00 UTC
Hi Guys,

  I am happy to apply the two patches that have been submitted here, as
  long as you are happy with them too.

  I am not sure however about the context for the ELF case that you are
  talking about.  Which ELF based target will produce section names with
  a $ separator ?

Cheers
  Nick
Comment 7 awson 2016-12-06 18:25:43 UTC
Sorry, my miswording. In `ELF` case we have *no* any '$'-separated sections.

What I meant was that (almost)counterpart of PECOFF dollar-separated sections is ELF dot-separated sections, but while PECOFF dollar-separated sections need to be sorted, ELF dot-separated sections need no.
Comment 8 awson 2016-12-06 18:27:37 UTC
And yes, I'm quite happy with the patches.
Comment 9 Sourceware Commits 2016-12-13 17:06:48 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit aa785360cfa271505394080c8e367017782ca57a
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Dec 13 17:05:20 2016 +0000

    PE linker script improvements.
    
    	PR ld/19254
    	* scripttempl/pe.sc (.fini): KEEP this section.
    	(.gcc_except_table): Likewise.
    	(.pdata): Also accept .pdata*.