On 9/16/20 11:13 AM, H.J. Lu wrote: > On Wed, Sep 16, 2020 at 10:10 AM Jeff Law <l...@redhat.com> wrote: >> >> On 9/16/20 11:05 AM, H.J. Lu wrote: >>> On Wed, Sep 16, 2020 at 9:53 AM Jeff Law via Gcc-patches >>> <gcc-patches@gcc.gnu.org> wrote: >>>> Consider a TU with file scoped "static const object utf8_sb_map". A >>>> routine within the TU will stuff &utf8_sb_map into an object, something >>>> like: >>>> >>>> fu (...) >>>> >>>> { >>>> >>>> if (cond) >>>> >>>> dfa->sb_char = utf8_sb_map; >>>> >>>> else >>>> >>>> dfa->sb_char = malloc (...); >>>> >>>> } >>>> >>>> >>>> There is another routine in the TU which looks like >>>> >>>> bar (...) >>>> >>>> { >>>> >>>> if (dfa->sb_char != utf8_sb_map) >>>> >>>> free (dfa->sb_char); >>>> >>>> } >>>> >>>> >>>> Now imagine that the TU is compiled (with LTO) into a static library, >>>> libgl.a and there's a DSO (libdso.so) which gets linked against libgl.a >>>> and references the first routine (fu). We get a copy of fu in the DSO >>>> along with a copy of utf8_sb_map. >>>> >>>> >>>> Then imagine there's a main executable that dynamicly links against >>>> libdso.so, then links statically against libgl.a. Assume the main >>>> executable does not directly reference fu(), but does call a routine in >>>> libdso.so which eventually calls fu(). Also assume the main executable >>>> directly calls bar(). Again, remember we're compiling with LTO, so we >>>> don't suck in the entire TU, just the routines/data we need. >>>> >>>> >>>> In this scenario, both libdso.so and the main executable are going to a >>>> copy of utf8_sb_map and they'll be at different addresses. So when the >>>> main executable calls into libdso.so which in turn calls libdso's copy >>>> of fu() which stuffs the address of utf8_sb_map from the DSO into >>>> dfa->sb_char. Later the main executable calls bar() that's in the main >>>> executable. It does the comparison to see if dfa->sb_char is equal to >>>> utf8_sb_map -- but it's using the main executable's copy of utf8_sb_map >>>> and naturally free() blows us because it was passed a static object, not >>>> a malloc'd object. >>>> >>>> >>>> ISTM this is a lot like the problem we have where we inline functions >>>> with static data. To fix those we use STB_GNU_UNIQUE. But I don't see >>>> any code in the C front-end which would utilize STB_GNU_UNIQUE. It's >>>> support seems limited to C++. >>>> >>>> >>>> How is this supposed to work for C? >>>> >>>> >>>> Jeff >>>> >>>> >>> Can you group utf8_sb_map, fu and bar together so that they are defined >>> together? >> They're all defined within the same TU in gnulib. It's the LTO >> dead/unreachable code elimination that results in just parts of the TU >> being copied into the DSO and a different set copied into the main >> executable. In many ways LTO makes this look a lot like the static data >> member problems we've had to deal with in the C++ world. > In this case, LTO should treat them as in a single group. Removing > one group member should remove the whole group. Keep one member > should keep the whole group.
Do you mean ensure they're all in a partition together? I think that might work in the immediate term, but is probably brittle in the long term. I'd tend to lean towards forcing these static data objects to be STB_GNU_UNIQUE -- that seems more robust to me. jeff >
pEpkey.asc
Description: application/pgp-keys