On 9/17/20 1:03 PM, Jakub Jelinek wrote:
[ ... Big snip, starting over ... ]

I may have not explained things too well.  So I've put together a small
example that folks can play with to show the underlying issue.


There's a static library libfu.a.  In this static library we have a hunk
of local static data (utf8_sb_map) and two functions.  One function puts
the address utf8_sb_map into a structure (rpl_regcomp), the other
verifies that the address stored in the structure is the same as the
address of utf8_sb_map (rpl_regfree).


That static library is linked into DSO libdso.so.  The DSO sources
define a single function xregcomp which calls rpl_regcomp, but
references  nothing else from the static library.  Since libfu.a was
linked into the library we actually get a *copy* of rpl_regcomp in the
DSO.  In fact, we get a copy of the entire .o file from libfu.a, which
matches traditional linkage models where the .o file is an atomic unit
for linking.


The main program calls xregcomp which is defined in the DSO and calls
rpl_regfree.  The main program links against libdso.so and libfu.a. 
Because it links libfu.a, it gets  a copy of rpl_regfree, but *only*
rpl_regfree.  That copy of rpl_regfree references a new and distinct
copy of utf8_sb_map.  Naturally the address of utf8_sb_map in the main
program is different from the one in libdso.so and the test aborts.


Without LTO the main program would still reference rpl_regfree, but the
main program would not have its own copy.  rpl_regfree and rpl_regcomp
would both be satisfied by the DSO (which remember has a complete copy
of the .o file from libfu.a).  Thus there would be only one utf8_sb_map
as well and naturally the program will exit normally.


So I've got a bunch of thoughts here, but will defer sharing them
immediately so as not to unduly influence anyone.


I don't have a sense of how pervasive this issue is.   I know it affects
man-db, but there could well be others.




jeff

Reply via email to