This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Is it possible to use a linker script to preserve unreferenced static C++ class instances defined in a static library?
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Bob Mowry <mowry86 at gmail dot com>
- Cc: binutils at sourceware dot org
- Date: Sat, 18 May 2013 09:19:40 +0100
- Subject: Re: Is it possible to use a linker script to preserve unreferenced static C++ class instances defined in a static library?
- References: <CAPJuS5c7cuJTJAkSn5hm1-fGqMN-k3rtdWJm557Ez=xkMKGsFg at mail dot gmail dot com>
Bob Mowry <mowry86@gmail.com> writes:
> I am trying to convert a C++ shared library to be a static library.
> Unfortunately one of the issues I've hit is that this library has some
> code that uses a C++ static initialization trick whereby there are
> static instances of a class that are not referenced beyond where they
> are defined. Subsequently the linker decides to eliminate these
> instances causing the resulting binary to fail to function correctly.
>
> I've spent a few days trying to puzzle out if I can use the KEEP
> linker script directive to instruct the linker to retain these
> unreferenced static C++ class instances. I have read about the
> -Wl,--whole-archive option I could pass to the linker, but I do not
> want to retain everything within the archive (in fact the reason for
> moving to static linking is to allow the linker to drop from the
> resulting binary lots of unused functions/objects reducing the run
> time image size).
>
> Currently I'm using this linker script in an attempt to get the
> linker to keep all items in the .data segment:
>
> SECTIONS
> {
> .data :
> {
> KEEP(*(.data))
> }
> }
>
> But it seems to have no impact. I'm not sure if what I am trying to
> do isn't possible with KEEP or if I'm simply not generating a valid
> linker script. I would appreciate any advice on this topic. I'd also
> like to point out that I'm willing to rename these static instances
> using a pattern that the KEEP statement could match (again if that's
> possible).
If I understand correctly, the linker isn't pulling in the objects you
want from the archive. Is that right? If so, I don't think KEEP will
help here. It doesn't change which objects are pulled in from the archive.
It just says that, if a section was originally scheduled to be linked,
the section mustn't be dropped by things like --gc-sections.
Is the initialisation trick you mention something along the lines of:
struct S { S() { ...magic initialisation...; } }
static S dummyS;
? If so, that would normally be handled by KEEPing things like the
.ctors*, .dtors*, .init_array* and .fini_array* sections. The default
linker script does FWIW.
Have you tried using --whole-archive in combination with --gc-sections?
The archive would need to be compiled with -ffunction-sections
-fdata-sections in order to get the best out of it.
Thanks,
Richard