There are certain events that occur within the scope of the runtime linker that a controlling process can track. These events are:
The runtime linker has loaded and relocated all the dynamic objects and is about to start calling the .init sections of each object loaded (see "Debugging Aids").
The runtime linker has finished calling all of the .init sections and is about to transfer control to the primary executable.
The runtime linker has been invoked to either load or unload a dynamic object (see "Loading Additional Objects").
These events can be monitored using the following interface (defined in sys/link.h and rtld_db.h):
typedef enum { RD_NONE = 0, RD_PREINIT, RD_POSTINIT, RD_DLACTIVITY } rd_event_e; /* * ways that the event notification can take place: */ typedef enum { RD_NOTIFY_BPT, RD_NOTIFY_AUTOBPT, RD_NOTIFY_SYSCALL } rd_notify_e; /* * information on ways that the event notification can take place: */ typedef struct rd_notify { rd_notify_e type; union { psaddr_t bptaddr; long syscallno; } u; } rd_notify_t; |
rd_err_e rd_event_enable(struct rd_agent * rdap, int onoff); |
Presently, for performance reasons, the runtime linker ignores event disabling. The controlling process should not assume that a given break-point will not be reached because of the last call to this routine.
rd_err_e rd_event_addr(rd_agent_t * rdap, rd_event_e event, rd_notify_t * notify); |
This function specifies how the controlling program will be notified of a given event.
Depending on the event type, the notification of the controlling process will take place by calling a benign, cheap system call which is identified by notify->u.syscallno, or executing a break point at the address specified by notify->u.bptaddr. It is the responsibility of the controlling process to trace the system call or place the actual break-point.
When an event has occurred, additional information can be obtained by this interface (defined in rtld_db.h):
typedef enum { RD_NOSTATE = 0, RD_CONSISTENT, RD_ADD, RD_DELETE } rd_state_e; typedef struct rd_event_msg { rd_event_e type; union { rd_state_e state; } u; } rd_event_msg_t; |
rd_state_e values have the following meaning:
There is no additional state information available.
The link-maps are in a stable state and can be examined.
A dynamic object is in the process of being loaded and the link-maps are not in a stable state. They should not be examined until the RD_CONSISTANT state is reached.
A dynamic object is in the process of being deleted and the link-maps are not in a stable state. They should not be examined until the RD_CONSISTANT state is reached.
rd_err_e rd_event_getmsg(struct rd_agent * rdap, rd_event_msg_t * msg); |
This function provides additional information concerning an event.
The following table shows the possible state for each of the different event types.
RD_PREINIT |
RD_POSTINIT |
RD_DLACTIVITY |
---|---|---|
RD_NOSTATE |
RD_NOSTATE |
RD_CONSISTANT |
|
|
RD_ADD |
|
|
RD_DELETE |