The dynamic linker, also known as rtld, Runtime ld, or ld.so, arranges to bring shared objects (load objects) into an executing application. There are two primary areas where rtld is active:
Program startup – At program startup, rtld runs first and dynamically loads all shared objects specified at link time. These are preloaded shared objects and may include libc.so, libC.so, or libX.so. Use ldd(1) to find out which shared objects a program will load.
Application requests– The application uses the function calls dlopen(3) and dlclose(3) to dynamically load and unload shared objects or executables.
dbx uses the term loadobject to refer to a shared object (.so) or executable (a.out). You can use the loadobject command (see loadobject Command) to list and manage symbolic information from load objects.
The dynamic linker maintains a list of all loaded objects in a list called a link map. The link map is maintained in the memory of the program being debugged, and is indirectly accessed through librtld_db.so, a special system library for use by debuggers.
A .init section is a piece of code belonging to a shared object that is executed when the shared object is loaded. For example, the .init section is used by the C++ runtime system to call all static initializers in a .so.
The dynamic linker first maps in all the shared objects, putting them on the link map. Then, the dynamic linker traverses the link map and executes the .init section for each shared object. The syncrtld event (see syncrtld) occurs between these two phases.
Procedure linkage tables (PLTs) are structures used by the rtld to facilitate calls across shared object boundaries. For instance, calls to printf go through this indirect table. The details of how this is done can be found in the generic and processor specific SVR4 ABI reference manuals.
For dbx to handle step and next commands across PLTs, it has to keep track of the PLT table of each load object. The table information is acquired at the same time as the rtld handshake.