xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_nv.h (revision 065c692a)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
26*065c692aSJosef 'Jeff' Sipek /*
27*065c692aSJosef 'Jeff' Sipek  * Copyright (c) 2013 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
28*065c692aSJosef 'Jeff' Sipek  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #ifndef	_MDB_NV_H
317c478bd9Sstevel@tonic-gate #define	_MDB_NV_H
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
367c478bd9Sstevel@tonic-gate extern "C" {
377c478bd9Sstevel@tonic-gate #endif
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #ifdef _MDB
407c478bd9Sstevel@tonic-gate 
41*065c692aSJosef 'Jeff' Sipek /*
42*065c692aSJosef 'Jeff' Sipek  * There used to be a cap (MDB_NV_NAMELEN bytes including null) on the
43*065c692aSJosef 'Jeff' Sipek  * length of variable names stored in-line.  This cap is no longer there,
44*065c692aSJosef 'Jeff' Sipek  * however parts of mdb use the constant to sanitize input.
45*065c692aSJosef 'Jeff' Sipek  */
467c478bd9Sstevel@tonic-gate #define	MDB_NV_NAMELEN	31	/* Max variable name length including null */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate  * These flags are stored inside each variable in v_flags:
507c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate #define	MDB_NV_PERSIST	0x01	/* Variable is persistent (cannot be unset) */
527c478bd9Sstevel@tonic-gate #define	MDB_NV_RDONLY	0x02	/* Variable is read-only (cannot insert over) */
537c478bd9Sstevel@tonic-gate #define	MDB_NV_EXTNAME	0x04	/* Variable name is stored externally */
547c478bd9Sstevel@tonic-gate #define	MDB_NV_TAGGED	0x08	/* Variable is tagged (user-defined) */
557c478bd9Sstevel@tonic-gate #define	MDB_NV_OVERLOAD	0x10	/* Variable can be overloaded (multiple defs) */
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate /*
587c478bd9Sstevel@tonic-gate  * These flags may be passed to mdb_nv_insert() but are not stored
597c478bd9Sstevel@tonic-gate  * inside the variable (and thus use bits outside of 0x00 - 0xff):
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate #define	MDB_NV_SILENT	0x100	/* Silence warnings about existing defs */
627c478bd9Sstevel@tonic-gate #define	MDB_NV_INTERPOS	0x200	/* Interpose definition over previous defs */
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate struct mdb_var;			/* Forward declaration */
657c478bd9Sstevel@tonic-gate struct mdb_walk_state;		/* Forward declaration */
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate /*
687c478bd9Sstevel@tonic-gate  * Each variable's behavior with respect to the get-value and set-value
697c478bd9Sstevel@tonic-gate  * operations can be changed using a discipline: a pointer to an ops
707c478bd9Sstevel@tonic-gate  * vector which can re-define these operations:
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate typedef struct mdb_nv_disc {
737c478bd9Sstevel@tonic-gate 	void (*disc_set)(struct mdb_var *, uintmax_t);
747c478bd9Sstevel@tonic-gate 	uintmax_t (*disc_get)(const struct mdb_var *);
757c478bd9Sstevel@tonic-gate } mdb_nv_disc_t;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * Each variable is defined by the following variable-length structure.
797c478bd9Sstevel@tonic-gate  * The debugger uses name/value collections to hash almost everything, so
807c478bd9Sstevel@tonic-gate  * we make a few simple space optimizations:
817c478bd9Sstevel@tonic-gate  *
827c478bd9Sstevel@tonic-gate  * A variable's name can be a pointer to external storage (v_ename and
83*065c692aSJosef 'Jeff' Sipek  * MDB_NV_EXTNAME set), or it can be stored locally (bytes of storage are
84*065c692aSJosef 'Jeff' Sipek  * allocated immediately after v_lname[0]).
857c478bd9Sstevel@tonic-gate  *
867c478bd9Sstevel@tonic-gate  * A variable may have multiple definitions (v_ndef chain), but this feature
877c478bd9Sstevel@tonic-gate  * is mutually exclusive with MDB_NV_EXTNAME in order to save space.
887c478bd9Sstevel@tonic-gate  */
897c478bd9Sstevel@tonic-gate typedef struct mdb_var {
907c478bd9Sstevel@tonic-gate 	uintmax_t v_uvalue;		/* Value as unsigned integral type */
917c478bd9Sstevel@tonic-gate 	union {
927c478bd9Sstevel@tonic-gate 		const char *v_ename;	/* Variable name if stored externally */
937c478bd9Sstevel@tonic-gate 		struct mdb_var *v_ndef;	/* Variable's next definition */
947c478bd9Sstevel@tonic-gate 	} v_du;
957c478bd9Sstevel@tonic-gate 	const mdb_nv_disc_t *v_disc;	/* Link to variable discipline */
967c478bd9Sstevel@tonic-gate 	struct mdb_var *v_next;		/* Link to next var in hash chain */
977c478bd9Sstevel@tonic-gate 	uchar_t v_flags;		/* Variable flags (see above) */
987c478bd9Sstevel@tonic-gate 	char v_lname[1];		/* Variable name if stored locally */
997c478bd9Sstevel@tonic-gate } mdb_var_t;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate #define	MDB_NV_VALUE(v)		((v)->v_uvalue)
1027c478bd9Sstevel@tonic-gate #define	MDB_NV_COOKIE(v)	((void *)(uintptr_t)((v)->v_uvalue))
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate #define	v_ename		v_du.v_ename
1057c478bd9Sstevel@tonic-gate #define	v_ndef		v_du.v_ndef
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate  * The name/value collection itself is a simple array of hash buckets,
1097c478bd9Sstevel@tonic-gate  * as well as a persistent bucket index and pointer for iteration:
1107c478bd9Sstevel@tonic-gate  */
1117c478bd9Sstevel@tonic-gate typedef struct mdb_nv {
1127c478bd9Sstevel@tonic-gate 	mdb_var_t **nv_hash;		/* Hash bucket array */
1137c478bd9Sstevel@tonic-gate 	size_t nv_hashsz;		/* Size of hash bucket array */
1147c478bd9Sstevel@tonic-gate 	size_t nv_nelems;		/* Total number of hashed elements */
1157c478bd9Sstevel@tonic-gate 	mdb_var_t *nv_iter_elt;		/* Iterator element pointer */
1167c478bd9Sstevel@tonic-gate 	size_t nv_iter_bucket;		/* Iterator bucket index */
1177c478bd9Sstevel@tonic-gate 	uint_t nv_um_flags;		/* Flags for the memory allocator */
1187c478bd9Sstevel@tonic-gate } mdb_nv_t;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate extern mdb_nv_t *mdb_nv_create(mdb_nv_t *, uint_t);
1217c478bd9Sstevel@tonic-gate extern void mdb_nv_destroy(mdb_nv_t *);
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate extern mdb_var_t *mdb_nv_insert(mdb_nv_t *, const char *,
1247c478bd9Sstevel@tonic-gate     const mdb_nv_disc_t *, uintmax_t, uint_t);
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate extern mdb_var_t *mdb_nv_lookup(mdb_nv_t *, const char *);
1277c478bd9Sstevel@tonic-gate extern void mdb_nv_remove(mdb_nv_t *, mdb_var_t *);
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate extern void mdb_nv_rewind(mdb_nv_t *);
1307c478bd9Sstevel@tonic-gate extern mdb_var_t *mdb_nv_advance(mdb_nv_t *);
1317c478bd9Sstevel@tonic-gate extern mdb_var_t *mdb_nv_peek(mdb_nv_t *);
1327c478bd9Sstevel@tonic-gate extern size_t mdb_nv_size(mdb_nv_t *);
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate extern void mdb_nv_sort_iter(mdb_nv_t *,
1357c478bd9Sstevel@tonic-gate     int (*)(mdb_var_t *, void *), void *, uint_t);
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate extern void mdb_nv_defn_iter(mdb_var_t *,
1387c478bd9Sstevel@tonic-gate     int (*)(mdb_var_t *, void *), void *);
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate extern uintmax_t mdb_nv_get_value(const mdb_var_t *);
1417c478bd9Sstevel@tonic-gate extern void mdb_nv_set_value(mdb_var_t *, uintmax_t);
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate extern void *mdb_nv_get_cookie(const mdb_var_t *);
1447c478bd9Sstevel@tonic-gate extern void mdb_nv_set_cookie(mdb_var_t *, void *);
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate extern const char *mdb_nv_get_name(const mdb_var_t *);
1477c478bd9Sstevel@tonic-gate extern mdb_var_t *mdb_nv_get_ndef(const mdb_var_t *);
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate #endif /* _MDB */
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate #endif
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate #endif	/* _MDB_NV_H */
156