Sourceware Bugzilla – Bug 11539
ld --gc-sections should work for PE-COFF on MinGW
Last modified: 2013-10-17 19:52:40 UTC
ld --gc-sections should work for PE-COFF on MinGW.
MSVC has supported this feature (under the name of /OPT:REF) since time began.
As a result, GCC generates significantly larger executables than MSVC.
Created attachment 5301 [details]
implement --gc-sections for coff (first shot)
- Mostly a copy and paste from elflink.c to cofflink.c
- This is only a first try; however, it reduces the size of a statically compiled wxWidgets app from 5.1 MB to 3.8 MB, so it does something useful for me; YMMV
- I’m by far no COFF export; some linker guru will need to review the patch and comment on all the "FIXME" comments
- I have not yet tried to generate a DLL with gc enabled
- Somehow the entry symbol does not get into _bfd_coff_gc_keep so no gc mark root is available; as a workaround, "-Wl,--undefined=_WinMainCRTStartup" should be used
I changed the Host/Target/Build to include x86_64 and removed the Build specification, because it's not relevant.
This is very useful. A static Qt binary gets from 12MB to 8MB with this.
I found problem with the patch: it will remove the .rsrc section too. This section should be kept, as it contains the application icon, version information, etc.
Created attachment 5960 [details]
Add KEEPs to the linker script template
Very nice. The patch saves me from some boring works splitting source files per function.
- entry symbol
I think "-Wl,-e" works and is better than "-Wl,--undefined" in this case.
For PE-COFF targets, the default entry symbol is used according to the subsystem,
unless explicitly specified by a command-line or a linker script.
And the code setting the gc root (search gc_sym_list in ldlang.c) ignores the linker's default.
MinGW-GCC's default specs file gives -e option to the linker only if the
generating file is a DLL, so for now the linker's default is used for EXE
unless you specify the explicit one.
I don't know whether ignoring the default entry symbol makes sense.
Anyway the current manual says --gc-sections requires -Wl,-e or -Wl,-u
or using KEEPs in a linker script to keep sections.
- .rsrc section
Default linker scripts(generated from pe.sc) lack KEEP commands.
The attached patch may fix it.
It seems to dll build can't use the patches, even if using -Wl,--undefined=_DllMainCRTStartup. Though the dll is generated successfully, we can't use other exes to link the dll (running the exe can't show anything).
How do we make the patches generate the dll correctly?
I try to keep eh_frame section, then the dll build can work (I test it in wxWidgets 2.8.12 Release Mono Unicode Dll).
So we should find some methods to keep some sections of eh_frame.
I was dissatisfied with my DLL size being an order of magnitude bigger than it should be and the search lead me to this bug report. I have just tried the provided patch with binutils-2.23.2 and the initial builds of my statically linked DLL failed with a section named "COMMON" missing. I have changed the cofflink.c to exclude this section from removal and it finally built. However, the functions from my DLL crash so probably something got badly removed. After debugging the removal process by -Wl,--print-gc-sections I also prevented .eh_frame from removal but my application still crashed. At this point I feel only despair as COFF is basically black magic to me. Does anybody work on this feature or have more up to date patches? I would happily do some testing and/or help in other ways.
Found several discussions linking to this page, but none mentioning a somewhat newer patch posted at https://sourceware.org/ml/binutils/2012-08/msg00386.html. Adding that link here for any future readers...