Tag Archives: UNIX

Link Order Failures

A common set of linkage failures looks something like this:

Undefined                        first referenced
symbol                              in file
rtxCtxtSetMemHeap                   /opt/asn1c-v613/c/libgcc3/libasn1ber.a(obj.o)
rtxFileReadBinary                   /opt/asn1c-v613/c/libgcc3/libasn1ber.a(rtb.o)

The two symbols rtxCtxtSetMemHeap and rtxReadFileBinary are defined in our common runtime library. Users always report these failures with the point that they are, in fact, linking against the common runtime, like this:

gcc -o executable -L/opt/asn1c-v613/c -lasn1rt -lasn1ber

The failure in this case occurs because the link order is incorrect. Link order in gcc is significant:

A library which calls an external function defined in another library should appear before the library containing the function.

In this case, we would want to link the application as follows:

gcc -o executable -L/opt/asn1c-v613/c -lasn1ber -lasn1rt

It is not uncommon for programs that manage makefiles (like Eclipse, for example) to improperly link our libraries, so one of the first places to look is the makefile generated by the IDE.

Stack Check Failures

A number of our Linux users have written to us about linking failures that look something like this:

undefined reference to `__stack_chk_fail'

Link errors of this sort arise when trying to link an application using a version of gcc that is inconsistent with the one we used to compile our runtime libraries.  In version 4.x, GNU introduced stack smashing protection as a built-in feature of the gcc compiler—this security feature makes runtime libraries compiled with gcc 4 incompatible with gcc 3.

If you use gcc 3.x, you’ll need to link against the appropriate set of runtime libraries to avoid this failure.  All that is needed is to update the symlinks in the c and cpp directories:

ln -sf libgcc3 lib
ln -sf platform.gcc3 platform.mk

ln -sf libgpp3 lib
ln -sf platform.gpp3 platform.mk

All platform-specific compilation rules are kept in the platform.* files; if gcc 3.x is the main compiler on your system, you may not need to relink platform.mk, since this will point to a different executable for gcc.

To test whether the change was sufficient, try relinking the application.

It should also be noted that some distributions of Linux don’t enable stack smashing protection in gcc 4.x (probably because it breaks ABI compatibility with gcc 3):

Currently, SSP is standard in OpenBSD, FreeBSD (since 8.0), Ubuntu (since 6.10), DragonFly BSD and the IPCop Linux distribution. It is also available in NetBSD, Debian and Gentoo, disabled by default.

(From the Wikipedia article.)  If you are using one of these distributions, it should be possible to get a newer version of gcc for these distributions:

Debian Sid comes with stack smashing built in; users of Etch or earlier versions may upgrade if they would like.