From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jakub Jelinek To: Lubos Lunak Cc: gcc@gcc.gnu.org, binutils@sources.redhat.com Subject: Re: KDE: C++ and shared libraries Date: Tue, 11 Sep 2001 14:40:00 -0000 Message-id: <20010911234244.E554@sunsite.ms.mff.cuni.cz> References: <200109111833.UAA12466@stoupa.sh.cvut.cz> X-SW-Source: 2001-09/msg00421.html On Tue, Sep 11, 2001 at 08:33:18PM +0200, Lubos Lunak wrote: > http://dforce.sh.cvut.cz/~seli/en/linking2/ a) prelink is still in development, and although it already does some minimal optimizations to minimize number of conflicts (like e.g. removes conflicts in provably unused virtual tables or typeinfo structures), there are still other optimizations I plan to implement in the future, see below. b) the number of conflict lines in LD_DEBUG_PRELINKING output is not equal to the number of conflicts, so it really does not matter how many lines for the same symbol it prints - what matters how many relocations against the symbols mentioned in LD_DEBUG_PRELINKING are in the libs c) concerning .data section, appart from .gnu.linkonce.d stuff (virtual tables, typeinfo, etc.) it could probably help if gcc differentiated things into .data, .data.reloc, .data.local_reloc sections (the latter two for things which are RW only because they contain relocations, the last one if all the relocations are against static symbols only) if this happens often (this would need some statistics). I write .data.* because then it means no changes in the linker are necessary. Optimizations I want to try are: 1) if prelink would run all programs with LD_TRACE_PRELINKING during collect pass too, some statistics could be gathered about which symbols are often conflicting and prelink could reorder virtual tables/typeinfo structures (and eventually if libs are linked with --emit-relocs all other data too) so that data which will need runtime fixups comes together and likewise for data which won't need runtime fixups 2) similarly, if conflict statistics is gathered, some virtual table methods (especially with conflicting symbols which happen in several vtables) could be lazy bound (leave the first one with normal reloc, the rest initially pointing to some stub which would copy the function pointer resp. descriptor from the first one), which would mean the methods which are never run would not have to be written into 3) implement http://sources.redhat.com/ml/binutils/2001-07/msg00200.html under some special option. Jason is right in that this cannot be generally used because in C++ there is no way (appart from symbol versioning which is not easy to do in C++) to specify what is really the exported API of a library and what is just a side effect of the implementation. But if a) ld supported the .gnu.linkonce.* sections marked SHF_MERGE specially as described in the thread (ie. such thing is not only to be merged accross one shared object or app, but can be also deleted entirelly if one of its DT_NEEDED libs contains it). Perhaps ld would only support this under some special option b) g++ emitted this if given some special switch, off by default c) some tightly coupled packages could use this switch This would make libs/apps compiled/linked with that switch smaller (because some redundant linkonce stuff could be killed), thus they could contail fewer relocations and with prelinking contain less conflicts. I've played with nm, readelf etc. a little bit and the figure is that this would save ~ 100KB of memory footprint in kmail application on IA-32 in old (2.95/2.96-RH) ABI, not counting the savings in SHT_REL* sections and far smaller .gnu.conflict section. Dunno how much would it do with gcc3 yet. The requirements for this would be that if some C++ library against which something was compiled with this magic -flinkonce-accross-libs is changed, it needs to ensure it exports at least the same set of nm -D library | sed -n 's/^[^ ]* W \(.*\)$/\1/p' | LC_ALL=C sort symbols as it exported before, or anything which was compiled/linked with -flinkonce-accross-libs requires the newer package. My understanding is that at least most of the common KDE stuff is usually built together, in which case this core part could be built with -flinkonce-accross-libs. If some linkonce symbol goes away from some lib, it would mean all the stuff built with -flinkonce-accross-libs against such library needs to be updated too. Programs/libs outside of this core part (ie. not built with -flinkonce-accross-libs) don't need to care, for them the core part acts as a blackbox which provides the linkonce symbols they need. Jakub