A controlling process can track certain events that occur within the scope of the runtime linker that. 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.
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.
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;
The following functions track events:
This function enables (1) or disables (0) event monitoring.
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 can not be reached because of the last call to this routine.
This function specifies how the controlling program is notified of a given event.
rd_err_e rd_event_addr(rd_agent_t * rdap, rd_event_e event, rd_notify_t * notify);
Depending on the event type, the notification of the controlling process takes place by calling a benign, cheap system call that is identified by notify->u.syscallno, or executing a break point at the address specified by notify->u.bptaddr. The controlling process is responsible for tracing 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;
The rd_state_e values are:
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.
The rd_event_getmsg() function is used to obtain this event state information.
This function provides additional information concerning an event.
rd_err_e rd_event_getmsg(struct rd_agent * rdap, rd_event_msg_t * msg);
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 |