Handling BIC-without-SONAME-bump in KDE SC libraries

Modestas Vainius modax at debian.org
Fri Mar 25 10:25:52 UTC 2011


Hello,

as SONAME changes + symbol versioning seems to be the most viable option, I 
did some experiments on what end effect it might have and how all this would
look like.

Glossary
--------

unstable-ABI library - a library which is prone to break BC without SONAME 
change.

Undefined (UNDEF) symbol - a plain symbol reference. It will be resolved to 
the implementation/definition in the external shared library by dynamic 
linker.

Conclusions
-----------

1) ABI-unstable libraries should get all symbols versioned from the start. 
That's because undefined unversioned symbols may bind to any symbol of the 
same name in any library which dynamic linker (recursively) loaded [1]:

 | In case only the object file with the reference does not use
 | versioning but the object with the definition does, then the reference
 | only matches the base definition. [ ...] If there is no symbol definition
 | with such an version index and there is exactly one version for which this
 | symbol is defined, then this version is accepted

It does not matter if a real symbol in the library is versioned or not. The 
first same-name real symbol seen by dynamic linker will be bound to 
the unversioned UNDEF. It means that we basically have no control over this 
unless we version the symbols.

2) Unlike unversioned (Base) symbols, versioned UNDEF symbols have version 
*and* originating library information assigned to them. According to 
[1]:

 | The last case is if the object with the references uses symbol
 | versions but the object with the definitions has none.  In this case a
 | matching symbol is accepted unless the object's name matches the one
 | in the Elfxx_Verneed entry.  In the latter case this is a fatal error.

However, I determined that this is not the case since middle 1999 [2]. This 
situation is not a fatal error but merely a warning [3]. However, I'm pretty 
sure that it's a bug in the dynamic linker which may get fixed one day. 
Respective assert() is in place [4] but it does not fire in release builds.

3) Versioned symbols cannot be easily "moved" from one library to another down 
the library dependency tree without breakage (as it was done e.g. with 
"libkutils4 -> libkcmutils4 libkemoticons4 libkidletime4 libkprintutils4" 
split). But this should be a non-issue for unstable-ABI libraries.

Having in mind the points 1 and 2 above, all symbols in the unstable-ABI 
libraries should get a unique-per-ABI version. As soon as upstream breaks BC 
without bumping SOVERSION, we bump SONAME and change a package name. However, 
initially, we keep original upstream SONAME. This strategy allows to keep some 
compatibility with the rest of the world as long as upstream does not break BC 
without bumping SOVERSION so we do not have to bump SONAME ourselves. In 
particular:

 a) external binaries (which supposedly have unversioned UNDEF symbols as 
pushed by upstream, see point 1) will work with unstable-ABI libraries as 
packaged by Debian;

 b) binaries with versioned UNDEF symbols (i.e. linked against our unstable-
ABI libraries) will work with unstable-ABI libraries as built from upstream 
sources (kdesrc-build) or packaged by other distros which do not use  
incompatible symbol versioning. That's because of point 2 and as long as the 
linker bug is not fixed.

So how to handle BIC?
---------------------

As said in previous mails, we need to choose a custom string for our 
SONAMEs (that is either SOVERSION or OUTPUT_NAME suffix, whatever toolchain 
eats better) and symbol versions. Let it be "abiN" (where N is an integer) for 
SONAME bumps and ABI_N for symbol versions respectively (with _0 for unchanged 
SOVERSION).

So in 4.6, we add symbol versions ABI_0 to all unstable-ABI libraries which 
kept BC throughout 4.4 -> 4.6 cycle. Otherwise, if libs broke BC, we rename 
their packages, bump their SONAMEs by adding "abi1" suffix and set their 
symbol versions to ABI_1.

As 4.6 is going to be a transitional release from unversioned to versioned 
symbols, we might consider adding "Breaks" against old libs (<< 4:4.6) to all 
future "abi1" packages. That's to avoid weird crashes if both old unversioned 
and new versioned BIC libraries end up getting loaded in the same process 
space. While it's possible, it's also highly unlikely because unstable-ABI 
libs are not very popular (unlike e.g. libjpeg). So let's not do this "Breaks" 
stuff at first and see what happens.

Implementation details
----------------------

In order to minimize patching, I propose the following scheme. All unstable-
ABI library packages would be marked with a custom "X-Custom-ABI: N" (or 
something like that) debian/control field. Then we would need to implement a 
cmake script which would parse debian/control, bump SONAME and add 
appropriate -Wl,--version-script,script-name to the linker command line on-
the-fly. This script would be shipped in pkg-kde-tools to be INCLUDEd from the 
bottom of /CMakeLists.txt of the each source package that needs this 
capability. That would effectively limit us to one patch per source package 
while the rest would be conveniently "configured" in debian/control.

[1] http://www.akkadia.org/drepper/symbol-versioning
[2] http://sourceware.org/git/?p=glibc.git;a=commit;h=9a8fcca0b33c26759134a545ac45251df53418a3
[3] <apppath>: <libpath>: no version information available (required by <apppath>)
[4] http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/dl-lookup.c;hb=glibc-2.13#l168

-- 
Modestas Vainius <modax at debian.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.alioth.debian.org/pipermail/pkg-kde-talk/attachments/20110325/1e6f852b/attachment.pgp>


More information about the pkg-kde-talk mailing list