Event Notification
A controlling process can track certain events that occur within the scope of the runtime linker that. These events are:
-
RD_PREINIT -
The runtime linker has loaded and relocated all the dynamic objects and is about to start calling the
.initsections of each object loaded. -
RD_POSTINIT -
The runtime linker has finished calling all of the
.initsections and is about to transfer control to the primary executable. -
RD_DLACTIVITY -
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.
-
rd_event_enable() -
This function enables (1) or disables (0) event monitoring.
rd_err_e rd_event_enable(struct rd_agent *rdap, int onoff);
Note:
Currently, 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. -
rd_event_addr() -
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 bynotify->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:
-
RD_NOSTATE -
There is no additional state information available.
-
RD_CONSISTENT -
The link-maps are in a stable state and can be examined.
-
RD_ADD -
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_CONSISTENTstate is reached. -
RD_DELETE -
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_CONSISTENTstate is reached.
The rd_event_getmsg() function is used to obtain this event
state information.
-
rd_event_getmsg() -
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_CONSISTENT RD_ADD RD_DELETE |