|  | Standard debugger interface | 
|  | =========================== | 
|  |  | 
|  | The run-time linker exposes a rendezvous structure to allow debuggers | 
|  | to interface with it.  This structure, r_debug, is defined in link.h. | 
|  | If the executable's dynamic section has a DT_DEBUG element, the | 
|  | run-time linker sets that element's value to the address where this | 
|  | structure can be found. | 
|  |  | 
|  | The r_debug structure contains (amongst others) the following fields: | 
|  |  | 
|  | struct link_map *r_map: | 
|  | A linked list of loaded objects. | 
|  |  | 
|  | enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state: | 
|  | The current state of the r_map list.  RT_CONSISTENT means that r_map | 
|  | is not currently being modified and may safely be inspected.  RT_ADD | 
|  | means that an object is being added to r_map, and that the list is | 
|  | not guaranteed to be consistent.  Likewise RT_DELETE means that an | 
|  | object is being removed from the list. | 
|  |  | 
|  | ElfW(Addr) r_brk: | 
|  | The address of a function internal to the run-time linker which is | 
|  | called whenever r_state is changed.  The debugger should set a | 
|  | breakpoint at this address if it wants to notice mapping changes. | 
|  |  | 
|  | This protocol is widely supported, but somewhat limited in that it | 
|  | has no provision to provide access to multiple namespaces, and that | 
|  | the notifications (via r_brk) only refer to changes to r_map--the | 
|  | debugger is notified that a new object has been added, for instance, | 
|  | but there is no way for the debugger to discover whether any of the | 
|  | objects in the link-map have been relocated or not. | 
|  |  | 
|  |  | 
|  | Probe-based debugger interface | 
|  | ============================== | 
|  |  | 
|  | Systemtap is a dynamic tracing/instrumenting tool available on Linux. | 
|  | Probes that are not fired at run time have close to zero overhead. | 
|  | glibc contains a number of probes that debuggers can set breakpoints | 
|  | on in order to notice certain events. | 
|  |  | 
|  | All rtld probes have the following arguments: | 
|  |  | 
|  | arg1: Lmid_t lmid: | 
|  | The link-map ID of the link-map list that the object was loaded | 
|  | into.  This will be LM_ID_BASE for the application's main link-map | 
|  | list, or some other value for different namespaces. | 
|  |  | 
|  | arg2: struct r_debug *r_debug: | 
|  | A pointer to the r_debug structure containing the link-map list | 
|  | that the object was loaded into.  This will be the value stored in | 
|  | DT_DEBUG for the application's main link-map list, or some other | 
|  | value for different namespaces. | 
|  |  | 
|  | map_complete and reloc_complete may have the following additional | 
|  | argument: | 
|  |  | 
|  | arg3: struct link_map *new: | 
|  | A pointer which, if not NULL, points to the entry in the specified | 
|  | r_debug structure's link-map list corresponding to the first new | 
|  | object to have been mapped or relocated, with new->l_next pointing | 
|  | to the link-map of the next new object to have been mapped or | 
|  | relocated, and so on.  Note that because `new' is an entry in a | 
|  | larger list, new->l_prev (if not NULL) will point to what was the | 
|  | last link-map in the link-map list prior to the new objects being | 
|  | mapped or relocated. | 
|  |  | 
|  | The following probes are available: | 
|  |  | 
|  | init_start: | 
|  | This is called once, when the linker is about to fill in the main | 
|  | r_debug structure at application startup.  init_start always has | 
|  | lmid set to LM_ID_BASE and r_debug set to the value stored in | 
|  | DT_DEBUG.  r_debug is not guaranteed to be consistent until | 
|  | init_complete is fired. | 
|  |  | 
|  | init_complete: | 
|  | This is called once, when the linker has filled in the main | 
|  | r_debug structure at application startup. init_complete always | 
|  | has lmid set to LM_ID_BASE and r_debug set to the value stored | 
|  | in DT_DEBUG.  The r_debug structure is consistent and may be | 
|  | inspected, and all objects in the link-map are guaranteed to | 
|  | have been relocated. | 
|  |  | 
|  | map_start: | 
|  | The linker is about to map new objects into the specified | 
|  | namespace.  The namespace's r_debug structure is not guaranteed | 
|  | to be consistent until a corresponding map_complete is fired. | 
|  |  | 
|  | map_complete: | 
|  | The linker has finished mapping new objects into the specified | 
|  | namespace.  The namespace's r_debug structure is consistent and | 
|  | may be inspected, although objects in the namespace's link-map | 
|  | are not guaranteed to have been relocated. | 
|  |  | 
|  | map_failed: | 
|  | The linker failed while attempting to map new objects into | 
|  | the specified namespace.  The namespace's r_debug structure | 
|  | is consistent and may be inspected. | 
|  |  | 
|  | reloc_start: | 
|  | The linker is about to relocate all unrelocated objects in the | 
|  | specified namespace.  The namespace's r_debug structure is not | 
|  | guaranteed to be consistent until a corresponding reloc_complete | 
|  | is fired. | 
|  |  | 
|  | reloc_complete: | 
|  | The linker has relocated all objects in the specified namespace. | 
|  | The namespace's r_debug structure is consistent and may be | 
|  | inspected, and all objects in the namespace's link-map are | 
|  | guaranteed to have been relocated. | 
|  |  | 
|  | unmap_start: | 
|  | The linker is about to remove objects from the specified | 
|  | namespace.  The namespace's r_debug structure is not guaranteed to | 
|  | be consistent until a corresponding unmap_complete is fired. | 
|  |  | 
|  | unmap_complete: | 
|  | The linker has finished removing objects into the specified | 
|  | namespace.  The namespace's r_debug structure is consistent and | 
|  | may be inspected. |