What is the difference between the runtime linker (ld.so) and the prelink program? I know the runtime linker (ld.so) loads all the dynamic libraries needed for a program but what is the benefit of prelink? Both are doing the same job, aren't they?


This is largely covered by the prelink manpage:

prelink is a program that modifies ELF shared libraries and ELF dynamically linked binaries in such a way that the time needed for the dynamic linker to perform relocations at startup significantly decreases. Due to fewer relocations, the run-time memory consumption decreases as well (especially the number of unshareable pages). The prelinking information is only used at startup time if none of the dependent libraries have changed since prelinking; otherwise programs are relocated normally.

prelink first collects ELF binaries to be prelinked and all the ELF shared libraries they depend on. Then it assigns a unique virtual address space slot to each library and relinks the shared library to that base address. When the dynamic linker attempts to load such a library, unless that virtual address space slot is already occupied, it maps the library into the given slot. After this is done, prelink, with the help of dynamic linker, resolves all relocations in the binary or library against its dependent libraries and stores the relocations into the ELF object. It also stores a list of all dependent libraries together with their checksums into the binary or library. For binaries, it also computes a list of conflicts (relocations that resolve differently in the binary's symbol search scope than in the smaller search scope in which the dependent library was resolved) and stores it into a special ELF section.

At runtime, the dynamic linker first checks whether all dependent libraries were successfully mapped into their designated address space slots, and whether they have not changed since the prelinking was done. If all checks are successful, the dynamic linker just replays the list of conflicts (which is usually significantly shorter than total number of relocations) instead of relocating each library.

The main difference between ld.so and prelink is that the former runs every time a dynamically-linked binary is loaded. prelink tries to reduce the time and memory taken by ld.so at program startup by pre-computing the library relocations involved in dynamically linking a binary; it stores these relocations, along with the information necessary to determine whether they are still valid, in the binary, and ld.so can use that information to skip doing its own relocation (as long as the pre-linked relocations worked).

Using prelink does have a number of adverse consequences, in particular:

  • it modifies binaries, which means they can no longer be compared to their “origin” (package etc.) to determine whether they have been tampered with;
  • it results in fixed relocations, which greatly reduces the scope of address-space layout randomisation and thus reduces the system’s security (for any given pre-linked binary, as long as the linked libraries don’t change the relocations will stay the same, which is very useful to an attacker trying to exploit a gadget in one of the libraries).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.