> Hi Jan, > > I'm using GNU ld 2.33.1. > > I'll attach a testcase simplified from fuse-3.9 code. "local: *;" in the > versioning script triggers the issue. Without it there would be no problem.
Thanks. You are right that I did not play with local:. Now I wonder what is the intended behaviour here. In resolution file I see: 1 foo.o 4 205 dc8dc21a4ac8d072 PREVAILING_DEF_IRONLY_EXP foo_v1 207 dc8dc21a4ac8d072 PREVAILING_DEF_IRONLY foo@VERS_1 216 dc8dc21a4ac8d072 PREVAILING_DEF_IRONLY foo_v2 218 dc8dc21a4ac8d072 PREVAILING_DEF_IRONLY foo@@VERS_2 If I link the DSO w/o -flto I get with objdump -T: 0000000000001100 g DF .text 0000000000000006 (VERS_1) foo 0000000000001100 g DF .text 0000000000000006 VERS_2 foo_v1 0000000000000000 g DO *ABS* 0000000000000000 VERS_1 VERS_1 0000000000001110 g DF .text 0000000000000006 VERS_2 foo 0000000000000000 g DO *ABS* 0000000000000000 VERS_2 VERS_2 So I think linker is right here that foo_v1 is exported. I would have expected PREVAILING_DEF_IRONLY_EXP for foo@VERS_1 and foo@@VERS_2 since that symbols do get exported even though they land in special way in the DSO symbol table. So I think meaingful behaviour would be 1) make linker plugin interface to not annotate symbol version symbols with any resolution at all, since they are "special" 2) make them PREVAILING_DEF_IRONLY_EXP/PREVAILING_DEF since they always get exported to non-LTO land. We could workaround that on GCC side but if you agree with this understanding I would fill in binutils PR. Also since we use resolution info at many places, I would simply add logic working around this at a time we read resolution rahter than on one of places we use it. Comparing to objedump -T 0000000000001100 g DF .text 0000000000000006 VERS_2 foo_v1 0000000000000000 g DO *ABS* 0000000000000000 VERS_1 VERS_1 0000000000000000 g DO *ABS* 0000000000000000 VERS_2 VERS_2 Why we also miss 0000000000001100 g DF .text 0000000000000006 (VERS_1) foo and what does it mean? I am not too happy about forcing GCC to keep foo_v2 exported when it is not. For example, calls to foo_v2 will then not be optimized as they could if GCC knew it is not used by non-LTO world (except for fact that symver is bound to it). Would it be equivalent to: 1) output foo_v2 local 2) producing static alias with local name (.L1) 3) do .symver .L1,foo@@@VERS_2 That is somewhat more systematic and would not lead to false visibilities. Honza > > > > 2. The actual function body implementing the symver-ed function is also > > > marked > > > as PREVAILING_DEF_IRONLY and then removed or marked as local. So no > > > ".globl" > > > directive is outputed for it. > > > > Here is the symver-ed function exported from the DSO (or is it set > > to have hidden attribute)? > > Again this was working for me, so it would be good to understand this > > issue. > > It's also triggered by "local: *;". > > Untar the attachment and use "make" to build it, then "make show-dynamic-syms" > to dump the dynamic symbol table. I believe (with 99% chance) you'll see only > foo (VERS_1) and foo_v1 (because foo_v1 is marked as global in the version > script). And foo (VERS_2) would be missing. With this patch foo (VERS_2) > would > show up. > > We can't mark "foo_v2" to be "global" because it should not be a part of DSO > ABI. > > The other 1% chance would be a regression in Binutils. > -- > Xi Ruoyao <xry...@mengyan1223.wang> > School of Aerospace Science and Technology, Xidian University