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.
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.
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.
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.)
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.
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.
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
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.
And yes, I'm quite happy with the patches.
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*.