Dynamic Loading Mechanics: Understanding the Global Offset Table and Procedure Linkage Table
The Real Problem: Position-Independent Calls
Static linking is simple: the linker knows every address at link time, writes direct calls. Done. Dynamic linking breaks this: libc.so gets mapped at different addresses every run (ASLR), potentially at different addresses in different processes (shared segments). Your code can’t hardcode call 0x7ffff7a54e10 – that address doesn’t exist at compile time.
The solution: indirection through data structures. The GOT (Global Offset Table) holds function pointers. The PLT (Procedure Linkage Table) provides trampoline code. Together they implement lazy binding: resolve symbols on first use, not at startup. This saves time when your binary links against 50 shared libraries but only calls functions from 3 of them.