[Bug 1187864] New: Semantic interposition inhibits optimization of shared libraries
https://bugzilla.suse.com/show_bug.cgi?id=1187864 Bug ID: 1187864 Summary: Semantic interposition inhibits optimization of shared libraries Classification: openSUSE Product: openSUSE Tumbleweed Version: Current Hardware: Other OS: Other Status: NEW Severity: Normal Priority: P5 - None Component: Basesystem Assignee: matz@suse.com Reporter: fvogt@suse.com QA Contact: qa-bugs@suse.de CC: martin.liska@suse.com, rguenther@suse.com Found By: --- Blocker: --- By default, any visible symbol in shared libraries (PIC) can be overwritten during runtime by the executable or mechanisms such as LD_PRELOAD, this is called semantic interposition. This however affects optimization of shared libraries quite badly, because any call or reference to exported functions (or symbols in general) in the same library might not actually resolve to the symbol in that library anymore. Any such references have to be resolved during runtime (GOT+PLT relocations) and interprocedural optimization is not possible anymore. For executables (also PIE) this is not the case, they can utilize direct calls and references to global data. Through the magic of copy relocations, it can even reference global data from shared objects directly. Libraries then use the copy of the global data from the executable instead of their own. As libraries actually make up the most code on the system, optimizing for those is actually worthwhile. Using the "-fno-semantic-interposition" compiler option, interprocedural optimization can be enabled for exported symbols and the linker option "-Bsymbolic(-functions)" allows symbol references inside the same object to be resolved directly instead of going through runtime relocation. Some libraries enable those options themselves already like openssl. Qt also used "-Bsymbolic" for a long time, but it conflicted with the "gcc-PIE" package which built incompatible executables and so it got disabled again (boo#1175278). However, executables have to be built with that in mind (by compiling them like PIC) to avoid features which rely on interposition, like copy relocations. The "-fno-direct-access-external-data" option achieves that FWICT. It would be great if we could build (most parts of) the distro such that libraries can be optimized more. Thread on the GCC ML about -fno-semantic-interposition: https://gcc.gnu.org/pipermail/gcc-patches/2021-June/572018.html GCC PR report about -fno-direct-access-external-data: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98112 Extensive discussion about Qt's reduce-relocations option: https://bugreports.qt.io/browse/QTBUG-86173 Blog posts about this topic: https://maskray.me/blog/2021-05-09-fno-semantic-interposition https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1187864 https://bugzilla.suse.com/show_bug.cgi?id=1187864#c3 --- Comment #3 from Michael Matz <matz@suse.com> --- As I wrote to maskray on the generic-abi list ( https://groups.google.com/g/generic-abi/c/LgSC6te51uM/m/WGzfjtFKAgAJ ) I'm quite heavily opposed to disabling interposition wholesale. I would perhaps support it when restricted to C++ symbols for functions. Also note that protected visiblity is going to be fixed on x86-64 (to not be worse than default visibility and break with copy relocations, i.e. it will work again like before 2014/15) over the next months. At that point packages choosing so can simply use that. -Bsymbolic should be regarded as a hack in the ELF world, because ELF has symbol visibility which is (or was, and will be again) designed to be exactly that. And of course the compiler doesn't know anything about it, so can't base it's inlining decisions on it. (Which is the whole reason why people had to invent still another flag for the compiler; well, that and because protected visibility wasn't working as designed/desired). So, my course of action would be: wait for protected symbol visibility to be fixed again, make it so that packages can select that visibility as default for C++ functions (select it in a way the compiler knows), let packages decide. Possibly make that default in the toolchain after quite some time. -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1187864 https://bugzilla.suse.com/show_bug.cgi?id=1187864#c4 --- Comment #4 from Michael Matz <matz@suse.com> --- Note that for instance in above generic-abi thread maskray says that most speedup for clang itself was by avoiding the symbolic relocations, i.e. what protected visibility or variants of -Bsymbolic* give you, _not_ what -fno-semantic-interposition gives you. There are unclear claims about fantastic speedups with cpython, which look a bit doubtful or are done on unrealistic microbenchmarks, that may or may not come from the disabled interposition or from reduced relocations. -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1187864 https://bugzilla.suse.com/show_bug.cgi?id=1187864#c7 --- Comment #7 from Michael Matz <matz@suse.com> --- Normally I do like language lawyering very much, but I think in this case it's not appropriate. Symbol interposition is an ELF feature, and hence, for us, a system feature; a fairly powerful one with some disadvantages. We can't just disable that feature after 30 years. At least not if there are ways where we can mitigate the disadvantages without throwing out the baby completely. Aaron: the power of interposition doesn't lie in being able to override known symbols, but rather to override _all_ (exported) symbols. The point being that the software authors don't have to explicitely mark symbols as overridable; if they were to be required to do that, that wouldn't then make it different from them explicitely designing hooks into their interfaces. There is for instance software that hooks many libc routines (and a changeable set of other routines) in order to, well, hook them (e.g. for tracing). Symbol interposition makes this trivial. Without it you need to resort to the contortions that equivalent Windows software needs to go through (basically patching either the import table, if it exists, or even the function code itself). Basically: if library authors would be required to make their exports hookable, we would end up with nothing being hookable. That is because the need for hooking can't be predicted; if someone needs it, it's usually not the library author but someone outside who doesn't necessarily (want to) have means to change the library. As I've written elsewhere (probably in the above generic-abi thread): I'll concede that such hooking usually takes place for C symbols, not for other language symbols. (Though of course there's nothing that would currently prevent that, and of course e.g. valgrind does hook the global c++ allocation routines). So, I'd be willing to try disabling interposition for C++ symbols (with exceptions). But before even that, we need to be clear what exactly we want to change and what the improvements of that change will be. Perhaps on a bit more than just clang (speedup due to fewer symbol lookups) and some anecdote from the web about cpython. (FWIW: I do know that libqt also goes to lengths to reduce symbolic lookups, and libreoffice (at the time still openoffice) had the same problem, which is why we now have .gnu.hash, and KDE had the problem which is why we have (had) kdeinit. I.e. I know that symbolic lookups are a problem for some software (all C++!) but I also know that it's absolutely no problem at all for other software, which is why I'm hammering so much on the protected visibility, being _exactly_ the right tool for avoiding symbolic lookups from within shared libs) And yes, Aaron: the idea for "fixing" protected vis is to not generate copy relocs for variables (i.e. cross module accesses will be indirect, like now but in the other direction). For function addresses something similar can be done; it must be the one from the defining module, not from the PLT slot in the exe. H.J. works on some patches that try to phase that into the world step by step to not break existing binaries. -- You are receiving this mail because: You are on the CC list for the bug.
participants (1)
-
bugzilla_noreply@suse.com