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