xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_nv.h (revision 065c692a)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * Copyright (c) 2013 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
28  */
29 
30 #ifndef	_MDB_NV_H
31 #define	_MDB_NV_H
32 
33 #include <sys/types.h>
34 
35 #ifdef	__cplusplus
36 extern "C" {
37 #endif
38 
39 #ifdef _MDB
40 
41 /*
42  * There used to be a cap (MDB_NV_NAMELEN bytes including null) on the
43  * length of variable names stored in-line.  This cap is no longer there,
44  * however parts of mdb use the constant to sanitize input.
45  */
46 #define	MDB_NV_NAMELEN	31	/* Max variable name length including null */
47 
48 /*
49  * These flags are stored inside each variable in v_flags:
50  */
51 #define	MDB_NV_PERSIST	0x01	/* Variable is persistent (cannot be unset) */
52 #define	MDB_NV_RDONLY	0x02	/* Variable is read-only (cannot insert over) */
53 #define	MDB_NV_EXTNAME	0x04	/* Variable name is stored externally */
54 #define	MDB_NV_TAGGED	0x08	/* Variable is tagged (user-defined) */
55 #define	MDB_NV_OVERLOAD	0x10	/* Variable can be overloaded (multiple defs) */
56 
57 /*
58  * These flags may be passed to mdb_nv_insert() but are not stored
59  * inside the variable (and thus use bits outside of 0x00 - 0xff):
60  */
61 #define	MDB_NV_SILENT	0x100	/* Silence warnings about existing defs */
62 #define	MDB_NV_INTERPOS	0x200	/* Interpose definition over previous defs */
63 
64 struct mdb_var;			/* Forward declaration */
65 struct mdb_walk_state;		/* Forward declaration */
66 
67 /*
68  * Each variable's behavior with respect to the get-value and set-value
69  * operations can be changed using a discipline: a pointer to an ops
70  * vector which can re-define these operations:
71  */
72 typedef struct mdb_nv_disc {
73 	void (*disc_set)(struct mdb_var *, uintmax_t);
74 	uintmax_t (*disc_get)(const struct mdb_var *);
75 } mdb_nv_disc_t;
76 
77 /*
78  * Each variable is defined by the following variable-length structure.
79  * The debugger uses name/value collections to hash almost everything, so
80  * we make a few simple space optimizations:
81  *
82  * A variable's name can be a pointer to external storage (v_ename and
83  * MDB_NV_EXTNAME set), or it can be stored locally (bytes of storage are
84  * allocated immediately after v_lname[0]).
85  *
86  * A variable may have multiple definitions (v_ndef chain), but this feature
87  * is mutually exclusive with MDB_NV_EXTNAME in order to save space.
88  */
89 typedef struct mdb_var {
90 	uintmax_t v_uvalue;		/* Value as unsigned integral type */
91 	union {
92 		const char *v_ename;	/* Variable name if stored externally */
93 		struct mdb_var *v_ndef;	/* Variable's next definition */
94 	} v_du;
95 	const mdb_nv_disc_t *v_disc;	/* Link to variable discipline */
96 	struct mdb_var *v_next;		/* Link to next var in hash chain */
97 	uchar_t v_flags;		/* Variable flags (see above) */
98 	char v_lname[1];		/* Variable name if stored locally */
99 } mdb_var_t;
100 
101 #define	MDB_NV_VALUE(v)		((v)->v_uvalue)
102 #define	MDB_NV_COOKIE(v)	((void *)(uintptr_t)((v)->v_uvalue))
103 
104 #define	v_ename		v_du.v_ename
105 #define	v_ndef		v_du.v_ndef
106 
107 /*
108  * The name/value collection itself is a simple array of hash buckets,
109  * as well as a persistent bucket index and pointer for iteration:
110  */
111 typedef struct mdb_nv {
112 	mdb_var_t **nv_hash;		/* Hash bucket array */
113 	size_t nv_hashsz;		/* Size of hash bucket array */
114 	size_t nv_nelems;		/* Total number of hashed elements */
115 	mdb_var_t *nv_iter_elt;		/* Iterator element pointer */
116 	size_t nv_iter_bucket;		/* Iterator bucket index */
117 	uint_t nv_um_flags;		/* Flags for the memory allocator */
118 } mdb_nv_t;
119 
120 extern mdb_nv_t *mdb_nv_create(mdb_nv_t *, uint_t);
121 extern void mdb_nv_destroy(mdb_nv_t *);
122 
123 extern mdb_var_t *mdb_nv_insert(mdb_nv_t *, const char *,
124     const mdb_nv_disc_t *, uintmax_t, uint_t);
125 
126 extern mdb_var_t *mdb_nv_lookup(mdb_nv_t *, const char *);
127 extern void mdb_nv_remove(mdb_nv_t *, mdb_var_t *);
128 
129 extern void mdb_nv_rewind(mdb_nv_t *);
130 extern mdb_var_t *mdb_nv_advance(mdb_nv_t *);
131 extern mdb_var_t *mdb_nv_peek(mdb_nv_t *);
132 extern size_t mdb_nv_size(mdb_nv_t *);
133 
134 extern void mdb_nv_sort_iter(mdb_nv_t *,
135     int (*)(mdb_var_t *, void *), void *, uint_t);
136 
137 extern void mdb_nv_defn_iter(mdb_var_t *,
138     int (*)(mdb_var_t *, void *), void *);
139 
140 extern uintmax_t mdb_nv_get_value(const mdb_var_t *);
141 extern void mdb_nv_set_value(mdb_var_t *, uintmax_t);
142 
143 extern void *mdb_nv_get_cookie(const mdb_var_t *);
144 extern void mdb_nv_set_cookie(mdb_var_t *, void *);
145 
146 extern const char *mdb_nv_get_name(const mdb_var_t *);
147 extern mdb_var_t *mdb_nv_get_ndef(const mdb_var_t *);
148 
149 #endif /* _MDB */
150 
151 #ifdef	__cplusplus
152 }
153 #endif
154 
155 #endif	/* _MDB_NV_H */
156