Home | History | Annotate | Download | only in mdb
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_MDB_TARGET_IMPL_H
     27 #define	_MDB_TARGET_IMPL_H
     28 
     29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     30 
     31 #include <mdb/mdb_target.h>
     32 #include <mdb/mdb_module.h>
     33 #include <mdb/mdb_list.h>
     34 #include <mdb/mdb_gelf.h>
     35 #include <sys/auxv.h>
     36 
     37 #ifdef	__cplusplus
     38 extern "C" {
     39 #endif
     40 
     41 #ifdef _MDB
     42 
     43 /*
     44  * Target Operations
     45  *
     46  * This ops vector implements the set of primitives which can be used by the
     47  * debugger to interact with the target, and encompasses most of the calls
     48  * found in <mdb/mdb_target.h>.  The remainder of the target interface is
     49  * implemented by common code that invokes these primitives or manipulates
     50  * the common target structures directly.
     51  */
     52 
     53 typedef struct mdb_tgt_ops {
     54 	int (*t_setflags)(mdb_tgt_t *, int);
     55 	int (*t_setcontext)(mdb_tgt_t *, void *);
     56 
     57 	void (*t_activate)(mdb_tgt_t *);
     58 	void (*t_deactivate)(mdb_tgt_t *);
     59 	void (*t_periodic)(mdb_tgt_t *);
     60 	void (*t_destroy)(mdb_tgt_t *);
     61 
     62 	const char *(*t_name)(mdb_tgt_t *);
     63 	const char *(*t_isa)(mdb_tgt_t *);
     64 	const char *(*t_platform)(mdb_tgt_t *);
     65 	int (*t_uname)(mdb_tgt_t *, struct utsname *);
     66 	int (*t_dmodel)(mdb_tgt_t *);
     67 
     68 	ssize_t (*t_aread)(mdb_tgt_t *,
     69 	    mdb_tgt_as_t, void *, size_t, mdb_tgt_addr_t);
     70 
     71 	ssize_t (*t_awrite)(mdb_tgt_t *,
     72 	    mdb_tgt_as_t, const void *, size_t, mdb_tgt_addr_t);
     73 
     74 	ssize_t (*t_vread)(mdb_tgt_t *, void *, size_t, uintptr_t);
     75 	ssize_t (*t_vwrite)(mdb_tgt_t *, const void *, size_t, uintptr_t);
     76 	ssize_t (*t_pread)(mdb_tgt_t *, void *, size_t, physaddr_t);
     77 	ssize_t (*t_pwrite)(mdb_tgt_t *, const void *, size_t, physaddr_t);
     78 	ssize_t (*t_fread)(mdb_tgt_t *, void *, size_t, uintptr_t);
     79 	ssize_t (*t_fwrite)(mdb_tgt_t *, const void *, size_t, uintptr_t);
     80 	ssize_t (*t_ioread)(mdb_tgt_t *, void *, size_t, uintptr_t);
     81 	ssize_t (*t_iowrite)(mdb_tgt_t *, const void *, size_t, uintptr_t);
     82 
     83 	int (*t_vtop)(mdb_tgt_t *, mdb_tgt_as_t, uintptr_t, physaddr_t *);
     84 
     85 	int (*t_lookup_by_name)(mdb_tgt_t *,
     86 	    const char *, const char *, GElf_Sym *, mdb_syminfo_t *);
     87 
     88 	int (*t_lookup_by_addr)(mdb_tgt_t *,
     89 	    uintptr_t, uint_t, char *, size_t, GElf_Sym *, mdb_syminfo_t *);
     90 
     91 	int (*t_symbol_iter)(mdb_tgt_t *,
     92 	    const char *, uint_t, uint_t, mdb_tgt_sym_f *, void *);
     93 
     94 	int (*t_mapping_iter)(mdb_tgt_t *, mdb_tgt_map_f *, void *);
     95 	int (*t_object_iter)(mdb_tgt_t *, mdb_tgt_map_f *, void *);
     96 
     97 	const mdb_map_t *(*t_addr_to_map)(mdb_tgt_t *, uintptr_t);
     98 	const mdb_map_t *(*t_name_to_map)(mdb_tgt_t *, const char *);
     99 	struct ctf_file *(*t_addr_to_ctf)(mdb_tgt_t *, uintptr_t);
    100 	struct ctf_file *(*t_name_to_ctf)(mdb_tgt_t *, const char *);
    101 
    102 	int (*t_status)(mdb_tgt_t *, mdb_tgt_status_t *);
    103 	int (*t_run)(mdb_tgt_t *, int, const struct mdb_arg *);
    104 	int (*t_step)(mdb_tgt_t *, mdb_tgt_status_t *);
    105 	int (*t_step_out)(mdb_tgt_t *, uintptr_t *);
    106 	int (*t_step_branch)(mdb_tgt_t *);
    107 	int (*t_next)(mdb_tgt_t *, uintptr_t *);
    108 	int (*t_cont)(mdb_tgt_t *, mdb_tgt_status_t *);
    109 	int (*t_signal)(mdb_tgt_t *, int);
    110 
    111 	int (*t_add_vbrkpt)(mdb_tgt_t *, uintptr_t,
    112 	    int, mdb_tgt_se_f *, void *);
    113 	int (*t_add_sbrkpt)(mdb_tgt_t *, const char *,
    114 	    int, mdb_tgt_se_f *, void *);
    115 
    116 	int (*t_add_pwapt)(mdb_tgt_t *, physaddr_t, size_t, uint_t,
    117 	    int, mdb_tgt_se_f *, void *);
    118 	int (*t_add_vwapt)(mdb_tgt_t *, uintptr_t, size_t, uint_t,
    119 	    int, mdb_tgt_se_f *, void *);
    120 	int (*t_add_iowapt)(mdb_tgt_t *, uintptr_t, size_t, uint_t,
    121 	    int, mdb_tgt_se_f *, void *);
    122 
    123 	int (*t_add_sysenter)(mdb_tgt_t *, int, int, mdb_tgt_se_f *, void *);
    124 	int (*t_add_sysexit)(mdb_tgt_t *, int, int, mdb_tgt_se_f *, void *);
    125 	int (*t_add_signal)(mdb_tgt_t *, int, int, mdb_tgt_se_f *, void *);
    126 	int (*t_add_fault)(mdb_tgt_t *, int, int, mdb_tgt_se_f *, void *);
    127 
    128 	int (*t_getareg)(mdb_tgt_t *, mdb_tgt_tid_t, const char *,
    129 	    mdb_tgt_reg_t *);
    130 	int (*t_putareg)(mdb_tgt_t *, mdb_tgt_tid_t, const char *,
    131 	    mdb_tgt_reg_t);
    132 
    133 	int (*t_stack_iter)(mdb_tgt_t *, const mdb_tgt_gregset_t *,
    134 	    mdb_tgt_stack_f *, void *);
    135 
    136 	int (*t_auxv)(mdb_tgt_t *, const auxv_t **auxvp);
    137 } mdb_tgt_ops_t;
    138 
    139 /*
    140  * Software Event Specifiers
    141  *
    142  * The common target layer provides support for the management of software
    143  * event specifiers, used to describe conditions under which a live executing
    144  * target program instance will stop and transfer control back to the debugger.
    145  * Software event management design is discussed in more detail in mdb_target.c.
    146  */
    147 
    148 struct mdb_sespec;			/* Software event specifier */
    149 struct mdb_vespec;			/* Virtual event specifier */
    150 
    151 typedef struct mdb_se_ops {
    152 	int (*se_ctor)(mdb_tgt_t *, struct mdb_sespec *, void *);
    153 	void (*se_dtor)(mdb_tgt_t *, struct mdb_sespec *);
    154 	char *(*se_info)(mdb_tgt_t *, struct mdb_sespec *,
    155 	    struct mdb_vespec *, mdb_tgt_spec_desc_t *, char *, size_t);
    156 	int (*se_secmp)(mdb_tgt_t *, struct mdb_sespec *, void *);
    157 	int (*se_vecmp)(mdb_tgt_t *, struct mdb_vespec *, void *);
    158 	int (*se_arm)(mdb_tgt_t *, struct mdb_sespec *);
    159 	int (*se_disarm)(mdb_tgt_t *, struct mdb_sespec *);
    160 	int (*se_cont)(mdb_tgt_t *, struct mdb_sespec *, mdb_tgt_status_t *);
    161 	int (*se_match)(mdb_tgt_t *, struct mdb_sespec *, mdb_tgt_status_t *);
    162 } mdb_se_ops_t;
    163 
    164 #define	T_SE_END	((void *)-1L)	/* Sentinel for end of t_matched list */
    165 
    166 typedef struct mdb_sespec {
    167 	mdb_list_t se_selist;		/* Sespec list forward/back pointers */
    168 	mdb_list_t se_velist;		/* List of layered virtual specifiers */
    169 	struct mdb_sespec *se_matched;	/* Pointer to next se on matched list */
    170 	const mdb_se_ops_t *se_ops;	/* Pointer to ops vector */
    171 	void *se_data;			/* Private storage for ops vector */
    172 	uint_t se_refs;			/* Reference count */
    173 	int se_state;			/* Event specifier state */
    174 	int se_errno;			/* Last error code (if error state) */
    175 } mdb_sespec_t;
    176 
    177 typedef struct mdb_vespec {
    178 	mdb_list_t ve_list;		/* Vespec list forward/back pointers */
    179 	int ve_id;			/* Virtual event specifier ID (VID) */
    180 	int ve_flags;			/* Flags (see mdb_target.h) */
    181 	uint_t ve_refs;			/* Reference count */
    182 	uint_t ve_hits;			/* Count of number of times matched */
    183 	uint_t ve_limit;		/* Limit on number of times matched */
    184 	mdb_sespec_t *ve_se;		/* Backpointer to sespec */
    185 	mdb_tgt_se_f *ve_callback;	/* Callback for event owner */
    186 	void *ve_data;			/* Private storage for callback */
    187 	void *ve_args;			/* Arguments for sespec constructor */
    188 	void (*ve_dtor)(struct mdb_vespec *); /* Destructor for ve_args */
    189 } mdb_vespec_t;
    190 
    191 /*
    192  * Xdata Descriptors
    193  *
    194  * Each external data item (xdata) exported by the target has a corresponding
    195  * descriptor associated with the target.  The descriptor provides the name
    196  * and description of the data, as well as the routine which is used to
    197  * retrieve the actual data or its size.
    198  */
    199 
    200 typedef struct mdb_xdata {
    201 	mdb_list_t xd_list;		/* Xdata list forward/back pointers */
    202 	const char *xd_name;		/* Buffer name */
    203 	const char *xd_desc;		/* Buffer description */
    204 	ssize_t (*xd_copy)(mdb_tgt_t *, void *, size_t); /* Copy routine */
    205 } mdb_xdata_t;
    206 
    207 /*
    208  * Target Structure
    209  *
    210  * The target itself contains a few common data members, and then a pointer to
    211  * the underlying ops vector and its private storage pointer.  MDB can manage
    212  * multiple targets simultaneously, and the list of all constructed targets is
    213  * pointed to by the mdb_t structure.
    214  */
    215 
    216 struct mdb_tgt {
    217 	mdb_list_t t_tgtlist;		/* Target list forward/back pointers */
    218 	mdb_list_t t_active;		/* List of active event specifiers */
    219 	mdb_list_t t_idle;		/* List of inactive event specifiers */
    220 	mdb_list_t t_xdlist;		/* List of xdata descriptors */
    221 	mdb_module_t *t_module;		/* Backpointer to containing module */
    222 	void *t_pshandle;		/* Proc service handle (if not tgt) */
    223 	const mdb_tgt_ops_t *t_ops;	/* Pointer to target ops vector */
    224 	void *t_data;			/* Private storage for implementation */
    225 	mdb_tgt_status_t t_status;	/* Cached target status */
    226 	mdb_sespec_t *t_matched;	/* List of matched event specifiers */
    227 	uint_t t_flags;			/* Mode flags (see <mdb_target.h>) */
    228 	uint_t t_vecnt;			/* Total number of vespecs */
    229 	int t_vepos;			/* Sequence # for next vespec id > 0 */
    230 	int t_veneg;			/* Sequence # for next vespec id < 0 */
    231 };
    232 
    233 /*
    234  * Special functions which targets can use to fill ops vector slots:
    235  */
    236 extern long mdb_tgt_notsup();		/* Return -1, errno EMDB_TGTNOTSUP */
    237 extern long mdb_tgt_hwnotsup();		/* return -1, errno EMDB_TGTHWNOTSUP */
    238 extern void *mdb_tgt_null();		/* Return NULL, errno EMDB_TGTNOTSUP */
    239 extern long mdb_tgt_nop();		/* Return 0 for success */
    240 
    241 /*
    242  * Utility structures for target implementations:
    243  */
    244 #define	MDB_TGT_R_PRIV		0x001	/* Privileged register */
    245 #define	MDB_TGT_R_EXPORT	0x002	/* Export register as a variable */
    246 #define	MDB_TGT_R_ALIAS		0x004	/* Alias for another register name */
    247 #define	MDB_TGT_R_XREG		0x008	/* Extended register */
    248 #define	MDB_TGT_R_FPS		0x010	/* Single-precision floating-point */
    249 #define	MDB_TGT_R_FPD		0x020	/* Double-precision floating-point */
    250 #define	MDB_TGT_R_FPQ		0x040	/* Quad-precision floating-point */
    251 #define	MDB_TGT_R_FPU		0x080	/* FPU control/status register */
    252 #define	MDB_TGT_R_RDONLY	0x100	/* Register is read-only */
    253 
    254 #define	MDB_TGT_R_IS_FP(f)	((f) & 0xf0) /* Test MDB_TGT_R_FP* bits */
    255 
    256 #define	MDB_TGT_R_NVAL(n, f)	((((ulong_t)(n)) << 16UL) | (f))
    257 #define	MDB_TGT_R_NUM(v)	(((v) >> 16) & 0xffff)
    258 #define	MDB_TGT_R_FLAGS(v)	((v) & 0xffff)
    259 
    260 typedef struct mdb_tgt_regdesc {
    261 	const char *rd_name;		/* Register string name */
    262 	ushort_t rd_num;		/* Register index number */
    263 	ushort_t rd_flags;		/* Register flags (see above) */
    264 } mdb_tgt_regdesc_t;
    265 
    266 /*
    267  * Utility functions for target implementations to use in order to simplify
    268  * the implementation of various routines and to insert and delete xdata
    269  * specifiers and software event specifiers.  Refer to the associated comments
    270  * in mdb_target.c for more information about each function.
    271  */
    272 
    273 extern int mdb_tgt_xdata_insert(mdb_tgt_t *, const char *, const char *,
    274 	ssize_t (*)(mdb_tgt_t *, void *, size_t));
    275 
    276 extern int mdb_tgt_xdata_delete(mdb_tgt_t *, const char *);
    277 
    278 extern int mdb_tgt_sym_match(const GElf_Sym *, uint_t);
    279 extern void mdb_tgt_elf_export(mdb_gelf_file_t *);
    280 
    281 extern int mdb_tgt_sespec_activate_one(mdb_tgt_t *t, mdb_sespec_t *);
    282 extern int mdb_tgt_sespec_activate_all(mdb_tgt_t *t);
    283 
    284 extern void mdb_tgt_sespec_idle_one(mdb_tgt_t *t, mdb_sespec_t *, int);
    285 extern void mdb_tgt_sespec_idle_all(mdb_tgt_t *t, int, int);
    286 
    287 extern void mdb_tgt_sespec_arm_one(mdb_tgt_t *t, mdb_sespec_t *);
    288 extern void mdb_tgt_sespec_arm_all(mdb_tgt_t *t);
    289 
    290 extern void mdb_tgt_sespec_idle_one(mdb_tgt_t *t, mdb_sespec_t *, int);
    291 extern void mdb_tgt_sespec_idle_all(mdb_tgt_t *t, int, int);
    292 
    293 extern void mdb_tgt_sespec_prune_one(mdb_tgt_t *t, mdb_sespec_t *);
    294 extern void mdb_tgt_sespec_prune_all(mdb_tgt_t *t);
    295 
    296 extern mdb_sespec_t *mdb_tgt_sespec_insert(mdb_tgt_t *,
    297     const mdb_se_ops_t *, mdb_list_t *);
    298 
    299 extern mdb_sespec_t *mdb_tgt_sespec_lookup_active(mdb_tgt_t *,
    300     const mdb_se_ops_t *, void *);
    301 
    302 extern mdb_sespec_t *mdb_tgt_sespec_lookup_idle(mdb_tgt_t *,
    303     const mdb_se_ops_t *, void *);
    304 
    305 extern void mdb_tgt_sespec_hold(mdb_tgt_t *, mdb_sespec_t *);
    306 extern void mdb_tgt_sespec_rele(mdb_tgt_t *, mdb_sespec_t *);
    307 
    308 extern void mdb_tgt_sespec_prune_one(mdb_tgt_t *t, mdb_sespec_t *);
    309 extern void mdb_tgt_sespec_prune_all(mdb_tgt_t *t);
    310 
    311 extern mdb_sespec_t *mdb_tgt_sespec_insert(mdb_tgt_t *,
    312     const mdb_se_ops_t *, mdb_list_t *);
    313 
    314 extern mdb_sespec_t *mdb_tgt_sespec_lookup_active(mdb_tgt_t *,
    315     const mdb_se_ops_t *, void *);
    316 
    317 extern mdb_sespec_t *mdb_tgt_sespec_lookup_idle(mdb_tgt_t *,
    318     const mdb_se_ops_t *, void *);
    319 
    320 extern void mdb_tgt_sespec_hold(mdb_tgt_t *, mdb_sespec_t *);
    321 extern void mdb_tgt_sespec_rele(mdb_tgt_t *, mdb_sespec_t *);
    322 
    323 extern int mdb_tgt_vespec_insert(mdb_tgt_t *, const mdb_se_ops_t *,
    324     int, mdb_tgt_se_f *, void *, void *, void (*)(mdb_vespec_t *));
    325 
    326 extern mdb_vespec_t *mdb_tgt_vespec_lookup(mdb_tgt_t *, int);
    327 
    328 extern int mdb_tgt_auxv(mdb_tgt_t *, const auxv_t **);
    329 
    330 extern void mdb_tgt_vespec_hold(mdb_tgt_t *, mdb_vespec_t *);
    331 extern void mdb_tgt_vespec_rele(mdb_tgt_t *, mdb_vespec_t *);
    332 
    333 /*
    334  * Utility function that target implementations can use to register dcmds,
    335  * walkers, and to create named variables for registers
    336  */
    337 extern int mdb_tgt_register_dcmds(mdb_tgt_t *, const mdb_dcmd_t *, int);
    338 extern int mdb_tgt_register_walkers(mdb_tgt_t *, const mdb_walker_t *, int);
    339 extern void mdb_tgt_register_regvars(mdb_tgt_t *, const mdb_tgt_regdesc_t *,
    340     const mdb_nv_disc_t *, int);
    341 
    342 /*
    343  * Utility functions that target implementations can use to fill in the
    344  * mdb_se_ops_t structure and vespec destructor.  Each software event specifier
    345  * must minimally supply its own constructor, info function, and match function.
    346  */
    347 
    348 extern void no_ve_dtor(mdb_vespec_t *);
    349 extern void no_se_dtor(mdb_tgt_t *, mdb_sespec_t *);
    350 
    351 extern int no_se_secmp(mdb_tgt_t *, mdb_sespec_t *, void *);
    352 extern int no_se_vecmp(mdb_tgt_t *, mdb_vespec_t *, void *);
    353 extern int no_se_arm(mdb_tgt_t *, mdb_sespec_t *);
    354 extern int no_se_disarm(mdb_tgt_t *, mdb_sespec_t *);
    355 extern int no_se_cont(mdb_tgt_t *, mdb_sespec_t *, mdb_tgt_status_t *);
    356 
    357 /*
    358  * In the initial version of MDB, the data model property is not part of the
    359  * public API.  However, I am providing this as a hidden part of the ABI as
    360  * one way we can handle the situation.  If this turns out to be the right
    361  * decision, we can document it later without having to rev the API version.
    362  */
    363 #define	MDB_TGT_MODEL_UNKNOWN	0	/* Unknown data model */
    364 #define	MDB_TGT_MODEL_ILP32	1	/* Target data model is ILP32 */
    365 #define	MDB_TGT_MODEL_LP64	2	/* Target data model is LP64 */
    366 
    367 #ifdef _LP64
    368 #define	MDB_TGT_MODEL_NATIVE	MDB_TGT_MODEL_LP64
    369 #else
    370 #define	MDB_TGT_MODEL_NATIVE	MDB_TGT_MODEL_ILP32
    371 #endif
    372 
    373 extern int mdb_prop_datamodel;
    374 
    375 #endif /* _MDB */
    376 
    377 #ifdef	__cplusplus
    378 }
    379 #endif
    380 
    381 #endif	/* _MDB_TARGET_IMPL_H */
    382