1*4a1c2431SJonathan Adams /*
2*4a1c2431SJonathan Adams  * CDDL HEADER START
3*4a1c2431SJonathan Adams  *
4*4a1c2431SJonathan Adams  * The contents of this file are subject to the terms of the
5*4a1c2431SJonathan Adams  * Common Development and Distribution License (the "License").
6*4a1c2431SJonathan Adams  * You may not use this file except in compliance with the License.
7*4a1c2431SJonathan Adams  *
8*4a1c2431SJonathan Adams  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4a1c2431SJonathan Adams  * or http://www.opensolaris.org/os/licensing.
10*4a1c2431SJonathan Adams  * See the License for the specific language governing permissions
11*4a1c2431SJonathan Adams  * and limitations under the License.
12*4a1c2431SJonathan Adams  *
13*4a1c2431SJonathan Adams  * When distributing Covered Code, include this CDDL HEADER in each
14*4a1c2431SJonathan Adams  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4a1c2431SJonathan Adams  * If applicable, add the following below this CDDL HEADER, with the
16*4a1c2431SJonathan Adams  * fields enclosed by brackets "[]" replaced with your own identifying
17*4a1c2431SJonathan Adams  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4a1c2431SJonathan Adams  *
19*4a1c2431SJonathan Adams  * CDDL HEADER END
20*4a1c2431SJonathan Adams  */
21*4a1c2431SJonathan Adams /*
22*4a1c2431SJonathan Adams  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*4a1c2431SJonathan Adams  * Use is subject to license terms.
24*4a1c2431SJonathan Adams  */
25*4a1c2431SJonathan Adams 
26*4a1c2431SJonathan Adams #ifndef	_MDB_WHATIS_H
27*4a1c2431SJonathan Adams #define	_MDB_WHATIS_H
28*4a1c2431SJonathan Adams 
29*4a1c2431SJonathan Adams #ifdef	__cplusplus
30*4a1c2431SJonathan Adams extern "C" {
31*4a1c2431SJonathan Adams #endif
32*4a1c2431SJonathan Adams 
33*4a1c2431SJonathan Adams struct mdb_whatis;
34*4a1c2431SJonathan Adams typedef struct mdb_whatis mdb_whatis_t;
35*4a1c2431SJonathan Adams 
36*4a1c2431SJonathan Adams /*
37*4a1c2431SJonathan Adams  * int mdb_whatis_overlaps(mdb_whatis_t *w, uintptr_t base, size_t size):
38*4a1c2431SJonathan Adams  *
39*4a1c2431SJonathan Adams  * Returns non-zero if and only if a call to
40*4a1c2431SJonathan Adams  *
41*4a1c2431SJonathan Adams  *	mdb_whatis_match(w, base, size, ...)
42*4a1c2431SJonathan Adams  *
43*4a1c2431SJonathan Adams  * will succeed;  that is, there is an address of interest in the
44*4a1c2431SJonathan Adams  * range [base, base+size).
45*4a1c2431SJonathan Adams  */
46*4a1c2431SJonathan Adams extern int mdb_whatis_overlaps(mdb_whatis_t *, uintptr_t, size_t);
47*4a1c2431SJonathan Adams 
48*4a1c2431SJonathan Adams /*
49*4a1c2431SJonathan Adams  * int mdb_whatis_match(mdb_whatis_t *w, uintptr_t base, size_t size,
50*4a1c2431SJonathan Adams  *	uintptr_t *out)
51*4a1c2431SJonathan Adams  *
52*4a1c2431SJonathan Adams  * Perform an iterative search for an address of interest in [base, base+size).
53*4a1c2431SJonathan Adams  * Each call returning a non-zero value returns the next interesting address
54*4a1c2431SJonathan Adams  * in the range.  This must be called repeatedly until it returns a zero
55*4a1c2431SJonathan Adams  * value, indicating that the search is complete.
56*4a1c2431SJonathan Adams  *
57*4a1c2431SJonathan Adams  * For example:
58*4a1c2431SJonathan Adams  *	uintptr_t cur;
59*4a1c2431SJonathan Adams  *
60*4a1c2431SJonathan Adams  *	while (mdb_whatis_match(w, base, size, &cur))
61*4a1c2431SJonathan Adams  *		mdb_whatis_report_object(w, cur, base, "allocated from ...");
62*4a1c2431SJonathan Adams  */
63*4a1c2431SJonathan Adams extern int mdb_whatis_match(mdb_whatis_t *, uintptr_t, size_t, uintptr_t *);
64*4a1c2431SJonathan Adams 
65*4a1c2431SJonathan Adams /*
66*4a1c2431SJonathan Adams  * void mdb_whatis_report_address(mdb_whatis_t *w, uintptr_t addr,
67*4a1c2431SJonathan Adams  *	uintptr_t base, const char *format, ...)
68*4a1c2431SJonathan Adams  *
69*4a1c2431SJonathan Adams  * Reports addr (an address from mdb_whatis_match()).  If addr is inside
70*4a1c2431SJonathan Adams  * a symbol, that will be reported. (format, ...) is an mdb_printf()
71*4a1c2431SJonathan Adams  * format string and associated arguments, and will follow a string like
72*4a1c2431SJonathan Adams  * "addr is ".  For example, it could be "in libfoo's text segment\n":
73*4a1c2431SJonathan Adams  *
74*4a1c2431SJonathan Adams  *	addr is in libfoo's text segment
75*4a1c2431SJonathan Adams  *
76*4a1c2431SJonathan Adams  * The caller should make sure to output a newline, either in format or in a
77*4a1c2431SJonathan Adams  * separate mdb_printf() call.
78*4a1c2431SJonathan Adams  */
79*4a1c2431SJonathan Adams extern void mdb_whatis_report_address(mdb_whatis_t *, uintptr_t,
80*4a1c2431SJonathan Adams     const char *, ...);
81*4a1c2431SJonathan Adams 
82*4a1c2431SJonathan Adams /*
83*4a1c2431SJonathan Adams  * void mdb_whatis_report_object(mdb_whatis_t *w, uintptr_t addr,
84*4a1c2431SJonathan Adams  *	uintptr_t base, const char *format, ...)
85*4a1c2431SJonathan Adams  *
86*4a1c2431SJonathan Adams  * Reports addr (an address from mdb_whatis_match()) as being part of an
87*4a1c2431SJonathan Adams  * object beginning at base.  (format, ...) is an mdb_printf() format
88*4a1c2431SJonathan Adams  * string and associated arguments, and will follow a string like
89*4a1c2431SJonathan Adams  * "addr is base+offset, ".  For example, it could be "allocated from foo\n":
90*4a1c2431SJonathan Adams  *
91*4a1c2431SJonathan Adams  *	addr is base+offset, allocated from foo
92*4a1c2431SJonathan Adams  *
93*4a1c2431SJonathan Adams  * The caller should make sure to output a newline, either in format or in a
94*4a1c2431SJonathan Adams  * separate mdb_printf() call.
95*4a1c2431SJonathan Adams  */
96*4a1c2431SJonathan Adams extern void mdb_whatis_report_object(mdb_whatis_t *, uintptr_t, uintptr_t,
97*4a1c2431SJonathan Adams     const char *, ...);
98*4a1c2431SJonathan Adams 
99*4a1c2431SJonathan Adams /*
100*4a1c2431SJonathan Adams  * uint_t mdb_whatis_flags(mdb_whatis_t *w)
101*4a1c2431SJonathan Adams  *
102*4a1c2431SJonathan Adams  * Reports which flags were passed to ::whatis.  See the flag definitions
103*4a1c2431SJonathan Adams  * for more details.
104*4a1c2431SJonathan Adams  */
105*4a1c2431SJonathan Adams extern uint_t mdb_whatis_flags(mdb_whatis_t *);
106*4a1c2431SJonathan Adams 
107*4a1c2431SJonathan Adams #define	WHATIS_BUFCTL	0x1	/* -b, the caller requested bufctls */
108*4a1c2431SJonathan Adams #define	WHATIS_IDSPACE 	0x2	/* -i, only search identifiers */
109*4a1c2431SJonathan Adams #define	WHATIS_QUIET	0x4	/* -q, single-line reports only */
110*4a1c2431SJonathan Adams #define	WHATIS_VERBOSE	0x8	/* -v, report information about the search */
111*4a1c2431SJonathan Adams 
112*4a1c2431SJonathan Adams /*
113*4a1c2431SJonathan Adams  * uint_t mdb_whatis_done(mdb_whatis_t *w)
114*4a1c2431SJonathan Adams  *
115*4a1c2431SJonathan Adams  * Returns non-zero if and only if all addresses have been reported, and it
116*4a1c2431SJonathan Adams  * is time to get out of the callback as quickly as possible.
117*4a1c2431SJonathan Adams  */
118*4a1c2431SJonathan Adams extern uint_t mdb_whatis_done(mdb_whatis_t *);
119*4a1c2431SJonathan Adams 
120*4a1c2431SJonathan Adams /* Macro for returning from a walker callback */
121*4a1c2431SJonathan Adams #define	WHATIS_WALKRET(w)	(mdb_whatis_done(w) ? WALK_DONE : WALK_NEXT)
122*4a1c2431SJonathan Adams 
123*4a1c2431SJonathan Adams typedef int mdb_whatis_cb_f(mdb_whatis_t *, void *);
124*4a1c2431SJonathan Adams 
125*4a1c2431SJonathan Adams /*
126*4a1c2431SJonathan Adams  * void mdb_whatis_register(const char *name, mdb_whatis_cb_f *cb, void *arg,
127*4a1c2431SJonathan Adams  *	uint_t prio, uint_t flags)
128*4a1c2431SJonathan Adams  *
129*4a1c2431SJonathan Adams  * May only be called from _mdb_init() for a module.
130*4a1c2431SJonathan Adams  *
131*4a1c2431SJonathan Adams  * Registers a whatis callback named "name" (which must be an MDB identifier),
132*4a1c2431SJonathan Adams  * with a callback function cb and argument arg.  prio determines when the
133*4a1c2431SJonathan Adams  * callback will be invoked, compared to other registered ones, and flags
134*4a1c2431SJonathan Adams  * determines when the callback will be invoked (see below).
135*4a1c2431SJonathan Adams  *
136*4a1c2431SJonathan Adams  * Callbacks with the same priority registered by the same module will be
137*4a1c2431SJonathan Adams  * executed in the order they were added.  The callbacks will be invoked as:
138*4a1c2431SJonathan Adams  *
139*4a1c2431SJonathan Adams  *	int ret = (*cb)(w, arg)
140*4a1c2431SJonathan Adams  *
141*4a1c2431SJonathan Adams  * Where w is an opaque mdb_whatis_t pointer which is to be passed to the API
142*4a1c2431SJonathan Adams  * routines, above.  The function should return 0 unless an error occurs.
143*4a1c2431SJonathan Adams  */
144*4a1c2431SJonathan Adams extern void mdb_whatis_register(const char *,
145*4a1c2431SJonathan Adams     mdb_whatis_cb_f *, void *, uint_t, uint_t);
146*4a1c2431SJonathan Adams 
147*4a1c2431SJonathan Adams #define	WHATIS_PRIO_EARLY	10	/* execute before allocator callbacks */
148*4a1c2431SJonathan Adams #define	WHATIS_PRIO_ALLOCATOR	20
149*4a1c2431SJonathan Adams #define	WHATIS_PRIO_LATE	30	/* execute after allocator callbacks */
150*4a1c2431SJonathan Adams 
151*4a1c2431SJonathan Adams #define	WHATIS_REG_ID_ONLY	0x1	/* only invoke for '-i' */
152*4a1c2431SJonathan Adams #define	WHATIS_REG_NO_ID	0x2	/* don't invoke for '-i' */
153*4a1c2431SJonathan Adams 
154*4a1c2431SJonathan Adams #ifdef	__cplusplus
155*4a1c2431SJonathan Adams }
156*4a1c2431SJonathan Adams #endif
157*4a1c2431SJonathan Adams 
158*4a1c2431SJonathan Adams #endif	/* _MDB_WHATIS_H */
159