Linker and Libraries Guide

Event Notification

There are certain events that occur within the scope of the runtime linker that a controlling process can track. These events are:

RD_PREINIT

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 "Initialization and Termination Routines").

RD_POSTINIT

The runtime linker has finished calling all of the .init sections 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 (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;

rderr_e rd_event_enable(struct rd_agent * rdap, int onoff);
rd_event_enable()

This function enables (1) or disables (0) event monitoring.


Note -

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.



rderr_e rd_event_addr(rd_agent_t * rdap, rd_event_e event,
        rd_notify_t * notify);
rd_event_addr()

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:

RD_NOSTATE

There is no additional state information available.

RD_CONSISTANT

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_CONSISTANT state 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_CONSISTANT state is reached.


rderr_e rd_event_getmsg(struct rd_agent * rdap,
        rd_event_msg_t * msg);
rd_event_getmsg()

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