xref: /onnv-gate/usr/src/cmd/mdb/common/modules/libuutil/libuutil.c (revision 407:f4075c116450)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*407Sjwadams  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include <pthread.h>
320Sstevel@tonic-gate #include <stddef.h>
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #include <libuutil.h>
350Sstevel@tonic-gate #include <libuutil_impl.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate /*ARGSUSED*/
380Sstevel@tonic-gate static int
uutil_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)390Sstevel@tonic-gate uutil_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
400Sstevel@tonic-gate {
410Sstevel@tonic-gate 	pthread_t uu_panic_thread = 0;
420Sstevel@tonic-gate 
430Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) || argc != 0)
440Sstevel@tonic-gate 		return (DCMD_USAGE);
450Sstevel@tonic-gate 
460Sstevel@tonic-gate 	if (mdb_readvar(&uu_panic_thread, "uu_panic_thread") == -1) {
470Sstevel@tonic-gate 		mdb_warn("unable to read uu_panic_thread");
480Sstevel@tonic-gate 	}
490Sstevel@tonic-gate 
500Sstevel@tonic-gate 	if (uu_panic_thread != 0) {
510Sstevel@tonic-gate 		mdb_printf("thread %d uu_panicked\n", uu_panic_thread);
520Sstevel@tonic-gate 	}
530Sstevel@tonic-gate 
540Sstevel@tonic-gate 	return (DCMD_OK);
550Sstevel@tonic-gate }
560Sstevel@tonic-gate 
570Sstevel@tonic-gate /*ARGSUSED*/
580Sstevel@tonic-gate static int
uutil_listpool(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)590Sstevel@tonic-gate uutil_listpool(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
600Sstevel@tonic-gate {
610Sstevel@tonic-gate 	uu_list_pool_t ulp;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
640Sstevel@tonic-gate 		if (mdb_walk_dcmd("uu_list_pool", "uu_list_pool", argc,
650Sstevel@tonic-gate 		    argv) == -1) {
660Sstevel@tonic-gate 			mdb_warn("can't walk uu_list_pool");
670Sstevel@tonic-gate 			return (DCMD_ERR);
680Sstevel@tonic-gate 		}
690Sstevel@tonic-gate 		return (DCMD_OK);
700Sstevel@tonic-gate 	}
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	if (argc != 0)
730Sstevel@tonic-gate 		return (DCMD_USAGE);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
760Sstevel@tonic-gate 		mdb_printf("%-?s %-30s %?s %5s\n",
770Sstevel@tonic-gate 		    "ADDR", "NAME", "COMPARE", "FLAGS");
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 	if (mdb_vread(&ulp, sizeof (uu_list_pool_t), addr) == -1) {
800Sstevel@tonic-gate 		mdb_warn("failed to read uu_list_pool\n");
810Sstevel@tonic-gate 		return (DCMD_ERR);
820Sstevel@tonic-gate 	}
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	mdb_printf("%0?p %-30s %08x     %c\n", addr, ulp.ulp_name, ulp.ulp_cmp,
850Sstevel@tonic-gate 	    ulp.ulp_debug ? 'D' : ' ');
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	return (DCMD_OK);
880Sstevel@tonic-gate }
890Sstevel@tonic-gate 
900Sstevel@tonic-gate /*ARGSUSED*/
910Sstevel@tonic-gate static int
uutil_list(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)920Sstevel@tonic-gate uutil_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
930Sstevel@tonic-gate {
940Sstevel@tonic-gate 	uu_list_t ul;
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC) || argc != 0)
970Sstevel@tonic-gate 		return (DCMD_USAGE);
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 	if (mdb_vread(&ul, sizeof (uu_list_t), addr) == -1) {
1000Sstevel@tonic-gate 		mdb_warn("failed to read uu_list\n");
1010Sstevel@tonic-gate 		return (DCMD_ERR);
1020Sstevel@tonic-gate 	}
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
1050Sstevel@tonic-gate 		mdb_printf("%-?s %-?s %-?s %6s %5s\n",
1060Sstevel@tonic-gate 		    "ADDR", "POOL", "PARENT", "NODES", "FLAGS");
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	mdb_printf("%0?p %0?p %0?p %6u    %c%c\n",
109*407Sjwadams 	    addr, ul.ul_pool, UU_PTR_DECODE(ul.ul_parent_enc),
110*407Sjwadams 	    ul.ul_numnodes, ul.ul_sorted ? 'S' : ' ', ul.ul_debug? 'D' : ' ');
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 	return (DCMD_OK);
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate typedef struct uutil_listpool_walk {
1160Sstevel@tonic-gate 	uintptr_t ulpw_final;
1170Sstevel@tonic-gate 	uintptr_t ulpw_current;
1180Sstevel@tonic-gate } uutil_listpool_walk_t;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate int
uutil_listpool_walk_init(mdb_walk_state_t * wsp)1210Sstevel@tonic-gate uutil_listpool_walk_init(mdb_walk_state_t *wsp)
1220Sstevel@tonic-gate {
1230Sstevel@tonic-gate 	uu_list_pool_t null_lpool;
1240Sstevel@tonic-gate 	uutil_listpool_walk_t *ulpw;
1250Sstevel@tonic-gate 	GElf_Sym sym;
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	bzero(&null_lpool, sizeof (uu_list_pool_t));
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 	if (mdb_lookup_by_obj("libuutil.so.1", "uu_null_lpool", &sym) ==
1300Sstevel@tonic-gate 	    -1) {
1310Sstevel@tonic-gate 		mdb_warn("failed to find 'uu_null_lpool'\n");
1320Sstevel@tonic-gate 		return (WALK_ERR);
1330Sstevel@tonic-gate 	}
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	if (mdb_vread(&null_lpool, sym.st_size, (uintptr_t)sym.st_value) ==
1360Sstevel@tonic-gate 	    -1) {
1370Sstevel@tonic-gate 		mdb_warn("failed to read data from 'uu_null_lpool' address\n");
1380Sstevel@tonic-gate 		return (WALK_ERR);
1390Sstevel@tonic-gate 	}
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	ulpw = mdb_alloc(sizeof (uutil_listpool_walk_t), UM_SLEEP);
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	ulpw->ulpw_final = (uintptr_t)null_lpool.ulp_prev;
1440Sstevel@tonic-gate 	ulpw->ulpw_current = (uintptr_t)null_lpool.ulp_next;
1450Sstevel@tonic-gate 	wsp->walk_data = ulpw;
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	return (WALK_NEXT);
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate int
uutil_listpool_walk_step(mdb_walk_state_t * wsp)1510Sstevel@tonic-gate uutil_listpool_walk_step(mdb_walk_state_t *wsp)
1520Sstevel@tonic-gate {
1530Sstevel@tonic-gate 	uu_list_pool_t ulp;
1540Sstevel@tonic-gate 	uutil_listpool_walk_t *ulpw = wsp->walk_data;
1550Sstevel@tonic-gate 	int status;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	if (mdb_vread(&ulp, sizeof (uu_list_pool_t),
1580Sstevel@tonic-gate 	    ulpw->ulpw_current) == -1) {
1590Sstevel@tonic-gate 		mdb_warn("failed to read uu_list_pool %x", ulpw->ulpw_current);
1600Sstevel@tonic-gate 		return (WALK_ERR);
1610Sstevel@tonic-gate 	}
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	status = wsp->walk_callback(ulpw->ulpw_current, &ulp, wsp->walk_cbdata);
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	if (ulpw->ulpw_current == ulpw->ulpw_final)
1660Sstevel@tonic-gate 		return (WALK_DONE);
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	ulpw->ulpw_current = (uintptr_t)ulp.ulp_next;
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	return (status);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate void
uutil_listpool_walk_fini(mdb_walk_state_t * wsp)1740Sstevel@tonic-gate uutil_listpool_walk_fini(mdb_walk_state_t *wsp)
1750Sstevel@tonic-gate {
1760Sstevel@tonic-gate 	uutil_listpool_walk_t *ulpw = wsp->walk_data;
1770Sstevel@tonic-gate 	mdb_free(ulpw, sizeof (uutil_listpool_walk_t));
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate typedef struct uutil_list_walk {
1810Sstevel@tonic-gate 	uintptr_t ulw_final;
1820Sstevel@tonic-gate 	uintptr_t ulw_current;
1830Sstevel@tonic-gate } uutil_list_walk_t;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate int
uutil_list_walk_init(mdb_walk_state_t * wsp)1860Sstevel@tonic-gate uutil_list_walk_init(mdb_walk_state_t *wsp)
1870Sstevel@tonic-gate {
1880Sstevel@tonic-gate 	uutil_list_walk_t *ulw;
1890Sstevel@tonic-gate 	uu_list_pool_t ulp;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	if (mdb_vread(&ulp, sizeof (uu_list_pool_t), wsp->walk_addr) == -1) {
1920Sstevel@tonic-gate 		mdb_warn("failed to read uu_list_pool_t at given address\n");
1930Sstevel@tonic-gate 		return (WALK_ERR);
1940Sstevel@tonic-gate 	}
1950Sstevel@tonic-gate 
196*407Sjwadams 	if (UU_LIST_PTR(ulp.ulp_null_list.ul_next_enc) ==
197*407Sjwadams 	    &((uu_list_pool_t *)wsp->walk_addr)->ulp_null_list)
198*407Sjwadams 		return (WALK_DONE);
199*407Sjwadams 
2000Sstevel@tonic-gate 	ulw = mdb_alloc(sizeof (uutil_list_walk_t), UM_SLEEP);
2010Sstevel@tonic-gate 
202*407Sjwadams 	ulw->ulw_final = (uintptr_t)UU_LIST_PTR(ulp.ulp_null_list.ul_prev_enc);
203*407Sjwadams 	ulw->ulw_current =
204*407Sjwadams 	    (uintptr_t)UU_LIST_PTR(ulp.ulp_null_list.ul_next_enc);
2050Sstevel@tonic-gate 	wsp->walk_data = ulw;
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 	return (WALK_NEXT);
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate int
uutil_list_walk_step(mdb_walk_state_t * wsp)2110Sstevel@tonic-gate uutil_list_walk_step(mdb_walk_state_t *wsp)
2120Sstevel@tonic-gate {
2130Sstevel@tonic-gate 	uu_list_t ul;
2140Sstevel@tonic-gate 	uutil_list_walk_t *ulw = wsp->walk_data;
2150Sstevel@tonic-gate 	int status;
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 	if (mdb_vread(&ul, sizeof (uu_list_t), ulw->ulw_current) == -1) {
2180Sstevel@tonic-gate 		mdb_warn("failed to read uu_list %x", ulw->ulw_current);
2190Sstevel@tonic-gate 		return (WALK_ERR);
2200Sstevel@tonic-gate 	}
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 	status = wsp->walk_callback(ulw->ulw_current, &ul, wsp->walk_cbdata);
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	if (ulw->ulw_current == ulw->ulw_final)
2250Sstevel@tonic-gate 		return (WALK_DONE);
2260Sstevel@tonic-gate 
227*407Sjwadams 	ulw->ulw_current = (uintptr_t)UU_LIST_PTR(ul.ul_next_enc);
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	return (status);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate void
uutil_list_walk_fini(mdb_walk_state_t * wsp)2330Sstevel@tonic-gate uutil_list_walk_fini(mdb_walk_state_t *wsp)
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate 	uutil_list_walk_t *ulw = wsp->walk_data;
2360Sstevel@tonic-gate 	mdb_free(ulw, sizeof (uutil_list_walk_t));
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate typedef struct uutil_list_node_walk {
2400Sstevel@tonic-gate 	size_t ulnw_offset;
2410Sstevel@tonic-gate 	uintptr_t ulnw_final;
2420Sstevel@tonic-gate 	uintptr_t ulnw_current;
2430Sstevel@tonic-gate 	void *ulnw_buf;
2440Sstevel@tonic-gate 	size_t ulnw_bufsz;
2450Sstevel@tonic-gate } uutil_list_node_walk_t;
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate int
uutil_list_node_walk_init(mdb_walk_state_t * wsp)2480Sstevel@tonic-gate uutil_list_node_walk_init(mdb_walk_state_t *wsp)
2490Sstevel@tonic-gate {
2500Sstevel@tonic-gate 	uutil_list_node_walk_t *ulnw;
2510Sstevel@tonic-gate 	uu_list_t ul;
2520Sstevel@tonic-gate 	uu_list_pool_t ulp;
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	if (mdb_vread(&ul, sizeof (uu_list_t), wsp->walk_addr) == -1) {
2550Sstevel@tonic-gate 		mdb_warn("failed to read uu_list_t at given address\n");
2560Sstevel@tonic-gate 		return (WALK_ERR);
2570Sstevel@tonic-gate 	}
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 	if (mdb_vread(&ulp, sizeof (uu_list_pool_t), (uintptr_t)ul.ul_pool) ==
2600Sstevel@tonic-gate 	    -1) {
2610Sstevel@tonic-gate 		mdb_warn("failed to read supporting uu_list_pool_t\n");
2620Sstevel@tonic-gate 		return (WALK_ERR);
2630Sstevel@tonic-gate 	}
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	ulnw = mdb_alloc(sizeof (uutil_list_node_walk_t), UM_SLEEP);
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 	ulnw->ulnw_offset = ul.ul_offset;
2680Sstevel@tonic-gate 	ulnw->ulnw_final = wsp->walk_addr + offsetof(uu_list_t, ul_null_node);
2690Sstevel@tonic-gate 	ulnw->ulnw_current = (uintptr_t)ul.ul_null_node.uln_next;
2700Sstevel@tonic-gate 	ulnw->ulnw_buf = mdb_alloc(ulp.ulp_objsize, UM_SLEEP);
2710Sstevel@tonic-gate 	ulnw->ulnw_bufsz = ulp.ulp_objsize;
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate 	wsp->walk_data = ulnw;
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate 	return (WALK_NEXT);
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate int
uutil_list_node_walk_step(mdb_walk_state_t * wsp)2790Sstevel@tonic-gate uutil_list_node_walk_step(mdb_walk_state_t *wsp)
2800Sstevel@tonic-gate {
2810Sstevel@tonic-gate 	uu_list_node_impl_t uln;
2820Sstevel@tonic-gate 	uutil_list_node_walk_t *ulnw = wsp->walk_data;
2830Sstevel@tonic-gate 	int status;
2840Sstevel@tonic-gate 	uintptr_t diff;
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 	if (ulnw->ulnw_current == ulnw->ulnw_final)
2870Sstevel@tonic-gate 		return (WALK_DONE);
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate 	if (mdb_vread(&uln, sizeof (uu_list_node_impl_t), ulnw->ulnw_current) ==
2900Sstevel@tonic-gate 	    -1) {
2910Sstevel@tonic-gate 		mdb_warn("failed to read uu_list_node %x", ulnw->ulnw_current);
2920Sstevel@tonic-gate 		return (WALK_ERR);
2930Sstevel@tonic-gate 	}
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	diff = ulnw->ulnw_current - ulnw->ulnw_offset;
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	if (mdb_vread(ulnw->ulnw_buf, ulnw->ulnw_bufsz, diff) == -1) {
2980Sstevel@tonic-gate 		mdb_warn("failed to read enclosing structure %x", diff);
2990Sstevel@tonic-gate 		return (WALK_ERR);
3000Sstevel@tonic-gate 	}
3010Sstevel@tonic-gate 	/*
3020Sstevel@tonic-gate 	 * Correct for offset; we return the address of the included structure.
3030Sstevel@tonic-gate 	 */
3040Sstevel@tonic-gate 	status = wsp->walk_callback(diff, ulnw->ulnw_buf, wsp->walk_cbdata);
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	ulnw->ulnw_current = (uintptr_t)uln.uln_next;
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	return (status);
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate void
uutil_list_node_walk_fini(mdb_walk_state_t * wsp)3120Sstevel@tonic-gate uutil_list_node_walk_fini(mdb_walk_state_t *wsp)
3130Sstevel@tonic-gate {
3140Sstevel@tonic-gate 	uutil_list_node_walk_t *ulnw = wsp->walk_data;
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	mdb_free(ulnw->ulnw_buf, ulnw->ulnw_bufsz);
3170Sstevel@tonic-gate 	mdb_free(ulnw, sizeof (uutil_list_node_walk_t));
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
3210Sstevel@tonic-gate 	{ "uutil_status", NULL, "libuutil status summary", uutil_status },
3220Sstevel@tonic-gate 	{ "uu_list_pool", NULL, "display uu_list_pool information",
3230Sstevel@tonic-gate 		uutil_listpool },
3240Sstevel@tonic-gate 	{ "uu_list", NULL, "display uu_list information",
3250Sstevel@tonic-gate 		uutil_list },
3260Sstevel@tonic-gate 	{ NULL }
3270Sstevel@tonic-gate };
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
3300Sstevel@tonic-gate 	{ "uu_list_pool", "walk uu_list_pools",
3310Sstevel@tonic-gate 		uutil_listpool_walk_init, uutil_listpool_walk_step,
3320Sstevel@tonic-gate 		uutil_listpool_walk_fini },
3330Sstevel@tonic-gate 	{ "uu_list", "given a uu_list_pool, walk its uu_lists",
3340Sstevel@tonic-gate 		uutil_list_walk_init, uutil_list_walk_step,
3350Sstevel@tonic-gate 		uutil_list_walk_fini },
3360Sstevel@tonic-gate 	{ "uu_list_node",
3370Sstevel@tonic-gate 		"given a uu_list, walk its nodes, returning container addr",
3380Sstevel@tonic-gate 		uutil_list_node_walk_init, uutil_list_node_walk_step,
3390Sstevel@tonic-gate 		uutil_list_node_walk_fini },
3400Sstevel@tonic-gate 	{ NULL }
3410Sstevel@tonic-gate };
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate static const mdb_modinfo_t modinfo = {
3440Sstevel@tonic-gate 	MDB_API_VERSION, dcmds, walkers
3450Sstevel@tonic-gate };
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)3480Sstevel@tonic-gate _mdb_init(void)
3490Sstevel@tonic-gate {
3500Sstevel@tonic-gate 	return (&modinfo);
3510Sstevel@tonic-gate }
352