This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RFC: .gnu.linkonce.* and shared libraries


Hi!

While testing the prelinking stuff I found that some KDE C++ programs have
excessive number of conflicts. Typically the ratio of conflicts vs. sum of
all non-RELATIVE relocations is like 1% and even some huge C++ programs like
konqueror which have more than 65000 relocations have something like 1500
conflicts. But some C++ programs have up to 30000 conflicts out of 80000
total relocations, like kmail. That seems bad.
Although prelinking still seems to be a win:
LD_DEBUG=statistics /usr/bin/popmail_conduit	# prelinked
20462:
20462:  runtime linker statistics:
20462:    total startup time in dynamic loader: 4485444 clock cycles
20462:              time needed for relocation: 2281637 clock cycles (50.8)
20462:                   number of relocations: 24041
20462:             time needed to load objects: 1987949 clock cycles (44.3)
LD_DEBUG=statistics /save/usr/bin/popmail_conduit	# non-prelinked, lazy
20466:
20466:  runtime linker statistics:
20466:    total startup time in dynamic loader: 110883574 clock cycles
20466:              time needed for relocation: 108693508 clock cycles (98.0)
20466:                   number of relocations: 46310
20466:             time needed to load objects: 1985271 clock cycles (1.7)
LD_DEBUG=statistics LD_BIND_NOW=1 /save/usr/bin/popmail_conduit # non-prelinked
20468:
20468:  runtime linker statistics:
20468:    total startup time in dynamic loader: 191296068 clock cycles
20468:              time needed for relocation: 189113247 clock cycles (98.8)
20468:                   number of relocations: 61628
20468:             time needed to load objects: 1977346 clock cycles (1.0)

24000 conflicts occupy 288K in the binary (note that 288K does not mean 288K
more of shared pages, because although ld.so accesses the conflict section,
it does not on the other side access the .rel* sections of the binary and
all libraries).

I believe the main reason is that .gnu.linkonce.* has link-once semantics
only within a single link object (be it shared library or binary), not
within whole program.

Now, what would you think about extending .gnu.linkonce.* semantics to the
whole program? My idea is this:

1) so that programs which rely on the current .gnu.linkonce.* semantics
would still work, compiler would specially mark the .gnu.linkonce.* section
which wants this new behaviour.
Using
        .section .gnu.linkonce.t._Z3foov,"axm",@progbits,.LFE1-.LFB1
looks like a good idea for this to me, since SHF_MERGE with entity size
equal to the size of the section is exactly what .gnu.linkonce.* is doing.

2) ld would normally eliminate all but once such section

3) once all dependent libraries are mapped, if there are any dynamic
libraries, linker searches all those libraries if it finds an area in the
corresponding section (.gnu.linkonce.t -> .text etc.) of the library, which:

  a) has the required alignment of .gnu.linkonce.* section
  b) all the symbols against the .gnu.linkonce.* section are present there
     too, with the same symbol properties, at the same relative offset
     from start of .gnu.linkonce.* section resp. of the area in the library
  c) likewise for relocations against .gnu.linkonce.* section resp. area,
     again it has to be the same relocation type, same visibility, against
     the same symbol, with the same addend etc.
  d) the content of the .gnu.linkonce.t section is identical to the content
     of the area (for RELA relocations against the area after all
     relocations are relocated to canonical form)

4) if all these conditions are met, then the .gnu.linkonce.* section is
thrown away from the link

I believe this would kill quite a lot of relocations in C++ shared libraries
and binaries linked against them and would reduce drastically the number of
conflicts too, in addition to making the libraries/binaries smaller.
What do you think?

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]