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