Reading — step 1 of 5
Read
~1 min readDynamic Linking
Dynamic Linking
Dynamic-linked executable: at runtime, the dynamic linker (ld-linux.so) resolves shared library symbols.
Pros:
- Smaller executables.
- Memory shared across processes (libc loaded once).
- Easier to update libraries (security patches without rebuild).
Cons:
- Runtime dependency.
- Slight startup cost.
- Versioning headaches ("DLL hell").
ELF interpreter:
- PT_INTERP segment names the dynamic linker (typically
/lib64/ld-linux-x86-64.so.2). - Kernel loads BOTH the executable AND the interpreter.
- Jumps to interpreter's entry point (NOT the executable's).
- Interpreter resolves symbols + then calls executable's entry.
Steps the dynamic linker performs:
- Load all needed libraries (DT_NEEDED entries in .dynamic).
- Recurse: each library's deps too.
- Build symbol lookup table.
- Resolve relocations: for each unresolved address in code/data, look up actual addr.
- Initialize libraries (run constructors / DT_INIT_ARRAY).
- Jump to executable's entry.
ldd /bin/cat:
linux-vdso.so.1
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
Library search:
- DT_RPATH / DT_RUNPATH (built into binary).
- LD_LIBRARY_PATH env.
- /etc/ld.so.cache (cached results of /etc/ld.so.conf paths).
- Default: /lib, /usr/lib.
LD_PRELOAD: forces loading of a library FIRST, overriding symbols. Used for debugging, instrumentation, malicious purposes.
LD_DEBUG=all: trace dynamic linker actions.
ld.so versioning:
- glibc tied to specific ld.so.
- Major version change = ABI break.
- Multiple ld.so coexist on same system rare.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…