July 04, 2014
https://issues.dlang.org/show_bug.cgi?id=879

--- Comment #17 from David Nadlinger <code@klickverbot.at> ---
(In reply to Martin Nowak from comment #15)
> ModuleInfos are exported global symbols, so the linker should not remove them.

I was under the impression that --gc-sections indeed does this when linking an executable. Default visibility on its own is not enough to keep a symbol (and thus its section) alive, unless it is required to resolve an undefined symbol from a linked shared object. Maybe we have a different understanding of what an "exported symbol" is, though.

(In reply to Martin Nowak from comment #16)
> Another problem that I have is that ld.gold with --gc-sections doesn't copy the .minfo_beg/.minfo_end sections from an archive object, so it breaks the section brackets even when all .minfo* sections are pinned.

What precisely do you refer to as "archive object"? An object file pulled in from a static library? As we discussed a while ago, for LDC I currently emit one unique global ctor per object file (as we emit one section per text/data symbol like -ffunction-sections, this is not quite as bad as it maybe would be for dmd -lib, even though still a bit wasteful). As .ctors are roots for the linker's live section graph, I can conveniently pin the bracketing symbols as well as the ModuleInfo reference itself that way.

The whole "design" was purely a workaround for LLVM bugs/limitations, but it lead to LDC passing the test suite [*] using both ld.bfd and ld.gold without too much effort. As mentioned above, LDC currently generates quite a bit of cruft in the executable due to unneeded symbols in .minfo_beg/.minfo_end and all the duplicate global ctors, but it's still better than not being able to use --gc-sections at all. On Linux x86_64, our static release-mode binaries are on average 1/4 the size of DMD's for small programs now (Git master vs. Git master, which isn't entirely fair because we are still on 2.065, of course).


[*] Except for the module conflict check in druntime being broken due to copy relocations.

--
July 05, 2014
https://issues.dlang.org/show_bug.cgi?id=879

--- Comment #18 from Martin Nowak <code@dawg.eu> ---
(In reply to David Nadlinger from comment #17)
> I was under the impression that --gc-sections indeed does this when linking an executable. Default visibility on its own is not enough to keep a symbol (and thus its section) alive, unless it is required to resolve an undefined symbol from a linked shared object. Maybe we have a different understanding of what an "exported symbol" is, though.

Right, gc-sections doesn't care about visibility, but the ModuleInfos are not emitted to individual sections (.rodata or .text) so they won't get removed unless they are the only symbols in .rodata/.text.

> (In reply to Martin Nowak from comment #16)
> > Another problem that I have is that ld.gold with --gc-sections doesn't copy the .minfo_beg/.minfo_end sections from an archive object, so it breaks the section brackets even when all .minfo* sections are pinned.
> 
> What precisely do you refer to as "archive object"? An object file pulled in from a static library?

Yes, object files from an archive. It's probably the same for normal objects. With --gc-sections the ld.gold linker seems to only copy sections that contain referenced symbols. I can also reference .minfo_beg/.minfo/.minfo_end in each ctor, but for some reason the order for the output sections isn't preserved.

> On Linux x86_64, our static release-mode binaries
> are on average 1/4 the size of DMD's for small programs now

Interesting, dmd uses a section per function by default, but for unknown reasons --gc-sections doesn't have a huge effect. https://github.com/D-Programming-Language/dmd/pull/3597#issuecomment-44671223

I'd like to give the linker as good information as possible. For example when a functions isn't used the linker should strip the associated EH data. Likewise ModuleInfo is needed only when any data or function of a module end up in a DSO.

--
July 05, 2014
https://issues.dlang.org/show_bug.cgi?id=879

--- Comment #19 from Martin Nowak <code@dawg.eu> ---
(In reply to Martin Nowak from comment #18)
> I can also reference .minfo_beg/.minfo/.minfo_end in each ctor.

Actually this doesn't work with ld.gold because dmd only uses a single ctor per DSO (COMDAT) and ld.gold will merge the ctors before checking their references. So I only end up with the .minfo* sections of the first object file.

--
July 05, 2014
https://issues.dlang.org/show_bug.cgi?id=879

--- Comment #20 from David Nadlinger <code@klickverbot.at> ---
(In reply to Martin Nowak from comment #19)
> Actually this doesn't work with ld.gold because dmd only uses a single ctor
> per DSO (COMDAT) and ld.gold will merge the ctors before checking their
> references.
> So I only end up with the .minfo* sections of the first object file.

This was the reason for me to switch to emitting one ctor per module (due to an LLVM implementation quirk, the situation was a bit different and I already ran into this problem with ld.bfd, but it was more or less the same). Of course, it's an ugly and hacky approach, but it seems to work for now.

The more beautiful option (doesn't apply to the pin-required-EH-tables-from-function, of course) seems to be to use a custom linker script for generating the bracketing symbols as well as KEEP()ing the .minfo section. Because of INSERT and implicit linker scripts, this probably could be made to work, but ensuring that this also works with ld.gold and doesn't break any user expectations was a can of worms I decided not to open just yet.

--
July 09, 2014
https://issues.dlang.org/show_bug.cgi?id=879

David Nadlinger <code@klickverbot.at> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|pull                        |

--- Comment #21 from David Nadlinger <code@klickverbot.at> ---
There is an additional complication: ld.bfd turns __bss_start/_end into local symbols when passing --gc-sections. This breaks the module collision check in druntime, as discussed here: http://forum.dlang.org/post/ferkvfamznsuhonokhco@forum.dlang.org. The linked discussion is about LDC in particular, but from a few preliminary tests, DMD also seems to be affected.

The root cause for this behavior seems to be this change in binutils 2.19: https://sourceware.org/bugzilla/show_bug.cgi?id=13683. It's hard to tell whether this is a bug in ld or not, but either way we'll have to live with it.

ld.gold is not affected.

--
July 09, 2014
https://issues.dlang.org/show_bug.cgi?id=879

--- Comment #22 from David Nadlinger <code@klickverbot.at> ---
(In reply to David Nadlinger from comment #21)
> There is an additional complication: ld.bfd turns __bss_start/_end into local symbols when passing --gc-sections. […]

LDC now uses special weak symbols, strongly defined in the D entry point module, to avoid this problem altogether:

https://github.com/ldc-developers/druntime/commit/f57df3f586ba445b94b167106f82a807c0f1738e https://github.com/ldc-developers/ldc/commit/4abdec752eed1d8eeff116251fdf8c3733927704

--
July 29, 2014
https://issues.dlang.org/show_bug.cgi?id=879

JR <zorael@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |zorael@gmail.com

--
June 09, 2015
https://issues.dlang.org/show_bug.cgi?id=879

Andrei Alexandrescu <andrei@erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|D1 & D2                     |D2

--
February 01, 2016
https://issues.dlang.org/show_bug.cgi?id=879

Marco Leise <Marco.Leise@gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Marco.Leise@gmx.de

--- Comment #23 from Marco Leise <Marco.Leise@gmx.de> ---
Issue persists with dmd-2.070 on amd64. For example compiling dub fails.

--
May 09, 2016
https://issues.dlang.org/show_bug.cgi?id=879

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #24 from Walter Bright <bugzilla@digitalmars.com> ---
DMD on Linux/Elf/OSX now uses Dwarf exception handling info, so the deh sections are no longer an issue.

--