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 what 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 load object to refer to a shared object (.so) or executable (a.out).
The dynamic linker maintains a list of all loaded objects in a list called a link map, which is maintained in the debugee's memory, and is indirectly accessed through librtld_db.so, a special system library for rtld debugging.
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 occurs between these two phases.
PLTs are structures used by the rtld to facilitate calls across shared object boundaries. For instance, the call to printf goes via 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.