On 9/24/19 2:59 PM, Neil Horman wrote:
> On Tue, Sep 24, 2019 at 12:25:35PM +0200, Bruce Richardson wrote:
>> On Tue, Sep 24, 2019 at 08:46:25AM +0200, Andrzej Ostruszka wrote:
>>> On 9/23/19 6:13 PM, Bruce Richardson wrote:
[...]
>> The real issue seems to be that the compat.h header has different
>> compilation paths for static and shared libraries, which means that any C
>> file including it can't have a .o file that can be used for both a .a and a
>> .so simultaneously. Having it default to the shared library path seems to
>> work fine thus far, but with LTO it seems broken as you say. Adding Neil as
>> the original file author of this in case he has any suggestions here. I'd
>> really rather not have to go back to building .a's and .so's separately.
>>
> The notion of using the same object file to link to a static archive and a dso
> seems somewhat suspect to me in general.
I'd think so too ... but there might be something fishy with gcc here.
More on this below.

[...]
> That said, if the goal is to just overcome this particular situation, it might
> (strong might), be sufficient to simply augment the MAP_STATIC_SYMBOL macro in
> the CONFIG_RTE_BUILD_SHARED_LIB=n case to append the 'used' attribute.
> Ostensibly, LTO would be smart enough then to not eliminate the symbol?  Just 
> a
> thought.
Just to clarify things here is the current status in a nutshell.
1. The make based build work with LTO (both static and shared).  It is
using CONFIG_*_SHARED_LIB option and thus different paths of
rte_compat.h are used.

2. The meson build is not using config and has "SHARED" fixed to "y" in
config/rte_config.h.  This works and produces:
- shared library that is working when linking both w/ and w/o LTO
- static library that is only working when linking w/o LTO - when
linking with LTO then it complains about missing symbols for which
different symbol versions are defined.

Augmenting MAP_STATIC_SYMBOL won't help since it is not used at all in
meson build.

I've played around with couple ideas.  Some of them might sound stupid
for you - but I'll report them anyway

Modifying symbol tables
-----------------------
I thought that since problems are only with versioned symbols then I'll
try to modify the symbols tables archives so they look like in "static
make" case e.g. (for just one symbol):

$ objcopy --strip-symbol=rte_timer_subsystem_init@DPDK_2.0 \
        --redefine-sym \
rte_timer_subsystem_init@@DPDK_19.05=rte_timer_subsystem_init \
        librte_timer.a

After this the symbol table looks like in fully static case but this
doesn't work so I'm pretty sure that when using LTO linker does not
check the symbol table at all and just looks in "lto" sections.

Adding static macro
-------------------
I've added for the shared case macro:
#define MAP_STATIC_SYMBOL(f, p) f \
        __attribute__((alias(RTE_STR(p)),weak))
with the idea that maybe during linking against *.a versioned symbols
are not taken into account and if I add weak non-versioned symbol then
it will be used when linking against *.a and when linking against *.so
the strong versioned one will be used.  This thinking is in contrast
with the fact that meson build works w/o LTO where only versioned
symbols are present in those problematic libs :) - and it doesn't work.
Linker reports multiple definitions.

So adding these two together it seems to me that:
a) gcc is using only internal "lto" sections when linking with LTO
b) gcc is storing those versioned symbols in those "lto" sections
c) when linking w/ LTO against archives is not capable to use those
versioned symbols in "lto" sections
d) when linking w/ LTO against shared libraries is capable to use
versioned symbols from "lto" sections
e) when linking w/o LTO against archive is capable to use versioned
symbols from global symbol table (in contrast with point 'c' above)

I'd appreciate some input from those who know gcc internals.  In the
meantime I'll try to come up with minimal example and follow up on gcc
related lists/groups.

Regards
Andrzej

Reply via email to