How to combine LTO with symbol versioning
WHOPR Driver Design gives some strong hints to what is going on. The function definitions fun1
and fun2
are not exported according to the version script. The LTO plugin is able to use this information, and since GCC does not peek into the asm
directives, it knows nothing about the .symver
directive, and therefore removes the function definition.
For now, adding __attribute__ ((externally_visible))
is the workaround for this. You also need to build with -flto-partition=none
, so that the .symver
directives do not land by accident in a different intermediate assembler file than the function definition (where it will not have the desired effect).
GCC PR 48200 tracks an enhancement request for symbol versioning at the compiler level, which would likely address this issue as well.
It looks like my externally_visible
fix works. This is:
#define DLLEXPORT __attribute__((visibility("default"),externally_visible))
DLLEXPORT int fun1(void);
Also see: https://gcc.gnu.org/onlinedocs/gccint/WHOPR.html
But I think your versionscript is wrong.
If I take out the visibility overrides and change your versionscript by adding fun1
and fun2
then it works. Like:
v1 {
global:
fun; fun1;
local:
*;
};
v2 {
global:
fun; fun2;
} v1;
The symbol alias targets have to be visible as well as the alias.