1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 3446 mrj * Common Development and Distribution License (the "License"). 6 3446 mrj * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 10843 Dave * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel /* 27 0 stevel * Libkvm Kernel Target 28 0 stevel * 29 0 stevel * The libkvm kernel target provides access to both crash dumps and live 30 0 stevel * kernels through /dev/ksyms and /dev/kmem, using the facilities provided by 31 0 stevel * the libkvm.so library. The target-specific data structures are shared 32 0 stevel * between this file (common code) and the ISA-dependent parts of the target, 33 0 stevel * and so they are defined in the mdb_kvm.h header. The target processes an 34 0 stevel * "executable" (/dev/ksyms or the unix.X file) which contains a primary 35 0 stevel * .symtab and .dynsym, and then also iterates over the krtld module chain in 36 0 stevel * the kernel in order to obtain a list of loaded modules and per-module symbol 37 0 stevel * tables. To improve startup performance, the per-module symbol tables are 38 0 stevel * instantiated on-the-fly whenever an address lookup falls within the text 39 0 stevel * section of a given module. The target also relies on services from the 40 0 stevel * mdb_ks (kernel support) module, which contains pieces of the implementation 41 0 stevel * that must be compiled against the kernel implementation. 42 0 stevel */ 43 0 stevel 44 0 stevel #include <sys/modctl.h> 45 0 stevel #include <sys/kobj.h> 46 0 stevel #include <sys/kobj_impl.h> 47 0 stevel #include <sys/utsname.h> 48 0 stevel #include <sys/panic.h> 49 0 stevel #include <sys/dumphdr.h> 50 0 stevel #include <sys/dumpadm.h> 51 0 stevel 52 0 stevel #include <dlfcn.h> 53 0 stevel #include <libctf.h> 54 0 stevel #include <string.h> 55 0 stevel #include <fcntl.h> 56 0 stevel #include <errno.h> 57 0 stevel 58 0 stevel #include <mdb/mdb_target_impl.h> 59 0 stevel #include <mdb/mdb_err.h> 60 0 stevel #include <mdb/mdb_debug.h> 61 0 stevel #include <mdb/mdb_string.h> 62 0 stevel #include <mdb/mdb_modapi.h> 63 0 stevel #include <mdb/mdb_io_impl.h> 64 0 stevel #include <mdb/mdb_ctf.h> 65 0 stevel #include <mdb/mdb_kvm.h> 66 0 stevel #include <mdb/mdb_module.h> 67 5084 johnlev #include <mdb/mdb_kb.h> 68 0 stevel #include <mdb/mdb.h> 69 0 stevel 70 0 stevel #define KT_RELOC_BUF(buf, obase, nbase) \ 71 0 stevel ((uintptr_t)(buf) - (uintptr_t)(obase) + (uintptr_t)(nbase)) 72 0 stevel 73 0 stevel #define KT_BAD_BUF(buf, base, size) \ 74 0 stevel ((uintptr_t)(buf) < (uintptr_t)(base) || \ 75 0 stevel ((uintptr_t)(buf) >= (uintptr_t)(base) + (uintptr_t)(size))) 76 0 stevel 77 0 stevel typedef struct kt_symarg { 78 0 stevel mdb_tgt_sym_f *sym_cb; /* Caller's callback function */ 79 0 stevel void *sym_data; /* Callback function argument */ 80 0 stevel uint_t sym_type; /* Symbol type/binding filter */ 81 0 stevel mdb_syminfo_t sym_info; /* Symbol id and table id */ 82 0 stevel const char *sym_obj; /* Containing object */ 83 0 stevel } kt_symarg_t; 84 0 stevel 85 0 stevel typedef struct kt_maparg { 86 0 stevel mdb_tgt_t *map_target; /* Target used for mapping iter */ 87 0 stevel mdb_tgt_map_f *map_cb; /* Caller's callback function */ 88 0 stevel void *map_data; /* Callback function argument */ 89 0 stevel } kt_maparg_t; 90 0 stevel 91 0 stevel static const char KT_MODULE[] = "mdb_ks"; 92 0 stevel static const char KT_CTFPARENT[] = "genunix"; 93 0 stevel 94 0 stevel static void 95 0 stevel kt_load_module(kt_data_t *kt, mdb_tgt_t *t, kt_module_t *km) 96 0 stevel { 97 0 stevel km->km_data = mdb_alloc(km->km_datasz, UM_SLEEP); 98 0 stevel 99 0 stevel (void) mdb_tgt_vread(t, km->km_data, km->km_datasz, km->km_symspace_va); 100 0 stevel 101 0 stevel km->km_symbuf = (void *) 102 0 stevel KT_RELOC_BUF(km->km_symtab_va, km->km_symspace_va, km->km_data); 103 0 stevel 104 0 stevel km->km_strtab = (char *) 105 0 stevel KT_RELOC_BUF(km->km_strtab_va, km->km_symspace_va, km->km_data); 106 0 stevel 107 0 stevel km->km_symtab = mdb_gelf_symtab_create_raw(&kt->k_file->gf_ehdr, 108 0 stevel &km->km_symtab_hdr, km->km_symbuf, 109 0 stevel &km->km_strtab_hdr, km->km_strtab, MDB_TGT_SYMTAB); 110 0 stevel } 111 0 stevel 112 0 stevel static void 113 0 stevel kt_load_modules(kt_data_t *kt, mdb_tgt_t *t) 114 0 stevel { 115 0 stevel char name[MAXNAMELEN]; 116 0 stevel uintptr_t addr, head; 117 0 stevel 118 0 stevel struct module kmod; 119 0 stevel struct modctl ctl; 120 0 stevel Shdr symhdr, strhdr; 121 0 stevel GElf_Sym sym; 122 0 stevel 123 0 stevel kt_module_t *km; 124 0 stevel 125 0 stevel if (mdb_tgt_lookup_by_name(t, MDB_TGT_OBJ_EXEC, 126 0 stevel "modules", &sym, NULL) == -1) { 127 0 stevel warn("failed to get 'modules' symbol"); 128 0 stevel return; 129 0 stevel } 130 0 stevel 131 0 stevel if (mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, &ctl, sizeof (ctl), 132 0 stevel MDB_TGT_OBJ_EXEC, "modules") != sizeof (ctl)) { 133 0 stevel warn("failed to read 'modules' struct"); 134 0 stevel return; 135 0 stevel } 136 0 stevel 137 0 stevel addr = head = (uintptr_t)sym.st_value; 138 0 stevel 139 0 stevel do { 140 0 stevel if (addr == NULL) 141 0 stevel break; /* Avoid spurious NULL pointers in list */ 142 0 stevel 143 0 stevel if (mdb_tgt_vread(t, &ctl, sizeof (ctl), addr) == -1) { 144 0 stevel warn("failed to read modctl at %p", (void *)addr); 145 0 stevel return; 146 0 stevel } 147 0 stevel 148 0 stevel if (ctl.mod_mp == NULL) 149 0 stevel continue; /* No associated krtld structure */ 150 0 stevel 151 0 stevel if (mdb_tgt_readstr(t, MDB_TGT_AS_VIRT, name, MAXNAMELEN, 152 0 stevel (uintptr_t)ctl.mod_modname) <= 0) { 153 0 stevel warn("failed to read module name at %p", 154 0 stevel (void *)ctl.mod_modname); 155 0 stevel continue; 156 0 stevel } 157 0 stevel 158 0 stevel mdb_dprintf(MDB_DBG_KMOD, "reading mod %s (%p)\n", 159 0 stevel name, (void *)addr); 160 0 stevel 161 0 stevel if (mdb_nv_lookup(&kt->k_modules, name) != NULL) { 162 0 stevel warn("skipping duplicate module '%s', id=%d\n", 163 0 stevel name, ctl.mod_id); 164 0 stevel continue; 165 0 stevel } 166 0 stevel 167 0 stevel if (mdb_tgt_vread(t, &kmod, sizeof (kmod), 168 0 stevel (uintptr_t)ctl.mod_mp) == -1) { 169 0 stevel warn("failed to read module at %p\n", 170 0 stevel (void *)ctl.mod_mp); 171 0 stevel continue; 172 0 stevel } 173 0 stevel 174 0 stevel if (kmod.symspace == NULL || kmod.symhdr == NULL || 175 0 stevel kmod.strhdr == NULL) { 176 0 stevel /* 177 0 stevel * If no buffer for the symbols has been allocated, 178 0 stevel * or the shdrs for .symtab and .strtab are missing, 179 0 stevel * then we're out of luck. 180 0 stevel */ 181 0 stevel continue; 182 0 stevel } 183 0 stevel 184 0 stevel if (mdb_tgt_vread(t, &symhdr, sizeof (Shdr), 185 0 stevel (uintptr_t)kmod.symhdr) == -1) { 186 0 stevel warn("failed to read .symtab header for '%s', id=%d", 187 0 stevel name, ctl.mod_id); 188 0 stevel continue; 189 0 stevel } 190 0 stevel 191 0 stevel if (mdb_tgt_vread(t, &strhdr, sizeof (Shdr), 192 0 stevel (uintptr_t)kmod.strhdr) == -1) { 193 0 stevel warn("failed to read .strtab header for '%s', id=%d", 194 0 stevel name, ctl.mod_id); 195 0 stevel continue; 196 0 stevel } 197 0 stevel 198 0 stevel /* 199 0 stevel * Now get clever: f(*^ing krtld didn't used to bother updating 200 0 stevel * its own kmod.symsize value. We know that prior to this bug 201 0 stevel * being fixed, symspace was a contiguous buffer containing 202 0 stevel * .symtab, .strtab, and the symbol hash table in that order. 203 0 stevel * So if symsize is zero, recompute it as the size of .symtab 204 0 stevel * plus the size of .strtab. We don't need to load the hash 205 0 stevel * table anyway since we re-hash all the symbols internally. 206 0 stevel */ 207 0 stevel if (kmod.symsize == 0) 208 0 stevel kmod.symsize = symhdr.sh_size + strhdr.sh_size; 209 0 stevel 210 0 stevel /* 211 0 stevel * Similar logic can be used to make educated guesses 212 0 stevel * at the values of kmod.symtbl and kmod.strings. 213 0 stevel */ 214 0 stevel if (kmod.symtbl == NULL) 215 0 stevel kmod.symtbl = kmod.symspace; 216 0 stevel if (kmod.strings == NULL) 217 0 stevel kmod.strings = kmod.symspace + symhdr.sh_size; 218 0 stevel 219 0 stevel /* 220 0 stevel * Make sure things seem reasonable before we proceed 221 0 stevel * to actually read and decipher the symspace. 222 0 stevel */ 223 0 stevel if (KT_BAD_BUF(kmod.symtbl, kmod.symspace, kmod.symsize) || 224 0 stevel KT_BAD_BUF(kmod.strings, kmod.symspace, kmod.symsize)) { 225 0 stevel warn("skipping module '%s', id=%d (corrupt symspace)\n", 226 0 stevel name, ctl.mod_id); 227 0 stevel continue; 228 0 stevel } 229 0 stevel 230 0 stevel km = mdb_zalloc(sizeof (kt_module_t), UM_SLEEP); 231 0 stevel km->km_name = strdup(name); 232 0 stevel 233 0 stevel (void) mdb_nv_insert(&kt->k_modules, km->km_name, NULL, 234 0 stevel (uintptr_t)km, MDB_NV_EXTNAME); 235 0 stevel 236 0 stevel km->km_datasz = kmod.symsize; 237 0 stevel km->km_symspace_va = (uintptr_t)kmod.symspace; 238 0 stevel km->km_symtab_va = (uintptr_t)kmod.symtbl; 239 0 stevel km->km_strtab_va = (uintptr_t)kmod.strings; 240 0 stevel km->km_symtab_hdr = symhdr; 241 0 stevel km->km_strtab_hdr = strhdr; 242 0 stevel km->km_text_va = (uintptr_t)kmod.text; 243 0 stevel km->km_text_size = kmod.text_size; 244 0 stevel km->km_data_va = (uintptr_t)kmod.data; 245 0 stevel km->km_data_size = kmod.data_size; 246 0 stevel km->km_bss_va = (uintptr_t)kmod.bss; 247 0 stevel km->km_bss_size = kmod.bss_size; 248 0 stevel 249 0 stevel if (kt->k_ctfvalid) { 250 0 stevel km->km_ctf_va = (uintptr_t)kmod.ctfdata; 251 0 stevel km->km_ctf_size = kmod.ctfsize; 252 0 stevel } 253 0 stevel 254 0 stevel /* 255 0 stevel * Add the module to the end of the list of modules in load- 256 0 stevel * dependency order. This is needed to load the corresponding 257 0 stevel * debugger modules in the same order for layering purposes. 258 0 stevel */ 259 0 stevel mdb_list_append(&kt->k_modlist, km); 260 0 stevel 261 0 stevel if (t->t_flags & MDB_TGT_F_PRELOAD) { 262 0 stevel mdb_iob_printf(mdb.m_out, " %s", name); 263 0 stevel mdb_iob_flush(mdb.m_out); 264 0 stevel kt_load_module(kt, t, km); 265 0 stevel } 266 0 stevel 267 0 stevel } while ((addr = (uintptr_t)ctl.mod_next) != head); 268 0 stevel } 269 0 stevel 270 0 stevel int 271 0 stevel kt_setflags(mdb_tgt_t *t, int flags) 272 0 stevel { 273 0 stevel int iochg = ((flags ^ t->t_flags) & MDB_TGT_F_ALLOWIO) && 274 0 stevel !mdb_prop_postmortem; 275 0 stevel int rwchg = (flags ^ t->t_flags) & MDB_TGT_F_RDWR; 276 0 stevel kt_data_t *kt = t->t_data; 277 0 stevel const char *kvmfile; 278 5084 johnlev void *cookie; 279 0 stevel int mode; 280 0 stevel 281 0 stevel if (!iochg && !rwchg) 282 0 stevel return (0); 283 5084 johnlev 284 5084 johnlev if (kt->k_xpv_domu) { 285 5084 johnlev warn("read-only target"); 286 5084 johnlev return (-1); 287 5084 johnlev } 288 0 stevel 289 0 stevel if (iochg) { 290 0 stevel kvmfile = (flags & MDB_TGT_F_ALLOWIO) ? "/dev/allkmem" : 291 0 stevel "/dev/kmem"; 292 0 stevel } else { 293 0 stevel kvmfile = kt->k_kvmfile; 294 0 stevel } 295 0 stevel 296 0 stevel mode = (flags & MDB_TGT_F_RDWR) ? O_RDWR : O_RDONLY; 297 0 stevel 298 5084 johnlev if ((cookie = kt->k_kb_ops->kb_open(kt->k_symfile, kvmfile, NULL, mode, 299 0 stevel mdb.m_pname)) == NULL) { 300 0 stevel /* We failed to re-open, so don't change t_flags */ 301 0 stevel warn("failed to re-open target"); 302 0 stevel return (-1); 303 0 stevel } 304 0 stevel 305 0 stevel /* 306 0 stevel * We successfully reopened the target, so update k_kvmfile. Also set 307 0 stevel * the RDWR and ALLOWIO bits in t_flags to match those in flags. 308 0 stevel */ 309 5084 johnlev (void) kt->k_kb_ops->kb_close(kt->k_cookie); 310 0 stevel kt->k_cookie = cookie; 311 0 stevel 312 0 stevel if (kvmfile != kt->k_kvmfile) { 313 0 stevel strfree(kt->k_kvmfile); 314 0 stevel kt->k_kvmfile = strdup(kvmfile); 315 0 stevel } 316 0 stevel 317 0 stevel t->t_flags = (t->t_flags & ~(MDB_TGT_F_RDWR | MDB_TGT_F_ALLOWIO)) | 318 0 stevel (flags & (MDB_TGT_F_RDWR | MDB_TGT_F_ALLOWIO)); 319 0 stevel 320 0 stevel return (0); 321 0 stevel } 322 0 stevel 323 0 stevel /* 324 0 stevel * Determine which PIDs (if any) have their pages saved in the dump. We 325 0 stevel * do this by looking for content flags in dump_flags in the header. These 326 0 stevel * flags, which won't be set in older dumps, tell us whether a single process 327 0 stevel * has had its pages included in the dump. If a single process has been 328 0 stevel * included, we need to get the PID for that process from the dump_pids 329 0 stevel * array in the dump. 330 0 stevel */ 331 0 stevel static int 332 0 stevel kt_find_dump_contents(kt_data_t *kt) 333 0 stevel { 334 0 stevel dumphdr_t *dh = kt->k_dumphdr; 335 0 stevel pid_t pid = -1; 336 0 stevel 337 0 stevel if (dh->dump_flags & DF_ALL) 338 0 stevel return (KT_DUMPCONTENT_ALL); 339 0 stevel 340 0 stevel if (dh->dump_flags & DF_CURPROC) { 341 0 stevel if ((pid = kt->k_dump_find_curproc()) == -1) 342 0 stevel return (KT_DUMPCONTENT_INVALID); 343 0 stevel else 344 0 stevel return (pid); 345 0 stevel } else { 346 0 stevel return (KT_DUMPCONTENT_KERNEL); 347 0 stevel } 348 0 stevel } 349 0 stevel 350 0 stevel static int 351 0 stevel kt_dump_contains_proc(mdb_tgt_t *t, void *context) 352 0 stevel { 353 0 stevel kt_data_t *kt = t->t_data; 354 0 stevel pid_t (*f_pid)(uintptr_t); 355 0 stevel pid_t reqpid; 356 0 stevel 357 0 stevel switch (kt->k_dumpcontent) { 358 0 stevel case KT_DUMPCONTENT_KERNEL: 359 0 stevel return (0); 360 0 stevel case KT_DUMPCONTENT_ALL: 361 0 stevel return (1); 362 0 stevel case KT_DUMPCONTENT_INVALID: 363 0 stevel goto procnotfound; 364 0 stevel default: 365 0 stevel f_pid = (pid_t (*)()) dlsym(RTLD_NEXT, "mdb_kproc_pid"); 366 0 stevel if (f_pid == NULL) 367 0 stevel goto procnotfound; 368 0 stevel 369 0 stevel reqpid = f_pid((uintptr_t)context); 370 0 stevel if (reqpid == -1) 371 0 stevel goto procnotfound; 372 0 stevel 373 0 stevel return (kt->k_dumpcontent == reqpid); 374 0 stevel } 375 0 stevel 376 0 stevel procnotfound: 377 0 stevel warn("unable to determine whether dump contains proc %p\n", context); 378 0 stevel return (1); 379 0 stevel } 380 0 stevel 381 0 stevel int 382 0 stevel kt_setcontext(mdb_tgt_t *t, void *context) 383 0 stevel { 384 0 stevel if (context != NULL) { 385 0 stevel const char *argv[2]; 386 0 stevel int argc = 0; 387 0 stevel mdb_tgt_t *ct; 388 0 stevel kt_data_t *kt = t->t_data; 389 0 stevel 390 0 stevel argv[argc++] = (const char *)context; 391 0 stevel argv[argc] = NULL; 392 0 stevel 393 0 stevel if (kt->k_dumphdr != NULL && 394 0 stevel !kt_dump_contains_proc(t, context)) { 395 0 stevel warn("dump does not contain pages for proc %p\n", 396 0 stevel context); 397 0 stevel return (-1); 398 0 stevel } 399 0 stevel 400 0 stevel if ((ct = mdb_tgt_create(mdb_kproc_tgt_create, 401 0 stevel t->t_flags, argc, argv)) == NULL) 402 0 stevel return (-1); 403 0 stevel 404 0 stevel mdb_printf("debugger context set to proc %p\n", context); 405 0 stevel mdb_tgt_activate(ct); 406 0 stevel } else 407 0 stevel mdb_printf("debugger context set to kernel\n"); 408 0 stevel 409 0 stevel return (0); 410 0 stevel } 411 0 stevel 412 0 stevel static int 413 0 stevel kt_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 414 0 stevel { 415 0 stevel kt_data_t *kt = mdb.m_target->t_data; 416 0 stevel return (kt->k_dcmd_stack(addr, flags, argc, argv)); 417 0 stevel } 418 0 stevel 419 0 stevel static int 420 0 stevel kt_stackv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 421 0 stevel { 422 0 stevel kt_data_t *kt = mdb.m_target->t_data; 423 0 stevel return (kt->k_dcmd_stackv(addr, flags, argc, argv)); 424 0 stevel } 425 0 stevel 426 0 stevel static int 427 0 stevel kt_stackr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 428 0 stevel { 429 0 stevel kt_data_t *kt = mdb.m_target->t_data; 430 0 stevel return (kt->k_dcmd_stackr(addr, flags, argc, argv)); 431 0 stevel } 432 0 stevel 433 0 stevel static int 434 0 stevel kt_regs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 435 0 stevel { 436 0 stevel kt_data_t *kt = mdb.m_target->t_data; 437 5084 johnlev 438 5084 johnlev if (argc != 0 || (flags & DCMD_ADDRSPEC)) 439 5084 johnlev return (DCMD_USAGE); 440 5084 johnlev 441 5084 johnlev addr = (uintptr_t)kt->k_regs; 442 5084 johnlev 443 0 stevel return (kt->k_dcmd_regs(addr, flags, argc, argv)); 444 0 stevel } 445 5084 johnlev 446 5084 johnlev #ifdef __x86 447 5084 johnlev static int 448 5084 johnlev kt_cpustack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 449 5084 johnlev { 450 5084 johnlev kt_data_t *kt = mdb.m_target->t_data; 451 5084 johnlev return (kt->k_dcmd_cpustack(addr, flags, argc, argv)); 452 5084 johnlev } 453 5084 johnlev 454 5084 johnlev static int 455 5084 johnlev kt_cpuregs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 456 5084 johnlev { 457 5084 johnlev kt_data_t *kt = mdb.m_target->t_data; 458 5084 johnlev return (kt->k_dcmd_cpuregs(addr, flags, argc, argv)); 459 5084 johnlev } 460 5084 johnlev #endif /* __x86 */ 461 0 stevel 462 0 stevel /*ARGSUSED*/ 463 0 stevel static int 464 0 stevel kt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 465 0 stevel { 466 0 stevel kt_data_t *kt = mdb.m_target->t_data; 467 0 stevel struct utsname uts; 468 0 stevel 469 0 stevel bzero(&uts, sizeof (uts)); 470 0 stevel (void) strcpy(uts.nodename, "unknown machine"); 471 0 stevel (void) kt_uname(mdb.m_target, &uts); 472 0 stevel 473 0 stevel if (mdb_prop_postmortem) { 474 5084 johnlev mdb_printf("debugging %scrash dump %s (%d-bit) from %s\n", 475 5084 johnlev kt->k_xpv_domu ? "domain " : "", kt->k_kvmfile, 476 5084 johnlev (int)(sizeof (void *) * NBBY), uts.nodename); 477 0 stevel } else { 478 0 stevel mdb_printf("debugging live kernel (%d-bit) on %s\n", 479 0 stevel (int)(sizeof (void *) * NBBY), uts.nodename); 480 0 stevel } 481 0 stevel 482 0 stevel mdb_printf("operating system: %s %s (%s)\n", 483 0 stevel uts.release, uts.version, uts.machine); 484 0 stevel 485 0 stevel if (kt->k_dumphdr) { 486 0 stevel dumphdr_t *dh = kt->k_dumphdr; 487 0 stevel 488 0 stevel mdb_printf("panic message: %s\n", dh->dump_panicstring); 489 0 stevel 490 0 stevel kt->k_dump_print_content(dh, kt->k_dumpcontent); 491 0 stevel } 492 0 stevel 493 0 stevel return (DCMD_OK); 494 0 stevel } 495 0 stevel 496 0 stevel static const mdb_dcmd_t kt_dcmds[] = { 497 0 stevel { "$c", "?[cnt]", "print stack backtrace", kt_stack }, 498 0 stevel { "$C", "?[cnt]", "print stack backtrace", kt_stackv }, 499 0 stevel { "$r", NULL, "print general-purpose registers", kt_regs }, 500 0 stevel { "$?", NULL, "print status and registers", kt_regs }, 501 0 stevel { "regs", NULL, "print general-purpose registers", kt_regs }, 502 0 stevel { "stack", "?[cnt]", "print stack backtrace", kt_stack }, 503 0 stevel { "stackregs", "?", "print stack backtrace and registers", kt_stackr }, 504 5084 johnlev #ifdef __x86 505 5084 johnlev { "cpustack", "?[-v] [-c cpuid] [cnt]", "print stack backtrace for a " 506 5084 johnlev "specific CPU", kt_cpustack }, 507 5084 johnlev { "cpuregs", "?[-c cpuid]", "print general-purpose registers for a " 508 5084 johnlev "specific CPU", kt_cpuregs }, 509 5084 johnlev #endif 510 0 stevel { "status", NULL, "print summary of current target", kt_status_dcmd }, 511 0 stevel { NULL } 512 0 stevel }; 513 0 stevel 514 0 stevel static uintmax_t 515 0 stevel reg_disc_get(const mdb_var_t *v) 516 0 stevel { 517 0 stevel mdb_tgt_t *t = MDB_NV_COOKIE(v); 518 0 stevel kt_data_t *kt = t->t_data; 519 0 stevel mdb_tgt_reg_t r = 0; 520 0 stevel 521 0 stevel (void) mdb_tgt_getareg(t, kt->k_tid, mdb_nv_get_name(v), &r); 522 0 stevel return (r); 523 0 stevel } 524 0 stevel 525 3446 mrj static kt_module_t * 526 3446 mrj kt_module_by_name(kt_data_t *kt, const char *name) 527 3446 mrj { 528 3446 mrj kt_module_t *km; 529 3446 mrj 530 3446 mrj for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) { 531 3446 mrj if (strcmp(name, km->km_name) == 0) 532 3446 mrj return (km); 533 3446 mrj } 534 3446 mrj 535 3446 mrj return (NULL); 536 3446 mrj } 537 3446 mrj 538 0 stevel void 539 0 stevel kt_activate(mdb_tgt_t *t) 540 0 stevel { 541 0 stevel static const mdb_nv_disc_t reg_disc = { NULL, reg_disc_get }; 542 0 stevel kt_data_t *kt = t->t_data; 543 0 stevel void *sym; 544 0 stevel 545 0 stevel int oflag; 546 0 stevel 547 5084 johnlev mdb_prop_postmortem = kt->k_xpv_domu || (kt->k_dumphdr != NULL); 548 0 stevel mdb_prop_kernel = TRUE; 549 0 stevel mdb_prop_datamodel = MDB_TGT_MODEL_NATIVE; 550 0 stevel 551 0 stevel if (kt->k_activated == FALSE) { 552 0 stevel struct utsname u1, u2; 553 0 stevel /* 554 0 stevel * If we're examining a crash dump, root is /, and uname(2) 555 0 stevel * does not match the utsname in the dump, issue a warning. 556 0 stevel * Note that we are assuming that the modules and macros in 557 0 stevel * /usr/lib are compiled against the kernel from uname -rv. 558 0 stevel */ 559 0 stevel if (mdb_prop_postmortem && strcmp(mdb.m_root, "/") == 0 && 560 0 stevel uname(&u1) >= 0 && kt_uname(t, &u2) >= 0 && 561 0 stevel (strcmp(u1.release, u2.release) || 562 0 stevel strcmp(u1.version, u2.version))) { 563 0 stevel mdb_warn("warning: dump is from %s %s %s; dcmds and " 564 0 stevel "macros may not match kernel implementation\n", 565 0 stevel u2.sysname, u2.release, u2.version); 566 0 stevel } 567 0 stevel 568 0 stevel if (mdb_module_load(KT_MODULE, MDB_MOD_GLOBAL) < 0) { 569 0 stevel warn("failed to load kernel support module -- " 570 0 stevel "some modules may not load\n"); 571 0 stevel } 572 0 stevel 573 5084 johnlev if (mdb_prop_postmortem && kt->k_dumphdr != NULL) { 574 0 stevel sym = dlsym(RTLD_NEXT, "mdb_dump_print_content"); 575 0 stevel if (sym != NULL) 576 0 stevel kt->k_dump_print_content = (void (*)())sym; 577 0 stevel 578 0 stevel sym = dlsym(RTLD_NEXT, "mdb_dump_find_curproc"); 579 0 stevel if (sym != NULL) 580 0 stevel kt->k_dump_find_curproc = (int (*)())sym; 581 0 stevel 582 0 stevel kt->k_dumpcontent = kt_find_dump_contents(kt); 583 0 stevel } 584 0 stevel 585 0 stevel if (t->t_flags & MDB_TGT_F_PRELOAD) { 586 0 stevel oflag = mdb_iob_getflags(mdb.m_out) & MDB_IOB_PGENABLE; 587 0 stevel 588 0 stevel mdb_iob_clrflags(mdb.m_out, oflag); 589 0 stevel mdb_iob_puts(mdb.m_out, "Preloading module symbols: ["); 590 0 stevel mdb_iob_flush(mdb.m_out); 591 0 stevel } 592 0 stevel 593 3446 mrj if (!(t->t_flags & MDB_TGT_F_NOLOAD)) { 594 0 stevel kt_load_modules(kt, t); 595 3446 mrj 596 3446 mrj /* 597 3446 mrj * Determine where the CTF data for krtld is. If krtld 598 3446 mrj * is rolled into unix, force load the MDB krtld 599 3446 mrj * module. 600 3446 mrj */ 601 3446 mrj kt->k_rtld_name = "krtld"; 602 3446 mrj 603 3446 mrj if (kt_module_by_name(kt, "krtld") == NULL) { 604 3446 mrj (void) mdb_module_load("krtld", MDB_MOD_SILENT); 605 3446 mrj kt->k_rtld_name = "unix"; 606 3446 mrj } 607 3446 mrj } 608 3446 mrj 609 0 stevel 610 0 stevel if (t->t_flags & MDB_TGT_F_PRELOAD) { 611 0 stevel mdb_iob_puts(mdb.m_out, " ]\n"); 612 0 stevel mdb_iob_setflags(mdb.m_out, oflag); 613 0 stevel } 614 0 stevel 615 0 stevel kt->k_activated = TRUE; 616 0 stevel } 617 0 stevel 618 0 stevel (void) mdb_tgt_register_dcmds(t, &kt_dcmds[0], MDB_MOD_FORCE); 619 0 stevel 620 0 stevel /* Export some of our registers as named variables */ 621 0 stevel mdb_tgt_register_regvars(t, kt->k_rds, ®_disc, MDB_NV_RDONLY); 622 0 stevel 623 0 stevel mdb_tgt_elf_export(kt->k_file); 624 0 stevel } 625 0 stevel 626 0 stevel void 627 0 stevel kt_deactivate(mdb_tgt_t *t) 628 0 stevel { 629 0 stevel kt_data_t *kt = t->t_data; 630 0 stevel 631 0 stevel const mdb_tgt_regdesc_t *rdp; 632 0 stevel const mdb_dcmd_t *dcp; 633 0 stevel 634 0 stevel for (rdp = kt->k_rds; rdp->rd_name != NULL; rdp++) { 635 0 stevel mdb_var_t *v; 636 0 stevel 637 0 stevel if (!(rdp->rd_flags & MDB_TGT_R_EXPORT)) 638 0 stevel continue; /* Didn't export register as a variable */ 639 0 stevel 640 0 stevel if ((v = mdb_nv_lookup(&mdb.m_nv, rdp->rd_name)) != NULL) { 641 0 stevel v->v_flags &= ~MDB_NV_PERSIST; 642 0 stevel mdb_nv_remove(&mdb.m_nv, v); 643 0 stevel } 644 0 stevel } 645 0 stevel 646 0 stevel for (dcp = &kt_dcmds[0]; dcp->dc_name != NULL; dcp++) { 647 0 stevel if (mdb_module_remove_dcmd(t->t_module, dcp->dc_name) == -1) 648 0 stevel warn("failed to remove dcmd %s", dcp->dc_name); 649 0 stevel } 650 0 stevel 651 0 stevel mdb_prop_postmortem = FALSE; 652 0 stevel mdb_prop_kernel = FALSE; 653 0 stevel mdb_prop_datamodel = MDB_TGT_MODEL_UNKNOWN; 654 0 stevel } 655 0 stevel 656 0 stevel /*ARGSUSED*/ 657 0 stevel const char * 658 0 stevel kt_name(mdb_tgt_t *t) 659 0 stevel { 660 0 stevel return ("kvm"); 661 0 stevel } 662 0 stevel 663 0 stevel const char * 664 0 stevel kt_platform(mdb_tgt_t *t) 665 0 stevel { 666 0 stevel kt_data_t *kt = t->t_data; 667 0 stevel return (kt->k_platform); 668 0 stevel } 669 0 stevel 670 0 stevel int 671 0 stevel kt_uname(mdb_tgt_t *t, struct utsname *utsp) 672 0 stevel { 673 0 stevel return (mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, utsp, 674 0 stevel sizeof (struct utsname), MDB_TGT_OBJ_EXEC, "utsname")); 675 0 stevel } 676 0 stevel 677 0 stevel /*ARGSUSED*/ 678 0 stevel int 679 0 stevel kt_dmodel(mdb_tgt_t *t) 680 0 stevel { 681 0 stevel return (MDB_TGT_MODEL_NATIVE); 682 0 stevel } 683 0 stevel 684 0 stevel ssize_t 685 0 stevel kt_aread(mdb_tgt_t *t, mdb_tgt_as_t as, void *buf, 686 0 stevel size_t nbytes, mdb_tgt_addr_t addr) 687 0 stevel { 688 0 stevel kt_data_t *kt = t->t_data; 689 0 stevel ssize_t rval; 690 0 stevel 691 5084 johnlev if ((rval = kt->k_kb_ops->kb_aread(kt->k_cookie, addr, buf, 692 5084 johnlev nbytes, as)) == -1) 693 0 stevel return (set_errno(EMDB_NOMAP)); 694 0 stevel 695 0 stevel return (rval); 696 0 stevel } 697 0 stevel 698 0 stevel ssize_t 699 0 stevel kt_awrite(mdb_tgt_t *t, mdb_tgt_as_t as, const void *buf, 700 0 stevel size_t nbytes, mdb_tgt_addr_t addr) 701 0 stevel { 702 0 stevel kt_data_t *kt = t->t_data; 703 0 stevel ssize_t rval; 704 0 stevel 705 5084 johnlev if ((rval = kt->k_kb_ops->kb_awrite(kt->k_cookie, addr, buf, 706 5084 johnlev nbytes, as)) == -1) 707 0 stevel return (set_errno(EMDB_NOMAP)); 708 0 stevel 709 0 stevel return (rval); 710 0 stevel } 711 0 stevel 712 0 stevel ssize_t 713 0 stevel kt_vread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr) 714 0 stevel { 715 0 stevel kt_data_t *kt = t->t_data; 716 0 stevel ssize_t rval; 717 0 stevel 718 5084 johnlev if ((rval = kt->k_kb_ops->kb_kread(kt->k_cookie, addr, buf, 719 5084 johnlev nbytes)) == -1) 720 0 stevel return (set_errno(EMDB_NOMAP)); 721 0 stevel 722 0 stevel return (rval); 723 0 stevel } 724 0 stevel 725 0 stevel ssize_t 726 0 stevel kt_vwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr) 727 0 stevel { 728 0 stevel kt_data_t *kt = t->t_data; 729 0 stevel ssize_t rval; 730 0 stevel 731 5084 johnlev if ((rval = kt->k_kb_ops->kb_kwrite(kt->k_cookie, addr, buf, 732 5084 johnlev nbytes)) == -1) 733 0 stevel return (set_errno(EMDB_NOMAP)); 734 0 stevel 735 0 stevel return (rval); 736 0 stevel } 737 0 stevel 738 0 stevel ssize_t 739 0 stevel kt_fread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr) 740 0 stevel { 741 0 stevel return (kt_vread(t, buf, nbytes, addr)); 742 0 stevel } 743 0 stevel 744 0 stevel ssize_t 745 0 stevel kt_fwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr) 746 0 stevel { 747 0 stevel return (kt_vwrite(t, buf, nbytes, addr)); 748 0 stevel } 749 0 stevel 750 0 stevel ssize_t 751 0 stevel kt_pread(mdb_tgt_t *t, void *buf, size_t nbytes, physaddr_t addr) 752 0 stevel { 753 0 stevel kt_data_t *kt = t->t_data; 754 0 stevel ssize_t rval; 755 0 stevel 756 5084 johnlev if ((rval = kt->k_kb_ops->kb_pread(kt->k_cookie, addr, buf, 757 5084 johnlev nbytes)) == -1) 758 0 stevel return (set_errno(EMDB_NOMAP)); 759 0 stevel 760 0 stevel return (rval); 761 0 stevel } 762 0 stevel 763 0 stevel ssize_t 764 0 stevel kt_pwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, physaddr_t addr) 765 0 stevel { 766 0 stevel kt_data_t *kt = t->t_data; 767 0 stevel ssize_t rval; 768 0 stevel 769 5084 johnlev if ((rval = kt->k_kb_ops->kb_pwrite(kt->k_cookie, addr, buf, 770 5084 johnlev nbytes)) == -1) 771 0 stevel return (set_errno(EMDB_NOMAP)); 772 0 stevel 773 0 stevel return (rval); 774 0 stevel } 775 0 stevel 776 0 stevel int 777 0 stevel kt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap) 778 0 stevel { 779 0 stevel kt_data_t *kt = t->t_data; 780 0 stevel 781 0 stevel struct as *asp; 782 0 stevel physaddr_t pa; 783 0 stevel mdb_module_t *mod; 784 0 stevel mdb_var_t *v; 785 0 stevel int (*fptr)(uintptr_t, struct as *, physaddr_t *); 786 0 stevel 787 0 stevel switch ((uintptr_t)as) { 788 0 stevel case (uintptr_t)MDB_TGT_AS_PHYS: 789 0 stevel case (uintptr_t)MDB_TGT_AS_FILE: 790 0 stevel case (uintptr_t)MDB_TGT_AS_IO: 791 0 stevel return (set_errno(EINVAL)); 792 0 stevel case (uintptr_t)MDB_TGT_AS_VIRT: 793 0 stevel asp = kt->k_as; 794 0 stevel break; 795 0 stevel default: 796 0 stevel asp = (struct as *)as; 797 0 stevel } 798 0 stevel 799 5084 johnlev if ((pa = kt->k_kb_ops->kb_vtop(kt->k_cookie, asp, va)) != -1ULL) { 800 0 stevel *pap = pa; 801 0 stevel return (0); 802 0 stevel } 803 0 stevel 804 0 stevel if ((v = mdb_nv_lookup(&mdb.m_modules, "unix")) != NULL && 805 0 stevel (mod = mdb_nv_get_cookie(v)) != NULL) { 806 0 stevel 807 0 stevel fptr = (int (*)(uintptr_t, struct as *, physaddr_t *)) 808 5084 johnlev dlsym(mod->mod_hdl, "platform_vtop"); 809 0 stevel 810 0 stevel if ((fptr != NULL) && ((*fptr)(va, asp, pap) == 0)) 811 0 stevel return (0); 812 0 stevel } 813 0 stevel 814 0 stevel return (set_errno(EMDB_NOMAP)); 815 0 stevel } 816 0 stevel 817 0 stevel int 818 0 stevel kt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name, 819 0 stevel GElf_Sym *symp, mdb_syminfo_t *sip) 820 0 stevel { 821 0 stevel kt_data_t *kt = t->t_data; 822 0 stevel kt_module_t *km, kmod; 823 0 stevel mdb_var_t *v; 824 0 stevel int n; 825 0 stevel 826 0 stevel /* 827 0 stevel * To simplify the implementation, we create a fake module on the stack 828 0 stevel * which is "prepended" to k_modlist and whose symtab is kt->k_symtab. 829 0 stevel */ 830 0 stevel kmod.km_symtab = kt->k_symtab; 831 0 stevel kmod.km_list.ml_next = mdb_list_next(&kt->k_modlist); 832 0 stevel 833 0 stevel switch ((uintptr_t)obj) { 834 0 stevel case (uintptr_t)MDB_TGT_OBJ_EXEC: 835 0 stevel km = &kmod; 836 0 stevel n = 1; 837 0 stevel break; 838 0 stevel 839 0 stevel case (uintptr_t)MDB_TGT_OBJ_EVERY: 840 0 stevel km = &kmod; 841 0 stevel n = mdb_nv_size(&kt->k_modules) + 1; 842 0 stevel break; 843 0 stevel 844 0 stevel case (uintptr_t)MDB_TGT_OBJ_RTLD: 845 3446 mrj obj = kt->k_rtld_name; 846 0 stevel /*FALLTHRU*/ 847 0 stevel 848 0 stevel default: 849 0 stevel if ((v = mdb_nv_lookup(&kt->k_modules, obj)) == NULL) 850 0 stevel return (set_errno(EMDB_NOOBJ)); 851 0 stevel 852 0 stevel km = mdb_nv_get_cookie(v); 853 0 stevel n = 1; 854 0 stevel 855 0 stevel if (km->km_symtab == NULL) 856 0 stevel kt_load_module(kt, t, km); 857 0 stevel } 858 0 stevel 859 0 stevel for (; n > 0; n--, km = mdb_list_next(km)) { 860 0 stevel if (mdb_gelf_symtab_lookup_by_name(km->km_symtab, name, 861 0 stevel symp, &sip->sym_id) == 0) { 862 0 stevel sip->sym_table = MDB_TGT_SYMTAB; 863 0 stevel return (0); 864 0 stevel } 865 0 stevel } 866 0 stevel 867 0 stevel return (set_errno(EMDB_NOSYM)); 868 0 stevel } 869 0 stevel 870 0 stevel int 871 0 stevel kt_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags, 872 0 stevel char *buf, size_t nbytes, GElf_Sym *symp, mdb_syminfo_t *sip) 873 0 stevel { 874 0 stevel kt_data_t *kt = t->t_data; 875 0 stevel kt_module_t kmods[3], *kmods_begin = &kmods[0], *kmods_end; 876 0 stevel const char *name; 877 0 stevel 878 0 stevel kt_module_t *km = &kmods[0]; /* Point km at first fake module */ 879 0 stevel kt_module_t *sym_km = NULL; /* Module associated with best sym */ 880 0 stevel GElf_Sym sym; /* Best symbol found so far if !exact */ 881 0 stevel uint_t symid; /* ID of best symbol found so far */ 882 0 stevel 883 0 stevel /* 884 0 stevel * To simplify the implementation, we create fake modules on the stack 885 0 stevel * that are "prepended" to k_modlist and whose symtab is set to 886 0 stevel * each of three special symbol tables, in order of precedence. 887 0 stevel */ 888 0 stevel km->km_symtab = mdb.m_prsym; 889 0 stevel 890 0 stevel if (kt->k_symtab != NULL) { 891 0 stevel km->km_list.ml_next = (mdb_list_t *)(km + 1); 892 0 stevel km = mdb_list_next(km); 893 0 stevel km->km_symtab = kt->k_symtab; 894 0 stevel } 895 0 stevel 896 0 stevel if (kt->k_dynsym != NULL) { 897 0 stevel km->km_list.ml_next = (mdb_list_t *)(km + 1); 898 0 stevel km = mdb_list_next(km); 899 0 stevel km->km_symtab = kt->k_dynsym; 900 0 stevel } 901 0 stevel 902 0 stevel km->km_list.ml_next = mdb_list_next(&kt->k_modlist); 903 0 stevel kmods_end = km; 904 0 stevel 905 0 stevel /* 906 0 stevel * Now iterate over the list of fake and real modules. If the module 907 0 stevel * has no symbol table and the address is in the text section, 908 0 stevel * instantiate the module's symbol table. In exact mode, we can 909 0 stevel * jump to 'found' immediately if we match. Otherwise we continue 910 0 stevel * looking and improve our choice if we find a closer symbol. 911 0 stevel */ 912 0 stevel for (km = &kmods[0]; km != NULL; km = mdb_list_next(km)) { 913 0 stevel if (km->km_symtab == NULL && addr >= km->km_text_va && 914 0 stevel addr < km->km_text_va + km->km_text_size) 915 0 stevel kt_load_module(kt, t, km); 916 0 stevel 917 0 stevel if (mdb_gelf_symtab_lookup_by_addr(km->km_symtab, addr, 918 0 stevel flags, buf, nbytes, symp, &sip->sym_id) != 0 || 919 0 stevel symp->st_value == 0) 920 0 stevel continue; 921 0 stevel 922 0 stevel if (flags & MDB_TGT_SYM_EXACT) { 923 0 stevel sym_km = km; 924 0 stevel goto found; 925 0 stevel } 926 0 stevel 927 0 stevel if (sym_km == NULL || mdb_gelf_sym_closer(symp, &sym, addr)) { 928 0 stevel sym_km = km; 929 0 stevel sym = *symp; 930 0 stevel symid = sip->sym_id; 931 0 stevel } 932 0 stevel } 933 0 stevel 934 0 stevel if (sym_km == NULL) 935 0 stevel return (set_errno(EMDB_NOSYMADDR)); 936 0 stevel 937 0 stevel *symp = sym; /* Copy our best symbol into the caller's symbol */ 938 0 stevel sip->sym_id = symid; 939 0 stevel found: 940 0 stevel /* 941 0 stevel * Once we've found something, copy the final name into the caller's 942 0 stevel * buffer and prefix it with the load object name if appropriate. 943 0 stevel */ 944 5084 johnlev if (sym_km != NULL) { 945 5084 johnlev name = mdb_gelf_sym_name(sym_km->km_symtab, symp); 946 0 stevel 947 5084 johnlev if (sym_km < kmods_begin || sym_km > kmods_end) { 948 5084 johnlev (void) mdb_snprintf(buf, nbytes, "%s`%s", 949 5084 johnlev sym_km->km_name, name); 950 5084 johnlev } else if (nbytes > 0) { 951 5084 johnlev (void) strncpy(buf, name, nbytes); 952 5084 johnlev buf[nbytes - 1] = '\0'; 953 5084 johnlev } 954 5084 johnlev 955 5084 johnlev if (sym_km->km_symtab == mdb.m_prsym) 956 5084 johnlev sip->sym_table = MDB_TGT_PRVSYM; 957 5084 johnlev else 958 5084 johnlev sip->sym_table = MDB_TGT_SYMTAB; 959 5084 johnlev } else { 960 5084 johnlev sip->sym_table = MDB_TGT_SYMTAB; 961 0 stevel } 962 0 stevel 963 0 stevel return (0); 964 0 stevel } 965 0 stevel 966 0 stevel static int 967 0 stevel kt_symtab_func(void *data, const GElf_Sym *sym, const char *name, uint_t id) 968 0 stevel { 969 0 stevel kt_symarg_t *argp = data; 970 0 stevel 971 0 stevel if (mdb_tgt_sym_match(sym, argp->sym_type)) { 972 0 stevel argp->sym_info.sym_id = id; 973 0 stevel 974 0 stevel return (argp->sym_cb(argp->sym_data, sym, name, 975 0 stevel &argp->sym_info, argp->sym_obj)); 976 0 stevel } 977 0 stevel 978 0 stevel return (0); 979 0 stevel } 980 0 stevel 981 0 stevel static void 982 0 stevel kt_symtab_iter(mdb_gelf_symtab_t *gst, uint_t type, const char *obj, 983 0 stevel mdb_tgt_sym_f *cb, void *p) 984 0 stevel { 985 0 stevel kt_symarg_t arg; 986 0 stevel 987 0 stevel arg.sym_cb = cb; 988 0 stevel arg.sym_data = p; 989 0 stevel arg.sym_type = type; 990 0 stevel arg.sym_info.sym_table = gst->gst_tabid; 991 0 stevel arg.sym_obj = obj; 992 0 stevel 993 0 stevel mdb_gelf_symtab_iter(gst, kt_symtab_func, &arg); 994 0 stevel } 995 0 stevel 996 0 stevel int 997 0 stevel kt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, uint_t type, 998 0 stevel mdb_tgt_sym_f *cb, void *data) 999 0 stevel { 1000 0 stevel kt_data_t *kt = t->t_data; 1001 0 stevel kt_module_t *km; 1002 0 stevel 1003 0 stevel mdb_gelf_symtab_t *symtab = NULL; 1004 0 stevel mdb_var_t *v; 1005 0 stevel 1006 0 stevel switch ((uintptr_t)obj) { 1007 0 stevel case (uintptr_t)MDB_TGT_OBJ_EXEC: 1008 0 stevel if (which == MDB_TGT_SYMTAB) 1009 0 stevel symtab = kt->k_symtab; 1010 0 stevel else 1011 0 stevel symtab = kt->k_dynsym; 1012 0 stevel break; 1013 0 stevel 1014 0 stevel case (uintptr_t)MDB_TGT_OBJ_EVERY: 1015 0 stevel if (which == MDB_TGT_DYNSYM) { 1016 0 stevel symtab = kt->k_dynsym; 1017 0 stevel obj = MDB_TGT_OBJ_EXEC; 1018 0 stevel break; 1019 0 stevel } 1020 0 stevel 1021 0 stevel mdb_nv_rewind(&kt->k_modules); 1022 0 stevel while ((v = mdb_nv_advance(&kt->k_modules)) != NULL) { 1023 0 stevel km = mdb_nv_get_cookie(v); 1024 0 stevel 1025 0 stevel if (km->km_symtab == NULL) 1026 0 stevel kt_load_module(kt, t, km); 1027 0 stevel 1028 0 stevel if (km->km_symtab != NULL) 1029 0 stevel kt_symtab_iter(km->km_symtab, type, 1030 0 stevel km->km_name, cb, data); 1031 0 stevel } 1032 0 stevel break; 1033 0 stevel 1034 0 stevel case (uintptr_t)MDB_TGT_OBJ_RTLD: 1035 3446 mrj obj = kt->k_rtld_name; 1036 0 stevel /*FALLTHRU*/ 1037 0 stevel 1038 0 stevel default: 1039 0 stevel v = mdb_nv_lookup(&kt->k_modules, obj); 1040 0 stevel 1041 0 stevel if (v == NULL) 1042 0 stevel return (set_errno(EMDB_NOOBJ)); 1043 0 stevel 1044 0 stevel km = mdb_nv_get_cookie(v); 1045 0 stevel 1046 0 stevel if (km->km_symtab == NULL) 1047 0 stevel kt_load_module(kt, t, km); 1048 0 stevel 1049 0 stevel symtab = km->km_symtab; 1050 0 stevel } 1051 0 stevel 1052 0 stevel if (symtab) 1053 0 stevel kt_symtab_iter(symtab, type, obj, cb, data); 1054 0 stevel 1055 0 stevel return (0); 1056 0 stevel } 1057 0 stevel 1058 0 stevel static int 1059 0 stevel kt_mapping_walk(uintptr_t addr, const void *data, kt_maparg_t *marg) 1060 0 stevel { 1061 0 stevel /* 1062 0 stevel * This is a bit sketchy but avoids problematic compilation of this 1063 0 stevel * target against the current VM implementation. Now that we have 1064 0 stevel * vmem, we can make this less broken and more informative by changing 1065 0 stevel * this code to invoke the vmem walker in the near future. 1066 0 stevel */ 1067 0 stevel const struct kt_seg { 1068 0 stevel caddr_t s_base; 1069 0 stevel size_t s_size; 1070 0 stevel } *segp = (const struct kt_seg *)data; 1071 0 stevel 1072 0 stevel mdb_map_t map; 1073 0 stevel GElf_Sym sym; 1074 0 stevel mdb_syminfo_t info; 1075 0 stevel 1076 0 stevel map.map_base = (uintptr_t)segp->s_base; 1077 0 stevel map.map_size = segp->s_size; 1078 0 stevel map.map_flags = MDB_TGT_MAP_R | MDB_TGT_MAP_W | MDB_TGT_MAP_X; 1079 0 stevel 1080 0 stevel if (kt_lookup_by_addr(marg->map_target, addr, MDB_TGT_SYM_EXACT, 1081 0 stevel map.map_name, MDB_TGT_MAPSZ, &sym, &info) == -1) { 1082 0 stevel 1083 0 stevel (void) mdb_iob_snprintf(map.map_name, MDB_TGT_MAPSZ, 1084 0 stevel "%lr", addr); 1085 0 stevel } 1086 0 stevel 1087 0 stevel return (marg->map_cb(marg->map_data, &map, map.map_name)); 1088 0 stevel } 1089 0 stevel 1090 0 stevel int 1091 0 stevel kt_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private) 1092 0 stevel { 1093 0 stevel kt_data_t *kt = t->t_data; 1094 0 stevel kt_maparg_t m; 1095 0 stevel 1096 0 stevel m.map_target = t; 1097 0 stevel m.map_cb = func; 1098 0 stevel m.map_data = private; 1099 0 stevel 1100 0 stevel return (mdb_pwalk("seg", (mdb_walk_cb_t)kt_mapping_walk, &m, 1101 0 stevel (uintptr_t)kt->k_as)); 1102 0 stevel } 1103 0 stevel 1104 0 stevel static const mdb_map_t * 1105 0 stevel kt_module_to_map(kt_module_t *km, mdb_map_t *map) 1106 0 stevel { 1107 0 stevel (void) strncpy(map->map_name, km->km_name, MDB_TGT_MAPSZ); 1108 0 stevel map->map_name[MDB_TGT_MAPSZ - 1] = '\0'; 1109 0 stevel map->map_base = km->km_text_va; 1110 0 stevel map->map_size = km->km_text_size; 1111 0 stevel map->map_flags = MDB_TGT_MAP_R | MDB_TGT_MAP_W | MDB_TGT_MAP_X; 1112 0 stevel 1113 0 stevel return (map); 1114 0 stevel } 1115 0 stevel 1116 0 stevel int 1117 0 stevel kt_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private) 1118 0 stevel { 1119 0 stevel kt_data_t *kt = t->t_data; 1120 0 stevel kt_module_t *km; 1121 0 stevel mdb_map_t m; 1122 0 stevel 1123 0 stevel for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) { 1124 0 stevel if (func(private, kt_module_to_map(km, &m), km->km_name) == -1) 1125 0 stevel break; 1126 0 stevel } 1127 0 stevel 1128 0 stevel return (0); 1129 0 stevel } 1130 0 stevel 1131 0 stevel const mdb_map_t * 1132 0 stevel kt_addr_to_map(mdb_tgt_t *t, uintptr_t addr) 1133 0 stevel { 1134 0 stevel kt_data_t *kt = t->t_data; 1135 0 stevel kt_module_t *km; 1136 0 stevel 1137 0 stevel for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) { 1138 0 stevel if (addr - km->km_text_va < km->km_text_size || 1139 0 stevel addr - km->km_data_va < km->km_data_size || 1140 0 stevel addr - km->km_bss_va < km->km_bss_size) 1141 0 stevel return (kt_module_to_map(km, &kt->k_map)); 1142 0 stevel } 1143 0 stevel 1144 0 stevel (void) set_errno(EMDB_NOMAP); 1145 0 stevel return (NULL); 1146 0 stevel } 1147 0 stevel 1148 0 stevel const mdb_map_t * 1149 0 stevel kt_name_to_map(mdb_tgt_t *t, const char *name) 1150 0 stevel { 1151 0 stevel kt_data_t *kt = t->t_data; 1152 0 stevel kt_module_t *km; 1153 0 stevel mdb_map_t m; 1154 0 stevel 1155 0 stevel /* 1156 0 stevel * If name is MDB_TGT_OBJ_EXEC, return the first module on the list, 1157 0 stevel * which will be unix since we keep k_modlist in load order. 1158 0 stevel */ 1159 0 stevel if (name == MDB_TGT_OBJ_EXEC) 1160 0 stevel return (kt_module_to_map(mdb_list_next(&kt->k_modlist), &m)); 1161 0 stevel 1162 0 stevel if (name == MDB_TGT_OBJ_RTLD) 1163 3446 mrj name = kt->k_rtld_name; 1164 0 stevel 1165 3446 mrj if ((km = kt_module_by_name(kt, name)) != NULL) 1166 3446 mrj return (kt_module_to_map(km, &m)); 1167 0 stevel 1168 0 stevel (void) set_errno(EMDB_NOOBJ); 1169 0 stevel return (NULL); 1170 0 stevel } 1171 0 stevel 1172 0 stevel static ctf_file_t * 1173 0 stevel kt_load_ctfdata(mdb_tgt_t *t, kt_module_t *km) 1174 0 stevel { 1175 0 stevel kt_data_t *kt = t->t_data; 1176 0 stevel int err; 1177 0 stevel 1178 0 stevel if (km->km_ctfp != NULL) 1179 0 stevel return (km->km_ctfp); 1180 0 stevel 1181 0 stevel if (km->km_ctf_va == NULL) { 1182 0 stevel (void) set_errno(EMDB_NOCTF); 1183 0 stevel return (NULL); 1184 0 stevel } 1185 0 stevel 1186 0 stevel if (km->km_symtab == NULL) 1187 0 stevel kt_load_module(t->t_data, t, km); 1188 0 stevel 1189 0 stevel if ((km->km_ctf_buf = mdb_alloc(km->km_ctf_size, UM_NOSLEEP)) == NULL) { 1190 0 stevel warn("failed to allocate memory to load %s debugging " 1191 0 stevel "information", km->km_name); 1192 0 stevel return (NULL); 1193 0 stevel } 1194 0 stevel 1195 0 stevel if (mdb_tgt_vread(t, km->km_ctf_buf, km->km_ctf_size, 1196 0 stevel km->km_ctf_va) != km->km_ctf_size) { 1197 0 stevel warn("failed to read %lu bytes of debug data for %s at %p", 1198 0 stevel (ulong_t)km->km_ctf_size, km->km_name, 1199 0 stevel (void *)km->km_ctf_va); 1200 0 stevel mdb_free(km->km_ctf_buf, km->km_ctf_size); 1201 0 stevel km->km_ctf_buf = NULL; 1202 0 stevel return (NULL); 1203 0 stevel } 1204 0 stevel 1205 0 stevel if ((km->km_ctfp = mdb_ctf_bufopen((const void *)km->km_ctf_buf, 1206 0 stevel km->km_ctf_size, km->km_symbuf, &km->km_symtab_hdr, 1207 0 stevel km->km_strtab, &km->km_strtab_hdr, &err)) == NULL) { 1208 0 stevel mdb_free(km->km_ctf_buf, km->km_ctf_size); 1209 0 stevel km->km_ctf_buf = NULL; 1210 0 stevel (void) set_errno(ctf_to_errno(err)); 1211 0 stevel return (NULL); 1212 0 stevel } 1213 0 stevel 1214 0 stevel mdb_dprintf(MDB_DBG_KMOD, "loaded %lu bytes of CTF data for %s\n", 1215 0 stevel (ulong_t)km->km_ctf_size, km->km_name); 1216 0 stevel 1217 0 stevel if (ctf_parent_name(km->km_ctfp) != NULL) { 1218 0 stevel mdb_var_t *v; 1219 0 stevel 1220 0 stevel if ((v = mdb_nv_lookup(&kt->k_modules, 1221 0 stevel ctf_parent_name(km->km_ctfp))) == NULL) { 1222 0 stevel warn("failed to load CTF data for %s - parent %s not " 1223 0 stevel "loaded\n", km->km_name, 1224 0 stevel ctf_parent_name(km->km_ctfp)); 1225 0 stevel } 1226 0 stevel 1227 0 stevel if (v != NULL) { 1228 0 stevel kt_module_t *pm = mdb_nv_get_cookie(v); 1229 0 stevel 1230 0 stevel if (pm->km_ctfp == NULL) 1231 0 stevel (void) kt_load_ctfdata(t, pm); 1232 0 stevel 1233 0 stevel if (pm->km_ctfp != NULL && ctf_import(km->km_ctfp, 1234 0 stevel pm->km_ctfp) == CTF_ERR) { 1235 0 stevel warn("failed to import parent types into " 1236 0 stevel "%s: %s\n", km->km_name, 1237 0 stevel ctf_errmsg(ctf_errno(km->km_ctfp))); 1238 0 stevel } 1239 0 stevel } 1240 0 stevel } 1241 0 stevel 1242 0 stevel return (km->km_ctfp); 1243 0 stevel } 1244 0 stevel 1245 0 stevel ctf_file_t * 1246 0 stevel kt_addr_to_ctf(mdb_tgt_t *t, uintptr_t addr) 1247 0 stevel { 1248 0 stevel kt_data_t *kt = t->t_data; 1249 0 stevel kt_module_t *km; 1250 0 stevel 1251 0 stevel for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) { 1252 0 stevel if (addr - km->km_text_va < km->km_text_size || 1253 0 stevel addr - km->km_data_va < km->km_data_size || 1254 0 stevel addr - km->km_bss_va < km->km_bss_size) 1255 0 stevel return (kt_load_ctfdata(t, km)); 1256 0 stevel } 1257 0 stevel 1258 0 stevel (void) set_errno(EMDB_NOMAP); 1259 0 stevel return (NULL); 1260 0 stevel } 1261 0 stevel 1262 0 stevel ctf_file_t * 1263 0 stevel kt_name_to_ctf(mdb_tgt_t *t, const char *name) 1264 0 stevel { 1265 0 stevel kt_data_t *kt = t->t_data; 1266 0 stevel kt_module_t *km; 1267 0 stevel 1268 0 stevel if (name == MDB_TGT_OBJ_EXEC) 1269 3446 mrj name = KT_CTFPARENT; 1270 0 stevel else if (name == MDB_TGT_OBJ_RTLD) 1271 3446 mrj name = kt->k_rtld_name; 1272 0 stevel 1273 3446 mrj if ((km = kt_module_by_name(kt, name)) != NULL) 1274 3446 mrj return (kt_load_ctfdata(t, km)); 1275 0 stevel 1276 0 stevel (void) set_errno(EMDB_NOOBJ); 1277 0 stevel return (NULL); 1278 0 stevel } 1279 0 stevel 1280 5084 johnlev /*ARGSUSED*/ 1281 0 stevel int 1282 0 stevel kt_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1283 0 stevel { 1284 0 stevel kt_data_t *kt = t->t_data; 1285 0 stevel bzero(tsp, sizeof (mdb_tgt_status_t)); 1286 5084 johnlev tsp->st_state = (kt->k_xpv_domu || (kt->k_dumphdr != NULL)) ? 1287 5084 johnlev MDB_TGT_DEAD : MDB_TGT_RUNNING; 1288 0 stevel return (0); 1289 0 stevel } 1290 0 stevel 1291 0 stevel static ssize_t 1292 0 stevel kt_xd_dumphdr(mdb_tgt_t *t, void *buf, size_t nbytes) 1293 0 stevel { 1294 0 stevel kt_data_t *kt = t->t_data; 1295 0 stevel 1296 0 stevel if (buf == NULL && nbytes == 0) 1297 0 stevel return (sizeof (dumphdr_t)); 1298 0 stevel 1299 0 stevel if (kt->k_dumphdr == NULL) 1300 0 stevel return (set_errno(ENODATA)); 1301 0 stevel 1302 0 stevel nbytes = MIN(nbytes, sizeof (dumphdr_t)); 1303 0 stevel bcopy(kt->k_dumphdr, buf, nbytes); 1304 0 stevel 1305 0 stevel return (nbytes); 1306 0 stevel } 1307 0 stevel 1308 0 stevel void 1309 0 stevel kt_destroy(mdb_tgt_t *t) 1310 0 stevel { 1311 0 stevel kt_data_t *kt = t->t_data; 1312 0 stevel kt_module_t *km, *nkm; 1313 0 stevel 1314 0 stevel (void) mdb_module_unload(KT_MODULE, 0); 1315 0 stevel 1316 0 stevel if (kt->k_regs != NULL) 1317 0 stevel mdb_free(kt->k_regs, kt->k_regsize); 1318 0 stevel 1319 0 stevel if (kt->k_symtab != NULL) 1320 0 stevel mdb_gelf_symtab_destroy(kt->k_symtab); 1321 0 stevel 1322 0 stevel if (kt->k_dynsym != NULL) 1323 0 stevel mdb_gelf_symtab_destroy(kt->k_dynsym); 1324 0 stevel 1325 0 stevel if (kt->k_dumphdr != NULL) 1326 0 stevel mdb_free(kt->k_dumphdr, sizeof (dumphdr_t)); 1327 0 stevel 1328 0 stevel mdb_gelf_destroy(kt->k_file); 1329 5084 johnlev 1330 5084 johnlev (void) kt->k_kb_ops->kb_close(kt->k_cookie); 1331 0 stevel 1332 0 stevel for (km = mdb_list_next(&kt->k_modlist); km; km = nkm) { 1333 0 stevel if (km->km_symtab) 1334 0 stevel mdb_gelf_symtab_destroy(km->km_symtab); 1335 0 stevel 1336 0 stevel if (km->km_data) 1337 0 stevel mdb_free(km->km_data, km->km_datasz); 1338 0 stevel 1339 0 stevel if (km->km_ctfp) 1340 0 stevel ctf_close(km->km_ctfp); 1341 0 stevel 1342 0 stevel if (km->km_ctf_buf != NULL) 1343 0 stevel mdb_free(km->km_ctf_buf, km->km_ctf_size); 1344 0 stevel 1345 0 stevel nkm = mdb_list_next(km); 1346 0 stevel strfree(km->km_name); 1347 0 stevel mdb_free(km, sizeof (kt_module_t)); 1348 0 stevel } 1349 0 stevel 1350 0 stevel mdb_nv_destroy(&kt->k_modules); 1351 0 stevel 1352 0 stevel strfree(kt->k_kvmfile); 1353 5084 johnlev if (kt->k_symfile != NULL) 1354 5084 johnlev strfree(kt->k_symfile); 1355 0 stevel 1356 0 stevel mdb_free(kt, sizeof (kt_data_t)); 1357 0 stevel } 1358 0 stevel 1359 0 stevel static int 1360 0 stevel kt_data_stub(void) 1361 0 stevel { 1362 0 stevel return (-1); 1363 0 stevel } 1364 0 stevel 1365 0 stevel int 1366 0 stevel mdb_kvm_tgt_create(mdb_tgt_t *t, int argc, const char *argv[]) 1367 0 stevel { 1368 0 stevel kt_data_t *kt = mdb_zalloc(sizeof (kt_data_t), UM_SLEEP); 1369 5084 johnlev mdb_kb_ops_t *kvm_kb_ops = libkvm_kb_ops(); 1370 0 stevel int oflag = (t->t_flags & MDB_TGT_F_RDWR) ? O_RDWR : O_RDONLY; 1371 0 stevel struct utsname uts; 1372 0 stevel GElf_Sym sym; 1373 0 stevel pgcnt_t pmem; 1374 0 stevel 1375 5084 johnlev 1376 5084 johnlev if (argc == 2) { 1377 5084 johnlev kt->k_symfile = strdup(argv[0]); 1378 5084 johnlev kt->k_kvmfile = strdup(argv[1]); 1379 5084 johnlev 1380 5084 johnlev kt->k_cookie = kvm_kb_ops->kb_open(kt->k_symfile, 1381 5084 johnlev kt->k_kvmfile, NULL, oflag, (char *)mdb.m_pname); 1382 5084 johnlev 1383 5084 johnlev if (kt->k_cookie == NULL) 1384 5084 johnlev goto err; 1385 5084 johnlev 1386 5084 johnlev kt->k_xpv_domu = 0; 1387 5084 johnlev kt->k_kb_ops = kvm_kb_ops; 1388 5084 johnlev } else { 1389 5084 johnlev #ifndef __x86 1390 0 stevel return (set_errno(EINVAL)); 1391 5084 johnlev #else 1392 5084 johnlev mdb_kb_ops_t *(*getops)(void); 1393 0 stevel 1394 5084 johnlev kt->k_symfile = NULL; 1395 5084 johnlev kt->k_kvmfile = strdup(argv[0]); 1396 0 stevel 1397 5084 johnlev getops = (mdb_kb_ops_t *(*)())dlsym(RTLD_NEXT, "mdb_kb_ops"); 1398 5084 johnlev 1399 6144 rab /* 1400 6144 rab * Load mdb_kb if it's not already loaded during 1401 6144 rab * identification. 1402 6144 rab */ 1403 6144 rab if (getops == NULL) { 1404 6144 rab (void) mdb_module_load("mdb_kb", 1405 6144 rab MDB_MOD_GLOBAL | MDB_MOD_SILENT); 1406 6144 rab getops = (mdb_kb_ops_t *(*)()) 1407 6144 rab dlsym(RTLD_NEXT, "mdb_kb_ops"); 1408 6144 rab } 1409 6144 rab 1410 5084 johnlev if (getops == NULL || (kt->k_kb_ops = getops()) == NULL) { 1411 5084 johnlev warn("failed to load KVM backend ops\n"); 1412 5084 johnlev goto err; 1413 5084 johnlev } 1414 5084 johnlev 1415 5084 johnlev kt->k_cookie = kt->k_kb_ops->kb_open(NULL, kt->k_kvmfile, NULL, 1416 5084 johnlev oflag, (char *)mdb.m_pname); 1417 5084 johnlev 1418 5084 johnlev if (kt->k_cookie == NULL) 1419 5084 johnlev goto err; 1420 5084 johnlev 1421 5084 johnlev kt->k_xpv_domu = 1; 1422 5084 johnlev #endif 1423 5084 johnlev } 1424 5084 johnlev 1425 5084 johnlev if ((kt->k_fio = kt->k_kb_ops->kb_sym_io(kt->k_cookie, 1426 5084 johnlev kt->k_symfile)) == NULL) 1427 0 stevel goto err; 1428 0 stevel 1429 0 stevel if ((kt->k_file = mdb_gelf_create(kt->k_fio, 1430 0 stevel ET_EXEC, GF_FILE)) == NULL) { 1431 0 stevel mdb_io_destroy(kt->k_fio); 1432 0 stevel goto err; 1433 0 stevel } 1434 0 stevel 1435 0 stevel kt->k_symtab = 1436 0 stevel mdb_gelf_symtab_create_file(kt->k_file, SHT_SYMTAB, MDB_TGT_SYMTAB); 1437 0 stevel 1438 0 stevel kt->k_dynsym = 1439 0 stevel mdb_gelf_symtab_create_file(kt->k_file, SHT_DYNSYM, MDB_TGT_DYNSYM); 1440 0 stevel 1441 0 stevel if (mdb_gelf_symtab_lookup_by_name(kt->k_symtab, "kas", 1442 0 stevel &sym, NULL) == -1) { 1443 0 stevel warn("'kas' symbol is missing from kernel\n"); 1444 0 stevel goto err; 1445 0 stevel } 1446 0 stevel 1447 0 stevel kt->k_as = (struct as *)(uintptr_t)sym.st_value; 1448 0 stevel 1449 0 stevel if (mdb_gelf_symtab_lookup_by_name(kt->k_symtab, "platform", 1450 0 stevel &sym, NULL) == -1) { 1451 0 stevel warn("'platform' symbol is missing from kernel\n"); 1452 0 stevel goto err; 1453 0 stevel } 1454 0 stevel 1455 5084 johnlev if (kt->k_kb_ops->kb_kread(kt->k_cookie, sym.st_value, 1456 0 stevel kt->k_platform, MAXNAMELEN) <= 0) { 1457 0 stevel warn("failed to read 'platform' string from kernel"); 1458 0 stevel goto err; 1459 0 stevel } 1460 0 stevel 1461 0 stevel if (mdb_gelf_symtab_lookup_by_name(kt->k_symtab, "utsname", 1462 0 stevel &sym, NULL) == -1) { 1463 0 stevel warn("'utsname' symbol is missing from kernel\n"); 1464 0 stevel goto err; 1465 0 stevel } 1466 0 stevel 1467 5084 johnlev if (kt->k_kb_ops->kb_kread(kt->k_cookie, sym.st_value, &uts, 1468 5084 johnlev sizeof (uts)) <= 0) { 1469 0 stevel warn("failed to read 'utsname' struct from kernel"); 1470 0 stevel goto err; 1471 0 stevel } 1472 0 stevel 1473 0 stevel kt->k_dump_print_content = (void (*)())kt_data_stub; 1474 0 stevel kt->k_dump_find_curproc = kt_data_stub; 1475 0 stevel 1476 0 stevel /* 1477 0 stevel * We set k_ctfvalid based on the presence of the CTF vmem arena 1478 0 stevel * symbol. The CTF members were added to the end of struct module at 1479 0 stevel * the same time, so this allows us to know whether we can use them. 1480 0 stevel */ 1481 0 stevel if (mdb_gelf_symtab_lookup_by_name(kt->k_symtab, "ctf_arena", &sym, 1482 0 stevel NULL) == 0 && !(mdb.m_flags & MDB_FL_NOCTF)) 1483 0 stevel kt->k_ctfvalid = 1; 1484 0 stevel 1485 0 stevel (void) mdb_nv_create(&kt->k_modules, UM_SLEEP); 1486 0 stevel t->t_pshandle = kt->k_cookie; 1487 0 stevel t->t_data = kt; 1488 0 stevel 1489 0 stevel #if defined(__sparc) 1490 0 stevel #if defined(__sparcv9) 1491 0 stevel kt_sparcv9_init(t); 1492 0 stevel #else 1493 0 stevel kt_sparcv7_init(t); 1494 0 stevel #endif 1495 0 stevel #elif defined(__amd64) 1496 0 stevel kt_amd64_init(t); 1497 0 stevel #elif defined(__i386) 1498 0 stevel kt_ia32_init(t); 1499 0 stevel #else 1500 0 stevel #error "unknown ISA" 1501 0 stevel #endif 1502 0 stevel 1503 0 stevel /* 1504 0 stevel * We read our representative thread ID (address) from the kernel's 1505 0 stevel * global panic_thread. It will remain 0 if this is a live kernel. 1506 0 stevel */ 1507 0 stevel (void) mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, &kt->k_tid, sizeof (void *), 1508 0 stevel MDB_TGT_OBJ_EXEC, "panic_thread"); 1509 0 stevel 1510 0 stevel if ((mdb.m_flags & MDB_FL_ADB) && mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, 1511 0 stevel &pmem, sizeof (pmem), MDB_TGT_OBJ_EXEC, "physmem") == sizeof (pmem)) 1512 0 stevel mdb_printf("physmem %lx\n", (ulong_t)pmem); 1513 0 stevel 1514 0 stevel /* 1515 5084 johnlev * If this is not a live kernel or a hypervisor dump, read the dump 1516 5084 johnlev * header. We don't have to sanity-check the header, as the open would 1517 5084 johnlev * not have succeeded otherwise. 1518 0 stevel */ 1519 5084 johnlev if (!kt->k_xpv_domu && strcmp(kt->k_symfile, "/dev/ksyms") != 0) { 1520 0 stevel mdb_io_t *vmcore; 1521 0 stevel 1522 0 stevel kt->k_dumphdr = mdb_alloc(sizeof (dumphdr_t), UM_SLEEP); 1523 0 stevel 1524 0 stevel if ((vmcore = mdb_fdio_create_path(NULL, kt->k_kvmfile, 1525 0 stevel O_RDONLY, 0)) == NULL) { 1526 0 stevel mdb_warn("failed to open %s", kt->k_kvmfile); 1527 0 stevel goto err; 1528 0 stevel } 1529 0 stevel 1530 0 stevel if (IOP_READ(vmcore, kt->k_dumphdr, sizeof (dumphdr_t)) != 1531 0 stevel sizeof (dumphdr_t)) { 1532 0 stevel mdb_warn("failed to read dump header"); 1533 0 stevel mdb_io_destroy(vmcore); 1534 0 stevel goto err; 1535 0 stevel } 1536 0 stevel 1537 0 stevel mdb_io_destroy(vmcore); 1538 0 stevel 1539 0 stevel (void) mdb_tgt_xdata_insert(t, "dumphdr", 1540 0 stevel "dump header structure", kt_xd_dumphdr); 1541 0 stevel } 1542 0 stevel 1543 0 stevel return (0); 1544 0 stevel 1545 0 stevel err: 1546 0 stevel if (kt->k_dumphdr != NULL) 1547 0 stevel mdb_free(kt->k_dumphdr, sizeof (dumphdr_t)); 1548 0 stevel 1549 0 stevel if (kt->k_symtab != NULL) 1550 0 stevel mdb_gelf_symtab_destroy(kt->k_symtab); 1551 0 stevel 1552 0 stevel if (kt->k_dynsym != NULL) 1553 0 stevel mdb_gelf_symtab_destroy(kt->k_dynsym); 1554 0 stevel 1555 0 stevel if (kt->k_file != NULL) 1556 0 stevel mdb_gelf_destroy(kt->k_file); 1557 0 stevel 1558 0 stevel if (kt->k_cookie != NULL) 1559 5084 johnlev (void) kt->k_kb_ops->kb_close(kt->k_cookie); 1560 0 stevel 1561 0 stevel mdb_free(kt, sizeof (kt_data_t)); 1562 0 stevel return (-1); 1563 0 stevel } 1564 10843 Dave 1565 10843 Dave int 1566 10843 Dave mdb_kvm_is_compressed_dump(mdb_io_t *io) 1567 10843 Dave { 1568 10843 Dave dumphdr_t h; 1569 10843 Dave 1570 10843 Dave return (IOP_READ(io, &h, sizeof (dumphdr_t)) == sizeof (dumphdr_t) && 1571 10843 Dave h.dump_magic == DUMP_MAGIC && 1572 10843 Dave (h.dump_flags & DF_COMPRESSED) != 0); 1573 10843 Dave } 1574