Dynamic Library Loading: Cheat Sheet
Table of Contents
1. The steps
- Kernel reads
PT_INTERPand starts that loader. - Loader finds every library listed in
DT_NEEDED(by SONAME). - Loader maps the libraries into memory.
- Loader checks that each required version exists in that library.
- Loader resolves symbols (name + version) and patches addresses.
- Loader runs initializers, then jumps to
main.
2. What a binary asks for
| Item | Meaning |
|---|---|
| PTINTERP | which loader to use |
| DTNEEDED | which libraries (SONAMEs) it needs |
| Version needs | which version nodes, from which library |
| Symbols | which name@version it imports |
3. Symbol versioning
Each symbol carries a version tag (memcpy@GLIBC_2.14), so old binaries keep
getting the old version while new links get the new one. Old on new works; new
on old fails.
This however, is an opt-in feature of the GNU toolchain and loader, and each library has to enable it when it is built.
4. Why glibc is special
glibc is the loader (ld.so) and also the C library. They share private
internals, so ld.so and libc.so.6 must come from the same build.
5. Useful commands
readelf -l prog # loader path
readelf -d prog # needed libraries
readelf -V prog # version needs
LD_BIND_NOW=1 ldd -r prog # check everything resolves
LD_DEBUG=libs prog # trace the library search