1*10696SDavid.Hollister@Sun.COM /*
2*10696SDavid.Hollister@Sun.COM * CDDL HEADER START
3*10696SDavid.Hollister@Sun.COM *
4*10696SDavid.Hollister@Sun.COM * The contents of this file are subject to the terms of the
5*10696SDavid.Hollister@Sun.COM * Common Development and Distribution License (the "License").
6*10696SDavid.Hollister@Sun.COM * You may not use this file except in compliance with the License.
7*10696SDavid.Hollister@Sun.COM *
8*10696SDavid.Hollister@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10696SDavid.Hollister@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*10696SDavid.Hollister@Sun.COM * See the License for the specific language governing permissions
11*10696SDavid.Hollister@Sun.COM * and limitations under the License.
12*10696SDavid.Hollister@Sun.COM *
13*10696SDavid.Hollister@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*10696SDavid.Hollister@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10696SDavid.Hollister@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*10696SDavid.Hollister@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*10696SDavid.Hollister@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*10696SDavid.Hollister@Sun.COM *
19*10696SDavid.Hollister@Sun.COM * CDDL HEADER END
20*10696SDavid.Hollister@Sun.COM */
21*10696SDavid.Hollister@Sun.COM /*
22*10696SDavid.Hollister@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23*10696SDavid.Hollister@Sun.COM * Use is subject to license terms.
24*10696SDavid.Hollister@Sun.COM */
25*10696SDavid.Hollister@Sun.COM
26*10696SDavid.Hollister@Sun.COM #include <mdb/mdb_modapi.h>
27*10696SDavid.Hollister@Sun.COM #include <sys/bitset.h>
28*10696SDavid.Hollister@Sun.COM
29*10696SDavid.Hollister@Sun.COM #include "bitset.h" /* XXX work out ifdef in include file... */
30*10696SDavid.Hollister@Sun.COM
31*10696SDavid.Hollister@Sun.COM void
bitset_help(void)32*10696SDavid.Hollister@Sun.COM bitset_help(void)
33*10696SDavid.Hollister@Sun.COM {
34*10696SDavid.Hollister@Sun.COM mdb_printf("Print the bitset at the address given\n");
35*10696SDavid.Hollister@Sun.COM }
36*10696SDavid.Hollister@Sun.COM
37*10696SDavid.Hollister@Sun.COM static void
bitset_free(bitset_t * bs)38*10696SDavid.Hollister@Sun.COM bitset_free(bitset_t *bs)
39*10696SDavid.Hollister@Sun.COM {
40*10696SDavid.Hollister@Sun.COM if (bs == NULL)
41*10696SDavid.Hollister@Sun.COM return;
42*10696SDavid.Hollister@Sun.COM if (bs->bs_set && bs->bs_words)
43*10696SDavid.Hollister@Sun.COM mdb_free(bs->bs_set, bs->bs_words * sizeof (ulong_t));
44*10696SDavid.Hollister@Sun.COM mdb_free(bs, sizeof (*bs));
45*10696SDavid.Hollister@Sun.COM }
46*10696SDavid.Hollister@Sun.COM
47*10696SDavid.Hollister@Sun.COM static bitset_t *
bitset_get(uintptr_t bsaddr)48*10696SDavid.Hollister@Sun.COM bitset_get(uintptr_t bsaddr)
49*10696SDavid.Hollister@Sun.COM {
50*10696SDavid.Hollister@Sun.COM bitset_t *bs;
51*10696SDavid.Hollister@Sun.COM
52*10696SDavid.Hollister@Sun.COM bs = mdb_zalloc(sizeof (*bs), UM_SLEEP);
53*10696SDavid.Hollister@Sun.COM if (mdb_vread(bs, sizeof (*bs), bsaddr) == -1) {
54*10696SDavid.Hollister@Sun.COM mdb_warn("couldn't read bitset 0x%p", bsaddr);
55*10696SDavid.Hollister@Sun.COM bitset_free(bs);
56*10696SDavid.Hollister@Sun.COM return (NULL);
57*10696SDavid.Hollister@Sun.COM }
58*10696SDavid.Hollister@Sun.COM
59*10696SDavid.Hollister@Sun.COM bsaddr = (uintptr_t)bs->bs_set;
60*10696SDavid.Hollister@Sun.COM bs->bs_set = mdb_alloc(bs->bs_words * sizeof (ulong_t), UM_SLEEP);
61*10696SDavid.Hollister@Sun.COM if (mdb_vread(bs->bs_set,
62*10696SDavid.Hollister@Sun.COM bs->bs_words * sizeof (ulong_t), bsaddr) == -1) {
63*10696SDavid.Hollister@Sun.COM mdb_warn("couldn't read bitset bs_set 0x%p", bsaddr);
64*10696SDavid.Hollister@Sun.COM bitset_free(bs);
65*10696SDavid.Hollister@Sun.COM return (NULL);
66*10696SDavid.Hollister@Sun.COM }
67*10696SDavid.Hollister@Sun.COM return (bs);
68*10696SDavid.Hollister@Sun.COM
69*10696SDavid.Hollister@Sun.COM }
70*10696SDavid.Hollister@Sun.COM
71*10696SDavid.Hollister@Sun.COM static int
bitset_highbit(bitset_t * bs)72*10696SDavid.Hollister@Sun.COM bitset_highbit(bitset_t *bs)
73*10696SDavid.Hollister@Sun.COM {
74*10696SDavid.Hollister@Sun.COM int high;
75*10696SDavid.Hollister@Sun.COM int i;
76*10696SDavid.Hollister@Sun.COM
77*10696SDavid.Hollister@Sun.COM if ((bs->bs_set == NULL) || (bs->bs_words == 0))
78*10696SDavid.Hollister@Sun.COM return (-1);
79*10696SDavid.Hollister@Sun.COM
80*10696SDavid.Hollister@Sun.COM /* move backwards through words */
81*10696SDavid.Hollister@Sun.COM for (i = bs->bs_words; i >= 0; i--)
82*10696SDavid.Hollister@Sun.COM if (bs->bs_set[i])
83*10696SDavid.Hollister@Sun.COM break;
84*10696SDavid.Hollister@Sun.COM if (i < 0)
85*10696SDavid.Hollister@Sun.COM return (-1);
86*10696SDavid.Hollister@Sun.COM
87*10696SDavid.Hollister@Sun.COM /* move backwards through bits */
88*10696SDavid.Hollister@Sun.COM high = i << BT_ULSHIFT;
89*10696SDavid.Hollister@Sun.COM for (i = BT_NBIPUL - 1; i; i--)
90*10696SDavid.Hollister@Sun.COM if (BT_TEST(bs->bs_set, high + i))
91*10696SDavid.Hollister@Sun.COM break;
92*10696SDavid.Hollister@Sun.COM return (high + i + 1);
93*10696SDavid.Hollister@Sun.COM }
94*10696SDavid.Hollister@Sun.COM
95*10696SDavid.Hollister@Sun.COM static int
pow10(int exp)96*10696SDavid.Hollister@Sun.COM pow10(int exp)
97*10696SDavid.Hollister@Sun.COM {
98*10696SDavid.Hollister@Sun.COM int res;
99*10696SDavid.Hollister@Sun.COM
100*10696SDavid.Hollister@Sun.COM for (res = 1; exp; exp--)
101*10696SDavid.Hollister@Sun.COM res *= 10;
102*10696SDavid.Hollister@Sun.COM return (res);
103*10696SDavid.Hollister@Sun.COM }
104*10696SDavid.Hollister@Sun.COM
105*10696SDavid.Hollister@Sun.COM static int
log10(int val)106*10696SDavid.Hollister@Sun.COM log10(int val)
107*10696SDavid.Hollister@Sun.COM {
108*10696SDavid.Hollister@Sun.COM int res = 0;
109*10696SDavid.Hollister@Sun.COM
110*10696SDavid.Hollister@Sun.COM do {
111*10696SDavid.Hollister@Sun.COM res++;
112*10696SDavid.Hollister@Sun.COM val /= 10;
113*10696SDavid.Hollister@Sun.COM } while (val);
114*10696SDavid.Hollister@Sun.COM return (res);
115*10696SDavid.Hollister@Sun.COM }
116*10696SDavid.Hollister@Sun.COM
117*10696SDavid.Hollister@Sun.COM /*
118*10696SDavid.Hollister@Sun.COM * The following prints a bitset with a 'ruler' that look like this
119*10696SDavid.Hollister@Sun.COM *
120*10696SDavid.Hollister@Sun.COM * 11111111112222222222333333333344444444445555555555666666666677
121*10696SDavid.Hollister@Sun.COM * 012345678901234567890123456789012345678901234567890123456789012345678901
122*10696SDavid.Hollister@Sun.COM * xx:........................................................................
123*10696SDavid.Hollister@Sun.COM * 11111111111111111111111111111111111111111111
124*10696SDavid.Hollister@Sun.COM * 777777778888888888999999999900000000001111111111222222222233333333334444
125*10696SDavid.Hollister@Sun.COM * 234567890123456789012345678901234567890123456789012345678901234567890123
126*10696SDavid.Hollister@Sun.COM * ........................................................................
127*10696SDavid.Hollister@Sun.COM * 111111111111111111111111111111111111111111111111111111112222222222222222
128*10696SDavid.Hollister@Sun.COM * 444444555555555566666666667777777777888888888899999999990000000000111111
129*10696SDavid.Hollister@Sun.COM * 456789012345678901234567890123456789012345678901234567890123456789012345
130*10696SDavid.Hollister@Sun.COM * ........................................................................
131*10696SDavid.Hollister@Sun.COM * 2222222222
132*10696SDavid.Hollister@Sun.COM * 1111222222
133*10696SDavid.Hollister@Sun.COM * 6789012345
134*10696SDavid.Hollister@Sun.COM * ..........
135*10696SDavid.Hollister@Sun.COM *
136*10696SDavid.Hollister@Sun.COM * to identify individual bits that are set.
137*10696SDavid.Hollister@Sun.COM */
138*10696SDavid.Hollister@Sun.COM static void
bitset_print(bitset_t * bs,char * label,int width)139*10696SDavid.Hollister@Sun.COM bitset_print(bitset_t *bs, char *label, int width)
140*10696SDavid.Hollister@Sun.COM {
141*10696SDavid.Hollister@Sun.COM int val_start;
142*10696SDavid.Hollister@Sun.COM int val_max;
143*10696SDavid.Hollister@Sun.COM int label_width;
144*10696SDavid.Hollister@Sun.COM int ruler_width;
145*10696SDavid.Hollister@Sun.COM int v, vm, vi;
146*10696SDavid.Hollister@Sun.COM int nl, l;
147*10696SDavid.Hollister@Sun.COM int i;
148*10696SDavid.Hollister@Sun.COM int p;
149*10696SDavid.Hollister@Sun.COM char c;
150*10696SDavid.Hollister@Sun.COM
151*10696SDavid.Hollister@Sun.COM val_start = 0;
152*10696SDavid.Hollister@Sun.COM val_max = bitset_highbit(bs) + 1;
153*10696SDavid.Hollister@Sun.COM if (val_max <= val_start) {
154*10696SDavid.Hollister@Sun.COM mdb_printf("%s: empty-set", label);
155*10696SDavid.Hollister@Sun.COM return;
156*10696SDavid.Hollister@Sun.COM }
157*10696SDavid.Hollister@Sun.COM
158*10696SDavid.Hollister@Sun.COM label_width = strlen(label) + 1;
159*10696SDavid.Hollister@Sun.COM ruler_width = width - label_width;
160*10696SDavid.Hollister@Sun.COM
161*10696SDavid.Hollister@Sun.COM for (v = val_start; v < val_max; v = vm) {
162*10696SDavid.Hollister@Sun.COM if ((v + ruler_width) < val_max)
163*10696SDavid.Hollister@Sun.COM vm = v + ruler_width;
164*10696SDavid.Hollister@Sun.COM else
165*10696SDavid.Hollister@Sun.COM vm = val_max;
166*10696SDavid.Hollister@Sun.COM
167*10696SDavid.Hollister@Sun.COM nl = log10(vm) - 1;
168*10696SDavid.Hollister@Sun.COM for (l = nl; l >= 0; l--) {
169*10696SDavid.Hollister@Sun.COM p = pow10(l);
170*10696SDavid.Hollister@Sun.COM for (i = 0; i < label_width; i++)
171*10696SDavid.Hollister@Sun.COM mdb_printf(" ");
172*10696SDavid.Hollister@Sun.COM
173*10696SDavid.Hollister@Sun.COM for (vi = v; vi < vm; vi++) {
174*10696SDavid.Hollister@Sun.COM c = '0' + ((vi / p) % 10);
175*10696SDavid.Hollister@Sun.COM if ((l == nl) && (c == '0'))
176*10696SDavid.Hollister@Sun.COM c = ' ';
177*10696SDavid.Hollister@Sun.COM mdb_printf("%c", c);
178*10696SDavid.Hollister@Sun.COM }
179*10696SDavid.Hollister@Sun.COM
180*10696SDavid.Hollister@Sun.COM mdb_printf("\n");
181*10696SDavid.Hollister@Sun.COM }
182*10696SDavid.Hollister@Sun.COM
183*10696SDavid.Hollister@Sun.COM if (v == val_start) {
184*10696SDavid.Hollister@Sun.COM mdb_printf("%s:", label);
185*10696SDavid.Hollister@Sun.COM } else {
186*10696SDavid.Hollister@Sun.COM for (i = 0; i < label_width; i++)
187*10696SDavid.Hollister@Sun.COM mdb_printf(" ");
188*10696SDavid.Hollister@Sun.COM }
189*10696SDavid.Hollister@Sun.COM for (vi = v; vi < vm; vi++) {
190*10696SDavid.Hollister@Sun.COM if (BT_TEST(bs->bs_set, vi))
191*10696SDavid.Hollister@Sun.COM mdb_printf("X");
192*10696SDavid.Hollister@Sun.COM else
193*10696SDavid.Hollister@Sun.COM mdb_printf(".");
194*10696SDavid.Hollister@Sun.COM }
195*10696SDavid.Hollister@Sun.COM mdb_printf("\n");
196*10696SDavid.Hollister@Sun.COM }
197*10696SDavid.Hollister@Sun.COM }
198*10696SDavid.Hollister@Sun.COM
199*10696SDavid.Hollister@Sun.COM /*ARGSUSED*/
200*10696SDavid.Hollister@Sun.COM int
bitset(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)201*10696SDavid.Hollister@Sun.COM bitset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
202*10696SDavid.Hollister@Sun.COM {
203*10696SDavid.Hollister@Sun.COM bitset_t *bs;
204*10696SDavid.Hollister@Sun.COM
205*10696SDavid.Hollister@Sun.COM bs = bitset_get(addr);
206*10696SDavid.Hollister@Sun.COM if (bs == NULL)
207*10696SDavid.Hollister@Sun.COM return (DCMD_ERR);
208*10696SDavid.Hollister@Sun.COM
209*10696SDavid.Hollister@Sun.COM bitset_print(bs, "label", 80);
210*10696SDavid.Hollister@Sun.COM bitset_free(bs);
211*10696SDavid.Hollister@Sun.COM return (DCMD_OK);
212*10696SDavid.Hollister@Sun.COM }
213