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 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 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 * 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 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 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 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 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 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