The GNU C Library With Versioned Interface

The current GNU C library provides the run-time backward compatibility. That means executables and shared libraries built against the previous versions of glibc will continue to work with the current shared glibc, libc.so. This functionality is implemented with the symbol versioning in libc.so. This work is based on the effort from Eric Youngdale.

But the run-time compatibility is not enough for the Independent Software Vendors (ISVs). Many software applications may come with not only executables and shared libraries, but also header files, regular object files and archives which may be used to develop softwares for the application. Since the new version of glibc may not provide the compile-time nor link-time compatibility, the software applications from ISVs built against the previous versions of glibc may not be compatible with the new version of glibc if they have header files, regular object files or archives which reference the interfaces updated in the new glibc. One such a  example is the problem of Oracle 8i under glibc 2.2.  It may not be the only software package having similar problems.

One way to solve this compile-time/link-time compatibility problem is for ISVs to recompile their applications against the new version of glibc. But it may not be practical for all ISVs. ISVs usually provide their software applications on more than one platform. Their applications may be very complex.  Porting their applications to a new version of glibc may take the same long, involved process as porting to a new platform since it not only needs to recompile and re-test, but also the new glibc may require other changes in the system, like new kernel. Also ISVs have to make decision if the want to support more than one version of glibc and which version of glibc they want to support. All of these may not something every ISV wants to endure. It may not be very helpful for more ISVs to develop/port their applications for Linux.

The current glibc only uses symbol versioning in shared libraries which provides the run-time backward compatibility. We may be able to extend it to regular objects and archives to provide the compile-time and link-time compatibility. It can be done by binding each symbol in glibc to a specific interface. In Eric's note on symbol versioning, he mentioned "In general, the version specification tags won't appear in any header files, and will only go in the library sources themselves, so external references will tend to be just for 'foo'.  If you are absolutely sure that you need to bind to a non-default interface, then you will have to fully specify the version you want in the place where you reference it.  An example of how you do this is not yet available." In the GNU binutils, the versioned symbol reference is also explicitly allowed. This is how this versioned interface for glibc is implemented here. The result is a glibc patch which provides 2 additional header files, <bits/symver.h> and <bits/symverinfo.h>. By default, the versioned interface is off. A Linux developer can do

1. Add -D_GLIBC_VERSIONED_SOURCE. It will turn on the versioned interface in glibc. Each source code file which includes any header files from glibc will get

__asm__(".symver foo,foo@@@GLIBC_2.x.x");

for each versioned interface. There are about 1500 of them. It will result in the versioned reference in .o files for the current interface.

2. Add -D_GLIBC_2_0_SOURCE will turn on the glibc 2.0 interface.

3. Add -D_GLIBC_2_1_SOURCE will turn on the glibc 2.1 interface.

4. Add -D_GLIBC_2_1_1_SOURCE will turn on the glibc 2.1.1 interface.

5. Add -D_GLIBC_2_1_2_SOURCE will turn on the glibc 2.1.2 interface.

6. Add -D_GLIBC_2_1_3_SOURCE will turn on the glibc 2.1.3 interface.

7. Add -D_GLIBC_2_1_4_SOURCE will turn on the glibc 2.1.4 interface.

I have a patch for glibc 2.1.3 and patched glibc 2.1.3 RPMs for RedHat 6.2:

1. The glibc 2.1.3 source rpm.
1. The glibc 2.1.3 run-time binary rpm.
2. The glibc 2.1.3 development binary rpm.
3. The glibc 2.1.3 profiling binary rpm.
4. The glibc 2.1.3 nscd binary rpm.

ISVs can install the glibc 2.1.3 development rpm and recompile their applications. The resulting binaries, including executables, shared libraries, regular objects and archives, are compatible with the unpatched Linux systems based on glibc 2.1.3. Those binaries are also compatible with glibc 2.2. You can get the compile-time compatibility for source code files by adding -D_GLIBC_2_1_3_SOURCE under glibc 2.2 with a similar glibc patch for 2.2. The versioned interface patch for glibc 2.2 and patched glibc 2.2 RPMs are available upon request.

With my glibc patch, .o files compiled from source code files which include any glibc header files will have versioned reference to the symbols in glibc. The unpatched glibc only has the versioned definitions in libc.so. That means "gcc -static" won't work unless libc.a also has the versioned definitions. The libc.a with the versioned definitions comes from the patched glibc build such as the one in the glibc 2.1.3 development rpm for RedHat 6.2.

In order to use the versioned interface for glibc, the current Linux binutils, 2.10.1.0.2 or newer, is required.

Please report any versioned interface related glibc/binutils problems to H.J. Lu.