Home | History | Annotate | Download | only in mdb
      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, &reg_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