Skip to content
Dynamic Linking
step 1/5

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:

  1. Load all needed libraries (DT_NEEDED entries in .dynamic).
  2. Recurse: each library's deps too.
  3. Build symbol lookup table.
  4. Resolve relocations: for each unresolved address in code/data, look up actual addr.
  5. Initialize libraries (run constructors / DT_INIT_ARRAY).
  6. 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…