root/usr/src/head/rtld_db.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
 *
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _RTLD_DB_H
#define _RTLD_DB_H

#ifdef  __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/lwp.h>
#include <sys/elf.h>
#include <link.h>
#include <proc_service.h>


/*
 * librtld_db interface versions
 */
#define RD_VERSION1     1
#define RD_VERSION2     2
#define RD_VERSION3     3
#define RD_VERSION4     4
#define RD_VERSION      RD_VERSION4

typedef enum {
        RD_ERR,         /* generic */
        RD_OK,          /* generic "call" succeeded */
        RD_NOCAPAB,     /* capability not available */
        RD_DBERR,       /* import service failed */
        RD_NOBASE,      /* 5.x: aux tag AT_BASE not found */
        RD_NODYNAM,     /* symbol 'DYNAMIC' not found */
        RD_NOMAPS       /* link-maps are not yet available */
} rd_err_e;


/*
 * ways that the event notification can take place:
 */
typedef enum {
        RD_NOTIFY_BPT,          /* set break-point at address */
        RD_NOTIFY_AUTOBPT,      /* 4.x compat. not used in 5.x */
        RD_NOTIFY_SYSCALL       /* watch for 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;        /* break point address */
                long            syscallno;      /* system call id */
        } u;
} rd_notify_t;

/*
 * information about event instance:
 */
typedef enum {
        RD_NOSTATE = 0,         /* no state information */
        RD_CONSISTENT,          /* link-maps are stable */
        RD_ADD,                 /* currently adding object to link-maps */
        RD_DELETE               /* currently deleteing object from link-maps */
} rd_state_e;

typedef struct rd_event_msg {
        rd_event_e      type;
        union {
                rd_state_e      state;  /* for DLACTIVITY */
        } u;
} rd_event_msg_t;


/*
 * iteration over load objects
 */
typedef struct rd_loadobj {
        psaddr_t        rl_nameaddr;    /* address of the name in user space */
        unsigned        rl_flags;
        psaddr_t        rl_base;        /* base of address of code */
        psaddr_t        rl_data_base;   /* base of address of data */
        Lmid_t          rl_lmident;     /* ident of link map */
        psaddr_t        rl_refnameaddr; /* reference name of filter in user */
                                        /* space.  If non null object is a */
                                        /* filter. */
        psaddr_t        rl_plt_base;    /* These fields are present for 4.x */
        unsigned        rl_plt_size;    /* compatibility and are not */
                                        /* currently used  in SunOS5.x */
        psaddr_t        rl_bend;        /* end of image (text+data+bss) */
        psaddr_t        rl_padstart;    /* start of padding */
        psaddr_t        rl_padend;      /* end of image after padding */
        psaddr_t        rl_dynamic;     /* points to the DYNAMIC section */
                                        /* in the target process */
        unsigned long   rl_tlsmodid;    /* module ID for TLS references */
} rd_loadobj_t;

/*
 * Values for rl_flags
 */
#define RD_FLG_MEM_OBJECT       0x0001  /* Identifies this object as */
                                        /* originating from a relocatable */
                                        /* module which was dynamically */
                                        /* loaded */

/*
 * Commands for rd_ctl()
 */
#define RD_CTL_SET_HELPPATH     0x01    /* Set the path used to find helpers */

typedef struct rd_agent rd_agent_t;
typedef int rl_iter_f(const rd_loadobj_t *, void *);


/*
 * PLT skipping
 */
typedef enum {
    RD_RESOLVE_NONE,            /* don't do anything special */
    RD_RESOLVE_STEP,            /* step 'pi_nstep' instructions */
    RD_RESOLVE_TARGET,          /* resolved target is in 'pi_target' */
    RD_RESOLVE_TARGET_STEP      /* put a bpt on target, then step nstep times */
} rd_skip_e;


typedef struct rd_plt_info {
        rd_skip_e       pi_skip_method;
        long            pi_nstep;
        psaddr_t        pi_target;
        psaddr_t        pi_baddr;
        unsigned int    pi_flags;
} rd_plt_info_t;


/*
 * Values for pi_flags
 */
#define RD_FLG_PI_PLTBOUND      0x0001  /* Indicates that the PLT */
                                        /* has been bound - and that */
                                        /* pi_baddr will contain its */
                                        /* destination address */

struct  ps_prochandle;

/*
 * librtld_db.so entry points
 */
extern void             rd_delete(rd_agent_t *);
extern char             *rd_errstr(rd_err_e rderr);
extern rd_err_e         rd_event_addr(rd_agent_t *, rd_event_e, rd_notify_t *);
extern rd_err_e         rd_event_enable(rd_agent_t *, int);
extern rd_err_e         rd_event_getmsg(rd_agent_t *, rd_event_msg_t *);
extern rd_err_e         rd_init(int);
extern rd_err_e         rd_ctl(int, void *);
extern rd_err_e         rd_loadobj_iter(rd_agent_t *, rl_iter_f *,
                                void *);
extern void             rd_log(const int);
extern rd_agent_t       *rd_new(struct ps_prochandle *);
extern rd_err_e         rd_objpad_enable(struct rd_agent *, size_t);
extern rd_err_e         rd_plt_resolution(rd_agent_t *, psaddr_t, lwpid_t,
                                psaddr_t, rd_plt_info_t *);
extern rd_err_e         rd_get_dyns(rd_agent_t *, psaddr_t, void **, size_t *);
extern rd_err_e         rd_reset(struct rd_agent *);

#ifdef  __cplusplus
}
#endif

#endif  /* _RTLD_DB_H */