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