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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 /* 26 * Mdb kernel support module. This module is loaded automatically when the 27 * kvm target is initialized. Any global functions declared here are exported 28 * for the resolution of symbols in subsequently loaded modules. 29 * 30 * WARNING: Do not assume that static variables in mdb_ks will be initialized 31 * to zero. 32 */ 33 34 35 #include <mdb/mdb_target.h> 36 #include <mdb/mdb_param.h> 37 #include <mdb/mdb_modapi.h> 38 #include <mdb/mdb_ks.h> 39 40 #include <sys/types.h> 41 #include <sys/procfs.h> 42 #include <sys/proc.h> 43 #include <sys/dnlc.h> 44 #include <sys/autoconf.h> 45 #include <sys/machelf.h> 46 #include <sys/modctl.h> 47 #include <sys/hwconf.h> 48 #include <sys/kobj.h> 49 #include <sys/fs/autofs.h> 50 #include <sys/ddi_impldefs.h> 51 #include <sys/refstr_impl.h> 52 #include <sys/cpuvar.h> 53 #include <sys/dlpi.h> 54 #include <sys/clock_impl.h> 55 #include <sys/swap.h> 56 #include <errno.h> 57 58 #include <vm/seg_vn.h> 59 #include <vm/page.h> 60 61 #define MDB_PATH_NELEM 256 /* Maximum path components */ 62 63 typedef struct mdb_path { 64 size_t mdp_nelem; /* Number of components */ 65 uint_t mdp_complete; /* Path completely resolved? */ 66 uintptr_t mdp_vnode[MDB_PATH_NELEM]; /* Array of vnode_t addresses */ 67 char *mdp_name[MDB_PATH_NELEM]; /* Array of name components */ 68 } mdb_path_t; 69 70 static int mdb_autonode2path(uintptr_t, mdb_path_t *); 71 static int mdb_sprintpath(char *, size_t, mdb_path_t *); 72 73 /* 74 * Kernel parameters from <sys/param.h> which we keep in-core: 75 */ 76 unsigned long _mdb_ks_pagesize; 77 unsigned int _mdb_ks_pageshift; 78 unsigned long _mdb_ks_pageoffset; 79 unsigned long long _mdb_ks_pagemask; 80 unsigned long _mdb_ks_mmu_pagesize; 81 unsigned int _mdb_ks_mmu_pageshift; 82 unsigned long _mdb_ks_mmu_pageoffset; 83 unsigned long _mdb_ks_mmu_pagemask; 84 uintptr_t _mdb_ks_kernelbase; 85 uintptr_t _mdb_ks_userlimit; 86 uintptr_t _mdb_ks_userlimit32; 87 uintptr_t _mdb_ks_argsbase; 88 unsigned long _mdb_ks_msg_bsize; 89 unsigned long _mdb_ks_defaultstksz; 90 int _mdb_ks_ncpu; 91 92 /* 93 * In-core copy of DNLC information: 94 */ 95 #define MDB_DNLC_HSIZE 1024 96 #define MDB_DNLC_HASH(vp) (((uintptr_t)(vp) >> 3) & (MDB_DNLC_HSIZE - 1)) 97 #define MDB_DNLC_NCACHE_SZ(ncp) (sizeof (ncache_t) + (ncp)->namlen) 98 #define MDB_DNLC_MAX_RETRY 4 99 100 101 static ncache_t **dnlc_hash; /* mdbs hash array of dnlc entries */ 102 103 /* 104 * This will be the location of the vnodeops pointer for "autofs_vnodeops" 105 * The pointer still needs to be read with mdb_vread() to get the location 106 * of the vnodeops structure for autofs. 107 */ 108 static struct vnodeops *autofs_vnops_ptr; 109 110 /* 111 * STREAMS queue registrations: 112 */ 113 typedef struct mdb_qinfo { 114 const mdb_qops_t *qi_ops; /* Address of ops vector */ 115 uintptr_t qi_addr; /* Address of qinit structure (key) */ 116 struct mdb_qinfo *qi_next; /* Next qinfo in list */ 117 } mdb_qinfo_t; 118 119 static mdb_qinfo_t *qi_head; /* Head of qinfo chain */ 120 121 /* 122 * Device naming callback structure: 123 */ 124 typedef struct nm_query { 125 const char *nm_name; /* Device driver name [in/out] */ 126 major_t nm_major; /* Device major number [in/out] */ 127 ushort_t nm_found; /* Did we find a match? [out] */ 128 } nm_query_t; 129 130 /* 131 * Address-to-modctl callback structure: 132 */ 133 typedef struct a2m_query { 134 uintptr_t a2m_addr; /* Virtual address [in] */ 135 uintptr_t a2m_where; /* Modctl address [out] */ 136 } a2m_query_t; 137 138 /* 139 * Segment-to-mdb_map callback structure: 140 */ 141 typedef struct { 142 struct seg_ops *asm_segvn_ops; /* Address of segvn ops [in] */ 143 void (*asm_callback)(const struct mdb_map *, void *); /* Callb [in] */ 144 void *asm_cbdata; /* Callback data [in] */ 145 } asmap_arg_t; 146 147 static void 148 dnlc_free(void) 149 { 150 ncache_t *ncp, *next; 151 int i; 152 153 if (dnlc_hash == NULL) { 154 return; 155 } 156 157 /* 158 * Free up current dnlc entries 159 */ 160 for (i = 0; i < MDB_DNLC_HSIZE; i++) { 161 for (ncp = dnlc_hash[i]; ncp; ncp = next) { 162 next = ncp->hash_next; 163 mdb_free(ncp, MDB_DNLC_NCACHE_SZ(ncp)); 164 } 165 } 166 mdb_free(dnlc_hash, MDB_DNLC_HSIZE * sizeof (ncache_t *)); 167 dnlc_hash = NULL; 168 } 169 170 char bad_dnlc[] = "inconsistent dnlc chain: %d, ncache va: %p" 171 " - continuing with the rest\n"; 172 173 static int 174 dnlc_load(void) 175 { 176 int i; /* hash index */ 177 int retry_cnt = 0; 178 int skip_bad_chains = 0; 179 int nc_hashsz; /* kernel hash array size */ 180 uintptr_t nc_hash_addr; /* kernel va of ncache hash array */ 181 uintptr_t head; /* kernel va of head of hash chain */ 182 183 /* 184 * If we've already cached the DNLC and we're looking at a dump, 185 * our cache is good forever, so don't bother re-loading. 186 */ 187 if (dnlc_hash && mdb_prop_postmortem) { 188 return (0); 189 } 190 191 /* 192 * For a core dump, retries wont help. 193 * Just print and skip any bad chains. 194 */ 195 if (mdb_prop_postmortem) { 196 skip_bad_chains = 1; 197 } 198 retry: 199 if (retry_cnt++ >= MDB_DNLC_MAX_RETRY) { 200 /* 201 * Give up retrying the rapidly changing dnlc. 202 * Just print and skip any bad chains 203 */ 204 skip_bad_chains = 1; 205 } 206 207 dnlc_free(); /* Free up the mdb hashed dnlc - if any */ 208 209 /* 210 * Although nc_hashsz and the location of nc_hash doesn't currently 211 * change, it may do in the future with a more dynamic dnlc. 212 * So always read these values afresh. 213 */ 214 if (mdb_readvar(&nc_hashsz, "nc_hashsz") == -1) { 215 mdb_warn("failed to read nc_hashsz"); 216 return (-1); 217 } 218 if (mdb_readvar(&nc_hash_addr, "nc_hash") == -1) { 219 mdb_warn("failed to read nc_hash"); 220 return (-1); 221 } 222 223 /* 224 * Allocate the mdb dnlc hash array 225 */ 226 dnlc_hash = mdb_zalloc(MDB_DNLC_HSIZE * sizeof (ncache_t *), UM_SLEEP); 227 228 /* for each kernel hash chain */ 229 for (i = 0, head = nc_hash_addr; i < nc_hashsz; 230 i++, head += sizeof (nc_hash_t)) { 231 nc_hash_t nch; /* kernel hash chain header */ 232 ncache_t *ncp; /* name cache pointer */ 233 int hash; /* mdb hash value */ 234 uintptr_t nc_va; /* kernel va of next ncache */ 235 uintptr_t ncprev_va; /* kernel va of previous ncache */ 236 int khash; /* kernel dnlc hash value */ 237 uchar_t namelen; /* name length */ 238 ncache_t nc; /* name cache entry */ 239 int nc_size; /* size of a name cache entry */ 240 241 /* 242 * We read each element of the nc_hash array individually 243 * just before we process the entries in its chain. This is 244 * because the chain can change so rapidly on a running system. 245 */ 246 if (mdb_vread(&nch, sizeof (nc_hash_t), head) == -1) { 247 mdb_warn("failed to read nc_hash chain header %d", i); 248 dnlc_free(); 249 return (-1); 250 } 251 252 ncprev_va = head; 253 nc_va = (uintptr_t)(nch.hash_next); 254 /* for each entry in the chain */ 255 while (nc_va != head) { 256 /* 257 * The size of the ncache entries varies 258 * because the name is appended to the structure. 259 * So we read in the structure then re-read 260 * for the structure plus name. 261 */ 262 if (mdb_vread(&nc, sizeof (ncache_t), nc_va) == -1) { 263 if (skip_bad_chains) { 264 mdb_warn(bad_dnlc, i, nc_va); 265 break; 266 } 267 goto retry; 268 } 269 nc_size = MDB_DNLC_NCACHE_SZ(&nc); 270 ncp = mdb_alloc(nc_size, UM_SLEEP); 271 if (mdb_vread(ncp, nc_size - 1, nc_va) == -1) { 272 mdb_free(ncp, nc_size); 273 if (skip_bad_chains) { 274 mdb_warn(bad_dnlc, i, nc_va); 275 break; 276 } 277 goto retry; 278 } 279 280 /* 281 * Check for chain consistency 282 */ 283 if ((uintptr_t)ncp->hash_prev != ncprev_va) { 284 mdb_free(ncp, nc_size); 285 if (skip_bad_chains) { 286 mdb_warn(bad_dnlc, i, nc_va); 287 break; 288 } 289 goto retry; 290 } 291 /* 292 * Terminate the new name with a null. 293 * Note, we allowed space for this null when 294 * allocating space for the entry. 295 */ 296 ncp->name[ncp->namlen] = '\0'; 297 298 /* 299 * Validate new entry by re-hashing using the 300 * kernel dnlc hash function and comparing the hash 301 */ 302 DNLCHASH(ncp->name, ncp->dp, khash, namelen); 303 if ((namelen != ncp->namlen) || 304 (khash != ncp->hash)) { 305 mdb_free(ncp, nc_size); 306 if (skip_bad_chains) { 307 mdb_warn(bad_dnlc, i, nc_va); 308 break; 309 } 310 goto retry; 311 } 312 313 /* 314 * Finally put the validated entry into the mdb 315 * hash chains. Reuse the kernel next hash field 316 * for the mdb hash chain pointer. 317 */ 318 hash = MDB_DNLC_HASH(ncp->vp); 319 ncprev_va = nc_va; 320 nc_va = (uintptr_t)(ncp->hash_next); 321 ncp->hash_next = dnlc_hash[hash]; 322 dnlc_hash[hash] = ncp; 323 } 324 } 325 return (0); 326 } 327 328 /*ARGSUSED*/ 329 int 330 dnlcdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 331 { 332 ncache_t *ent; 333 int i; 334 335 if ((flags & DCMD_ADDRSPEC) || argc != 0) 336 return (DCMD_USAGE); 337 338 if (dnlc_load() == -1) 339 return (DCMD_ERR); 340 341 mdb_printf("%<u>%-?s %-?s %-32s%</u>\n", "VP", "DVP", "NAME"); 342 343 for (i = 0; i < MDB_DNLC_HSIZE; i++) { 344 for (ent = dnlc_hash[i]; ent != NULL; ent = ent->hash_next) { 345 mdb_printf("%0?p %0?p %s\n", 346 ent->vp, ent->dp, ent->name); 347 } 348 } 349 350 return (DCMD_OK); 351 } 352 353 static int 354 mdb_sprintpath(char *buf, size_t len, mdb_path_t *path) 355 { 356 char *s = buf; 357 int i; 358 359 if (len < sizeof ("/...")) 360 return (-1); 361 362 if (!path->mdp_complete) { 363 (void) strcpy(s, "??"); 364 s += 2; 365 366 if (path->mdp_nelem == 0) 367 return (-1); 368 } 369 370 if (path->mdp_nelem == 0) { 371 (void) strcpy(s, "/"); 372 return (0); 373 } 374 375 for (i = path->mdp_nelem - 1; i >= 0; i--) { 376 /* 377 * Number of bytes left is the distance from where we 378 * are to the end, minus 2 for '/' and '\0' 379 */ 380 ssize_t left = (ssize_t)(&buf[len] - s) - 2; 381 382 if (left <= 0) 383 break; 384 385 *s++ = '/'; 386 (void) strncpy(s, path->mdp_name[i], left); 387 s[left - 1] = '\0'; 388 s += strlen(s); 389 390 if (left < strlen(path->mdp_name[i])) 391 break; 392 } 393 394 if (i >= 0) 395 (void) strcpy(&buf[len - 4], "..."); 396 397 return (0); 398 } 399 400 static int 401 mdb_autonode2path(uintptr_t addr, mdb_path_t *path) 402 { 403 fninfo_t fni; 404 fnnode_t fn; 405 406 vnode_t vn; 407 vfs_t vfs; 408 struct vnodeops *autofs_vnops = NULL; 409 410 /* 411 * "autofs_vnops_ptr" is the address of the pointer to the vnodeops 412 * structure for autofs. We want to read it each time we access 413 * it since autofs could (in theory) be unloaded and reloaded. 414 */ 415 if (mdb_vread(&autofs_vnops, sizeof (autofs_vnops), 416 (uintptr_t)autofs_vnops_ptr) == -1) 417 return (-1); 418 419 if (mdb_vread(&vn, sizeof (vn), addr) == -1) 420 return (-1); 421 422 if (autofs_vnops == NULL || vn.v_op != autofs_vnops) 423 return (-1); 424 425 addr = (uintptr_t)vn.v_data; 426 427 if (mdb_vread(&vfs, sizeof (vfs), (uintptr_t)vn.v_vfsp) == -1 || 428 mdb_vread(&fni, sizeof (fni), (uintptr_t)vfs.vfs_data) == -1 || 429 mdb_vread(&vn, sizeof (vn), (uintptr_t)fni.fi_rootvp) == -1) 430 return (-1); 431 432 for (;;) { 433 size_t elem = path->mdp_nelem++; 434 char elemstr[MAXNAMELEN]; 435 char *c, *p; 436 437 if (elem == MDB_PATH_NELEM) { 438 path->mdp_nelem--; 439 return (-1); 440 } 441 442 if (mdb_vread(&fn, sizeof (fn), addr) != sizeof (fn)) { 443 path->mdp_nelem--; 444 return (-1); 445 } 446 447 if (mdb_readstr(elemstr, sizeof (elemstr), 448 (uintptr_t)fn.fn_name) <= 0) { 449 (void) strcpy(elemstr, "?"); 450 } 451 452 c = mdb_alloc(strlen(elemstr) + 1, UM_SLEEP | UM_GC); 453 (void) strcpy(c, elemstr); 454 455 path->mdp_vnode[elem] = (uintptr_t)fn.fn_vnode; 456 457 if (addr == (uintptr_t)fn.fn_parent) { 458 path->mdp_name[elem] = &c[1]; 459 path->mdp_complete = TRUE; 460 break; 461 } 462 463 if ((p = strrchr(c, '/')) != NULL) 464 path->mdp_name[elem] = p + 1; 465 else 466 path->mdp_name[elem] = c; 467 468 addr = (uintptr_t)fn.fn_parent; 469 } 470 471 return (0); 472 } 473 474 int 475 mdb_vnode2path(uintptr_t addr, char *buf, size_t buflen) 476 { 477 uintptr_t rootdir; 478 ncache_t *ent; 479 vnode_t vp; 480 mdb_path_t path; 481 482 /* 483 * Check to see if we have a cached value for this vnode 484 */ 485 if (mdb_vread(&vp, sizeof (vp), addr) != -1 && 486 vp.v_path != NULL && 487 mdb_readstr(buf, buflen, (uintptr_t)vp.v_path) != -1) 488 return (0); 489 490 if (dnlc_load() == -1) 491 return (-1); 492 493 if (mdb_readvar(&rootdir, "rootdir") == -1) { 494 mdb_warn("failed to read 'rootdir'"); 495 return (-1); 496 } 497 498 bzero(&path, sizeof (mdb_path_t)); 499 again: 500 if ((addr == NULL) && (path.mdp_nelem == 0)) { 501 /* 502 * 0 elems && complete tells sprintpath to just print "/" 503 */ 504 path.mdp_complete = TRUE; 505 goto out; 506 } 507 508 if (addr == rootdir) { 509 path.mdp_complete = TRUE; 510 goto out; 511 } 512 513 for (ent = dnlc_hash[MDB_DNLC_HASH(addr)]; ent; ent = ent->hash_next) { 514 if ((uintptr_t)ent->vp == addr) { 515 if (strcmp(ent->name, "..") == 0 || 516 strcmp(ent->name, ".") == 0) 517 continue; 518 519 path.mdp_vnode[path.mdp_nelem] = (uintptr_t)ent->vp; 520 path.mdp_name[path.mdp_nelem] = ent->name; 521 path.mdp_nelem++; 522 523 if (path.mdp_nelem == MDB_PATH_NELEM) { 524 path.mdp_nelem--; 525 mdb_warn("path exceeded maximum expected " 526 "elements\n"); 527 return (-1); 528 } 529 530 addr = (uintptr_t)ent->dp; 531 goto again; 532 } 533 } 534 535 (void) mdb_autonode2path(addr, &path); 536 537 out: 538 return (mdb_sprintpath(buf, buflen, &path)); 539 } 540 541 542 uintptr_t 543 mdb_pid2proc(pid_t pid, proc_t *proc) 544 { 545 int pid_hashsz, hash; 546 uintptr_t paddr, pidhash, procdir; 547 struct pid pidp; 548 549 if (mdb_readvar(&pidhash, "pidhash") == -1) 550 return (NULL); 551 552 if (mdb_readvar(&pid_hashsz, "pid_hashsz") == -1) 553 return (NULL); 554 555 if (mdb_readvar(&procdir, "procdir") == -1) 556 return (NULL); 557 558 hash = pid & (pid_hashsz - 1); 559 560 if (mdb_vread(&paddr, sizeof (paddr), 561 pidhash + (hash * sizeof (paddr))) == -1) 562 return (NULL); 563 564 while (paddr != 0) { 565 if (mdb_vread(&pidp, sizeof (pidp), paddr) == -1) 566 return (NULL); 567 568 if (pidp.pid_id == pid) { 569 uintptr_t procp; 570 571 if (mdb_vread(&procp, sizeof (procp), procdir + 572 (pidp.pid_prslot * sizeof (procp))) == -1) 573 return (NULL); 574 575 if (proc != NULL) 576 (void) mdb_vread(proc, sizeof (proc_t), procp); 577 578 return (procp); 579 } 580 paddr = (uintptr_t)pidp.pid_link; 581 } 582 return (NULL); 583 } 584 585 int 586 mdb_cpu2cpuid(uintptr_t cpup) 587 { 588 cpu_t cpu; 589 590 if (mdb_vread(&cpu, sizeof (cpu_t), cpup) != sizeof (cpu_t)) 591 return (-1); 592 593 return (cpu.cpu_id); 594 } 595 596 int 597 mdb_cpuset_find(uintptr_t cpusetp) 598 { 599 ulong_t *cpuset; 600 size_t nr_words = BT_BITOUL(NCPU); 601 size_t sz = nr_words * sizeof (ulong_t); 602 size_t i; 603 int cpu = -1; 604 605 cpuset = mdb_alloc(sz, UM_SLEEP); 606 607 if (mdb_vread((void *)cpuset, sz, cpusetp) != sz) 608 goto out; 609 610 for (i = 0; i < nr_words; i++) { 611 size_t j; 612 ulong_t m; 613 614 for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1) { 615 if (cpuset[i] & m) { 616 cpu = i * BT_NBIPUL + j; 617 goto out; 618 } 619 } 620 } 621 622 out: 623 mdb_free(cpuset, sz); 624 return (cpu); 625 } 626 627 uintptr_t 628 mdb_page_lookup(uintptr_t vp, u_offset_t offset) 629 { 630 long page_hashsz, ndx; 631 int page_hashsz_shift; /* Needed for PAGE_HASH_FUNC */ 632 uintptr_t page_hash, pp; 633 634 if (mdb_readvar(&page_hashsz, "page_hashsz") == -1 || 635 mdb_readvar(&page_hashsz_shift, "page_hashsz_shift") == -1 || 636 mdb_readvar(&page_hash, "page_hash") == -1) 637 return (NULL); 638 639 ndx = PAGE_HASH_FUNC(vp, offset); 640 page_hash += ndx * sizeof (uintptr_t); 641 642 mdb_vread(&pp, sizeof (pp), page_hash); 643 644 while (pp != NULL) { 645 page_t page; 646 647 mdb_vread(&page, sizeof (page), pp); 648 649 if ((uintptr_t)page.p_vnode == vp && 650 (uint64_t)page.p_offset == offset) 651 return (pp); 652 653 pp = (uintptr_t)page.p_hash; 654 } 655 656 return (NULL); 657 } 658 659 char 660 mdb_vtype2chr(vtype_t type, mode_t mode) 661 { 662 static const char vttab[] = { 663 ' ', /* VNON */ 664 ' ', /* VREG */ 665 '/', /* VDIR */ 666 ' ', /* VBLK */ 667 ' ', /* VCHR */ 668 '@', /* VLNK */ 669 '|', /* VFIFO */ 670 '>', /* VDOOR */ 671 ' ', /* VPROC */ 672 '=', /* VSOCK */ 673 ' ', /* VBAD */ 674 }; 675 676 if (type < 0 || type >= sizeof (vttab) / sizeof (vttab[0])) 677 return ('?'); 678 679 if (type == VREG && (mode & 0111) != 0) 680 return ('*'); 681 682 return (vttab[type]); 683 } 684 685 struct pfn2page { 686 pfn_t pfn; 687 page_t *pp; 688 }; 689 690 /*ARGSUSED*/ 691 static int 692 pfn2page_cb(uintptr_t addr, const struct memseg *msp, void *data) 693 { 694 struct pfn2page *p = data; 695 696 if (p->pfn >= msp->pages_base && p->pfn < msp->pages_end) { 697 p->pp = msp->pages + (p->pfn - msp->pages_base); 698 return (WALK_DONE); 699 } 700 701 return (WALK_NEXT); 702 } 703 704 uintptr_t 705 mdb_pfn2page(pfn_t pfn) 706 { 707 struct pfn2page arg; 708 struct page page; 709 710 arg.pfn = pfn; 711 arg.pp = NULL; 712 713 if (mdb_walk("memseg", (mdb_walk_cb_t)pfn2page_cb, &arg) == -1) { 714 mdb_warn("pfn2page: can't walk memsegs"); 715 return (0); 716 } 717 if (arg.pp == NULL) { 718 mdb_warn("pfn2page: unable to find page_t for pfn %lx\n", 719 pfn); 720 return (0); 721 } 722 723 if (mdb_vread(&page, sizeof (page_t), (uintptr_t)arg.pp) == -1) { 724 mdb_warn("pfn2page: can't read page 0x%lx at %p", pfn, arg.pp); 725 return (0); 726 } 727 if (page.p_pagenum != pfn) { 728 mdb_warn("pfn2page: page_t 0x%p should have PFN 0x%lx, " 729 "but actually has 0x%lx\n", arg.pp, pfn, page.p_pagenum); 730 return (0); 731 } 732 733 return ((uintptr_t)arg.pp); 734 } 735 736 pfn_t 737 mdb_page2pfn(uintptr_t addr) 738 { 739 struct page page; 740 741 if (mdb_vread(&page, sizeof (page_t), addr) == -1) { 742 mdb_warn("pp2pfn: can't read page at %p", addr); 743 return ((pfn_t)(-1)); 744 } 745 746 return (page.p_pagenum); 747 } 748 749 static int 750 a2m_walk_modctl(uintptr_t addr, const struct modctl *m, a2m_query_t *a2m) 751 { 752 struct module mod; 753 754 if (m->mod_mp == NULL) 755 return (0); 756 757 if (mdb_vread(&mod, sizeof (mod), (uintptr_t)m->mod_mp) == -1) { 758 mdb_warn("couldn't read modctl %p's module", addr); 759 return (0); 760 } 761 762 if (a2m->a2m_addr >= (uintptr_t)mod.text && 763 a2m->a2m_addr < (uintptr_t)mod.text + mod.text_size) 764 goto found; 765 766 if (a2m->a2m_addr >= (uintptr_t)mod.data && 767 a2m->a2m_addr < (uintptr_t)mod.data + mod.data_size) 768 goto found; 769 770 return (0); 771 772 found: 773 a2m->a2m_where = addr; 774 return (-1); 775 } 776 777 uintptr_t 778 mdb_addr2modctl(uintptr_t addr) 779 { 780 a2m_query_t a2m; 781 782 a2m.a2m_addr = addr; 783 a2m.a2m_where = NULL; 784 785 (void) mdb_walk("modctl", (mdb_walk_cb_t)a2m_walk_modctl, &a2m); 786 return (a2m.a2m_where); 787 } 788 789 static mdb_qinfo_t * 790 qi_lookup(uintptr_t qinit_addr) 791 { 792 mdb_qinfo_t *qip; 793 794 for (qip = qi_head; qip != NULL; qip = qip->qi_next) { 795 if (qip->qi_addr == qinit_addr) 796 return (qip); 797 } 798 799 return (NULL); 800 } 801 802 void 803 mdb_qops_install(const mdb_qops_t *qops, uintptr_t qinit_addr) 804 { 805 mdb_qinfo_t *qip = qi_lookup(qinit_addr); 806 807 if (qip != NULL) { 808 qip->qi_ops = qops; 809 return; 810 } 811 812 qip = mdb_alloc(sizeof (mdb_qinfo_t), UM_SLEEP); 813 814 qip->qi_ops = qops; 815 qip->qi_addr = qinit_addr; 816 qip->qi_next = qi_head; 817 818 qi_head = qip; 819 } 820 821 void 822 mdb_qops_remove(const mdb_qops_t *qops, uintptr_t qinit_addr) 823 { 824 mdb_qinfo_t *qip, *p = NULL; 825 826 for (qip = qi_head; qip != NULL; p = qip, qip = qip->qi_next) { 827 if (qip->qi_addr == qinit_addr && qip->qi_ops == qops) { 828 if (qi_head == qip) 829 qi_head = qip->qi_next; 830 else 831 p->qi_next = qip->qi_next; 832 mdb_free(qip, sizeof (mdb_qinfo_t)); 833 return; 834 } 835 } 836 } 837 838 char * 839 mdb_qname(const queue_t *q, char *buf, size_t nbytes) 840 { 841 struct module_info mi; 842 struct qinit qi; 843 844 if (mdb_vread(&qi, sizeof (qi), (uintptr_t)q->q_qinfo) == -1) { 845 mdb_warn("failed to read qinit at %p", q->q_qinfo); 846 goto err; 847 } 848 849 if (mdb_vread(&mi, sizeof (mi), (uintptr_t)qi.qi_minfo) == -1) { 850 mdb_warn("failed to read module_info at %p", qi.qi_minfo); 851 goto err; 852 } 853 854 if (mdb_readstr(buf, nbytes, (uintptr_t)mi.mi_idname) <= 0) { 855 mdb_warn("failed to read mi_idname at %p", mi.mi_idname); 856 goto err; 857 } 858 859 return (buf); 860 861 err: 862 (void) mdb_snprintf(buf, nbytes, "???"); 863 return (buf); 864 } 865 866 void 867 mdb_qinfo(const queue_t *q, char *buf, size_t nbytes) 868 { 869 mdb_qinfo_t *qip = qi_lookup((uintptr_t)q->q_qinfo); 870 buf[0] = '\0'; 871 872 if (qip != NULL) 873 qip->qi_ops->q_info(q, buf, nbytes); 874 } 875 876 uintptr_t 877 mdb_qrnext(const queue_t *q) 878 { 879 mdb_qinfo_t *qip = qi_lookup((uintptr_t)q->q_qinfo); 880 881 if (qip != NULL) 882 return (qip->qi_ops->q_rnext(q)); 883 884 return (NULL); 885 } 886 887 uintptr_t 888 mdb_qwnext(const queue_t *q) 889 { 890 mdb_qinfo_t *qip = qi_lookup((uintptr_t)q->q_qinfo); 891 892 if (qip != NULL) 893 return (qip->qi_ops->q_wnext(q)); 894 895 return (NULL); 896 } 897 898 uintptr_t 899 mdb_qrnext_default(const queue_t *q) 900 { 901 return ((uintptr_t)q->q_next); 902 } 903 904 uintptr_t 905 mdb_qwnext_default(const queue_t *q) 906 { 907 return ((uintptr_t)q->q_next); 908 } 909 910 /* 911 * The following three routines borrowed from modsubr.c 912 */ 913 static int 914 nm_hash(const char *name) 915 { 916 char c; 917 int hash = 0; 918 919 for (c = *name++; c; c = *name++) 920 hash ^= c; 921 922 return (hash & MOD_BIND_HASHMASK); 923 } 924 925 static uintptr_t 926 find_mbind(const char *name, uintptr_t *hashtab) 927 { 928 int hashndx; 929 uintptr_t mb; 930 struct bind mb_local; 931 char node_name[MAXPATHLEN + 1]; 932 933 hashndx = nm_hash(name); 934 mb = hashtab[hashndx]; 935 while (mb) { 936 if (mdb_vread(&mb_local, sizeof (mb_local), mb) == -1) { 937 mdb_warn("failed to read struct bind at %p", mb); 938 return (NULL); 939 } 940 if (mdb_readstr(node_name, sizeof (node_name), 941 (uintptr_t)mb_local.b_name) == -1) { 942 mdb_warn("failed to read node name string at %p", 943 mb_local.b_name); 944 return (NULL); 945 } 946 947 if (strcmp(name, node_name) == 0) 948 break; 949 950 mb = (uintptr_t)mb_local.b_next; 951 } 952 return (mb); 953 } 954 955 int 956 mdb_name_to_major(const char *name, major_t *major) 957 { 958 uintptr_t mbind; 959 uintptr_t mb_hashtab[MOD_BIND_HASHSIZE]; 960 struct bind mbind_local; 961 962 963 if (mdb_readsym(mb_hashtab, sizeof (mb_hashtab), "mb_hashtab") == -1) { 964 mdb_warn("failed to read symbol 'mb_hashtab'"); 965 return (-1); 966 } 967 968 if ((mbind = find_mbind(name, mb_hashtab)) != NULL) { 969 if (mdb_vread(&mbind_local, sizeof (mbind_local), mbind) == 970 -1) { 971 mdb_warn("failed to read mbind struct at %p", mbind); 972 return (-1); 973 } 974 975 *major = (major_t)mbind_local.b_num; 976 return (0); 977 } 978 return (-1); 979 } 980 981 const char * 982 mdb_major_to_name(major_t major) 983 { 984 static char name[MODMAXNAMELEN + 1]; 985 986 uintptr_t devnamesp; 987 struct devnames dn; 988 uint_t devcnt; 989 990 if (mdb_readvar(&devcnt, "devcnt") == -1 || major >= devcnt || 991 mdb_readvar(&devnamesp, "devnamesp") == -1) 992 return (NULL); 993 994 if (mdb_vread(&dn, sizeof (struct devnames), devnamesp + 995 major * sizeof (struct devnames)) != sizeof (struct devnames)) 996 return (NULL); 997 998 if (mdb_readstr(name, MODMAXNAMELEN + 1, (uintptr_t)dn.dn_name) == -1) 999 return (NULL); 1000 1001 return ((const char *)name); 1002 } 1003 1004 /* 1005 * Return the name of the driver attached to the dip in drivername. 1006 */ 1007 int 1008 mdb_devinfo2driver(uintptr_t dip_addr, char *drivername, size_t namebufsize) 1009 { 1010 struct dev_info devinfo; 1011 char bind_name[MAXPATHLEN + 1]; 1012 major_t major; 1013 const char *namestr; 1014 1015 1016 if (mdb_vread(&devinfo, sizeof (devinfo), dip_addr) == -1) { 1017 mdb_warn("failed to read devinfo at %p", dip_addr); 1018 return (-1); 1019 } 1020 1021 if (mdb_readstr(bind_name, sizeof (bind_name), 1022 (uintptr_t)devinfo.devi_binding_name) == -1) { 1023 mdb_warn("failed to read binding name at %p", 1024 devinfo.devi_binding_name); 1025 return (-1); 1026 } 1027 1028 /* 1029 * Many->one relation: various names to one major number 1030 */ 1031 if (mdb_name_to_major(bind_name, &major) == -1) { 1032 mdb_warn("failed to translate bind name to major number\n"); 1033 return (-1); 1034 } 1035 1036 /* 1037 * One->one relation: one major number corresponds to one driver 1038 */ 1039 if ((namestr = mdb_major_to_name(major)) == NULL) { 1040 (void) strncpy(drivername, "???", namebufsize); 1041 return (-1); 1042 } 1043 1044 (void) strncpy(drivername, namestr, namebufsize); 1045 return (0); 1046 } 1047 1048 /* 1049 * Find the name of the driver attached to this dip (if any), given: 1050 * - the address of a dip (in core) 1051 * - the NAME of the global pointer to the driver's i_ddi_soft_state struct 1052 * - pointer to a pointer to receive the address 1053 */ 1054 int 1055 mdb_devinfo2statep(uintptr_t dip_addr, char *soft_statep_name, 1056 uintptr_t *statep) 1057 { 1058 struct dev_info dev_info; 1059 1060 1061 if (mdb_vread(&dev_info, sizeof (dev_info), dip_addr) == -1) { 1062 mdb_warn("failed to read devinfo at %p", dip_addr); 1063 return (-1); 1064 } 1065 1066 return (mdb_get_soft_state_byname(soft_statep_name, 1067 dev_info.devi_instance, statep, NULL, 0)); 1068 } 1069 1070 /* 1071 * Returns a pointer to the top of the soft state struct for the instance 1072 * specified (in state_addr), given the address of the global soft state 1073 * pointer and size of the struct. Also fills in the buffer pointed to by 1074 * state_buf_p (if non-NULL) with the contents of the state struct. 1075 */ 1076 int 1077 mdb_get_soft_state_byaddr(uintptr_t ssaddr, uint_t instance, 1078 uintptr_t *state_addr, void *state_buf_p, size_t sizeof_state) 1079 { 1080 struct i_ddi_soft_state ss; 1081 void *statep; 1082 1083 1084 if (mdb_vread(&ss, sizeof (ss), ssaddr) == -1) 1085 return (-1); 1086 1087 if (instance >= ss.n_items) 1088 return (-1); 1089 1090 if (mdb_vread(&statep, sizeof (statep), (uintptr_t)ss.array + 1091 (sizeof (statep) * instance)) == -1) 1092 return (-1); 1093 1094 if (state_addr != NULL) 1095 *state_addr = (uintptr_t)statep; 1096 1097 if (statep == NULL) { 1098 errno = ENOENT; 1099 return (-1); 1100 } 1101 1102 if (state_buf_p != NULL) { 1103 1104 /* Read the state struct into the buffer in local space. */ 1105 if (mdb_vread(state_buf_p, sizeof_state, 1106 (uintptr_t)statep) == -1) 1107 return (-1); 1108 } 1109 1110 return (0); 1111 } 1112 1113 1114 /* 1115 * Returns a pointer to the top of the soft state struct for the instance 1116 * specified (in state_addr), given the name of the global soft state pointer 1117 * and size of the struct. Also fills in the buffer pointed to by 1118 * state_buf_p (if non-NULL) with the contents of the state struct. 1119 */ 1120 int 1121 mdb_get_soft_state_byname(char *softstatep_name, uint_t instance, 1122 uintptr_t *state_addr, void *state_buf_p, size_t sizeof_state) 1123 { 1124 uintptr_t ssaddr; 1125 1126 if (mdb_readvar((void *)&ssaddr, softstatep_name) == -1) 1127 return (-1); 1128 1129 return (mdb_get_soft_state_byaddr(ssaddr, instance, state_addr, 1130 state_buf_p, sizeof_state)); 1131 } 1132 1133 static const mdb_dcmd_t dcmds[] = { 1134 { "dnlc", NULL, "print DNLC contents", dnlcdump }, 1135 { NULL } 1136 }; 1137 1138 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds }; 1139 1140 /*ARGSUSED*/ 1141 static void 1142 update_vars(void *arg) 1143 { 1144 GElf_Sym sym; 1145 1146 if (mdb_lookup_by_name("auto_vnodeops", &sym) == 0) 1147 autofs_vnops_ptr = (struct vnodeops *)(uintptr_t)sym.st_value; 1148 else 1149 autofs_vnops_ptr = NULL; 1150 1151 (void) mdb_readvar(&_mdb_ks_pagesize, "_pagesize"); 1152 (void) mdb_readvar(&_mdb_ks_pageshift, "_pageshift"); 1153 (void) mdb_readvar(&_mdb_ks_pageoffset, "_pageoffset"); 1154 (void) mdb_readvar(&_mdb_ks_pagemask, "_pagemask"); 1155 (void) mdb_readvar(&_mdb_ks_mmu_pagesize, "_mmu_pagesize"); 1156 (void) mdb_readvar(&_mdb_ks_mmu_pageshift, "_mmu_pageshift"); 1157 (void) mdb_readvar(&_mdb_ks_mmu_pageoffset, "_mmu_pageoffset"); 1158 (void) mdb_readvar(&_mdb_ks_mmu_pagemask, "_mmu_pagemask"); 1159 (void) mdb_readvar(&_mdb_ks_kernelbase, "_kernelbase"); 1160 1161 (void) mdb_readvar(&_mdb_ks_userlimit, "_userlimit"); 1162 (void) mdb_readvar(&_mdb_ks_userlimit32, "_userlimit32"); 1163 (void) mdb_readvar(&_mdb_ks_argsbase, "_argsbase"); 1164 (void) mdb_readvar(&_mdb_ks_msg_bsize, "_msg_bsize"); 1165 (void) mdb_readvar(&_mdb_ks_defaultstksz, "_defaultstksz"); 1166 (void) mdb_readvar(&_mdb_ks_ncpu, "_ncpu"); 1167 } 1168 1169 const mdb_modinfo_t * 1170 _mdb_init(void) 1171 { 1172 /* 1173 * When used with mdb, mdb_ks is a separate dmod. With kmdb, however, 1174 * mdb_ks is compiled into the debugger module. kmdb cannot 1175 * automatically modunload itself when it exits. If it restarts after 1176 * debugger fault, static variables may not be initialized to zero. 1177 * They must be manually reinitialized here. 1178 */ 1179 dnlc_hash = NULL; 1180 qi_head = NULL; 1181 1182 mdb_callback_add(MDB_CALLBACK_STCHG, update_vars, NULL); 1183 1184 update_vars(NULL); 1185 1186 return (&modinfo); 1187 } 1188 1189 void 1190 _mdb_fini(void) 1191 { 1192 dnlc_free(); 1193 while (qi_head != NULL) { 1194 mdb_qinfo_t *qip = qi_head; 1195 qi_head = qip->qi_next; 1196 mdb_free(qip, sizeof (mdb_qinfo_t)); 1197 } 1198 } 1199 1200 /* 1201 * Interface between MDB kproc target and mdb_ks. The kproc target relies 1202 * on looking up and invoking these functions in mdb_ks so that dependencies 1203 * on the current kernel implementation are isolated in mdb_ks. 1204 */ 1205 1206 /* 1207 * Given the address of a proc_t, return the p.p_as pointer; return NULL 1208 * if we were unable to read a proc structure from the given address. 1209 */ 1210 uintptr_t 1211 mdb_kproc_as(uintptr_t proc_addr) 1212 { 1213 proc_t p; 1214 1215 if (mdb_vread(&p, sizeof (p), proc_addr) == sizeof (p)) 1216 return ((uintptr_t)p.p_as); 1217 1218 return (NULL); 1219 } 1220 1221 /* 1222 * Given the address of a proc_t, return the p.p_model value; return 1223 * PR_MODEL_UNKNOWN if we were unable to read a proc structure or if 1224 * the model value does not match one of the two known values. 1225 */ 1226 uint_t 1227 mdb_kproc_model(uintptr_t proc_addr) 1228 { 1229 proc_t p; 1230 1231 if (mdb_vread(&p, sizeof (p), proc_addr) == sizeof (p)) { 1232 switch (p.p_model) { 1233 case DATAMODEL_ILP32: 1234 return (PR_MODEL_ILP32); 1235 case DATAMODEL_LP64: 1236 return (PR_MODEL_LP64); 1237 } 1238 } 1239 1240 return (PR_MODEL_UNKNOWN); 1241 } 1242 1243 /* 1244 * Callback function for walking process's segment list. For each segment, 1245 * we fill in an mdb_map_t describing its properties, and then invoke 1246 * the callback function provided by the kproc target. 1247 */ 1248 static int 1249 asmap_step(uintptr_t addr, const struct seg *seg, asmap_arg_t *asmp) 1250 { 1251 struct segvn_data svd; 1252 mdb_map_t map; 1253 1254 if (seg->s_ops == asmp->asm_segvn_ops && mdb_vread(&svd, 1255 sizeof (svd), (uintptr_t)seg->s_data) == sizeof (svd)) { 1256 1257 if (svd.vp != NULL) { 1258 if (mdb_vnode2path((uintptr_t)svd.vp, map.map_name, 1259 MDB_TGT_MAPSZ) != 0) { 1260 (void) mdb_snprintf(map.map_name, 1261 MDB_TGT_MAPSZ, "[ vnode %p ]", svd.vp); 1262 } 1263 } else 1264 (void) strcpy(map.map_name, "[ anon ]"); 1265 1266 } else { 1267 (void) mdb_snprintf(map.map_name, MDB_TGT_MAPSZ, 1268 "[ seg %p ]", addr); 1269 } 1270 1271 map.map_base = (uintptr_t)seg->s_base; 1272 map.map_size = seg->s_size; 1273 map.map_flags = 0; 1274 1275 asmp->asm_callback((const struct mdb_map *)&map, asmp->asm_cbdata); 1276 return (WALK_NEXT); 1277 } 1278 1279 /* 1280 * Given a process address space, walk its segment list using the seg walker, 1281 * convert the segment data to an mdb_map_t, and pass this information 1282 * back to the kproc target via the given callback function. 1283 */ 1284 int 1285 mdb_kproc_asiter(uintptr_t as, 1286 void (*func)(const struct mdb_map *, void *), void *p) 1287 { 1288 asmap_arg_t arg; 1289 GElf_Sym sym; 1290 1291 arg.asm_segvn_ops = NULL; 1292 arg.asm_callback = func; 1293 arg.asm_cbdata = p; 1294 1295 if (mdb_lookup_by_name("segvn_ops", &sym) == 0) 1296 arg.asm_segvn_ops = (struct seg_ops *)(uintptr_t)sym.st_value; 1297 1298 return (mdb_pwalk("seg", (mdb_walk_cb_t)asmap_step, &arg, as)); 1299 } 1300 1301 /* 1302 * Copy the auxv array from the given process's u-area into the provided 1303 * buffer. If the buffer is NULL, only return the size of the auxv array 1304 * so the caller knows how much space will be required. 1305 */ 1306 int 1307 mdb_kproc_auxv(uintptr_t proc, auxv_t *auxv) 1308 { 1309 if (auxv != NULL) { 1310 proc_t p; 1311 1312 if (mdb_vread(&p, sizeof (p), proc) != sizeof (p)) 1313 return (-1); 1314 1315 bcopy(p.p_user.u_auxv, auxv, 1316 sizeof (auxv_t) * __KERN_NAUXV_IMPL); 1317 } 1318 1319 return (__KERN_NAUXV_IMPL); 1320 } 1321 1322 /* 1323 * Given a process address, return the PID. 1324 */ 1325 pid_t 1326 mdb_kproc_pid(uintptr_t proc_addr) 1327 { 1328 struct pid pid; 1329 proc_t p; 1330 1331 if (mdb_vread(&p, sizeof (p), proc_addr) == sizeof (p) && 1332 mdb_vread(&pid, sizeof (pid), (uintptr_t)p.p_pidp) == sizeof (pid)) 1333 return (pid.pid_id); 1334 1335 return (-1); 1336 } 1337 1338 /* 1339 * Interface between the MDB kvm target and mdb_ks. The kvm target relies 1340 * on looking up and invoking these functions in mdb_ks so that dependencies 1341 * on the current kernel implementation are isolated in mdb_ks. 1342 */ 1343 1344 /* 1345 * Determine whether or not the thread that panicked the given kernel was a 1346 * kernel thread (panic_thread->t_procp == &p0). 1347 */ 1348 void 1349 mdb_dump_print_content(dumphdr_t *dh, pid_t content) 1350 { 1351 GElf_Sym sym; 1352 uintptr_t pt; 1353 uintptr_t procp; 1354 int expcont = 0; 1355 int actcont; 1356 1357 (void) mdb_readvar(&expcont, "dump_conflags"); 1358 actcont = dh->dump_flags & DF_CONTENT; 1359 1360 if (actcont == DF_ALL) { 1361 mdb_printf("dump content: all kernel and user pages\n"); 1362 return; 1363 } else if (actcont == DF_CURPROC) { 1364 mdb_printf("dump content: kernel pages and pages from " 1365 "PID %d", content); 1366 return; 1367 } 1368 1369 mdb_printf("dump content: kernel pages only\n"); 1370 if (!(expcont & DF_CURPROC)) 1371 return; 1372 1373 if (mdb_readvar(&pt, "panic_thread") != sizeof (pt) || pt == NULL) 1374 goto kthreadpanic_err; 1375 1376 if (mdb_vread(&procp, sizeof (procp), pt + OFFSETOF(kthread_t, 1377 t_procp)) == -1 || procp == NULL) 1378 goto kthreadpanic_err; 1379 1380 if (mdb_lookup_by_name("p0", &sym) != 0) 1381 goto kthreadpanic_err; 1382 1383 if (procp == (uintptr_t)sym.st_value) { 1384 mdb_printf(" (curproc requested, but a kernel thread " 1385 "panicked)\n"); 1386 } else { 1387 mdb_printf(" (curproc requested, but the process that " 1388 "panicked could not be dumped)\n"); 1389 } 1390 1391 return; 1392 1393 kthreadpanic_err: 1394 mdb_printf(" (curproc requested, but the process that panicked could " 1395 "not be found)\n"); 1396 } 1397 1398 /* 1399 * Determine the process that was saved in a `curproc' dump. This process will 1400 * be recorded as the first element in dump_pids[]. 1401 */ 1402 int 1403 mdb_dump_find_curproc(void) 1404 { 1405 uintptr_t pidp; 1406 pid_t pid = -1; 1407 1408 if (mdb_readvar(&pidp, "dump_pids") == sizeof (pidp) && 1409 mdb_vread(&pid, sizeof (pid), pidp) == sizeof (pid) && 1410 pid > 0) 1411 return (pid); 1412 else 1413 return (-1); 1414 } 1415 1416 1417 /* 1418 * Following three funcs extracted from sunddi.c 1419 */ 1420 1421 /* 1422 * Return core address of root node of devinfo tree 1423 */ 1424 static uintptr_t 1425 mdb_ddi_root_node(void) 1426 { 1427 uintptr_t top_devinfo_addr; 1428 1429 /* return (top_devinfo); */ 1430 if (mdb_readvar(&top_devinfo_addr, "top_devinfo") == -1) { 1431 mdb_warn("failed to read top_devinfo"); 1432 return (NULL); 1433 } 1434 return (top_devinfo_addr); 1435 } 1436 1437 /* 1438 * Return the name of the devinfo node pointed at by 'dip_addr' in the buffer 1439 * pointed at by 'name.' 1440 * 1441 * - dip_addr is a pointer to a dev_info struct in core. 1442 */ 1443 static char * 1444 mdb_ddi_deviname(uintptr_t dip_addr, char *name, size_t name_size) 1445 { 1446 uintptr_t addrname; 1447 ssize_t length; 1448 char *local_namep = name; 1449 size_t local_name_size = name_size; 1450 struct dev_info local_dip; 1451 1452 1453 if (dip_addr == mdb_ddi_root_node()) { 1454 if (name_size < 1) { 1455 mdb_warn("failed to get node name: buf too small\n"); 1456 return (NULL); 1457 } 1458 1459 *name = '\0'; 1460 return (name); 1461 } 1462 1463 if (name_size < 2) { 1464 mdb_warn("failed to get node name: buf too small\n"); 1465 return (NULL); 1466 } 1467 1468 local_namep = name; 1469 *local_namep++ = '/'; 1470 *local_namep = '\0'; 1471 local_name_size--; 1472 1473 if (mdb_vread(&local_dip, sizeof (struct dev_info), dip_addr) == -1) { 1474 mdb_warn("failed to read devinfo struct"); 1475 } 1476 1477 length = mdb_readstr(local_namep, local_name_size, 1478 (uintptr_t)local_dip.devi_node_name); 1479 if (length == -1) { 1480 mdb_warn("failed to read node name"); 1481 return (NULL); 1482 } 1483 local_namep += length; 1484 local_name_size -= length; 1485 addrname = (uintptr_t)local_dip.devi_addr; 1486 1487 if (addrname != NULL) { 1488 1489 if (local_name_size < 2) { 1490 mdb_warn("not enough room for node address string"); 1491 return (name); 1492 } 1493 *local_namep++ = '@'; 1494 *local_namep = '\0'; 1495 local_name_size--; 1496 1497 length = mdb_readstr(local_namep, local_name_size, addrname); 1498 if (length == -1) { 1499 mdb_warn("failed to read name"); 1500 return (NULL); 1501 } 1502 } 1503 1504 return (name); 1505 } 1506 1507 /* 1508 * Generate the full path under the /devices dir to the device entry. 1509 * 1510 * dip is a pointer to a devinfo struct in core (not in local memory). 1511 */ 1512 char * 1513 mdb_ddi_pathname(uintptr_t dip_addr, char *path, size_t pathlen) 1514 { 1515 struct dev_info local_dip; 1516 uintptr_t parent_dip; 1517 char *bp; 1518 size_t buf_left; 1519 1520 1521 if (dip_addr == mdb_ddi_root_node()) { 1522 *path = '\0'; 1523 return (path); 1524 } 1525 1526 1527 if (mdb_vread(&local_dip, sizeof (struct dev_info), dip_addr) == -1) { 1528 mdb_warn("failed to read devinfo struct"); 1529 } 1530 1531 parent_dip = (uintptr_t)local_dip.devi_parent; 1532 (void) mdb_ddi_pathname(parent_dip, path, pathlen); 1533 1534 bp = path + strlen(path); 1535 buf_left = pathlen - strlen(path); 1536 (void) mdb_ddi_deviname(dip_addr, bp, buf_left); 1537 return (path); 1538 } 1539 1540 1541 /* 1542 * Read in the string value of a refstr, which is appended to the end of 1543 * the structure. 1544 */ 1545 ssize_t 1546 mdb_read_refstr(uintptr_t refstr_addr, char *str, size_t nbytes) 1547 { 1548 struct refstr *r = (struct refstr *)refstr_addr; 1549 1550 return (mdb_readstr(str, nbytes, (uintptr_t)r->rs_string)); 1551 } 1552 1553 /* 1554 * Chase an mblk list by b_next and return the length. 1555 */ 1556 int 1557 mdb_mblk_count(const mblk_t *mb) 1558 { 1559 int count; 1560 mblk_t mblk; 1561 1562 if (mb == NULL) 1563 return (0); 1564 1565 count = 1; 1566 while (mb->b_next != NULL) { 1567 count++; 1568 if (mdb_vread(&mblk, sizeof (mblk), (uintptr_t)mb->b_next) == 1569 -1) 1570 break; 1571 mb = &mblk; 1572 } 1573 return (count); 1574 } 1575 1576 /* 1577 * Write the given MAC address as a printable string in the usual colon- 1578 * separated format. Assumes that buflen is at least 2. 1579 */ 1580 void 1581 mdb_mac_addr(const uint8_t *addr, size_t alen, char *buf, size_t buflen) 1582 { 1583 int slen; 1584 1585 if (alen == 0 || buflen < 4) { 1586 (void) strcpy(buf, "?"); 1587 return; 1588 } 1589 for (;;) { 1590 /* 1591 * If there are more MAC address bytes available, but we won't 1592 * have any room to print them, then add "..." to the string 1593 * instead. See below for the 'magic number' explanation. 1594 */ 1595 if ((alen == 2 && buflen < 6) || (alen > 2 && buflen < 7)) { 1596 (void) strcpy(buf, "..."); 1597 break; 1598 } 1599 slen = mdb_snprintf(buf, buflen, "%02x", *addr++); 1600 buf += slen; 1601 if (--alen == 0) 1602 break; 1603 *buf++ = ':'; 1604 buflen -= slen + 1; 1605 /* 1606 * At this point, based on the first 'if' statement above, 1607 * either alen == 1 and buflen >= 3, or alen > 1 and 1608 * buflen >= 4. The first case leaves room for the final "xx" 1609 * number and trailing NUL byte. The second leaves room for at 1610 * least "...". Thus the apparently 'magic' numbers chosen for 1611 * that statement. 1612 */ 1613 } 1614 } 1615 1616 /* 1617 * Produce a string that represents a DLPI primitive, or NULL if no such string 1618 * is possible. 1619 */ 1620 const char * 1621 mdb_dlpi_prim(int prim) 1622 { 1623 switch (prim) { 1624 case DL_INFO_REQ: return ("DL_INFO_REQ"); 1625 case DL_INFO_ACK: return ("DL_INFO_ACK"); 1626 case DL_ATTACH_REQ: return ("DL_ATTACH_REQ"); 1627 case DL_DETACH_REQ: return ("DL_DETACH_REQ"); 1628 case DL_BIND_REQ: return ("DL_BIND_REQ"); 1629 case DL_BIND_ACK: return ("DL_BIND_ACK"); 1630 case DL_UNBIND_REQ: return ("DL_UNBIND_REQ"); 1631 case DL_OK_ACK: return ("DL_OK_ACK"); 1632 case DL_ERROR_ACK: return ("DL_ERROR_ACK"); 1633 case DL_ENABMULTI_REQ: return ("DL_ENABMULTI_REQ"); 1634 case DL_DISABMULTI_REQ: return ("DL_DISABMULTI_REQ"); 1635 case DL_PROMISCON_REQ: return ("DL_PROMISCON_REQ"); 1636 case DL_PROMISCOFF_REQ: return ("DL_PROMISCOFF_REQ"); 1637 case DL_UNITDATA_REQ: return ("DL_UNITDATA_REQ"); 1638 case DL_UNITDATA_IND: return ("DL_UNITDATA_IND"); 1639 case DL_UDERROR_IND: return ("DL_UDERROR_IND"); 1640 case DL_PHYS_ADDR_REQ: return ("DL_PHYS_ADDR_REQ"); 1641 case DL_PHYS_ADDR_ACK: return ("DL_PHYS_ADDR_ACK"); 1642 case DL_SET_PHYS_ADDR_REQ: return ("DL_SET_PHYS_ADDR_REQ"); 1643 case DL_NOTIFY_REQ: return ("DL_NOTIFY_REQ"); 1644 case DL_NOTIFY_ACK: return ("DL_NOTIFY_ACK"); 1645 case DL_NOTIFY_IND: return ("DL_NOTIFY_IND"); 1646 case DL_NOTIFY_CONF: return ("DL_NOTIFY_CONF"); 1647 case DL_CAPABILITY_REQ: return ("DL_CAPABILITY_REQ"); 1648 case DL_CAPABILITY_ACK: return ("DL_CAPABILITY_ACK"); 1649 case DL_CONTROL_REQ: return ("DL_CONTROL_REQ"); 1650 case DL_CONTROL_ACK: return ("DL_CONTROL_ACK"); 1651 case DL_PASSIVE_REQ: return ("DL_PASSIVE_REQ"); 1652 default: return (NULL); 1653 } 1654 } 1655 1656 /* 1657 * mdb_gethrtime() returns the hires system time. This will be the timestamp at 1658 * which we dropped into, if called from, kmdb(1); the core dump's hires time 1659 * if inspecting one; or the running system's hires time if we're inspecting 1660 * a live kernel. 1661 */ 1662 hrtime_t 1663 mdb_gethrtime(void) 1664 { 1665 uintptr_t ptr; 1666 GElf_Sym sym; 1667 lbolt_info_t lbi; 1668 hrtime_t ts; 1669 1670 /* 1671 * We first check whether the lbolt info structure has been allocated 1672 * and initialized. If not, lbolt_hybrid will be pointing at 1673 * lbolt_bootstrap. 1674 */ 1675 if (mdb_lookup_by_name("lbolt_bootstrap", &sym) == -1) 1676 return (0); 1677 1678 if (mdb_readvar(&ptr, "lbolt_hybrid") == -1) 1679 return (0); 1680 1681 if (ptr == (uintptr_t)sym.st_value) 1682 return (0); 1683 1684 #ifdef _KMDB 1685 if (mdb_readvar(&ptr, "lb_info") == -1) 1686 return (0); 1687 1688 if (mdb_vread(&lbi, sizeof (lbolt_info_t), ptr) != 1689 sizeof (lbolt_info_t)) 1690 return (0); 1691 1692 ts = lbi.lbi_debug_ts; 1693 #else 1694 if (mdb_prop_postmortem) { 1695 if (mdb_readvar(&ptr, "lb_info") == -1) 1696 return (0); 1697 1698 if (mdb_vread(&lbi, sizeof (lbolt_info_t), ptr) != 1699 sizeof (lbolt_info_t)) 1700 return (0); 1701 1702 ts = lbi.lbi_debug_ts; 1703 } else { 1704 ts = gethrtime(); 1705 } 1706 #endif 1707 return (ts); 1708 } 1709 1710 /* 1711 * mdb_get_lbolt() returns the number of clock ticks since system boot. 1712 * Depending on the context in which it's called, the value will be derived 1713 * from different sources per mdb_gethrtime(). If inspecting a panicked 1714 * system, the routine returns the 'panic_lbolt64' variable from the core file. 1715 */ 1716 int64_t 1717 mdb_get_lbolt(void) 1718 { 1719 lbolt_info_t lbi; 1720 uintptr_t ptr; 1721 int64_t pl; 1722 hrtime_t ts; 1723 int nsec; 1724 1725 if (mdb_readvar(&pl, "panic_lbolt64") != -1 && pl > 0) 1726 return (pl); 1727 1728 /* 1729 * mdb_gethrtime() will return zero if the lbolt info structure hasn't 1730 * been allocated and initialized yet, or if it fails to read it. 1731 */ 1732 if ((ts = mdb_gethrtime()) <= 0) 1733 return (0); 1734 1735 /* 1736 * Load the time spent in kmdb, if any. 1737 */ 1738 if (mdb_readvar(&ptr, "lb_info") == -1) 1739 return (0); 1740 1741 if (mdb_vread(&lbi, sizeof (lbolt_info_t), ptr) != 1742 sizeof (lbolt_info_t)) 1743 return (0); 1744 1745 if (mdb_readvar(&nsec, "nsec_per_tick") == -1 || nsec == 0) { 1746 mdb_warn("failed to read 'nsec_per_tick'"); 1747 return (-1); 1748 } 1749 1750 return ((ts/nsec) - lbi.lbi_debug_time); 1751 } 1752