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 2001-2002 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/time.h> 28 #include <ipp/ipp.h> 29 #include <ipp/ipp_impl.h> 30 #include <mdb/mdb_modapi.h> 31 32 static uintptr_t ipp_mod_byid; 33 static uintptr_t ipp_action_byid; 34 35 static int byid_walk_init(mdb_walk_state_t *); 36 static int byid_walk_step(mdb_walk_state_t *); 37 static void byid_walk_fini(mdb_walk_state_t *); 38 39 static int action(uintptr_t, uint_t, int, const mdb_arg_t *); 40 static int action_format(uintptr_t, const void *, void *); 41 static int action_dump(uintptr_t, ipp_action_t *, boolean_t); 42 static int action_summary(uintptr_t, ipp_action_t *, boolean_t); 43 44 static int cfglock(uintptr_t, uint_t, int, const mdb_arg_t *); 45 46 static int mod(uintptr_t, uint_t, int, const mdb_arg_t *); 47 static int mod_format(uintptr_t, const void *, void *); 48 static int mod_dump(uintptr_t, ipp_mod_t *, boolean_t); 49 static int mod_summary(uintptr_t, ipp_mod_t *, boolean_t); 50 static int cfglock(uintptr_t, uint_t, int, const mdb_arg_t *); 51 52 static int ippops(uintptr_t, uint_t, int, const mdb_arg_t *); 53 54 static int packet(uintptr_t, uint_t, int, const mdb_arg_t *); 55 static void dump_classes(uintptr_t, uint_t); 56 static void dump_log(uintptr_t, uint_t); 57 static void aid2aname(ipp_action_id_t, char *); 58 59 static int ref_walk_init(mdb_walk_state_t *); 60 static int ref_walk_step(mdb_walk_state_t *); 61 static void ref_walk_fini(mdb_walk_state_t *); 62 63 typedef struct afdata { 64 boolean_t af_banner; 65 uint_t af_flags; 66 } afdata_t; 67 68 #define AF_VERBOSE 1 69 70 typedef struct mfdata { 71 boolean_t mf_banner; 72 uint_t mf_flags; 73 } mfdata_t; 74 75 #define MF_VERBOSE 1 76 77 /* 78 * walker. Skips entries that are NULL. 79 */ 80 81 static int 82 byid_walk_init( 83 mdb_walk_state_t *wsp) 84 { 85 uintptr_t start; 86 87 if (mdb_vread(&start, sizeof (uintptr_t), wsp->walk_addr) == -1) { 88 mdb_warn("failed to read from address %p", wsp->walk_addr); 89 return (WALK_ERR); 90 } 91 92 wsp->walk_addr = start; 93 94 return (WALK_NEXT); 95 } 96 97 static int 98 byid_walk_step( 99 mdb_walk_state_t *wsp) 100 { 101 int status; 102 void *ptr; 103 104 if (mdb_vread(&ptr, sizeof (void *), wsp->walk_addr) == -1) { 105 mdb_warn("failed to read from address %p", wsp->walk_addr); 106 return (WALK_ERR); 107 } 108 109 if (ptr == (void *)-1) { 110 status = WALK_DONE; 111 } else if (ptr == NULL) { 112 status = WALK_NEXT; 113 } else { 114 status = wsp->walk_callback((uintptr_t)ptr, NULL, 115 wsp->walk_cbdata); 116 } 117 118 wsp->walk_addr += sizeof (void *); 119 120 return (status); 121 } 122 123 /*ARGSUSED*/ 124 static void 125 byid_walk_fini( 126 mdb_walk_state_t *wsp) 127 { 128 } 129 130 131 /*ARGSUSED*/ 132 static int 133 action( 134 uintptr_t addr, 135 uint_t flags, 136 int argc, 137 const mdb_arg_t *argv) 138 { 139 int status; 140 int rc = DCMD_OK; 141 afdata_t *afp; 142 143 afp = mdb_zalloc(sizeof (afdata_t), UM_SLEEP); 144 145 if (mdb_getopts(argc, argv, 146 'v', MDB_OPT_SETBITS, AF_VERBOSE, &afp->af_flags, 147 NULL) != argc) 148 return (DCMD_USAGE); 149 150 if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) 151 afp->af_banner = B_TRUE; 152 153 if (flags & DCMD_ADDRSPEC) { 154 status = action_format(addr, NULL, afp); 155 rc = (status == WALK_NEXT) ? DCMD_OK : DCMD_ERR; 156 goto cleanup; 157 } 158 159 if (mdb_pwalk("ipp_byid", action_format, afp, 160 ipp_action_byid) == -1) { 161 mdb_warn("failed to execute ipp_byid walk"); 162 rc = DCMD_ERR; 163 } 164 165 cleanup: 166 mdb_free(afp, sizeof (afdata_t)); 167 168 return (rc); 169 } 170 171 /*ARGSUSED*/ 172 static int 173 action_format( 174 uintptr_t addr, 175 const void *data, 176 void *arg) 177 { 178 afdata_t *afp = (afdata_t *)arg; 179 ipp_action_t *ap; 180 int rc; 181 182 ap = mdb_alloc(sizeof (ipp_action_t), UM_SLEEP); 183 if (mdb_vread(ap, sizeof (ipp_action_t), addr) == -1) { 184 mdb_warn("failed to read ipp_action_t at %p", addr); 185 rc = WALK_ERR; 186 goto done; 187 } 188 189 if (afp->af_flags & AF_VERBOSE) 190 rc = action_dump(addr, ap, afp->af_banner); 191 else 192 rc = action_summary(addr, ap, afp->af_banner); 193 194 afp->af_banner = B_FALSE; 195 done: 196 mdb_free(ap, sizeof (ipp_action_t)); 197 return (rc); 198 } 199 200 /*ARGSUSED*/ 201 static int 202 action_dump( 203 uintptr_t addr, 204 ipp_action_t *ap, 205 boolean_t banner) 206 { 207 mdb_printf("%?p: %20s = %d\n", addr, "id", ap->ippa_id); 208 if (!ap->ippa_nameless) { 209 mdb_printf("%?s %20s = %s\n", "", "name", ap->ippa_name); 210 } 211 mdb_printf("%?s %20s = 0x%p\n", "", "mod", ap->ippa_mod); 212 mdb_printf("%?s %20s = 0x%p\n", "", "ref", ap->ippa_ref); 213 mdb_printf("%?s %20s = 0x%p\n", "", "refby", ap->ippa_refby); 214 mdb_printf("%?s %20s = 0x%p\n", "", "ptr", ap->ippa_ptr); 215 216 mdb_printf("%?s %20s = ", "", "state"); 217 switch (ap->ippa_state) { 218 case IPP_ASTATE_PROTO: 219 mdb_printf("%s\n", "PROTO"); 220 break; 221 case IPP_ASTATE_CONFIG_PENDING: 222 mdb_printf("%s\n", "CONFIG_PENDING"); 223 break; 224 case IPP_ASTATE_AVAILABLE: 225 mdb_printf("%s\n", "AVAILABLE"); 226 break; 227 default: 228 mdb_printf("%s\n", "<unknown>"); 229 break; 230 } 231 232 mdb_printf("%?s %20s = %d\n", "", "packets", ap->ippa_packets); 233 mdb_printf("%?s %20s = %d\n", "", "hold_count", ap->ippa_hold_count); 234 mdb_printf("%?s %20s = %s\n", "", "destruct_pending", 235 (ap->ippa_destruct_pending) ? "TRUE" : "FALSE"); 236 mdb_printf("%?s %20s = 0x%p\n", "", "lock", 237 addr + ((uintptr_t)ap->ippa_lock - (uintptr_t)ap)); 238 mdb_printf("%?s %20s = 0x%p\n", "", "config_lock", 239 addr + ((uintptr_t)ap->ippa_config_lock - (uintptr_t)ap)); 240 mdb_printf("\n"); 241 242 return (WALK_NEXT); 243 } 244 245 static int 246 action_summary( 247 uintptr_t addr, 248 ipp_action_t *ap, 249 boolean_t banner) 250 { 251 ipp_mod_t *imp; 252 uintptr_t ptr; 253 254 if (banner) 255 mdb_printf("%?s %<u>%20s %5s %20s%</u>\n", 256 "", "NAME", "ID", "MODNAME"); 257 258 imp = mdb_alloc(sizeof (ipp_mod_t), UM_SLEEP); 259 ptr = (uintptr_t)ap->ippa_mod; 260 if (mdb_vread(imp, sizeof (ipp_mod_t), ptr) == -1) { 261 mdb_warn("failed to read ipp_mod_t at %p", ptr); 262 mdb_free(imp, sizeof (ipp_mod_t)); 263 return (WALK_ERR); 264 } 265 266 mdb_printf("%?p:%20s %5d %20s\n", addr, ap->ippa_name, ap->ippa_id, 267 imp->ippm_name); 268 269 mdb_free(imp, sizeof (ipp_mod_t)); 270 return (WALK_NEXT); 271 } 272 273 /*ARGSUSED*/ 274 static int 275 cfglock( 276 uintptr_t addr, 277 uint_t flags, 278 int argc, 279 const mdb_arg_t *argv) 280 { 281 cfglock_t *clp; 282 283 if ((flags & DCMD_ADDRSPEC) == 0) 284 return (DCMD_ERR); 285 286 clp = mdb_alloc(sizeof (cfglock_t), UM_SLEEP); 287 if (mdb_vread(clp, sizeof (cfglock_t), addr) == -1) { 288 mdb_warn("failed to read cfglock_t at %p", addr); 289 mdb_free(clp, sizeof (cfglock_t)); 290 return (WALK_ERR); 291 } 292 293 mdb_printf("%?p: %20s = %p\n", addr, "owner", clp->cl_owner); 294 mdb_printf("%?s %20s = %s\n", "", "reader", 295 clp->cl_reader ? "TRUE" : "FALSE"); 296 mdb_printf("%?s %20s = %d\n", "", "writers", clp->cl_writers); 297 mdb_printf("%?s %20s = 0x%p\n", "", "mutex", 298 addr + ((uintptr_t)clp->cl_mutex - (uintptr_t)clp)); 299 mdb_printf("%?s %20s = 0x%p\n", "", "cv", 300 addr + ((uintptr_t)clp->cl_cv - (uintptr_t)clp)); 301 mdb_printf("\n"); 302 303 mdb_free(clp, sizeof (cfglock_t)); 304 305 return (DCMD_OK); 306 } 307 308 /*ARGSUSED*/ 309 static int 310 mod( 311 uintptr_t addr, 312 uint_t flags, 313 int argc, 314 const mdb_arg_t *argv) 315 { 316 int status; 317 int rc = DCMD_OK; 318 mfdata_t *mfp; 319 320 mfp = mdb_zalloc(sizeof (mfdata_t), UM_SLEEP); 321 322 if (mdb_getopts(argc, argv, 323 'v', MDB_OPT_SETBITS, MF_VERBOSE, &mfp->mf_flags, 324 NULL) != argc) 325 return (DCMD_USAGE); 326 327 if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) 328 mfp->mf_banner = B_TRUE; 329 330 if (flags & DCMD_ADDRSPEC) { 331 status = mod_format(addr, NULL, mfp); 332 rc = (status == WALK_NEXT) ? DCMD_OK : DCMD_ERR; 333 goto cleanup; 334 } 335 336 if (mdb_pwalk("ipp_byid", mod_format, mfp, 337 ipp_mod_byid) == -1) { 338 mdb_warn("failed to execute ipp_byid walk"); 339 rc = DCMD_ERR; 340 } 341 342 cleanup: 343 mdb_free(mfp, sizeof (mfdata_t)); 344 345 return (rc); 346 } 347 348 /*ARGSUSED*/ 349 static int 350 mod_format( 351 uintptr_t addr, 352 const void *data, 353 void *arg) 354 { 355 mfdata_t *mfp = (mfdata_t *)arg; 356 ipp_mod_t *imp; 357 int rc; 358 359 imp = mdb_alloc(sizeof (ipp_mod_t), UM_SLEEP); 360 if (mdb_vread(imp, sizeof (ipp_mod_t), addr) == -1) { 361 mdb_warn("failed to read ipp_mod_t at %p", addr); 362 rc = WALK_ERR; 363 goto done; 364 } 365 366 if (mfp->mf_flags & MF_VERBOSE) 367 rc = mod_dump(addr, imp, mfp->mf_banner); 368 else 369 rc = mod_summary(addr, imp, mfp->mf_banner); 370 371 mfp->mf_banner = B_FALSE; 372 done: 373 mdb_free(imp, sizeof (ipp_mod_t)); 374 return (rc); 375 } 376 377 /*ARGSUSED*/ 378 static int 379 mod_dump( 380 uintptr_t addr, 381 ipp_mod_t *imp, 382 boolean_t banner) 383 { 384 mdb_printf("%?p: %20s = %d\n", addr, "id", imp->ippm_id); 385 mdb_printf("%?s %20s = %s\n", "", "name", imp->ippm_name); 386 mdb_printf("%?s %20s = 0x%p\n", "", "ops", imp->ippm_ops); 387 mdb_printf("%?s %20s = 0x%p\n", "", "action", imp->ippm_action); 388 389 mdb_printf("%?s %20s = ", "", "state"); 390 switch (imp->ippm_state) { 391 case IPP_MODSTATE_PROTO: 392 mdb_printf("%s\n", "PROTO"); 393 break; 394 case IPP_MODSTATE_AVAILABLE: 395 mdb_printf("%s\n", "AVAILABLE"); 396 break; 397 default: 398 mdb_printf("%s\n", "<unknown>"); 399 break; 400 } 401 402 mdb_printf("%?s %20s = %d\n", "", "hold_count", imp->ippm_hold_count); 403 mdb_printf("%?s %20s = %s\n", "", "destruct_pending", 404 (imp->ippm_destruct_pending) ? "TRUE" : "FALSE"); 405 mdb_printf("%?s %20s = 0x%p\n", "", "lock", 406 addr + ((uintptr_t)imp->ippm_lock - (uintptr_t)imp)); 407 mdb_printf("\n"); 408 409 return (WALK_NEXT); 410 } 411 412 static int 413 mod_summary( 414 uintptr_t addr, 415 ipp_mod_t *imp, 416 boolean_t banner) 417 { 418 if (banner) 419 mdb_printf("%?s %<u>%20s %5s%</u>\n", 420 "", "NAME", "ID"); 421 422 mdb_printf("%?p:%20s %5d\n", addr, imp->ippm_name, imp->ippm_id); 423 424 return (WALK_NEXT); 425 } 426 427 /*ARGSUSED*/ 428 static int 429 ippops( 430 uintptr_t addr, 431 uint_t flags, 432 int argc, 433 const mdb_arg_t *argv) 434 { 435 ipp_ops_t *ippo; 436 GElf_Sym sym; 437 char buf[MDB_SYM_NAMLEN]; 438 439 if ((flags & DCMD_ADDRSPEC) == 0) 440 return (DCMD_ERR); 441 442 ippo = mdb_alloc(sizeof (ipp_ops_t), UM_SLEEP); 443 if (mdb_vread(ippo, sizeof (ipp_ops_t), addr) == -1) { 444 mdb_warn("failed to read ipp_ops_t at %p", addr); 445 mdb_free(ippo, sizeof (ipp_ops_t)); 446 return (DCMD_ERR); 447 } 448 449 mdb_printf("%?p: %20s = %d\n", addr, "rev", ippo->ippo_rev); 450 451 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_create, 452 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0) 453 mdb_printf("%?s %20s = %s\n", "", "action_create", buf); 454 else 455 mdb_printf("%?s %20s = 0x%p\n", "", "action_create", 456 ippo->ippo_action_create); 457 458 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_modify, 459 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0) 460 mdb_printf("%?s %20s = %s\n", "", "action_modify", buf); 461 else 462 mdb_printf("%?s %20s = 0x%p\n", "", "action_modify", 463 ippo->ippo_action_modify); 464 465 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_destroy, 466 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0) 467 mdb_printf("%?s %20s = %s\n", "", "action_destroy", buf); 468 else 469 mdb_printf("%?s %20s = 0x%p\n", "", "action_destroy", 470 ippo->ippo_action_destroy); 471 472 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_info, 473 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0) 474 mdb_printf("%?s %20s = %s\n", "", "action_info", buf); 475 else 476 mdb_printf("%?s %20s = 0x%p\n", "", "action_info", 477 ippo->ippo_action_info); 478 479 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_invoke, 480 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0) 481 mdb_printf("%?s %20s = %s\n", "", "action_invoke", buf); 482 else 483 mdb_printf("%?s %20s = 0x%p\n", "", "action_invoke", 484 ippo->ippo_action_invoke); 485 486 mdb_printf("\n"); 487 488 mdb_free(ippo, sizeof (ipp_ops_t)); 489 return (DCMD_OK); 490 } 491 492 static int 493 ref_walk_init( 494 mdb_walk_state_t *wsp) 495 { 496 if (wsp->walk_addr == 0) 497 return (WALK_DONE); 498 499 return (WALK_NEXT); 500 } 501 502 static int 503 ref_walk_step( 504 mdb_walk_state_t *wsp) 505 { 506 ipp_ref_t *rp; 507 int status; 508 509 if (wsp->walk_addr == 0) 510 return (WALK_DONE); 511 512 rp = mdb_alloc(sizeof (ipp_ref_t), UM_SLEEP); 513 514 if (mdb_vread(rp, sizeof (ipp_ref_t), wsp->walk_addr) == -1) { 515 mdb_warn("failed to read ipp_ref_t at %p", wsp->walk_addr); 516 mdb_free(rp, sizeof (ipp_ref_t)); 517 return (WALK_ERR); 518 } 519 520 status = wsp->walk_callback((uintptr_t)rp->ippr_ptr, NULL, 521 wsp->walk_cbdata); 522 523 wsp->walk_addr = (uintptr_t)(rp->ippr_nextp); 524 525 mdb_free(rp, sizeof (ipp_ref_t)); 526 return (status); 527 } 528 529 /*ARGSUSED*/ 530 static void 531 ref_walk_fini( 532 mdb_walk_state_t *wsp) 533 { 534 } 535 536 /*ARGSUSED*/ 537 static int 538 packet( 539 uintptr_t addr, 540 uint_t flags, 541 int argc, 542 const mdb_arg_t *argv) 543 { 544 ipp_packet_t *pp; 545 546 if ((flags & DCMD_ADDRSPEC) == 0) 547 return (DCMD_ERR); 548 549 pp = mdb_alloc(sizeof (ipp_packet_t), UM_SLEEP); 550 if (mdb_vread(pp, sizeof (ipp_packet_t), addr) == -1) { 551 mdb_warn("failed to read ipp_packet_t at %p", addr); 552 mdb_free(pp, sizeof (ipp_packet_t)); 553 return (DCMD_ERR); 554 } 555 556 mdb_printf("%?p: %20s = 0x%p\n", addr, "data", pp->ippp_data); 557 mdb_printf("%?s %20s = 0x%p\n", "", "private", pp->ippp_private); 558 dump_classes((uintptr_t)pp->ippp_class_array, pp->ippp_class_windex); 559 dump_log((uintptr_t)pp->ippp_log, pp->ippp_log_windex); 560 561 mdb_free(pp, sizeof (ipp_packet_t)); 562 return (DCMD_OK); 563 } 564 565 static void 566 dump_classes( 567 uintptr_t ptr, 568 uint_t nelt) 569 { 570 ipp_class_t *array; 571 ipp_class_t *cp; 572 uint_t i; 573 boolean_t first_time = B_TRUE; 574 char buf[MAXNAMELEN]; 575 576 array = mdb_alloc(sizeof (ipp_class_t) * nelt, UM_SLEEP); 577 if (mdb_vread(array, sizeof (ipp_class_t) * nelt, ptr) == -1) { 578 mdb_warn("failed to read ipp_class_t array at %p", ptr); 579 return; 580 } 581 582 for (i = 0; i < nelt; i++) { 583 if (first_time) { 584 mdb_printf("%20s %?s %<u>%15s %15s%</u>\n", "", 585 "classes", "NAME", "ACTION"); 586 first_time = B_FALSE; 587 } 588 589 cp = &(array[i]); 590 aid2aname(cp->ippc_aid, buf); 591 mdb_printf("%20s %?p: %15s %15s%\n", "", 592 ptr + (i * sizeof (ipp_class_t)), cp->ippc_name, buf); 593 } 594 595 mdb_free(cp, sizeof (ipp_class_t) * nelt); 596 } 597 598 static void 599 dump_log( 600 uintptr_t ptr, 601 uint_t nelt) 602 { 603 ipp_log_t *array; 604 ipp_log_t *lp; 605 uint_t i; 606 boolean_t first_time = B_TRUE; 607 char buf[MAXNAMELEN]; 608 609 array = mdb_alloc(sizeof (ipp_log_t) * nelt, UM_SLEEP); 610 if (mdb_vread(array, sizeof (ipp_log_t) * nelt, ptr) == -1) { 611 mdb_warn("failed to read ipp_log_t array at %p", ptr); 612 return; 613 } 614 615 for (i = 0; i < nelt; i++) { 616 if (first_time) { 617 mdb_printf("%20s %?s %<u>%15s %15s%</u>\n", "", 618 "log", "CLASS NAME", "ACTION"); 619 first_time = B_FALSE; 620 } 621 622 lp = &(array[i]); 623 aid2aname(lp->ippl_aid, buf); 624 mdb_printf("%20s %?p: %15s %15s\n", "", 625 ptr + (i * sizeof (ipp_class_t)), lp->ippl_name, buf); 626 } 627 628 mdb_free(lp, sizeof (ipp_log_t) * nelt); 629 } 630 631 static void 632 aid2aname( 633 ipp_action_id_t aid, 634 char *buf) 635 { 636 uintptr_t addr; 637 uintptr_t ptr; 638 ipp_action_t *ap; 639 640 switch (aid) { 641 case IPP_ACTION_INVAL: 642 strcpy(buf, "invalid"); 643 break; 644 case IPP_ACTION_CONT: 645 strcpy(buf, "continue"); 646 break; 647 case IPP_ACTION_DEFER: 648 strcpy(buf, "defer"); 649 break; 650 case IPP_ACTION_DROP: 651 strcpy(buf, "drop"); 652 break; 653 default: 654 if (mdb_vread(&addr, sizeof (uintptr_t), 655 ipp_action_byid) == -1) { 656 mdb_warn("failed to read from address %p", 657 ipp_action_byid); 658 strcpy(buf, "???"); 659 break; 660 } 661 662 addr += ((int32_t)aid * sizeof (void *)); 663 if (mdb_vread(&ptr, sizeof (uintptr_t), addr) == -1) { 664 mdb_warn("failed to read from address %p", addr); 665 strcpy(buf, "???"); 666 break; 667 } 668 669 ap = mdb_alloc(sizeof (ipp_action_t), UM_SLEEP); 670 if (mdb_vread(ap, sizeof (ipp_action_t), ptr) == -1) { 671 mdb_warn("failed to read ipp_action_t at %p", ptr); 672 mdb_free(ap, sizeof (ipp_action_t)); 673 strcpy(buf, "???"); 674 break; 675 } 676 677 if (ap->ippa_id != aid) { 678 mdb_warn("corrupt action at %p", ptr); 679 mdb_free(ap, sizeof (ipp_action_t)); 680 strcpy(buf, "???"); 681 break; 682 } 683 684 strcpy(buf, ap->ippa_name); 685 } 686 } 687 688 static const mdb_dcmd_t dcmds[] = { 689 { "ipp_action", "?[-v]", 690 "display ipp_action structure", action }, 691 { "ipp_mod", "?[-v]", 692 "display ipp_mod structure", mod }, 693 { "cfglock", ":", 694 "display cfglock structure", cfglock }, 695 { "ippops", ":", 696 "display ipp_ops structure", ippops }, 697 { "ipp_packet", ":", 698 "display ipp_packet structure", packet }, 699 { NULL } 700 }; 701 702 static const mdb_walker_t walkers[] = { 703 { "ipp_byid", "walk byid array", byid_walk_init, byid_walk_step, 704 byid_walk_fini }, 705 { "ipp_ref", "walk reference list", ref_walk_init, ref_walk_step, 706 ref_walk_fini }, 707 { NULL } 708 }; 709 710 static const mdb_modinfo_t ipp_modinfo = { MDB_API_VERSION, dcmds, walkers }; 711 712 const mdb_modinfo_t * 713 _mdb_init(void) 714 { 715 GElf_Sym sym; 716 717 if (mdb_lookup_by_name("ipp_action_byid", &sym) == -1) { 718 mdb_warn("failed to lookup 'ipp_action_byid'"); 719 return (NULL); 720 } 721 722 ipp_action_byid = (uintptr_t)sym.st_value; 723 724 if (mdb_lookup_by_name("ipp_mod_byid", &sym) == -1) { 725 mdb_warn("failed to lookup 'ipp_mod_byid'"); 726 return (NULL); 727 } 728 729 ipp_mod_byid = (uintptr_t)sym.st_value; 730 731 return (&ipp_modinfo); 732 } 733