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