Linux Binary Compatibility: An Experience Report

Update from 2009

This is on a Debian Lenny AMD64 (64-bit) distribution. The old binaries I tried to run are all i386 (32-bit) binaries.

A Mosaic binary from 1994 just segfaults, as well as all the other ZMAGIC binaries (1994-1995) I have lying around.

The QMAGIC binaries (1995-1997) all report "can't load dynamic linker '/lib/ld.so nor /usr/i486-linux/lib/ld.so'" and could probably be made to work by copying the appropriate file to the right place (plus any libraries needed).

Then we get into the ELF era (since 1998), and the binaries (e.g., ssh 1.2.25) work if (compatible versions of) the libraries they use are present; for that ssh binary the libraries are libnsl.so.1 libcrypt.so.1 libutil.so.1 libc.so.6 /lib/ld-linux.so.2, which came with the libc6-i386 package on Lenny. Not bad.

I usually preserve old distributions I used to use, so I can easily copy the old libraries to my new distribution if I need them (or maybe just include the old library directories in ld.so.conf). I have not needed to do that for quite some time, though.

Original report from 1998

Some people have claimed that Linux is not a viable platform for commercial programs; the reason they give is that Linux is constantly changing, with a new kernel every week, and that there is not a standard distribution; they claim that these things are an obstacle for binary compatibility, and thus for commercial programs.

Here I report my experience with binary compatibility of programs from kernel 1.0 to 2.0.34 and between two different distributions that are more than 3.5 years and two major libaray versions apart and that use different binary formats.

For those who don't have the time to read the rest, the bottom line is: Most programs I tested run on the spot in the new environment, and most of the rest can be made to run with a few tweaks; every program I tested ran to some degree, in the end, but a few did not produce satisfactory results. The binary format and the libraries were no real problem, because Linux still provides support for the old (a.out) format and the Red Hat 5.1 distribution includes the old libraries.

The Setup

In Autumn 1994 I installed Slackware 2.1. I first used it with the 1.0 kernel I had then, and later upgraded to 1.2.13 (with a few intermediate steps). I also upgraded a few components (gcc once, the X-server twice, when a new graphics card made it necessary). I had no problems with binary compatibility during this time, with one exception: upgrading to the 1.2 kernels also required an upgrade of bootpd (boot protocol deamon, which I used for booting an X-Terminal).

A few days ago, in June 1998, I installed the Red Hat 5.1 distribution, and I currently run it with the 2.0.34 kernel.

The main changes (with respect to binary compatibility) in the meantime have been the switch from the a.out binary format to the ELF format, and changes in the library that resulted in two major version number changes (indicating that the library is not binary backwards compatible): the switch from a.out to ELF resulted in bumping the libc major version from 4 to 5, the switch to glibc 2 caused another bump of the major version number to 6.

The Programs

I performed the test on all binaries I had in my /usr/local/bin directory. I copied the whole /usr/local hierarchy from the slackware to the Red Hat installation (yes, I should put /usr/local on a separate partition). All of these binaries are in the a.out format. These binaries belong to several packets:
Mosaic
WWW browser NCSA Mosaic 2.4, statically linked (due to Motif license).
tgif
a drawing program.
xvcg
a graph visualization program.
graphviz
another graph visualization package.
lp_solve
a linear programming problem solver.
ox
compiler generator (for attributed grammars).
gcc-i2.6.3
compiler (gcc-2.6.3 with some Intel enhancements).
sgmls
SGML parser.
fdutils
floppy control and formatting programs.
workman
CD player.
setmix
set sound card's mixer
gforth
Forth interpreter.
ldefx
game (Defender clone).
texinfo
programs dealing with the texinfo documentation format.

The Results

The status indicator below means:
y
runs, tested on some real input.
r
runs, but not tested on serious input (because it is quite a bit of work, or because I am not interested in the program and don't know any serious input).
n
does not run satisfactory.
t
needed tweaks; look for remarks below.
binary		package	      result
------------------------------------
Mosaic		Mosaic		y
dot		graphviz	r
dspserver	ldefx		y
fdrawcmd	fdutils		y
fixref		sgmls		r
floppycontrol   fdutils		y
gcc-i2.6.3	gcc		y
getfdprm	fdutils		y
gforth-0.2.1	gforth		y
gforth-0.3.0	gforth		y
html2html	sgmls		r
info		texinfo 	yt
install-info	texinfo		r
ldefx		ldefx		yt
lefty		graphviz	nt
lp_solve	lp_solve	y
makeinfo	texinfo		r
neato		graphviz	r
ox		ox		r
prtgif		tgif		y
rtf2rtf		sgmls		r
setfdprm	fdutils		r
setmix		setmix		y
sgmls		sgmls		r
sgmlsasp	sgmls		r
superformat	fdutils		r
tcldot		graphviz	n
texindex	texinfo		r
tgif-2.16pl12	tgif		y
tgif-2.12	tgif		yt
tkdot		graphviz	n
workman		workman		yt
xvcg		xvcg		yt	

Remarks

gcc-i2.6.3
The compiler runs and produces assembly or object code. But when linking it misses a file crt0.o. Using that file from the Slackware distribution does not help, because then we get many unresolvbed symbols from this file. Apparently it is not so easy to get a compiler configured for a.out binaries running in an ELF environment.
info
file path changed (/usr/lib/terminfo/x/xterm -> /usr/share/terminfo/x/xterm). I added a link to make it run.
ldefx
at first I had no sound, because the appropriate file was not installed in the /usr/local hierarchy (IMO this is a bug in the installation script of the application). After fixing that, it did run with some warning about the minor version of libXpm.so.4.
lefty
runs, but does not display characters (only the graphics); it complains "Warning: Unable to load any usable fontset". This makes it unusable, so I classified it as n.
tcldot, tkdot
Even if I help by supplying the TCL_LIBRARY environment variable, they do not run, complaining about the TCL version. However, since I did not use these programs earlier, I do not know if they ran on Slackware.
tgif-2.12, xvcg
did not find it's library (does not use ld.so); adding a symbolic link in /lib helped.
workman
this program requires the OpenWindows/Open Look libraries (a toolkit advocated by Sun once upon a time), which are not included in Red Hat 5.1. I copied them from the Slackware distribution to /usr/local/lib/openwin, added that directory to /etc/ld.so.conf and ran ldconfig. Now workman works.

Discussion

Most programs run smoothly because the kernel supports the a.out format and because the distribution includes the old libraries (except the OpenWindows libraries). Differences in library paths are taken care of by ld.so (except for ancient binaries that do not use ld.so).

There were also few problems with file paths, although at the time of Slackware 2.1 the File Hierarchy Standard was not as refined as today (and I don't know how well Slackware complied).

Note that some of the tweaking (e.g. info and ldefx) was necessary due to my testing post-installation compatibility, and would not occur if the program was installed on Red Hat 5.1 with its install script. To improve post-installation compatibility (i.e., compatibility over system upgrades), I recommend shifting work like file-finding from installation time to run time as much as possible.

The failures were due to the interaction with other components: the binutils and libraries for gcc-i2.6.3, Tcl/tk for tcldot and tkdot, and probably some X issue for lefty.

This poses the question whether scripts are not just as much of a problem as binary compatibility, but I will leave a thorough investigation of this to someone else; in general, I believe that a script that works between different Unices can be expected to work betwenn different Linux versions.

I expect that the platform will be more stable in the future than in the past (due to efforts such as the File Hierarchy Standard and the Linux standards base, so we can expect even better binary compatibility for packages built now.

Conclusion

Every program I tested ran to some degree even though there were major upgrades of the kernel and the libraries; the reasons are that the kernel is backwards compatible, and that the distributions include old libraries in addition to the new ones. Some programs needed some tweaking before they ran. File path problems proved less common than expected.

A few programs ran, but did not work satisfactorily, due to various interactions with other components.

I expect even better binary compatibility for packages built nowadays, on a more stable platform.


Anton Ertl