What is preloading?

by Jakub Hrozek and Andreas Schneider

The LD_PRELOAD trick!

Preloading is a feature of the dynamic linker (ld). It is a available on most Unix system and allows to load a user specified, shared library before all other shared libraries which are linked to an executable.

Library pre-loading is most commonly used when you need a custom version of a library function to be called. You might want to implement your own malloc(3) and free(3) functions that would perform a rudimentary leak checking or memory access control for example, or you might want to extend the I/O calls to dump data when reverse engineering a binary blob. In this case, the library to be preloaded would implement the functions you want to override with prelinking. Only functions of dynamically loaded libraries can be overridden. You’re not able to override a function the application implements by itself or links statically with.

The library to preload is defined by the environment variable LD_PRELOAD, such as LD_PRELOAD=libwurst.so. The symbols of the preloaded library are bound first, before other linked shared libraries.
Lets look into symbol binding in more details. If your application calls a function, then the linker looks if it is available in the application itself first. If the symbol is not found, the linker checks all preloaded libraries and only then all the libraries which have been linked to your application. The shared libraries are searched in the order which has been given during compilation and linking. You can find out the linking order by calling 'ldd /path/to/my/applicaton'. If you’re interested how the linker is searching for the symbols it needs or if you want do debug if the symbol of your preloaded library is used correctly, you can do that by enabling tracing in the linker.

A simple example would be 'LD_DEBUG=symbols ls'. You can find more details about debugging with the linker in the manpage: 'man ld.so'.


Your application uses the function open(2).

  • Your application doesn’t implement it.
  • LD_PRELOAD=libcwrap.so provides open(2).
  • The linked libc.so provides open(2).

=> The open(2) symbol from libcwrap.so gets bound!

The wrappers used for creating complex testing environments of the cwrap project use preloading to supply their own variants of several system or library calls suitable for unit testing of networked software or privilege separation. For example, one wrapper includes its version of most of the standard API used to communicate over sockets that routes the communication over local sockets.

The Gold Linker

After the Update to Fedora 20 I forgot to update the linker to Gold. Today I released that linking Samba is horribly slow. Time to change the linker to Gold again:


ll /etc/alternatives/ld
/usr/sbin/alternatives --set ld /usr/bin/ld.gold


ll /etc/alternatives/ld
/usr/sbin/update-alternatives --set ld /usr/bin/ld.gold

To still build a special project with ld.bfq use:


undefined reference to “function name”

Since hermes is flooding my mailbox I haven’t looked if all my packages are compiling on Factory. So I had a look for interesting emails today. ctrlproxy (irc proxy/bouncer) didn’t build with undefined reference to ““. I wondered if the libarary packages have been renamed, but everything looked fine. I’ve talked to darix and he told me about the –as-needed flag of the linker which is set by default now. I’ve searched for some documentation didn’t find something which explains the problems so here is my documentation.

The problem is the linking order of the libraries and source code! Lets look at an example:

Assume that you built a static library libwurst and it uses the pow() function from the math library.

$ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lm -lwurst
./libwurst.a(wurst.o): In function `wurst':
wurst.c:(.text+0x29): undefined reference to `pow'

The problem here is, that the linker doesn’t find any reference to pow() in main.c. Then the first library is libm and as it is not needed, the linker skips it. So you have to link against libwurst.a before you link against libm.

$ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lwurst -lm

To summarize it: When using –as-needed, the order in which the libraries appear in the command line is relevant: any library X must precede all libraries Y that offer symbols that X uses.

I’ve created a page in the openSUSE wiki, you can find it here.