Getting Started 41
As we see along with the main program’s hello_world, a range of the
addresses is allocated to libc and the dynamic linker ld.so. The memory map
of the application is created at runtime and then the symbol resolution (in
our case the
printf) is done. This is done by a series of steps. The ELF
loader, which is built as a part of the kernel, scans the executable and finds
out that the process has shared library dependency; hence it calls the dynamic
linker ld.so. The ld.so, which is also implemented as a shared library, is a
bootstrap library; it loads itself and the rest of the shared libraries (libc.so)
into memory thus freezing the memory map of the application and does the
rest of the symbol resolution.
This leaves us with one last ...