Home | History | Annotate | Download | only in kmdb
      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  10271    Jason  * 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 #include <kmdb/kmdb_kvm.h>
     27      0   stevel #include <kmdb/kvm.h>
     28      0   stevel #include <kmdb/kmdb_kdi.h>
     29      0   stevel #include <kmdb/kmdb_promif.h>
     30      0   stevel #include <kmdb/kmdb_module.h>
     31      0   stevel #include <kmdb/kmdb_asmutil.h>
     32      0   stevel #include <mdb/mdb_types.h>
     33      0   stevel #include <mdb/mdb_conf.h>
     34      0   stevel #include <mdb/mdb_err.h>
     35      0   stevel #include <mdb/mdb_modapi.h>
     36      0   stevel #include <mdb/mdb_target_impl.h>
     37      0   stevel #include <mdb/mdb_debug.h>
     38      0   stevel #include <mdb/mdb_string.h>
     39      0   stevel #include <mdb/mdb_ctf.h>
     40      0   stevel #include <mdb/mdb_kreg_impl.h>
     41   1234  johnlev #include <mdb/mdb_ks.h>
     42      0   stevel #include <mdb/mdb.h>
     43      0   stevel 
     44      0   stevel #include <strings.h>
     45      0   stevel #include <dlfcn.h>
     46      0   stevel #include <sys/isa_defs.h>
     47      0   stevel #include <sys/kobj.h>
     48      0   stevel #include <sys/kobj_impl.h>
     49      0   stevel #include <sys/bitmap.h>
     50      0   stevel #include <vm/as.h>
     51      0   stevel 
     52      0   stevel static const char KMT_RTLD_NAME[] = "krtld";
     53      0   stevel static const char KMT_MODULE[] = "mdb_ks";
     54      0   stevel static const char KMT_CTFPARENT[] = "genunix";
     55      0   stevel 
     56      0   stevel static mdb_list_t kmt_defbp_list;	/* List of current deferred bp's */
     57      0   stevel static int kmt_defbp_lock;		/* For list, running kernel holds */
     58      0   stevel static uint_t kmt_defbp_modchg_isload;	/* Whether mod change is load/unload */
     59      0   stevel static struct modctl *kmt_defbp_modchg_modctl; /* modctl for defbp checking */
     60      0   stevel static uint_t kmt_defbp_num;		/* Number of referenced def'd bp's */
     61      0   stevel static int kmt_defbp_bpspec;		/* vespec for def'd bp activation bp */
     62      0   stevel 
     63      0   stevel static const mdb_se_ops_t kmt_brkpt_ops;
     64      0   stevel static const mdb_se_ops_t kmt_wapt_ops;
     65      0   stevel 
     66      0   stevel static void kmt_sync(mdb_tgt_t *);
     67      0   stevel 
     68      0   stevel typedef struct kmt_symarg {
     69      0   stevel 	mdb_tgt_sym_f *sym_cb;		/* Caller's callback function */
     70      0   stevel 	void *sym_data;			/* Callback function argument */
     71      0   stevel 	uint_t sym_type;		/* Symbol type/binding filter */
     72      0   stevel 	mdb_syminfo_t sym_info;		/* Symbol id and table id */
     73      0   stevel 	const char *sym_obj;		/* Containing object */
     74      0   stevel } kmt_symarg_t;
     75      0   stevel 
     76      0   stevel typedef struct kmt_maparg {
     77      0   stevel 	mdb_tgt_t *map_target;		/* Target used for mapping iter */
     78      0   stevel 	mdb_tgt_map_f *map_cb;		/* Caller's callback function */
     79      0   stevel 	void *map_data;			/* Callback function argument */
     80      0   stevel } kmt_maparg_t;
     81      0   stevel 
     82      0   stevel /*ARGSUSED*/
     83      0   stevel int
     84      0   stevel kmt_setflags(mdb_tgt_t *t, int flags)
     85      0   stevel {
     86      0   stevel 	/*
     87      0   stevel 	 * We only handle one flag (ALLOWIO), and we can't fail to set or clear
     88      0   stevel 	 * it, so we just blindly replace the t_flags version with the one
     89      0   stevel 	 * passed.
     90      0   stevel 	 */
     91      0   stevel 	t->t_flags = (t->t_flags & ~MDB_TGT_F_ALLOWIO) |
     92      0   stevel 	    (flags & MDB_TGT_F_ALLOWIO);
     93      0   stevel 
     94      0   stevel 	return (0);
     95      0   stevel }
     96      0   stevel 
     97      0   stevel /*ARGSUSED*/
     98      0   stevel const char *
     99      0   stevel kmt_name(mdb_tgt_t *t)
    100      0   stevel {
    101      0   stevel 	return ("kmdb_kvm");
    102      0   stevel }
    103      0   stevel 
    104      0   stevel /*ARGSUSED*/
    105      0   stevel static const char *
    106      0   stevel kmt_platform(mdb_tgt_t *t)
    107      0   stevel {
    108      0   stevel 	static char platform[SYS_NMLN];
    109      0   stevel 
    110      0   stevel 	if (kmdb_dpi_get_state(NULL) == DPI_STATE_INIT)
    111      0   stevel 		return (mdb_conf_platform());
    112      0   stevel 
    113      0   stevel 	if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, platform,
    114      0   stevel 	    sizeof (platform), "unix", "platform") != sizeof (platform)) {
    115      0   stevel 		warn("'platform' symbol is missing from kernel\n");
    116      0   stevel 		return ("unknown");
    117      0   stevel 	}
    118      0   stevel 
    119      0   stevel 	return (platform);
    120      0   stevel }
    121      0   stevel 
    122      0   stevel static int
    123      0   stevel kmt_uname(mdb_tgt_t *t, struct utsname *utsp)
    124      0   stevel {
    125      0   stevel 	return (mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, utsp,
    126      0   stevel 	    sizeof (struct utsname), MDB_TGT_OBJ_EXEC, "utsname"));
    127      0   stevel }
    128      0   stevel 
    129      0   stevel /*ARGSUSED*/
    130      0   stevel static int
    131      0   stevel kmt_dmodel(mdb_tgt_t *t)
    132      0   stevel {
    133      0   stevel 	return (MDB_TGT_MODEL_NATIVE);
    134      0   stevel }
    135      0   stevel 
    136      0   stevel /*ARGSUSED*/
    137      0   stevel ssize_t
    138      0   stevel kmt_rw(mdb_tgt_t *t, void *buf, size_t nbytes, uint64_t addr,
    139      0   stevel     ssize_t (*rw)(void *, size_t, uint64_t))
    140      0   stevel {
    141      0   stevel 	size_t n, ndone, chunksz;
    142      0   stevel 	jmp_buf *oldpcb = NULL;
    143      0   stevel 	jmp_buf pcb;
    144      0   stevel 	ssize_t res;
    145      0   stevel 
    146      0   stevel 	kmdb_prom_check_interrupt();
    147      0   stevel 
    148      0   stevel 	if (nbytes == 0)
    149      0   stevel 		return (0);
    150      0   stevel 
    151      0   stevel 	/*
    152      0   stevel 	 * Try to process the entire buffer, as requested.  If we catch a fault,
    153      0   stevel 	 * try smaller chunks.  This allows us to handle regions that cross
    154      0   stevel 	 * mapping boundaries.
    155      0   stevel 	 */
    156      0   stevel 	chunksz = nbytes;
    157      0   stevel 	ndone = 0;
    158      0   stevel 	if (setjmp(pcb) != 0) {
    159      0   stevel 		if (chunksz == 1) {
    160      0   stevel 			/* We failed with the smallest chunk - give up */
    161      0   stevel 			kmdb_dpi_restore_fault_hdlr(oldpcb);
    162      0   stevel 			return (ndone > 0 ? ndone : -1); /* errno set for us */
    163      0   stevel 		} else if (chunksz > 4)
    164      0   stevel 			chunksz = 4;
    165      0   stevel 		else
    166      0   stevel 			chunksz = 1;
    167      0   stevel 	}
    168      0   stevel 
    169      0   stevel 	oldpcb = kmdb_dpi_set_fault_hdlr(&pcb);
    170      0   stevel 	while (nbytes > 0) {
    171      0   stevel 		n = MIN(chunksz, nbytes);
    172      0   stevel 
    173      0   stevel 		if ((res = rw(buf, n, addr)) != n)
    174      0   stevel 			return (res < 0 ? res : ndone + res);
    175      0   stevel 
    176      0   stevel 		addr += n;
    177      0   stevel 		nbytes -= n;
    178      0   stevel 		ndone += n;
    179      0   stevel 		buf = ((caddr_t)buf + n);
    180      0   stevel 	}
    181      0   stevel 
    182      0   stevel 	kmdb_dpi_restore_fault_hdlr(oldpcb);
    183      0   stevel 
    184      0   stevel 	return (ndone);
    185      0   stevel }
    186      0   stevel 
    187      0   stevel static void
    188      0   stevel kmt_bcopy(const void *s1, void *s2, size_t n)
    189      0   stevel {
    190      0   stevel 	/*
    191      0   stevel 	 * We need to guarantee atomic accesses for certain sizes.  bcopy won't
    192      0   stevel 	 * make that guarantee, so we need to do it ourselves.
    193      0   stevel 	 */
    194      0   stevel #ifdef	_LP64
    195      0   stevel 	if (n == 8 && ((uintptr_t)s1 & 7) == 0 && ((uintptr_t)s2 & 7) == 0)
    196      0   stevel 		*(uint64_t *)s2 = *(uint64_t *)s1;
    197      0   stevel 	else
    198      0   stevel #endif
    199      0   stevel 	if (n == 4 && ((uintptr_t)s1 & 3) == 0 && ((uintptr_t)s2 & 3) == 0)
    200      0   stevel 		*(uint32_t *)s2 = *(uint32_t *)s1;
    201      0   stevel 	else if (n == 2 && ((uintptr_t)s1 & 1) == 0 && ((uintptr_t)s2 & 1) == 0)
    202      0   stevel 		*(uint16_t *)s2 = *(uint16_t *)s1;
    203      0   stevel 	else if (n == 1)
    204      0   stevel 		*(uint8_t *)s2 = *(uint8_t *)s1;
    205      0   stevel 	else
    206      0   stevel 		bcopy(s1, s2, n);
    207      0   stevel }
    208      0   stevel 
    209      0   stevel static ssize_t
    210      0   stevel kmt_reader(void *buf, size_t nbytes, uint64_t addr)
    211      0   stevel {
    212      0   stevel 	kmt_bcopy((void *)(uintptr_t)addr, buf, nbytes);
    213      0   stevel 	return (nbytes);
    214      0   stevel }
    215      0   stevel 
    216      0   stevel ssize_t
    217      0   stevel kmt_writer(void *buf, size_t nbytes, uint64_t addr)
    218      0   stevel {
    219      0   stevel 	kmt_bcopy(buf, (void *)(uintptr_t)addr, nbytes);
    220      0   stevel 	return (nbytes);
    221      0   stevel }
    222      0   stevel 
    223      0   stevel /*ARGSUSED*/
    224      0   stevel static ssize_t
    225      0   stevel kmt_read(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
    226      0   stevel {
    227      0   stevel 	/*
    228      0   stevel 	 * We don't want to allow reads of I/O-mapped memory.  Multi-page reads
    229      0   stevel 	 * that cross into I/O-mapped memory should be restricted to the initial
    230      0   stevel 	 * non-I/O region.  Reads that begin in I/O-mapped memory are failed
    231      0   stevel 	 * outright.
    232      0   stevel 	 */
    233      0   stevel 	if (!(t->t_flags & MDB_TGT_F_ALLOWIO) &&
    234      0   stevel 	    (nbytes = kmdb_kdi_range_is_nontoxic(addr, nbytes, 0)) == 0)
    235      0   stevel 		return (set_errno(EMDB_NOMAP));
    236      0   stevel 
    237      0   stevel 	return (kmt_rw(t, buf, nbytes, addr, kmt_reader));
    238      0   stevel }
    239      0   stevel 
    240      0   stevel /*ARGSUSED*/
    241      0   stevel static ssize_t
    242      0   stevel kmt_pread(mdb_tgt_t *t, void *buf, size_t nbytes, physaddr_t addr)
    243      0   stevel {
    244      0   stevel 	return (kmt_rw(t, buf, nbytes, addr, kmdb_kdi_pread));
    245      0   stevel }
    246      0   stevel 
    247      0   stevel /*ARGSUSED*/
    248      0   stevel ssize_t
    249      0   stevel kmt_pwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, physaddr_t addr)
    250      0   stevel {
    251      0   stevel 	return (kmt_rw(t, (void *)buf, nbytes, addr, kmdb_kdi_pwrite));
    252      0   stevel }
    253      0   stevel 
    254      0   stevel static uintptr_t
    255      0   stevel kmt_read_kas(mdb_tgt_t *t)
    256      0   stevel {
    257      0   stevel 	GElf_Sym sym;
    258      0   stevel 
    259      0   stevel 	if (mdb_tgt_lookup_by_name(t, "unix", "kas", &sym, NULL) < 0) {
    260      0   stevel 		warn("'kas' symbol is missing from kernel\n");
    261      0   stevel 		(void) set_errno(EMDB_NOSYM);
    262      0   stevel 		return (0);
    263      0   stevel 	}
    264      0   stevel 
    265      0   stevel 	return ((uintptr_t)sym.st_value);
    266      0   stevel }
    267      0   stevel 
    268      0   stevel static int
    269      0   stevel kmt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap)
    270      0   stevel {
    271      0   stevel 	mdb_module_t *mod;
    272      0   stevel 	struct as *asp;
    273      0   stevel 	mdb_var_t *v;
    274      0   stevel 
    275      0   stevel 	switch ((uintptr_t)as) {
    276      0   stevel 	case (uintptr_t)MDB_TGT_AS_PHYS:
    277      0   stevel 	case (uintptr_t)MDB_TGT_AS_FILE:
    278      0   stevel 	case (uintptr_t)MDB_TGT_AS_IO:
    279      0   stevel 		return (set_errno(EINVAL));
    280      0   stevel 	case (uintptr_t)MDB_TGT_AS_VIRT:
    281      0   stevel 		if ((asp = (struct as *)kmt_read_kas(t)) == NULL)
    282      0   stevel 			return (-1); /* errno is set for us */
    283      0   stevel 		break;
    284      0   stevel 	default:
    285      0   stevel 		asp = (struct as *)as;
    286      0   stevel 
    287      0   stevel 		/* We don't support non-kas vtop */
    288      0   stevel 		if (asp != (struct as *)kmt_read_kas(t))
    289      0   stevel 			return (set_errno(EMDB_TGTNOTSUP));
    290      0   stevel 	}
    291      0   stevel 
    292      0   stevel 	if (kmdb_prom_vtop(va, pap) == 0)
    293      0   stevel 		return (0);
    294      0   stevel 
    295      0   stevel 	if ((v = mdb_nv_lookup(&mdb.m_modules, "unix")) != NULL &&
    296      0   stevel 	    (mod = mdb_nv_get_cookie(v)) != NULL) {
    297      0   stevel 		int (*fptr)(uintptr_t, struct as *, physaddr_t *);
    298      0   stevel 
    299      0   stevel 		fptr = (int (*)(uintptr_t, struct as *, physaddr_t *))
    300      0   stevel 		    dlsym(mod->mod_hdl, "platform_vtop");
    301      0   stevel 
    302      0   stevel 		if ((fptr != NULL) && ((*fptr)(va, asp, pap) == 0))
    303      0   stevel 			return (0);
    304      0   stevel 	}
    305      0   stevel 
    306      0   stevel 	return (set_errno(EMDB_NOMAP));
    307      0   stevel }
    308      0   stevel 
    309      0   stevel /*ARGSUSED*/
    310      0   stevel static int
    311      0   stevel kmt_cpuregs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    312      0   stevel {
    313      0   stevel 	const mdb_tgt_gregset_t *gregs;
    314   1234  johnlev 	intptr_t cpuid = DPI_MASTER_CPUID;
    315      0   stevel 	int i;
    316      0   stevel 
    317      0   stevel 	if (flags & DCMD_ADDRSPEC) {
    318      0   stevel 		if (argc != 0)
    319      0   stevel 			return (DCMD_USAGE);
    320   1234  johnlev 		if ((cpuid = mdb_cpu2cpuid(addr)) < 0) {
    321   1234  johnlev 			(void) set_errno(EMDB_NOMAP);
    322   1234  johnlev 			mdb_warn("failed to find cpuid for cpu at %p", addr);
    323   1234  johnlev 			return (DCMD_ERR);
    324   1234  johnlev 		}
    325      0   stevel 	}
    326      0   stevel 
    327      0   stevel 	i = mdb_getopts(argc, argv,
    328   1234  johnlev 	    'c', MDB_OPT_UINTPTR, &cpuid,
    329      0   stevel 	    NULL);
    330      0   stevel 
    331      0   stevel 	argc -= i;
    332      0   stevel 	argv += i;
    333      0   stevel 
    334      0   stevel 	if (argc != 0)
    335      0   stevel 		return (DCMD_USAGE);
    336      0   stevel 
    337   1234  johnlev 	if ((gregs = kmdb_dpi_get_gregs(cpuid)) == NULL) {
    338   1234  johnlev 		warn("failed to retrieve registers for cpu %d", (int)cpuid);
    339      0   stevel 		return (DCMD_ERR);
    340      0   stevel 	}
    341      0   stevel 
    342      0   stevel 	kmt_printregs(gregs);
    343      0   stevel 
    344      0   stevel 	return (DCMD_OK);
    345      0   stevel }
    346      0   stevel 
    347      0   stevel static int
    348      0   stevel kmt_regs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    349      0   stevel {
    350      0   stevel 	if (flags & DCMD_ADDRSPEC)
    351      0   stevel 		return (DCMD_USAGE);
    352      0   stevel 
    353      0   stevel 	return (kmt_cpuregs(addr, flags, argc, argv));
    354   1234  johnlev }
    355   1234  johnlev 
    356   1234  johnlev static int
    357   1234  johnlev kmt_cpustack_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    358   1234  johnlev {
    359   1234  johnlev 	intptr_t cpuid = DPI_MASTER_CPUID;
    360   1234  johnlev 	uint_t verbose = 0;
    361   1234  johnlev 	int i;
    362   1234  johnlev 
    363   1234  johnlev 	if (flags & DCMD_ADDRSPEC) {
    364   1234  johnlev 		if ((cpuid = mdb_cpu2cpuid(addr)) < 0) {
    365   1234  johnlev 			(void) set_errno(EMDB_NOMAP);
    366   1234  johnlev 			mdb_warn("failed to find cpuid for cpu at %p", addr);
    367   1234  johnlev 			return (DCMD_ERR);
    368   1234  johnlev 		}
    369   1234  johnlev 		flags &= ~DCMD_ADDRSPEC;
    370   1234  johnlev 	}
    371   1234  johnlev 
    372   1234  johnlev 	i = mdb_getopts(argc, argv,
    373   1234  johnlev 	    'c', MDB_OPT_UINTPTR, &cpuid,
    374   1234  johnlev 	    'v', MDB_OPT_SETBITS, 1, &verbose,
    375   1234  johnlev 	    NULL);
    376   1234  johnlev 
    377   1234  johnlev 	argc -= i;
    378   1234  johnlev 	argv += i;
    379   1234  johnlev 
    380   1234  johnlev 	return (kmt_cpustack(addr, flags, argc, argv, cpuid, verbose));
    381      0   stevel }
    382      0   stevel 
    383      0   stevel /*
    384      0   stevel  * Lasciate ogne speranza, voi ch'intrate.
    385      0   stevel  */
    386      0   stevel static int
    387      0   stevel kmt_call(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    388      0   stevel {
    389      0   stevel 	uintptr_t *call_argv, rval;
    390      0   stevel 	int parse_strings = 1;
    391      0   stevel 	GElf_Sym sym;
    392      0   stevel 	jmp_buf *oldpcb = NULL;
    393      0   stevel 	jmp_buf pcb;
    394      0   stevel 	int i;
    395      0   stevel 
    396      0   stevel 	if (!(flags & DCMD_ADDRSPEC))
    397      0   stevel 		return (DCMD_USAGE);
    398      0   stevel 
    399      0   stevel 	if (mdb_tgt_lookup_by_addr(mdb.m_target, addr, MDB_TGT_SYM_EXACT,
    400      0   stevel 	    NULL, 0, &sym, NULL) == 0 && GELF_ST_TYPE(sym.st_info) !=
    401      0   stevel 	    STT_FUNC) {
    402      0   stevel 		warn("%a is not a function\n", addr);
    403      0   stevel 		return (DCMD_ERR);
    404      0   stevel 	}
    405      0   stevel 
    406      0   stevel 	if (argc > 1 && argv[0].a_type == MDB_TYPE_STRING &&
    407      0   stevel 	    strcmp(argv[0].a_un.a_str, "-s") == 0) {
    408      0   stevel 		parse_strings = 0;
    409      0   stevel 		argc--;
    410      0   stevel 		argv++;
    411      0   stevel 	}
    412      0   stevel 
    413      0   stevel 	call_argv = mdb_alloc(sizeof (uintptr_t) * argc, UM_SLEEP);
    414      0   stevel 
    415      0   stevel 	for (i = 0; i < argc; i++) {
    416      0   stevel 		switch (argv[i].a_type) {
    417      0   stevel 		case MDB_TYPE_STRING:
    418      0   stevel 			/*
    419      0   stevel 			 * mdb_strtoull doesn't return on error, so we have to
    420      0   stevel 			 * pre-check strings suspected to contain numbers.
    421      0   stevel 			 */
    422      0   stevel 			if (parse_strings && strisbasenum(argv[i].a_un.a_str)) {
    423      0   stevel 				call_argv[i] = (uintptr_t)mdb_strtoull(
    424      0   stevel 				    argv[i].a_un.a_str);
    425      0   stevel 			} else
    426      0   stevel 				call_argv[i] = (uintptr_t)argv[i].a_un.a_str;
    427      0   stevel 
    428      0   stevel 			break;
    429      0   stevel 
    430      0   stevel 		case MDB_TYPE_IMMEDIATE:
    431      0   stevel 			call_argv[i] = argv[i].a_un.a_val;
    432      0   stevel 			break;
    433      0   stevel 
    434      0   stevel 		default:
    435      0   stevel 			mdb_free(call_argv,
    436      0   stevel 			    sizeof (uintptr_t) * argc);
    437      0   stevel 			return (DCMD_USAGE);
    438      0   stevel 		}
    439      0   stevel 	}
    440      0   stevel 
    441      0   stevel 	if (setjmp(pcb) != 0) {
    442      0   stevel 		warn("call failed: caught a trap\n");
    443      0   stevel 
    444      0   stevel 		kmdb_dpi_restore_fault_hdlr(oldpcb);
    445      0   stevel 		mdb_free(call_argv, sizeof (uintptr_t) * argc);
    446      0   stevel 		return (DCMD_ERR);
    447      0   stevel 	}
    448      0   stevel 
    449      0   stevel 	oldpcb = kmdb_dpi_set_fault_hdlr(&pcb);
    450      0   stevel 	rval = kmdb_dpi_call(addr, argc, call_argv);
    451      0   stevel 	kmdb_dpi_restore_fault_hdlr(oldpcb);
    452      0   stevel 
    453      0   stevel 	if (flags & DCMD_PIPE_OUT) {
    454      0   stevel 		mdb_printf("%p\n", rval);
    455      0   stevel 	} else {
    456      0   stevel 		/* pretty-print the results */
    457      0   stevel 		mdb_printf("%p = %a(", rval, addr);
    458      0   stevel 		for (i = 0; i < argc; i++) {
    459      0   stevel 			if (i > 0)
    460      0   stevel 				mdb_printf(", ");
    461      0   stevel 			if (argv[i].a_type == MDB_TYPE_STRING) {
    462      0   stevel 				/* I'm ashamed but amused */
    463      0   stevel 				char *quote = &("\""[parse_strings &&
    464      0   stevel 				    strisbasenum(argv[i].a_un.a_str)]);
    465      0   stevel 
    466      0   stevel 				mdb_printf("%s%s%s", quote, argv[i].a_un.a_str,
    467      0   stevel 				    quote);
    468      0   stevel 			} else
    469      0   stevel 				mdb_printf("%p", argv[i].a_un.a_val);
    470      0   stevel 		}
    471      0   stevel 		mdb_printf(");\n");
    472      0   stevel 	}
    473      0   stevel 
    474      0   stevel 	mdb_free(call_argv, sizeof (uintptr_t) * argc);
    475      0   stevel 
    476      0   stevel 	return (DCMD_OK);
    477      0   stevel }
    478      0   stevel 
    479      0   stevel /*ARGSUSED*/
    480      0   stevel int
    481      0   stevel kmt_dump_crumbs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    482      0   stevel {
    483      0   stevel 	intptr_t cpu = -1;
    484      0   stevel 
    485      0   stevel 	if (flags & DCMD_ADDRSPEC) {
    486      0   stevel 		if (argc != 0)
    487      0   stevel 			return (DCMD_USAGE);
    488      0   stevel 	} else {
    489      0   stevel 		addr = 0;
    490      0   stevel 
    491      0   stevel 		if (mdb_getopts(argc, argv,
    492      0   stevel 		    'c', MDB_OPT_UINTPTR, &cpu,
    493      0   stevel 		    NULL) != argc)
    494      0   stevel 			return (DCMD_USAGE);
    495      0   stevel 	}
    496      0   stevel 
    497      0   stevel 	kmdb_dpi_dump_crumbs(addr, cpu);
    498      0   stevel 
    499      0   stevel 	return (DCMD_OK);
    500      0   stevel }
    501      0   stevel 
    502      0   stevel /*ARGSUSED*/
    503      0   stevel static int
    504      0   stevel kmt_noducttape(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    505      0   stevel {
    506      0   stevel 	int a = 0;
    507      0   stevel 
    508      0   stevel 	return (a/a);
    509      0   stevel }
    510      0   stevel 
    511      0   stevel static int
    512      0   stevel kmt_dmod_status(char *msg, int state)
    513      0   stevel {
    514      0   stevel 	kmdb_modctl_t *kmc;
    515      0   stevel 	mdb_var_t *v;
    516      0   stevel 	int first = 1, n = 0;
    517      0   stevel 
    518      0   stevel 	mdb_nv_rewind(&mdb.m_dmodctl);
    519      0   stevel 	while ((v = mdb_nv_advance(&mdb.m_dmodctl)) != NULL) {
    520      0   stevel 		kmc = MDB_NV_COOKIE(v);
    521      0   stevel 
    522      0   stevel 		if (kmc->kmc_state != state)
    523      0   stevel 			continue;
    524      0   stevel 
    525      0   stevel 		n++;
    526      0   stevel 
    527      0   stevel 		if (msg != NULL) {
    528      0   stevel 			if (first) {
    529      0   stevel 				mdb_printf(msg, NULL);
    530      0   stevel 				first = 0;
    531      0   stevel 			}
    532      0   stevel 
    533      0   stevel 			mdb_printf(" %s", kmc->kmc_modname);
    534      0   stevel 		}
    535      0   stevel 	}
    536      0   stevel 
    537      0   stevel 	if (!first && msg != NULL)
    538      0   stevel 		mdb_printf("\n");
    539      0   stevel 
    540      0   stevel 	return (n);
    541      0   stevel }
    542      0   stevel 
    543      0   stevel /*ARGSUSED*/
    544      0   stevel static int
    545      0   stevel kmt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    546      0   stevel {
    547      0   stevel 	kmt_data_t *kmt = mdb.m_target->t_data;
    548      0   stevel 	struct utsname uts;
    549      0   stevel 	kreg_t tt;
    550      0   stevel 
    551      0   stevel 	if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, &uts, sizeof (uts),
    552      0   stevel 	    "unix", "utsname") != sizeof (uts)) {
    553      0   stevel 		warn("failed to read 'utsname' struct from kernel\n");
    554      0   stevel 		bzero(&uts, sizeof (uts));
    555      0   stevel 		(void) strcpy(uts.nodename, "unknown machine");
    556      0   stevel 	}
    557      0   stevel 
    558      0   stevel 	mdb_printf("debugging live kernel (%d-bit) on %s\n",
    559      0   stevel 	    (int)(sizeof (void *) * NBBY),
    560      0   stevel 	    (*uts.nodename == '\0' ? "(not set)" : uts.nodename));
    561      0   stevel 	mdb_printf("operating system: %s %s (%s)\n",
    562      0   stevel 	    uts.release, uts.version, uts.machine);
    563      0   stevel 
    564      0   stevel 	if (kmt->kmt_cpu != NULL) {
    565      0   stevel 		mdb_printf("CPU-specific support: %s\n",
    566      0   stevel 		    kmt_cpu_name(kmt->kmt_cpu));
    567      0   stevel 	}
    568      0   stevel 
    569      0   stevel 	mdb_printf("DTrace state: %s\n", (kmdb_kdi_dtrace_get_state() ==
    570      0   stevel 	    KDI_DTSTATE_DTRACE_ACTIVE ? "active (debugger breakpoints cannot "
    571      0   stevel 	    "be armed)" : "inactive"));
    572      0   stevel 
    573      0   stevel 	(void) kmdb_dpi_get_register("tt", &tt);
    574      0   stevel 	mdb_printf("stopped on: %s\n", kmt_trapname(tt));
    575      0   stevel 
    576      0   stevel 	(void) kmt_dmod_status("pending dmod loads:", KMDB_MC_STATE_LOADING);
    577      0   stevel 	(void) kmt_dmod_status("pending dmod unloads:",
    578      0   stevel 	    KMDB_MC_STATE_UNLOADING);
    579      0   stevel 
    580      0   stevel 	return (DCMD_OK);
    581      0   stevel }
    582      0   stevel 
    583      0   stevel /*ARGSUSED*/
    584      0   stevel static int
    585      0   stevel kmt_switch(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
    586      0   stevel {
    587      0   stevel 	if (!(flags & DCMD_ADDRSPEC) || argc != 0)
    588      0   stevel 		return (DCMD_USAGE);
    589      0   stevel 
    590      0   stevel 	if (kmdb_dpi_switch_master((int)addr) < 0) {
    591      0   stevel 		warn("failed to switch to CPU %d", (int)addr);
    592      0   stevel 		return (DCMD_ERR);
    593      0   stevel 	}
    594      0   stevel 
    595      0   stevel 	return (DCMD_OK);
    596      0   stevel }
    597      0   stevel 
    598      0   stevel static const mdb_dcmd_t kmt_dcmds[] = {
    599      0   stevel 	{ "$c", "?[cnt]", "print stack backtrace", kmt_stack },
    600      0   stevel 	{ "$C", "?[cnt]", "print stack backtrace", kmt_stackv },
    601      0   stevel 	{ "$r", NULL, "print general-purpose registers", kmt_regs },
    602      0   stevel 	{ "$?", NULL, "print status and registers", kmt_regs },
    603      0   stevel 	{ ":x", ":", "change the active CPU", kmt_switch },
    604      0   stevel 	{ "call", ":[arg ...]", "call a kernel function", kmt_call },
    605      0   stevel 	{ "cpustack", "?[-v] [-c cpuid] [cnt]", "print stack backtrace for a "
    606      0   stevel 	    "specific CPU", kmt_cpustack_dcmd },
    607      0   stevel 	{ "cpuregs", "?[-c cpuid]", "print general-purpose registers for a "
    608      0   stevel 	    "specific CPU", kmt_cpuregs },
    609      0   stevel 	{ "crumbs", NULL, NULL, kmt_dump_crumbs },
    610      0   stevel #if defined(__i386) || defined(__amd64)
    611      0   stevel 	{ "in", ":[-L len]", "read from I/O port", kmt_in_dcmd },
    612      0   stevel 	{ "out", ":[-L len] val", "write to I/O port", kmt_out_dcmd },
    613      0   stevel 	{ "rdmsr", ":", "read an MSR", kmt_rdmsr },
    614      0   stevel 	{ "wrmsr", ": val", "write an MSR", kmt_wrmsr },
    615   1414    cindi 	{ "rdpcicfg", ": bus dev func", "read a register in PCI config space",
    616   1414    cindi 	kmt_rdpcicfg },
    617   1414    cindi 	{ "wrpcicfg", ": bus dev func val", "write a register in PCI config "
    618   1414    cindi 	"space", kmt_wrpcicfg },
    619      0   stevel #endif
    620      0   stevel 	{ "noducttape", NULL, NULL, kmt_noducttape },
    621      0   stevel 	{ "regs", NULL, "print general-purpose registers", kmt_regs },
    622      0   stevel 	{ "stack", "?[cnt]", "print stack backtrace", kmt_stack },
    623      0   stevel 	{ "stackregs", "?", "print stack backtrace and registers", kmt_stackr },
    624      0   stevel 	{ "status", NULL, "print summary of current target", kmt_status_dcmd },
    625      0   stevel 	{ "switch", ":", "change the active CPU", kmt_switch },
    626      0   stevel 	{ NULL }
    627      0   stevel };
    628      0   stevel 
    629      0   stevel static uintmax_t
    630      0   stevel kmt_reg_disc_get(const mdb_var_t *v)
    631      0   stevel {
    632      0   stevel 	mdb_tgt_reg_t r = 0;
    633      0   stevel 
    634      0   stevel 	(void) mdb_tgt_getareg(MDB_NV_COOKIE(v), 0, mdb_nv_get_name(v), &r);
    635      0   stevel 
    636      0   stevel 	return (r);
    637      0   stevel }
    638      0   stevel 
    639      0   stevel static void
    640      0   stevel kmt_reg_disc_set(mdb_var_t *v, uintmax_t r)
    641      0   stevel {
    642      0   stevel 	if (mdb_tgt_putareg(MDB_NV_COOKIE(v), 0, mdb_nv_get_name(v), r) == -1)
    643      0   stevel 		warn("failed to modify %%%s register", mdb_nv_get_name(v));
    644      0   stevel }
    645      0   stevel 
    646      0   stevel static const mdb_nv_disc_t kmt_reg_disc = {
    647      0   stevel 	kmt_reg_disc_set,
    648      0   stevel 	kmt_reg_disc_get
    649      0   stevel };
    650      0   stevel 
    651      0   stevel /*ARGSUSED*/
    652      0   stevel static int
    653      0   stevel kmt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, const char *rname,
    654      0   stevel     mdb_tgt_reg_t *rp)
    655      0   stevel {
    656      0   stevel 	kreg_t val;
    657      0   stevel 
    658      0   stevel 	if (kmdb_dpi_get_register(rname, &val) < 0)
    659      0   stevel 		return (set_errno(EMDB_BADREG));
    660      0   stevel 
    661      0   stevel 	*rp = val;
    662      0   stevel 	return (0);
    663      0   stevel }
    664      0   stevel 
    665      0   stevel /*ARGSUSED*/
    666      0   stevel static int
    667      0   stevel kmt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, const char *rname, mdb_tgt_reg_t r)
    668      0   stevel {
    669      0   stevel 	if (kmdb_dpi_set_register(rname, r) < 0)
    670      0   stevel 		return (set_errno(EMDB_BADREG));
    671      0   stevel 
    672      0   stevel 	return (0);
    673      0   stevel }
    674      0   stevel 
    675      0   stevel static void
    676      0   stevel kmt_mod_destroy(kmt_module_t *km)
    677      0   stevel {
    678      0   stevel 	if (km->km_name != NULL)
    679      0   stevel 		strfree(km->km_name);
    680      0   stevel 	if (km->km_symtab != NULL)
    681      0   stevel 		mdb_gelf_symtab_destroy(km->km_symtab);
    682      0   stevel 	if (km->km_ctfp != NULL)
    683      0   stevel 		mdb_ctf_close(km->km_ctfp);
    684      0   stevel }
    685      0   stevel 
    686      0   stevel static kmt_module_t *
    687      0   stevel kmt_mod_create(mdb_tgt_t *t, struct modctl *ctlp, char *name)
    688      0   stevel {
    689      0   stevel 	kmt_module_t *km = mdb_zalloc(sizeof (kmt_module_t), UM_SLEEP);
    690      0   stevel 	struct module *mod;
    691      0   stevel 
    692      0   stevel 	km->km_name = mdb_alloc(strlen(name) + 1, UM_SLEEP);
    693  11053    Surya 	(void) strcpy(km->km_name, name);
    694      0   stevel 
    695      0   stevel 	bcopy(ctlp, &km->km_modctl, sizeof (struct modctl));
    696      0   stevel 
    697      0   stevel 	if (mdb_tgt_vread(t, &km->km_module, sizeof (struct module),
    698      0   stevel 	    (uintptr_t)km->km_modctl.mod_mp) != sizeof (struct module))
    699      0   stevel 		goto create_module_cleanup;
    700      0   stevel 	mod = &km->km_module;
    701      0   stevel 
    702      0   stevel 	if (mod->symhdr != NULL && mod->strhdr != NULL && mod->symtbl != NULL &&
    703      0   stevel 	    mod->strings != NULL) {
    704      0   stevel 		mdb_gelf_ehdr_to_gehdr(&mod->hdr, &km->km_ehdr);
    705      0   stevel 
    706      0   stevel 		km->km_symtab = mdb_gelf_symtab_create_raw(&km->km_ehdr,
    707      0   stevel 		    mod->symhdr, mod->symtbl, mod->strhdr, mod->strings,
    708      0   stevel 		    MDB_TGT_SYMTAB);
    709      0   stevel 
    710      0   stevel 		km->km_symtab_va = mod->symtbl;
    711      0   stevel 		km->km_strtab_va = mod->strings;
    712      0   stevel 
    713      0   stevel 		if (mdb_tgt_vread(t, &km->km_symtab_hdr, sizeof (Shdr),
    714      0   stevel 		    (uintptr_t)mod->symhdr) != sizeof (Shdr) ||
    715      0   stevel 		    mdb_tgt_vread(t, &km->km_strtab_hdr, sizeof (Shdr),
    716      0   stevel 		    (uintptr_t)mod->strhdr) != sizeof (Shdr))
    717      0   stevel 			goto create_module_cleanup;
    718      0   stevel 	}
    719      0   stevel 
    720      0   stevel 	/*
    721      0   stevel 	 * We don't want everyone rooting around in the module structure, so we
    722      0   stevel 	 * make copies of the interesting members.
    723      0   stevel 	 */
    724      0   stevel 	km->km_text_va = (uintptr_t)mod->text;
    725      0   stevel 	km->km_text_size = mod->text_size;
    726      0   stevel 	km->km_data_va = (uintptr_t)mod->data;
    727      0   stevel 	km->km_data_size = mod->data_size;
    728      0   stevel 	km->km_bss_va = (uintptr_t)mod->bss;
    729      0   stevel 	km->km_bss_size = mod->bss_size;
    730      0   stevel 	km->km_ctf_va = mod->ctfdata;
    731      0   stevel 	km->km_ctf_size = mod->ctfsize;
    732      0   stevel 
    733      0   stevel 	if (mod->flags & KOBJ_PRIM)
    734      0   stevel 		km->km_flags |= KM_F_PRIMARY;
    735      0   stevel 
    736      0   stevel 	return (km);
    737      0   stevel 
    738      0   stevel create_module_cleanup:
    739      0   stevel 	warn("failed to read module %s\n", name);
    740      0   stevel 	kmt_mod_destroy(km);
    741      0   stevel 	return (NULL);
    742      0   stevel }
    743      0   stevel 
    744      0   stevel static void
    745      0   stevel kmt_mod_remove(kmt_data_t *kmt, kmt_module_t *km)
    746      0   stevel {
    747      0   stevel 	mdb_var_t *v = mdb_nv_lookup(&kmt->kmt_modules, km->km_name);
    748      0   stevel 
    749      0   stevel 	ASSERT(v != NULL);
    750      0   stevel 
    751      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "removing module %s\n", km->km_name);
    752      0   stevel 
    753      0   stevel 	mdb_list_delete(&kmt->kmt_modlist, km);
    754      0   stevel 	mdb_nv_remove(&kmt->kmt_modules, v);
    755      0   stevel 	kmt_mod_destroy(km);
    756      0   stevel }
    757      0   stevel 
    758      0   stevel static int
    759      0   stevel kmt_modlist_update_cb(struct modctl *modp, void *arg)
    760      0   stevel {
    761      0   stevel 	mdb_tgt_t *t = arg;
    762      0   stevel 	kmt_data_t *kmt = t->t_data;
    763      0   stevel 	kmt_module_t *km;
    764      0   stevel 	mdb_var_t *v;
    765      0   stevel 	char name[MAXNAMELEN];
    766      0   stevel 
    767      0   stevel 	if (mdb_tgt_readstr(t, MDB_TGT_AS_VIRT, name, MAXNAMELEN,
    768      0   stevel 	    (uintptr_t)modp->mod_modname) <= 0) {
    769      0   stevel 		warn("failed to read module name at %p",
    770      0   stevel 		    (void *)modp->mod_modname);
    771      0   stevel 	}
    772      0   stevel 
    773      0   stevel 	/* We only care about modules that are actually loaded */
    774      0   stevel 	if (!kmdb_kdi_mod_isloaded(modp))
    775      0   stevel 		return (0);
    776      0   stevel 
    777      0   stevel 	/*
    778      0   stevel 	 * Skip the modules we already know about and that haven't
    779      0   stevel 	 * changed since last time we were here.
    780      0   stevel 	 */
    781      0   stevel 	if ((v = mdb_nv_lookup(&kmt->kmt_modules, name)) != NULL) {
    782      0   stevel 		km = MDB_NV_COOKIE(v);
    783      0   stevel 
    784      0   stevel 		if (kmdb_kdi_mod_haschanged(&km->km_modctl, &km->km_module,
    785      0   stevel 		    modp, modp->mod_mp)) {
    786      0   stevel 			/*
    787      0   stevel 			 * The module has changed since last we saw it.  For
    788      0   stevel 			 * safety, remove our old version, and treat it as a
    789      0   stevel 			 * new module.
    790      0   stevel 			 */
    791      0   stevel 			mdb_dprintf(MDB_DBG_KMOD, "stutter module %s\n", name);
    792      0   stevel 			kmt_mod_remove(kmt, km);
    793      0   stevel 		} else {
    794      0   stevel 			km->km_seen = 1;
    795      0   stevel 			return (0);
    796      0   stevel 		}
    797      0   stevel 	}
    798      0   stevel 
    799      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "found new module %s\n", name);
    800      0   stevel 
    801      0   stevel 	if ((km = kmt_mod_create(t, modp, name)) != NULL) {
    802      0   stevel 		mdb_list_append(&kmt->kmt_modlist, km);
    803      0   stevel 		(void) mdb_nv_insert(&kmt->kmt_modules, name, NULL,
    804      0   stevel 		    (uintptr_t)km, 0);
    805      0   stevel 		km->km_seen = 1;
    806      0   stevel 	}
    807      0   stevel 
    808      0   stevel 	return (0);
    809      0   stevel }
    810      0   stevel 
    811      0   stevel static void
    812      0   stevel kmt_modlist_update(mdb_tgt_t *t)
    813      0   stevel {
    814      0   stevel 	kmt_data_t *kmt = t->t_data;
    815      0   stevel 	kmt_module_t *km, *kmn;
    816      0   stevel 
    817      0   stevel 	if (kmdb_kdi_mod_iter(kmt_modlist_update_cb, t) < 0) {
    818      0   stevel 		warn("failed to complete update of kernel module list\n");
    819      0   stevel 		return;
    820      0   stevel 	}
    821      0   stevel 
    822      0   stevel 	km = mdb_list_next(&kmt->kmt_modlist);
    823      0   stevel 	while (km != NULL) {
    824      0   stevel 		kmn = mdb_list_next(km);
    825      0   stevel 
    826      0   stevel 		if (km->km_seen == 1) {
    827      0   stevel 			/* Reset the mark for next time */
    828      0   stevel 			km->km_seen = 0;
    829      0   stevel 		} else {
    830      0   stevel 			/*
    831      0   stevel 			 * We didn't see it on the kernel's module list, so
    832      0   stevel 			 * remove it from our view of the world.
    833      0   stevel 			 */
    834      0   stevel 			kmt_mod_remove(kmt, km);
    835      0   stevel 		}
    836      0   stevel 
    837      0   stevel 		km = kmn;
    838      0   stevel 	}
    839      0   stevel }
    840      0   stevel 
    841      0   stevel static void
    842      0   stevel kmt_periodic(mdb_tgt_t *t)
    843      0   stevel {
    844      0   stevel 	(void) mdb_tgt_status(t, &t->t_status);
    845      0   stevel }
    846      0   stevel 
    847      0   stevel int
    848      0   stevel kmt_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags,
    849      0   stevel     char *buf, size_t nbytes, GElf_Sym *symp, mdb_syminfo_t *sip)
    850      0   stevel {
    851      0   stevel 	kmt_data_t *kmt = t->t_data;
    852      0   stevel 	kmt_module_t *km = mdb_list_next(&kmt->kmt_modlist);
    853      0   stevel 	kmt_module_t *sym_km = NULL;
    854      0   stevel 	kmt_module_t prmod;
    855      0   stevel 	GElf_Sym sym;
    856      0   stevel 	uint_t symid;
    857      0   stevel 	const char *name;
    858      0   stevel 
    859      0   stevel 	/*
    860      0   stevel 	 * We look through the private symbols (if any), then through the module
    861      0   stevel 	 * symbols.  We can simplify the loop if we pretend the private symbols
    862      0   stevel 	 * come from a module.
    863      0   stevel 	 */
    864      0   stevel 	if (mdb.m_prsym != NULL) {
    865      0   stevel 		bzero(&prmod, sizeof (kmt_module_t));
    866      0   stevel 		prmod.km_name = "<<<prmod>>>";
    867      0   stevel 		prmod.km_symtab = mdb.m_prsym;
    868      0   stevel 		prmod.km_list.ml_next = (mdb_list_t *)km;
    869      0   stevel 		km = &prmod;
    870      0   stevel 	}
    871      0   stevel 
    872      0   stevel 	/* Symbol resolution isn't available during initialization */
    873      0   stevel 	if (kmdb_dpi_get_state(NULL) == DPI_STATE_INIT)
    874      0   stevel 		return (set_errno(EMDB_NOSYM));
    875      0   stevel 
    876      0   stevel 	for (; km != NULL; km = mdb_list_next(km)) {
    877      0   stevel 		if (km != &prmod && !kmt->kmt_symavail)
    878      0   stevel 			continue;
    879      0   stevel 
    880      0   stevel 		if (km->km_symtab == NULL)
    881      0   stevel 			continue;
    882      0   stevel 
    883      0   stevel 		if (mdb_gelf_symtab_lookup_by_addr(km->km_symtab, addr, flags,
    884      0   stevel 		    buf, nbytes, symp, &sip->sym_id) != 0 ||
    885      0   stevel 		    symp->st_value == 0)
    886      0   stevel 			continue;
    887      0   stevel 
    888      0   stevel 		if (flags & MDB_TGT_SYM_EXACT) {
    889      0   stevel 			sym_km = km;
    890      0   stevel 			goto found;
    891      0   stevel 		}
    892      0   stevel 
    893      0   stevel 		/*
    894      0   stevel 		 * If this is the first match we've found, or if this symbol is
    895      0   stevel 		 * closer to the specified address than the last one we found,
    896      0   stevel 		 * use it.
    897      0   stevel 		 */
    898      0   stevel 		if (sym_km == NULL || mdb_gelf_sym_closer(symp, &sym, addr)) {
    899      0   stevel 			sym_km = km;
    900      0   stevel 			sym = *symp;
    901      0   stevel 			symid = sip->sym_id;
    902      0   stevel 		}
    903      0   stevel 	}
    904      0   stevel 
    905      0   stevel 	/*
    906      0   stevel 	 * kmdb dmods are normal kernel modules, loaded by krtld as such.  To
    907      0   stevel 	 * avoid polluting modinfo, and to keep from confusing the module
    908      0   stevel 	 * subsystem (many dmods have the same names as real kernel modules),
    909      0   stevel 	 * kmdb keeps their modctls separate, and doesn't allow their loading
    910      0   stevel 	 * to be broadcast via the krtld module load/unload mechanism.  As a
    911      0   stevel 	 * result, kmdb_kvm doesn't find out about them, and can't turn their
    912      0   stevel 	 * addresses into symbols.  This can be most inconvenient during
    913      0   stevel 	 * debugger faults, as the dmod frames will show up without names.
    914   1234  johnlev 	 * We weren't able to turn the requested address into a symbol, so we'll
    915      0   stevel 	 * take a spin through the dmods, trying to match our address against
    916      0   stevel 	 * their symbols.
    917      0   stevel 	 */
    918      0   stevel 	if (sym_km == NULL) {
    919      0   stevel 		return (kmdb_module_lookup_by_addr(addr, flags, buf, nbytes,
    920      0   stevel 		    symp, sip));
    921      0   stevel 	}
    922      0   stevel 
    923      0   stevel 	*symp = sym;
    924      0   stevel 	sip->sym_id = symid;
    925      0   stevel 
    926      0   stevel found:
    927      0   stevel 	/*
    928      0   stevel 	 * Once we've found something, copy the final name into the caller's
    929      0   stevel 	 * buffer and prefix it with the load object name if appropriate.
    930      0   stevel 	 */
    931      0   stevel 	name = mdb_gelf_sym_name(sym_km->km_symtab, symp);
    932      0   stevel 
    933      0   stevel 	if (sym_km == &prmod) {
    934      0   stevel 		if (buf != NULL) {
    935      0   stevel 			(void) strncpy(buf, name, nbytes);
    936      0   stevel 			buf[nbytes - 1] = '\0';
    937      0   stevel 		}
    938      0   stevel 		sip->sym_table = MDB_TGT_PRVSYM;
    939      0   stevel 	} else {
    940      0   stevel 		if (buf != NULL) {
    941      0   stevel 			if (sym_km->km_flags & KM_F_PRIMARY) {
    942      0   stevel 				(void) strncpy(buf, name, nbytes);
    943      0   stevel 				buf[nbytes - 1] = '\0';
    944      0   stevel 			} else {
    945      0   stevel 				(void) mdb_snprintf(buf, nbytes, "%s`%s",
    946      0   stevel 				    sym_km->km_name, name);
    947      0   stevel 			}
    948      0   stevel 		}
    949      0   stevel 		sip->sym_table = MDB_TGT_SYMTAB;
    950      0   stevel 	}
    951      0   stevel 
    952      0   stevel 	return (0);
    953      0   stevel }
    954      0   stevel 
    955      0   stevel static int
    956      0   stevel kmt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name,
    957      0   stevel     GElf_Sym *symp, mdb_syminfo_t *sip)
    958      0   stevel {
    959      0   stevel 	kmt_data_t *kmt = t->t_data;
    960      0   stevel 	kmt_module_t *km;
    961      0   stevel 	mdb_var_t *v;
    962      0   stevel 	GElf_Sym sym;
    963      0   stevel 	uint_t symid;
    964      0   stevel 	int n;
    965      0   stevel 
    966      0   stevel 	if (!kmt->kmt_symavail)
    967      0   stevel 		return (set_errno(EMDB_NOSYM));
    968      0   stevel 
    969      0   stevel 	switch ((uintptr_t)obj) {
    970      0   stevel 	case (uintptr_t)MDB_TGT_OBJ_EXEC:
    971      0   stevel 	case (uintptr_t)MDB_TGT_OBJ_EVERY:
    972      0   stevel 		km = mdb_list_next(&kmt->kmt_modlist);
    973      0   stevel 		n = mdb_nv_size(&kmt->kmt_modules);
    974      0   stevel 		break;
    975      0   stevel 
    976      0   stevel 	case (uintptr_t)MDB_TGT_OBJ_RTLD:
    977   3446      mrj 		obj = kmt->kmt_rtld_name;
    978      0   stevel 		/*FALLTHROUGH*/
    979      0   stevel 
    980      0   stevel 	default:
    981      0   stevel 		/*
    982      0   stevel 		 * If this is a request for a dmod symbol, let kmdb_module
    983      0   stevel 		 * handle it.
    984      0   stevel 		 */
    985      0   stevel 		if (obj != NULL && strncmp(obj, "DMOD`", 5) == 0) {
    986      0   stevel 			return (kmdb_module_lookup_by_name(obj + 5, name,
    987      0   stevel 			    symp, sip));
    988      0   stevel 		}
    989      0   stevel 
    990      0   stevel 		if ((v = mdb_nv_lookup(&kmt->kmt_modules, obj)) == NULL)
    991      0   stevel 			return (set_errno(EMDB_NOOBJ));
    992      0   stevel 
    993      0   stevel 		km = mdb_nv_get_cookie(v);
    994      0   stevel 		n = 1;
    995      0   stevel 	}
    996      0   stevel 
    997      0   stevel 	/*
    998      0   stevel 	 * kmdb's kvm target is at a bit of a disadvantage compared to mdb's
    999      0   stevel 	 * kvm target when it comes to global symbol lookups.  mdb has ksyms,
   1000      0   stevel 	 * which hides pesky things like symbols that are undefined in unix,
   1001      0   stevel 	 * but which are defined in genunix.  We don't have such a facility -
   1002      0   stevel 	 * we simply iterate through the modules, looking for a given symbol
   1003      0   stevel 	 * in each.  Unless we're careful, we'll return the undef in the
   1004      0   stevel 	 * aforementioned case.
   1005      0   stevel 	 */
   1006      0   stevel 	for (; n > 0; n--, km = mdb_list_next(km)) {
   1007      0   stevel 		if (mdb_gelf_symtab_lookup_by_name(km->km_symtab, name,
   1008      0   stevel 		    &sym, &symid) == 0 && sym.st_shndx != SHN_UNDEF)
   1009      0   stevel 			break;
   1010      0   stevel 	}
   1011      0   stevel 
   1012      0   stevel 	if (n == 0)
   1013      0   stevel 		return (set_errno(EMDB_NOSYM));
   1014      0   stevel 
   1015      0   stevel found:
   1016      0   stevel 	bcopy(&sym, symp, sizeof (GElf_Sym));
   1017      0   stevel 	sip->sym_id = symid;
   1018      0   stevel 	sip->sym_table = MDB_TGT_SYMTAB;
   1019      0   stevel 
   1020      0   stevel 	return (0);
   1021      0   stevel }
   1022      0   stevel 
   1023      0   stevel static int
   1024      0   stevel kmt_symtab_func(void *data, const GElf_Sym *sym, const char *name, uint_t id)
   1025      0   stevel {
   1026      0   stevel 	kmt_symarg_t *arg = data;
   1027      0   stevel 
   1028      0   stevel 	if (mdb_tgt_sym_match(sym, arg->sym_type)) {
   1029      0   stevel 		arg->sym_info.sym_id = id;
   1030      0   stevel 
   1031      0   stevel 		return (arg->sym_cb(arg->sym_data, sym, name, &arg->sym_info,
   1032      0   stevel 		    arg->sym_obj));
   1033      0   stevel 	}
   1034      0   stevel 
   1035      0   stevel 	return (0);
   1036      0   stevel }
   1037      0   stevel 
   1038      0   stevel static void
   1039      0   stevel kmt_symtab_iter(mdb_gelf_symtab_t *gst, uint_t type, const char *obj,
   1040      0   stevel     mdb_tgt_sym_f *cb, void *p)
   1041      0   stevel {
   1042      0   stevel 	kmt_symarg_t arg;
   1043      0   stevel 
   1044      0   stevel 	arg.sym_cb = cb;
   1045      0   stevel 	arg.sym_data = p;
   1046      0   stevel 	arg.sym_type = type;
   1047      0   stevel 	arg.sym_info.sym_table = gst->gst_tabid;
   1048      0   stevel 	arg.sym_obj = obj;
   1049      0   stevel 
   1050      0   stevel 	mdb_gelf_symtab_iter(gst, kmt_symtab_func, &arg);
   1051      0   stevel }
   1052      0   stevel 
   1053      0   stevel static int
   1054      0   stevel kmt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, uint_t type,
   1055      0   stevel     mdb_tgt_sym_f *cb, void *data)
   1056      0   stevel {
   1057      0   stevel 	kmt_data_t *kmt = t->t_data;
   1058      0   stevel 	kmt_module_t *km;
   1059      0   stevel 
   1060      0   stevel 	mdb_gelf_symtab_t *symtab = NULL;
   1061      0   stevel 	mdb_var_t *v;
   1062      0   stevel 
   1063      0   stevel 	if (which == MDB_TGT_DYNSYM)
   1064      0   stevel 		return (set_errno(EMDB_TGTNOTSUP));
   1065      0   stevel 
   1066      0   stevel 	switch ((uintptr_t)obj) {
   1067      0   stevel 	case (uintptr_t)MDB_TGT_OBJ_EXEC:
   1068      0   stevel 	case (uintptr_t)MDB_TGT_OBJ_EVERY:
   1069      0   stevel 		mdb_nv_rewind(&kmt->kmt_modules);
   1070      0   stevel 		while ((v = mdb_nv_advance(&kmt->kmt_modules)) != NULL) {
   1071      0   stevel 			km = mdb_nv_get_cookie(v);
   1072      0   stevel 
   1073      0   stevel 			if (km->km_symtab != NULL) {
   1074      0   stevel 				kmt_symtab_iter(km->km_symtab, type,
   1075      0   stevel 				    km->km_name, cb, data);
   1076      0   stevel 			}
   1077      0   stevel 		}
   1078      0   stevel 		return (0);
   1079      0   stevel 
   1080      0   stevel 	case (uintptr_t)MDB_TGT_OBJ_RTLD:
   1081   3446      mrj 		obj = kmt->kmt_rtld_name;
   1082      0   stevel 		/*FALLTHROUGH*/
   1083      0   stevel 
   1084      0   stevel 	default:
   1085      0   stevel 		if (strncmp(obj, "DMOD`", 5) == 0) {
   1086      0   stevel 			return (kmdb_module_symbol_iter(obj + 5, type,
   1087      0   stevel 			    cb, data));
   1088      0   stevel 		}
   1089      0   stevel 
   1090      0   stevel 		if ((v = mdb_nv_lookup(&kmt->kmt_modules, obj)) == NULL)
   1091      0   stevel 			return (set_errno(EMDB_NOOBJ));
   1092      0   stevel 		km = mdb_nv_get_cookie(v);
   1093      0   stevel 
   1094      0   stevel 		symtab = km->km_symtab;
   1095      0   stevel 	}
   1096      0   stevel 
   1097      0   stevel 	if (symtab != NULL)
   1098      0   stevel 		kmt_symtab_iter(symtab, type, obj, cb, data);
   1099      0   stevel 
   1100      0   stevel 	return (0);
   1101      0   stevel }
   1102      0   stevel 
   1103      0   stevel static int
   1104      0   stevel kmt_mapping_walk(uintptr_t addr, const void *data, kmt_maparg_t *marg)
   1105      0   stevel {
   1106      0   stevel 	/*
   1107      0   stevel 	 * This is a bit sketchy but avoids problematic compilation of this
   1108      0   stevel 	 * target against the current VM implementation.  Now that we have
   1109      0   stevel 	 * vmem, we can make this less broken and more informative by changing
   1110      0   stevel 	 * this code to invoke the vmem walker in the near future.
   1111      0   stevel 	 */
   1112      0   stevel 	const struct kmt_seg {
   1113      0   stevel 		caddr_t s_base;
   1114      0   stevel 		size_t s_size;
   1115      0   stevel 	} *segp = (const struct kmt_seg *)data;
   1116      0   stevel 
   1117      0   stevel 	mdb_map_t map;
   1118      0   stevel 	GElf_Sym sym;
   1119      0   stevel 	mdb_syminfo_t info;
   1120      0   stevel 
   1121      0   stevel 	map.map_base = (uintptr_t)segp->s_base;
   1122      0   stevel 	map.map_size = segp->s_size;
   1123      0   stevel 	map.map_flags = MDB_TGT_MAP_R | MDB_TGT_MAP_W | MDB_TGT_MAP_X;
   1124      0   stevel 
   1125      0   stevel 	if (kmt_lookup_by_addr(marg->map_target, addr, MDB_TGT_SYM_EXACT,
   1126      0   stevel 	    map.map_name, MDB_TGT_MAPSZ, &sym, &info) == -1) {
   1127      0   stevel 
   1128      0   stevel 		(void) mdb_iob_snprintf(map.map_name, MDB_TGT_MAPSZ,
   1129      0   stevel 		    "%lr", addr);
   1130      0   stevel 	}
   1131      0   stevel 
   1132      0   stevel 	return (marg->map_cb(marg->map_data, &map, map.map_name));
   1133      0   stevel }
   1134      0   stevel 
   1135      0   stevel static int
   1136      0   stevel kmt_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private)
   1137      0   stevel {
   1138      0   stevel 	kmt_maparg_t m;
   1139      0   stevel 	uintptr_t kas;
   1140      0   stevel 
   1141      0   stevel 	m.map_target = t;
   1142      0   stevel 	m.map_cb = func;
   1143      0   stevel 	m.map_data = private;
   1144      0   stevel 
   1145      0   stevel 	if ((kas = kmt_read_kas(t)) == NULL)
   1146      0   stevel 		return (-1); /* errno is set for us */
   1147      0   stevel 
   1148      0   stevel 	return (mdb_pwalk("seg", (mdb_walk_cb_t)kmt_mapping_walk, &m, kas));
   1149      0   stevel }
   1150      0   stevel 
   1151      0   stevel static const mdb_map_t *
   1152      0   stevel kmt_mod_to_map(kmt_module_t *km, mdb_map_t *map)
   1153      0   stevel {
   1154      0   stevel 	(void) strncpy(map->map_name, km->km_name, MDB_TGT_MAPSZ);
   1155      0   stevel 	map->map_name[MDB_TGT_MAPSZ - 1] = '\0';
   1156      0   stevel 	map->map_base = km->km_text_va;
   1157      0   stevel 	map->map_size = km->km_text_size;
   1158      0   stevel 	map->map_flags = MDB_TGT_MAP_R | MDB_TGT_MAP_W | MDB_TGT_MAP_X;
   1159      0   stevel 
   1160      0   stevel 	return (map);
   1161      0   stevel }
   1162      0   stevel 
   1163      0   stevel static int
   1164      0   stevel kmt_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private)
   1165      0   stevel {
   1166      0   stevel 	kmt_data_t *kmt = t->t_data;
   1167      0   stevel 	kmt_module_t *km;
   1168      0   stevel 	mdb_map_t m;
   1169      0   stevel 
   1170      0   stevel 	for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
   1171      0   stevel 	    km = mdb_list_next(km)) {
   1172      0   stevel 		if (func(private, kmt_mod_to_map(km, &m), km->km_name) == -1)
   1173      0   stevel 			break;
   1174      0   stevel 	}
   1175      0   stevel 
   1176      0   stevel 	return (0);
   1177      0   stevel }
   1178      0   stevel 
   1179      0   stevel static const mdb_map_t *
   1180      0   stevel kmt_addr_to_map(mdb_tgt_t *t, uintptr_t addr)
   1181      0   stevel {
   1182      0   stevel 	kmt_data_t *kmt = t->t_data;
   1183      0   stevel 	kmt_module_t *km;
   1184      0   stevel 
   1185      0   stevel 	for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
   1186      0   stevel 	    km = mdb_list_next(km)) {
   1187      0   stevel 		if (addr - km->km_text_va < km->km_text_size ||
   1188      0   stevel 		    addr - km->km_data_va < km->km_data_size ||
   1189      0   stevel 		    addr - km->km_bss_va < km->km_bss_size)
   1190      0   stevel 			return (kmt_mod_to_map(km, &kmt->kmt_map));
   1191      0   stevel 	}
   1192      0   stevel 
   1193      0   stevel 	(void) set_errno(EMDB_NOMAP);
   1194      0   stevel 	return (NULL);
   1195      0   stevel }
   1196      0   stevel 
   1197   3446      mrj static kmt_module_t *
   1198   3446      mrj kmt_module_by_name(kmt_data_t *kmt, const char *name)
   1199   3446      mrj {
   1200   3446      mrj 	kmt_module_t *km;
   1201   3446      mrj 
   1202   3446      mrj 	for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
   1203   3446      mrj 	    km = mdb_list_next(km)) {
   1204   3446      mrj 		if (strcmp(name, km->km_name) == 0)
   1205   3446      mrj 			return (km);
   1206   3446      mrj 	}
   1207   3446      mrj 
   1208   3446      mrj 	return (NULL);
   1209   3446      mrj }
   1210   3446      mrj 
   1211      0   stevel static const mdb_map_t *
   1212      0   stevel kmt_name_to_map(mdb_tgt_t *t, const char *name)
   1213      0   stevel {
   1214      0   stevel 	kmt_data_t *kmt = t->t_data;
   1215      0   stevel 	kmt_module_t *km;
   1216      0   stevel 	mdb_map_t m;
   1217      0   stevel 
   1218      0   stevel 	/*
   1219      0   stevel 	 * If name is MDB_TGT_OBJ_EXEC, return the first module on the list,
   1220      0   stevel 	 * which will be unix since we keep kmt_modlist in load order.
   1221      0   stevel 	 */
   1222      0   stevel 	if (name == MDB_TGT_OBJ_EXEC) {
   1223      0   stevel 		return (kmt_mod_to_map(mdb_list_next(&kmt->kmt_modlist),
   1224      0   stevel 		    &m));
   1225      0   stevel 	}
   1226      0   stevel 
   1227      0   stevel 	if (name == MDB_TGT_OBJ_RTLD)
   1228   3446      mrj 		name = kmt->kmt_rtld_name;
   1229      0   stevel 
   1230   3446      mrj 	if ((km = kmt_module_by_name(kmt, name)) != NULL)
   1231   3446      mrj 		return (kmt_mod_to_map(km, &m));
   1232      0   stevel 
   1233      0   stevel 	(void) set_errno(EMDB_NOOBJ);
   1234      0   stevel 	return (NULL);
   1235      0   stevel }
   1236      0   stevel 
   1237      0   stevel static ctf_file_t *
   1238      0   stevel kmt_load_ctfdata(mdb_tgt_t *t, kmt_module_t *km)
   1239      0   stevel {
   1240      0   stevel 	kmt_data_t *kmt = t->t_data;
   1241      0   stevel 	int err;
   1242      0   stevel 
   1243      0   stevel 	if (km->km_ctfp != NULL)
   1244      0   stevel 		return (km->km_ctfp);
   1245      0   stevel 
   1246      0   stevel 	if (km->km_ctf_va == NULL || km->km_symtab == NULL) {
   1247      0   stevel 		(void) set_errno(EMDB_NOCTF);
   1248      0   stevel 		return (NULL);
   1249      0   stevel 	}
   1250      0   stevel 
   1251      0   stevel 	if ((km->km_ctfp = mdb_ctf_bufopen(km->km_ctf_va, km->km_ctf_size,
   1252      0   stevel 	    km->km_symtab_va, &km->km_symtab_hdr, km->km_strtab_va,
   1253      0   stevel 	    &km->km_strtab_hdr, &err)) == NULL) {
   1254      0   stevel 		(void) set_errno(ctf_to_errno(err));
   1255      0   stevel 		return (NULL);
   1256      0   stevel 	}
   1257      0   stevel 
   1258      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "loaded %lu bytes of CTF data for %s\n",
   1259      0   stevel 	    (ulong_t)km->km_ctf_size, km->km_name);
   1260      0   stevel 
   1261      0   stevel 	if (ctf_parent_name(km->km_ctfp) != NULL) {
   1262      0   stevel 		mdb_var_t *v;
   1263      0   stevel 
   1264      0   stevel 		if ((v = mdb_nv_lookup(&kmt->kmt_modules,
   1265      0   stevel 		    ctf_parent_name(km->km_ctfp))) != NULL) {
   1266      0   stevel 			kmt_module_t *pm = mdb_nv_get_cookie(v);
   1267      0   stevel 
   1268      0   stevel 			if (pm->km_ctfp == NULL)
   1269      0   stevel 				(void) kmt_load_ctfdata(t, pm);
   1270      0   stevel 
   1271      0   stevel 			if (pm->km_ctfp != NULL && ctf_import(km->km_ctfp,
   1272      0   stevel 			    pm->km_ctfp) == CTF_ERR) {
   1273      0   stevel 				warn("failed to import parent types into "
   1274      0   stevel 				    "%s: %s\n", km->km_name,
   1275      0   stevel 				    ctf_errmsg(ctf_errno(km->km_ctfp)));
   1276      0   stevel 			}
   1277      0   stevel 		} else {
   1278      0   stevel 			warn("failed to load CTF data for %s - parent %s not "
   1279      0   stevel 			    "loaded\n", km->km_name,
   1280      0   stevel 			    ctf_parent_name(km->km_ctfp));
   1281      0   stevel 		}
   1282      0   stevel 	}
   1283      0   stevel 
   1284      0   stevel 	return (km->km_ctfp);
   1285      0   stevel }
   1286      0   stevel 
   1287      0   stevel ctf_file_t *
   1288      0   stevel kmt_addr_to_ctf(mdb_tgt_t *t, uintptr_t addr)
   1289      0   stevel {
   1290      0   stevel 	kmt_data_t *kmt = t->t_data;
   1291      0   stevel 	kmt_module_t *km;
   1292      0   stevel 
   1293      0   stevel 	for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
   1294      0   stevel 	    km = mdb_list_next(km)) {
   1295      0   stevel 		if (addr - km->km_text_va < km->km_text_size ||
   1296      0   stevel 		    addr - km->km_data_va < km->km_data_size ||
   1297      0   stevel 		    addr - km->km_bss_va < km->km_bss_size)
   1298      0   stevel 			return (kmt_load_ctfdata(t, km));
   1299      0   stevel 	}
   1300      0   stevel 
   1301   1348  johnlev 	return (kmdb_module_addr_to_ctf(addr));
   1302      0   stevel }
   1303      0   stevel 
   1304      0   stevel ctf_file_t *
   1305      0   stevel kmt_name_to_ctf(mdb_tgt_t *t, const char *name)
   1306      0   stevel {
   1307      0   stevel 	kmt_data_t *kt = t->t_data;
   1308      0   stevel 	kmt_module_t *km;
   1309      0   stevel 
   1310   1348  johnlev 	if (name == MDB_TGT_OBJ_EXEC) {
   1311   3446      mrj 		name = KMT_CTFPARENT;
   1312   1348  johnlev 	} else if (name == MDB_TGT_OBJ_RTLD) {
   1313   3446      mrj 		name = kt->kmt_rtld_name;
   1314   1348  johnlev 	} else if (strncmp(name, "DMOD`", 5) == 0) {
   1315   1348  johnlev 		/* Request for CTF data for a DMOD symbol */
   1316   1348  johnlev 		return (kmdb_module_name_to_ctf(name + 5));
   1317   1348  johnlev 	}
   1318      0   stevel 
   1319   3446      mrj 	if ((km = kmt_module_by_name(kt, name)) != NULL)
   1320   3446      mrj 		return (kmt_load_ctfdata(t, km));
   1321      0   stevel 
   1322      0   stevel 	(void) set_errno(EMDB_NOOBJ);
   1323      0   stevel 	return (NULL);
   1324      0   stevel }
   1325      0   stevel 
   1326      0   stevel /*ARGSUSED*/
   1327      0   stevel static int
   1328      0   stevel kmt_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
   1329      0   stevel {
   1330      0   stevel 	int state;
   1331      0   stevel 
   1332      0   stevel 	bzero(tsp, sizeof (mdb_tgt_status_t));
   1333      0   stevel 
   1334      0   stevel 	switch ((state = kmdb_dpi_get_state(NULL))) {
   1335      0   stevel 	case DPI_STATE_INIT:
   1336      0   stevel 		tsp->st_state = MDB_TGT_RUNNING;
   1337      0   stevel 		tsp->st_pc = 0;
   1338      0   stevel 		break;
   1339      0   stevel 
   1340      0   stevel 	case DPI_STATE_STOPPED:
   1341      0   stevel 		tsp->st_state = MDB_TGT_STOPPED;
   1342      0   stevel 
   1343      0   stevel 		(void) kmdb_dpi_get_register("pc", &tsp->st_pc);
   1344      0   stevel 		break;
   1345      0   stevel 
   1346      0   stevel 	case DPI_STATE_FAULTED:
   1347      0   stevel 		tsp->st_state = MDB_TGT_STOPPED;
   1348      0   stevel 
   1349      0   stevel 		(void) kmdb_dpi_get_register("pc", &tsp->st_pc);
   1350      0   stevel 
   1351      0   stevel 		tsp->st_flags |= MDB_TGT_ISTOP;
   1352      0   stevel 		break;
   1353      0   stevel 
   1354      0   stevel 	case DPI_STATE_LOST:
   1355      0   stevel 		tsp->st_state = MDB_TGT_LOST;
   1356      0   stevel 
   1357      0   stevel 		(void) kmdb_dpi_get_register("pc", &tsp->st_pc);
   1358      0   stevel 		break;
   1359      0   stevel 	}
   1360      0   stevel 
   1361      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "kmt_status, dpi: %d tsp: %d, pc = %p %A\n",
   1362      0   stevel 	    state, tsp->st_state, (void *)tsp->st_pc, tsp->st_pc);
   1363      0   stevel 
   1364      0   stevel 	return (0);
   1365      0   stevel }
   1366      0   stevel 
   1367      0   stevel /*
   1368      0   stevel  * Invoked when kmt_defbp_enter_debugger is called, this routine activates and
   1369      0   stevel  * deactivates deferred breakpoints in response to module load and unload
   1370      0   stevel  * events.
   1371      0   stevel  */
   1372      0   stevel /*ARGSUSED*/
   1373      0   stevel static void
   1374      0   stevel kmt_defbp_event(mdb_tgt_t *t, int vid, void *private)
   1375      0   stevel {
   1376      0   stevel 	if (kmt_defbp_modchg_isload) {
   1377      0   stevel 		if (!mdb_tgt_sespec_activate_all(t) &&
   1378      0   stevel 		    (mdb.m_flags & MDB_FL_BPTNOSYMSTOP)) {
   1379      0   stevel 			/*
   1380      0   stevel 			 * We weren't able to activate the breakpoints.
   1381      0   stevel 			 * If so requested, we'll return without calling
   1382      0   stevel 			 * continue, thus throwing the user into the debugger.
   1383      0   stevel 			 */
   1384      0   stevel 			return;
   1385      0   stevel 		}
   1386      0   stevel 
   1387      0   stevel 	} else {
   1388      0   stevel 		mdb_sespec_t *sep, *nsep;
   1389      0   stevel 		const mdb_map_t *map, *bpmap;
   1390      0   stevel 		mdb_map_t modmap;
   1391      0   stevel 
   1392      0   stevel 		if ((map = kmt_addr_to_map(t,
   1393      0   stevel 		    (uintptr_t)kmt_defbp_modchg_modctl->mod_text)) == NULL) {
   1394      0   stevel 			warn("module unload notification for unknown module %s",
   1395      0   stevel 			    kmt_defbp_modchg_modctl->mod_modname);
   1396      0   stevel 			return; /* drop into the debugger */
   1397      0   stevel 		}
   1398      0   stevel 
   1399      0   stevel 		bcopy(map, &modmap, sizeof (mdb_map_t));
   1400      0   stevel 
   1401      0   stevel 		for (sep = mdb_list_next(&t->t_active); sep; sep = nsep) {
   1402      0   stevel 			nsep = mdb_list_next(sep);
   1403      0   stevel 
   1404      0   stevel 			if (sep->se_ops == &kmt_brkpt_ops) {
   1405      0   stevel 				kmt_brkpt_t *kb = sep->se_data;
   1406      0   stevel 
   1407      0   stevel 				if ((bpmap = kmt_addr_to_map(t,
   1408      0   stevel 				    kb->kb_addr)) == NULL ||
   1409      0   stevel 				    (bpmap->map_base == modmap.map_base &&
   1410      0   stevel 				    bpmap->map_size == modmap.map_size)) {
   1411      0   stevel 					mdb_tgt_sespec_idle_one(t, sep,
   1412      0   stevel 					    EMDB_NOMAP);
   1413      0   stevel 				}
   1414      0   stevel 			}
   1415      0   stevel 		}
   1416      0   stevel 	}
   1417      0   stevel 
   1418      0   stevel 	(void) mdb_tgt_continue(t, NULL);
   1419      0   stevel }
   1420      0   stevel 
   1421      0   stevel static void
   1422      0   stevel kmt_defbp_enter_debugger(void)
   1423      0   stevel {
   1424      0   stevel 	/*
   1425      0   stevel 	 * The debugger places a breakpoint here.  We can't have a simple
   1426      0   stevel 	 * nop function here, because GCC knows much more than we do, and
   1427   1234  johnlev 	 * will optimize away the call to it.
   1428      0   stevel 	 */
   1429      0   stevel 	(void) get_fp();
   1430      0   stevel }
   1431      0   stevel 
   1432      0   stevel /*
   1433      0   stevel  * This routine is called while the kernel is running.  It attempts to determine
   1434      0   stevel  * whether any deferred breakpoints exist for the module being changed (loaded
   1435      0   stevel  * or unloaded).  If any such breakpoints exist, the debugger will be entered to
   1436      0   stevel  * process them.
   1437      0   stevel  */
   1438      0   stevel static void
   1439      0   stevel kmt_defbp_modchg(struct modctl *mctl, int isload)
   1440      0   stevel {
   1441      0   stevel 	kmt_defbp_t *dbp;
   1442      0   stevel 
   1443      0   stevel 	kmt_defbp_lock = 1;
   1444      0   stevel 
   1445      0   stevel 	for (dbp = mdb_list_next(&kmt_defbp_list); dbp;
   1446      0   stevel 	    dbp = mdb_list_next(dbp)) {
   1447      0   stevel 		if (!dbp->dbp_ref)
   1448      0   stevel 			continue;
   1449      0   stevel 
   1450      0   stevel 		if (strcmp(mctl->mod_modname, dbp->dbp_objname) == 0) {
   1451      0   stevel 			/*
   1452      0   stevel 			 * Activate the breakpoint
   1453      0   stevel 			 */
   1454      0   stevel 			kmt_defbp_modchg_isload = isload;
   1455      0   stevel 			kmt_defbp_modchg_modctl = mctl;
   1456      0   stevel 
   1457      0   stevel 			kmt_defbp_enter_debugger();
   1458      0   stevel 			break;
   1459      0   stevel 		}
   1460      0   stevel 	}
   1461      0   stevel 
   1462      0   stevel 	kmt_defbp_lock = 0;
   1463      0   stevel }
   1464      0   stevel 
   1465      0   stevel /*ARGSUSED*/
   1466      0   stevel static int
   1467      0   stevel kmt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
   1468      0   stevel {
   1469      0   stevel 	int n;
   1470      0   stevel 
   1471      0   stevel 	kmdb_dpi_resume();
   1472      0   stevel 
   1473      0   stevel 	/*
   1474      0   stevel 	 * The order of the following two calls is important.  If there are
   1475      0   stevel 	 * load acks on the work queue, we'll initialize the dmods they
   1476      0   stevel 	 * represent.  This will involve a call to _mdb_init, which may very
   1477      0   stevel 	 * well result in a symbol lookup.  If we haven't resynced our view
   1478      0   stevel 	 * of symbols with the current state of the world, this lookup could
   1479      0   stevel 	 * end very badly.  We therefore make sure to sync before processing
   1480      0   stevel 	 * the work queue.
   1481      0   stevel 	 */
   1482      0   stevel 	kmt_sync(t);
   1483      0   stevel 	kmdb_dpi_process_work_queue();
   1484      0   stevel 
   1485      0   stevel 	if (kmdb_kdi_get_unload_request())
   1486      0   stevel 		t->t_flags |= MDB_TGT_F_UNLOAD;
   1487      0   stevel 
   1488      0   stevel 	(void) mdb_tgt_status(t, &t->t_status);
   1489      0   stevel 
   1490      0   stevel 	if ((n = kmt_dmod_status(NULL, KMDB_MC_STATE_LOADING) +
   1491      0   stevel 	    kmt_dmod_status(NULL, KMDB_MC_STATE_UNLOADING)) != 0) {
   1492      0   stevel 		mdb_warn("%d dmod load%c/unload%c pending\n", n,
   1493      0   stevel 		    "s"[n == 1], "s"[n == 1]);
   1494      0   stevel 	}
   1495      0   stevel 
   1496      0   stevel 	return (0);
   1497      0   stevel }
   1498      0   stevel 
   1499      0   stevel /*ARGSUSED*/
   1500      0   stevel static int
   1501      0   stevel kmt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
   1502      0   stevel {
   1503      0   stevel 	int rc;
   1504      0   stevel 
   1505      0   stevel 	if ((rc = kmdb_dpi_step()) == 0)
   1506      0   stevel 		(void) mdb_tgt_status(t, &t->t_status);
   1507      0   stevel 
   1508      0   stevel 	return (rc);
   1509      0   stevel }
   1510      0   stevel 
   1511      0   stevel static int
   1512      0   stevel kmt_defbp_activate(mdb_tgt_t *t)
   1513      0   stevel {
   1514      0   stevel 	kmdb_dpi_modchg_register(kmt_defbp_modchg);
   1515      0   stevel 
   1516      0   stevel 	/*
   1517      0   stevel 	 * The routines that add and arm breakpoints will check for the proper
   1518      0   stevel 	 * DTrace state, but they'll just put this breakpoint on the idle list
   1519      0   stevel 	 * if DTrace is active.  It'll correctly move to the active list when
   1520      0   stevel 	 * DTrace deactivates, but that's insufficient for our purposes -- we
   1521      0   stevel 	 * need to do extra processing at that point.  We won't get to do said
   1522      0   stevel 	 * processing with with a normal idle->active transition, so we just
   1523      0   stevel 	 * won't add it add it until we're sure that it'll stick.
   1524      0   stevel 	 */
   1525      0   stevel 
   1526      0   stevel 	if (kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_DTRACE_ACTIVE)
   1527      0   stevel 		return (set_errno(EMDB_DTACTIVE));
   1528      0   stevel 
   1529      0   stevel 	kmt_defbp_bpspec = mdb_tgt_add_vbrkpt(t,
   1530      0   stevel 	    (uintptr_t)kmt_defbp_enter_debugger,
   1531      0   stevel 	    MDB_TGT_SPEC_HIDDEN, kmt_defbp_event, NULL);
   1532      0   stevel 
   1533      0   stevel 	return (0);
   1534      0   stevel }
   1535      0   stevel 
   1536      0   stevel static void
   1537      0   stevel kmt_defbp_deactivate(mdb_tgt_t *t)
   1538      0   stevel {
   1539      0   stevel 	kmdb_dpi_modchg_cancel();
   1540      0   stevel 
   1541      0   stevel 	if (kmt_defbp_bpspec != 0) {
   1542      0   stevel 		if (t != NULL)
   1543      0   stevel 			(void) mdb_tgt_vespec_delete(t, kmt_defbp_bpspec);
   1544      0   stevel 
   1545      0   stevel 		kmt_defbp_bpspec = 0;
   1546      0   stevel 	}
   1547      0   stevel }
   1548      0   stevel 
   1549      0   stevel static kmt_defbp_t *
   1550      0   stevel kmt_defbp_create(mdb_tgt_t *t, const char *objname, const char *symname)
   1551      0   stevel {
   1552      0   stevel 	kmt_defbp_t *dbp = mdb_alloc(sizeof (kmt_defbp_t), UM_SLEEP);
   1553      0   stevel 
   1554      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "defbp_create %s`%s\n", objname, symname);
   1555      0   stevel 
   1556      0   stevel 	dbp->dbp_objname = strdup(objname);
   1557      0   stevel 	dbp->dbp_symname = strdup(symname);
   1558      0   stevel 	dbp->dbp_ref = 1;
   1559      0   stevel 
   1560      0   stevel 	kmt_defbp_num++;
   1561      0   stevel 
   1562      0   stevel 	if (kmt_defbp_num == 1 || kmt_defbp_bpspec == 0) {
   1563      0   stevel 		if (kmt_defbp_activate(t) < 0)
   1564      0   stevel 			warn("failed to activate deferred breakpoints");
   1565      0   stevel 	}
   1566      0   stevel 
   1567      0   stevel 	mdb_list_append(&kmt_defbp_list, dbp);
   1568      0   stevel 
   1569      0   stevel 	return (dbp);
   1570      0   stevel }
   1571      0   stevel 
   1572      0   stevel static void
   1573      0   stevel kmt_defbp_destroy(kmt_defbp_t *dbp)
   1574      0   stevel {
   1575      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "defbp_destroy %s`%s\n", dbp->dbp_objname,
   1576      0   stevel 	    dbp->dbp_symname);
   1577      0   stevel 
   1578      0   stevel 	mdb_list_delete(&kmt_defbp_list, dbp);
   1579      0   stevel 
   1580      0   stevel 	strfree(dbp->dbp_objname);
   1581      0   stevel 	strfree(dbp->dbp_symname);
   1582      0   stevel 	mdb_free(dbp, sizeof (kmt_defbp_t));
   1583      0   stevel }
   1584      0   stevel 
   1585      0   stevel static void
   1586      0   stevel kmt_defbp_prune_common(int all)
   1587      0   stevel {
   1588      0   stevel 	kmt_defbp_t *dbp, *ndbp;
   1589      0   stevel 
   1590      0   stevel 	/* We can't remove items from the list while the driver is using it. */
   1591      0   stevel 	if (kmt_defbp_lock)
   1592      0   stevel 		return;
   1593      0   stevel 
   1594      0   stevel 	for (dbp = mdb_list_next(&kmt_defbp_list); dbp != NULL; dbp = ndbp) {
   1595      0   stevel 		ndbp = mdb_list_next(dbp);
   1596      0   stevel 
   1597      0   stevel 		if (!all && dbp->dbp_ref)
   1598      0   stevel 			continue;
   1599      0   stevel 
   1600      0   stevel 		kmt_defbp_destroy(dbp);
   1601      0   stevel 	}
   1602      0   stevel }
   1603      0   stevel 
   1604      0   stevel static void
   1605      0   stevel kmt_defbp_prune(void)
   1606      0   stevel {
   1607      0   stevel 	kmt_defbp_prune_common(0);
   1608      0   stevel }
   1609      0   stevel 
   1610      0   stevel static void
   1611      0   stevel kmt_defbp_destroy_all(void)
   1612      0   stevel {
   1613      0   stevel 	kmt_defbp_prune_common(1);
   1614      0   stevel }
   1615      0   stevel 
   1616      0   stevel static void
   1617      0   stevel kmt_defbp_delete(mdb_tgt_t *t, kmt_defbp_t *dbp)
   1618      0   stevel {
   1619      0   stevel 	dbp->dbp_ref = 0;
   1620      0   stevel 
   1621      0   stevel 	ASSERT(kmt_defbp_num > 0);
   1622      0   stevel 	kmt_defbp_num--;
   1623      0   stevel 
   1624      0   stevel 	if (kmt_defbp_num == 0)
   1625      0   stevel 		kmt_defbp_deactivate(t);
   1626      0   stevel 
   1627      0   stevel 	kmt_defbp_prune();
   1628      0   stevel }
   1629      0   stevel 
   1630      0   stevel static int
   1631      0   stevel kmt_brkpt_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
   1632      0   stevel {
   1633      0   stevel 	mdb_tgt_status_t tsp;
   1634      0   stevel 	kmt_bparg_t *ka = args;
   1635      0   stevel 	kmt_brkpt_t *kb;
   1636      0   stevel 	GElf_Sym s;
   1637      0   stevel 	mdb_instr_t instr;
   1638      0   stevel 
   1639      0   stevel 	(void) mdb_tgt_status(t, &tsp);
   1640      0   stevel 	if (tsp.st_state != MDB_TGT_RUNNING && tsp.st_state != MDB_TGT_STOPPED)
   1641      0   stevel 		return (set_errno(EMDB_NOPROC));
   1642      0   stevel 
   1643      0   stevel 	if (ka->ka_symbol != NULL) {
   1644      0   stevel 		if (mdb_tgt_lookup_by_scope(t, ka->ka_symbol, &s, NULL) == -1) {
   1645      0   stevel 			if (errno != EMDB_NOOBJ && !(errno == EMDB_NOSYM &&
   1646      0   stevel 			    !(mdb.m_flags & MDB_FL_BPTNOSYMSTOP))) {
   1647      0   stevel 				warn("breakpoint %s activation failed",
   1648      0   stevel 				    ka->ka_symbol);
   1649      0   stevel 			}
   1650      0   stevel 			return (-1); /* errno is set for us */
   1651      0   stevel 		}
   1652      0   stevel 
   1653      0   stevel 		ka->ka_addr = (uintptr_t)s.st_value;
   1654      0   stevel 	}
   1655      0   stevel 
   1656      0   stevel #ifdef __sparc
   1657      0   stevel 	if (ka->ka_addr & 3)
   1658      0   stevel 		return (set_errno(EMDB_BPALIGN));
   1659      0   stevel #endif
   1660      0   stevel 
   1661      0   stevel 	if (mdb_vread(&instr, sizeof (instr), ka->ka_addr) != sizeof (instr))
   1662      0   stevel 		return (-1); /* errno is set for us */
   1663      0   stevel 
   1664      0   stevel 	if (kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_DTRACE_ACTIVE)
   1665      0   stevel 		warn("breakpoint will not arm until DTrace is inactive\n");
   1666      0   stevel 
   1667      0   stevel 	kb = mdb_zalloc(sizeof (kmt_brkpt_t), UM_SLEEP);
   1668      0   stevel 	kb->kb_addr = ka->ka_addr;
   1669      0   stevel 	sep->se_data = kb;
   1670      0   stevel 
   1671      0   stevel 	return (0);
   1672      0   stevel }
   1673      0   stevel 
   1674      0   stevel /*ARGSUSED*/
   1675      0   stevel static void
   1676      0   stevel kmt_brkpt_dtor(mdb_tgt_t *t, mdb_sespec_t *sep)
   1677      0   stevel {
   1678      0   stevel 	mdb_free(sep->se_data, sizeof (kmt_brkpt_t));
   1679      0   stevel }
   1680      0   stevel 
   1681      0   stevel /*ARGSUSED*/
   1682      0   stevel static char *
   1683      0   stevel kmt_brkpt_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep,
   1684      0   stevel     mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes)
   1685      0   stevel {
   1686      0   stevel 	uintptr_t addr = NULL;
   1687      0   stevel 
   1688      0   stevel 	if (vep != NULL) {
   1689      0   stevel 		kmt_bparg_t *ka = vep->ve_args;
   1690      0   stevel 
   1691      0   stevel 		if (ka->ka_symbol != NULL) {
   1692      0   stevel 			(void) mdb_iob_snprintf(buf, nbytes, "stop at %s",
   1693      0   stevel 			    ka->ka_symbol);
   1694      0   stevel 		} else {
   1695      0   stevel 			(void) mdb_iob_snprintf(buf, nbytes, "stop at %a",
   1696      0   stevel 			    ka->ka_addr);
   1697      0   stevel 			addr = ka->ka_addr;
   1698      0   stevel 		}
   1699      0   stevel 
   1700      0   stevel 	} else {
   1701      0   stevel 		addr = ((kmt_brkpt_t *)sep->se_data)->kb_addr;
   1702      0   stevel 		(void) mdb_iob_snprintf(buf, nbytes, "stop at %a", addr);
   1703      0   stevel 	}
   1704      0   stevel 
   1705      0   stevel 	sp->spec_base = addr;
   1706      0   stevel 	sp->spec_size = sizeof (mdb_instr_t);
   1707      0   stevel 
   1708      0   stevel 	return (buf);
   1709      0   stevel }
   1710      0   stevel 
   1711      0   stevel static int
   1712      0   stevel kmt_brkpt_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
   1713      0   stevel {
   1714      0   stevel 	kmt_brkpt_t *kb = sep->se_data;
   1715      0   stevel 	kmt_bparg_t *ka = args;
   1716      0   stevel 	GElf_Sym sym;
   1717      0   stevel 
   1718      0   stevel 	if (ka->ka_symbol != NULL) {
   1719      0   stevel 		return (mdb_tgt_lookup_by_scope(t, ka->ka_symbol,
   1720      0   stevel 		    &sym, NULL) == 0 && sym.st_value == kb->kb_addr);
   1721      0   stevel 	}
   1722      0   stevel 
   1723      0   stevel 	return (ka->ka_addr == kb->kb_addr);
   1724      0   stevel }
   1725      0   stevel 
   1726      0   stevel /*ARGSUSED*/
   1727      0   stevel static int
   1728      0   stevel kmt_brkpt_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args)
   1729      0   stevel {
   1730      0   stevel 	kmt_bparg_t *ka1 = vep->ve_args;
   1731      0   stevel 	kmt_bparg_t *ka2 = args;
   1732      0   stevel 
   1733      0   stevel 	if (ka1->ka_symbol != NULL && ka2->ka_symbol != NULL)
   1734      0   stevel 		return (strcmp(ka1->ka_symbol, ka2->ka_symbol) == 0);
   1735      0   stevel 
   1736      0   stevel 	if (ka1->ka_symbol == NULL && ka2->ka_symbol == NULL)
   1737      0   stevel 		return (ka1->ka_addr == ka2->ka_addr);
   1738      0   stevel 
   1739      0   stevel 	return (0); /* fail if one is symbolic, other is an explicit address */
   1740      0   stevel }
   1741      0   stevel 
   1742      0   stevel static int
   1743      0   stevel kmt_brkpt_arm(mdb_tgt_t *t, mdb_sespec_t *sep)
   1744      0   stevel {
   1745      0   stevel 	kmt_data_t *kmt = t->t_data;
   1746      0   stevel 	kmt_brkpt_t *kb = sep->se_data;
   1747      0   stevel 	int rv;
   1748      0   stevel 
   1749      0   stevel 	if (kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_DTRACE_ACTIVE)
   1750      0   stevel 		return (set_errno(EMDB_DTACTIVE));
   1751      0   stevel 
   1752      0   stevel 	if ((rv = kmdb_dpi_brkpt_arm(kb->kb_addr, &kb->kb_oinstr)) != 0)
   1753      0   stevel 		return (rv);
   1754      0   stevel 
   1755      0   stevel 	if (kmt->kmt_narmedbpts++ == 0)
   1756      0   stevel 		(void) kmdb_kdi_dtrace_set(KDI_DTSET_KMDB_BPT_ACTIVATE);
   1757      0   stevel 
   1758      0   stevel 	return (0);
   1759      0   stevel }
   1760      0   stevel 
   1761      0   stevel static int
   1762      0   stevel kmt_brkpt_disarm(mdb_tgt_t *t, mdb_sespec_t *sep)
   1763      0   stevel {
   1764      0   stevel 	kmt_data_t *kmt = t->t_data;
   1765      0   stevel 	kmt_brkpt_t *kb = sep->se_data;
   1766      0   stevel 	int rv;
   1767      0   stevel 
   1768      0   stevel 	ASSERT(kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_KMDB_BPT_ACTIVE);
   1769      0   stevel 
   1770      0   stevel 	if ((rv = kmdb_dpi_brkpt_disarm(kb->kb_addr, kb->kb_oinstr)) != 0)
   1771      0   stevel 		return (rv);
   1772      0   stevel 
   1773      0   stevel 	if (--kmt->kmt_narmedbpts == 0)
   1774      0   stevel 		(void) kmdb_kdi_dtrace_set(KDI_DTSET_KMDB_BPT_DEACTIVATE);
   1775      0   stevel 
   1776      0   stevel 	return (0);
   1777      0   stevel }
   1778      0   stevel 
   1779      0   stevel /*
   1780      0   stevel  * Determine whether the specified sespec is an armed watchpoint that overlaps
   1781      0   stevel  * with the given breakpoint and has the given flags set.  We use this to find
   1782      0   stevel  * conflicts with breakpoints, below.
   1783      0   stevel  */
   1784      0   stevel static int
   1785      0   stevel kmt_wp_overlap(mdb_sespec_t *sep, kmt_brkpt_t *kb, int flags)
   1786      0   stevel {
   1787      0   stevel 	const kmdb_wapt_t *wp = sep->se_data;
   1788      0   stevel 
   1789      0   stevel 	return (sep->se_state == MDB_TGT_SPEC_ARMED &&
   1790      0   stevel 	    sep->se_ops == &kmt_wapt_ops && (wp->wp_wflags & flags) &&
   1791      0   stevel 	    kb->kb_addr - wp->wp_addr < wp->wp_size);
   1792      0   stevel }
   1793      0   stevel 
   1794      0   stevel /*
   1795      0   stevel  * We step over breakpoints using our single-stepper.  If a conflicting
   1796      0   stevel  * watchpoint is present, we must temporarily remove it before stepping over the
   1797      0   stevel  * breakpoint so we don't immediately re-trigger the watchpoint.  We know the
   1798      0   stevel  * watchpoint has already triggered on our trap instruction as part of fetching
   1799      0   stevel  * it.  Before we return, we must re-install any disabled watchpoints.
   1800      0   stevel  */
   1801      0   stevel static int
   1802      0   stevel kmt_brkpt_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
   1803      0   stevel {
   1804      0   stevel 	kmt_brkpt_t *kb = sep->se_data;
   1805      0   stevel 	int status = -1;
   1806      0   stevel 	int error;
   1807      0   stevel 
   1808      0   stevel 	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
   1809      0   stevel 		if (kmt_wp_overlap(sep, kb, MDB_TGT_WA_X))
   1810      0   stevel 			(void) kmdb_dpi_wapt_disarm(sep->se_data);
   1811      0   stevel 	}
   1812      0   stevel 
   1813      0   stevel 	if (kmdb_dpi_brkpt_disarm(kb->kb_addr, kb->kb_oinstr) == 0 &&
   1814      0   stevel 	    kmt_step(t, tsp) == 0)
   1815      0   stevel 		status = kmt_status(t, tsp);
   1816      0   stevel 
   1817      0   stevel 	error = errno; /* save errno from disarm, step, or status */
   1818      0   stevel 
   1819      0   stevel 	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
   1820      0   stevel 		if (kmt_wp_overlap(sep, kb, MDB_TGT_WA_X))
   1821      0   stevel 			kmdb_dpi_wapt_arm(sep->se_data);
   1822      0   stevel 	}
   1823      0   stevel 
   1824      0   stevel 	(void) set_errno(error);
   1825      0   stevel 	return (status);
   1826      0   stevel }
   1827      0   stevel 
   1828      0   stevel /*ARGSUSED*/
   1829      0   stevel static int
   1830      0   stevel kmt_brkpt_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
   1831      0   stevel {
   1832      0   stevel 	kmt_brkpt_t *kb = sep->se_data;
   1833      0   stevel 	int state, why;
   1834      0   stevel 	kreg_t pc;
   1835      0   stevel 
   1836      0   stevel 	state = kmdb_dpi_get_state(&why);
   1837      0   stevel 	(void) kmdb_dpi_get_register("pc", &pc);
   1838      0   stevel 
   1839      0   stevel 	return (state == DPI_STATE_FAULTED && why == DPI_STATE_WHY_BKPT &&
   1840      0   stevel 	    pc == kb->kb_addr);
   1841      0   stevel }
   1842      0   stevel 
   1843      0   stevel static const mdb_se_ops_t kmt_brkpt_ops = {
   1844      0   stevel 	kmt_brkpt_ctor,		/* se_ctor */
   1845      0   stevel 	kmt_brkpt_dtor,		/* se_dtor */
   1846      0   stevel 	kmt_brkpt_info,		/* se_info */
   1847      0   stevel 	kmt_brkpt_secmp,	/* se_secmp */
   1848      0   stevel 	kmt_brkpt_vecmp,	/* se_vecmp */
   1849      0   stevel 	kmt_brkpt_arm,		/* se_arm */
   1850      0   stevel 	kmt_brkpt_disarm,	/* se_disarm */
   1851      0   stevel 	kmt_brkpt_cont,		/* se_cont */
   1852      0   stevel 	kmt_brkpt_match		/* se_match */
   1853      0   stevel };
   1854      0   stevel 
   1855      0   stevel static int
   1856      0   stevel kmt_wapt_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
   1857      0   stevel {
   1858      0   stevel 	mdb_tgt_status_t tsp;
   1859      0   stevel 	kmdb_wapt_t *vwp = args;
   1860      0   stevel 	kmdb_wapt_t *swp;
   1861      0   stevel 
   1862      0   stevel 	(void) mdb_tgt_status(t, &tsp);
   1863      0   stevel 	if (tsp.st_state != MDB_TGT_RUNNING && tsp.st_state != MDB_TGT_STOPPED)
   1864      0   stevel 		return (set_errno(EMDB_NOPROC));
   1865      0   stevel 
   1866      0   stevel 	swp = mdb_alloc(sizeof (kmdb_wapt_t), UM_SLEEP);
   1867      0   stevel 	bcopy(vwp, swp, sizeof (kmdb_wapt_t));
   1868      0   stevel 
   1869      0   stevel 	if (kmdb_dpi_wapt_reserve(swp) < 0) {
   1870      0   stevel 		mdb_free(swp, sizeof (kmdb_wapt_t));
   1871      0   stevel 		return (-1); /* errno is set for us */
   1872      0   stevel 	}
   1873      0   stevel 
   1874      0   stevel 	sep->se_data = swp;
   1875      0   stevel 
   1876      0   stevel 	return (0);
   1877      0   stevel }
   1878      0   stevel 
   1879      0   stevel /*ARGSUSED*/
   1880      0   stevel static void
   1881      0   stevel kmt_wapt_dtor(mdb_tgt_t *t, mdb_sespec_t *sep)
   1882      0   stevel {
   1883      0   stevel 	kmdb_wapt_t *wp = sep->se_data;
   1884      0   stevel 
   1885      0   stevel 	kmdb_dpi_wapt_release(wp);
   1886      0   stevel 	mdb_free(wp, sizeof (kmdb_wapt_t));
   1887      0   stevel }
   1888      0   stevel 
   1889      0   stevel /*ARGSUSED*/
   1890      0   stevel static char *
   1891      0   stevel kmt_wapt_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep,
   1892      0   stevel     mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes)
   1893      0   stevel {
   1894      0   stevel 	kmdb_wapt_t *wp = vep != NULL ? vep->ve_args : sep->se_data;
   1895      0   stevel 	const char *fmt;
   1896      0   stevel 	char desc[24];
   1897      0   stevel 
   1898      0   stevel 	ASSERT(wp->wp_wflags != 0);
   1899      0   stevel 	desc[0] = '\0';
   1900      0   stevel 
   1901      0   stevel 	switch (wp->wp_wflags) {
   1902      0   stevel 	case MDB_TGT_WA_R:
   1903      0   stevel 		(void) strcat(desc, "/read");
   1904      0   stevel 		break;
   1905      0   stevel 	case MDB_TGT_WA_W:
   1906      0   stevel 		(void) strcat(desc, "/write");
   1907      0   stevel 		break;
   1908      0   stevel 	case MDB_TGT_WA_X:
   1909      0   stevel 		(void) strcat(desc, "/exec");
   1910      0   stevel 		break;
   1911      0   stevel 	default:
   1912      0   stevel 		if (wp->wp_wflags & MDB_TGT_WA_R)
   1913      0   stevel 			(void) strcat(desc, "/r");
   1914      0   stevel 		if (wp->wp_wflags & MDB_TGT_WA_W)
   1915      0   stevel 			(void) strcat(desc, "/w");
   1916      0   stevel 		if (wp->wp_wflags & MDB_TGT_WA_X)
   1917      0   stevel 			(void) strcat(desc, "/x");
   1918      0   stevel 	}
   1919      0   stevel 
   1920      0   stevel 	switch (wp->wp_type) {
   1921      0   stevel 	case DPI_WAPT_TYPE_PHYS:
   1922      0   stevel 		fmt = "stop on %s of phys [%p, %p)";
   1923      0   stevel 		break;
   1924      0   stevel 
   1925      0   stevel 	case DPI_WAPT_TYPE_VIRT:
   1926      0   stevel 		fmt = "stop on %s of [%la, %la)";
   1927      0   stevel 		break;
   1928      0   stevel 
   1929      0   stevel 	case DPI_WAPT_TYPE_IO:
   1930      0   stevel 		if (wp->wp_size == 1)
   1931      0   stevel 			fmt = "stop on %s of I/O port %p";
   1932      0   stevel 		else
   1933      0   stevel 			fmt = "stop on %s of I/O port [%p, %p)";
   1934      0   stevel 		break;
   1935      0   stevel 	}
   1936      0   stevel 
   1937      0   stevel 	(void) mdb_iob_snprintf(buf, nbytes, fmt, desc + 1, wp->wp_addr,
   1938      0   stevel 	    wp->wp_addr + wp->wp_size);
   1939      0   stevel 
   1940      0   stevel 	sp->spec_base = wp->wp_addr;
   1941      0   stevel 	sp->spec_size = wp->wp_size;
   1942      0   stevel 
   1943      0   stevel 	return (buf);
   1944      0   stevel }
   1945      0   stevel 
   1946      0   stevel /*ARGSUSED*/
   1947      0   stevel static int
   1948      0   stevel kmt_wapt_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
   1949      0   stevel {
   1950      0   stevel 	kmdb_wapt_t *wp1 = sep->se_data;
   1951      0   stevel 	kmdb_wapt_t *wp2 = args;
   1952      0   stevel 
   1953      0   stevel 	return (wp1->wp_addr == wp2->wp_addr && wp1->wp_size == wp2->wp_size &&
   1954      0   stevel 	    wp1->wp_wflags == wp2->wp_wflags);
   1955      0   stevel }
   1956      0   stevel 
   1957      0   stevel /*ARGSUSED*/
   1958      0   stevel static int
   1959      0   stevel kmt_wapt_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args)
   1960      0   stevel {
   1961      0   stevel 	kmdb_wapt_t *wp1 = vep->ve_args;
   1962      0   stevel 	kmdb_wapt_t *wp2 = args;
   1963      0   stevel 
   1964      0   stevel 	return (wp1->wp_addr == wp2->wp_addr && wp1->wp_size == wp2->wp_size &&
   1965      0   stevel 	    wp1->wp_wflags == wp2->wp_wflags);
   1966      0   stevel }
   1967      0   stevel 
   1968      0   stevel /*ARGSUSED*/
   1969      0   stevel static int
   1970      0   stevel kmt_wapt_arm(mdb_tgt_t *t, mdb_sespec_t *sep)
   1971      0   stevel {
   1972      0   stevel 	kmdb_dpi_wapt_arm(sep->se_data);
   1973      0   stevel 
   1974      0   stevel 	return (0);
   1975      0   stevel }
   1976      0   stevel 
   1977      0   stevel /*ARGSUSED*/
   1978      0   stevel static int
   1979      0   stevel kmt_wapt_disarm(mdb_tgt_t *t, mdb_sespec_t *sep)
   1980      0   stevel {
   1981      0   stevel 	kmdb_dpi_wapt_disarm(sep->se_data);
   1982      0   stevel 
   1983      0   stevel 	return (0);
   1984      0   stevel }
   1985      0   stevel 
   1986      0   stevel /*
   1987      0   stevel  * Determine whether the specified sespec is an armed breakpoint at the given
   1988      0   stevel  * %pc.  We use this to find conflicts with watchpoints below.
   1989      0   stevel  */
   1990      0   stevel static int
   1991      0   stevel kmt_bp_overlap(mdb_sespec_t *sep, uintptr_t pc)
   1992      0   stevel {
   1993      0   stevel 	kmt_brkpt_t *kb = sep->se_data;
   1994      0   stevel 
   1995      0   stevel 	return (sep->se_state == MDB_TGT_SPEC_ARMED &&
   1996      0   stevel 	    sep->se_ops == &kmt_brkpt_ops && kb->kb_addr == pc);
   1997      0   stevel }
   1998      0   stevel 
   1999      0   stevel /*
   2000      0   stevel  * We step over watchpoints using our single-stepper.  If a conflicting
   2001      0   stevel  * breakpoint is present, we must temporarily disarm it before stepping over
   2002      0   stevel  * the watchpoint so we do not immediately re-trigger the breakpoint.  This is
   2003      0   stevel  * similar to the case handled in kmt_brkpt_cont(), above.
   2004      0   stevel  */
   2005      0   stevel static int
   2006      0   stevel kmt_wapt_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
   2007      0   stevel {
   2008      0   stevel 	mdb_sespec_t *bep = NULL;
   2009      0   stevel 	int status = -1;
   2010      0   stevel 	int error, why;
   2011      0   stevel 
   2012      0   stevel 	/*
   2013      0   stevel 	 * If we stopped for anything other than a watchpoint, check to see
   2014      0   stevel 	 * if there's a breakpoint here.
   2015      0   stevel 	 */
   2016      0   stevel 	if (!(kmdb_dpi_get_state(&why) == DPI_STATE_FAULTED &&
   2017      0   stevel 	    (why == DPI_STATE_WHY_V_WAPT || why == DPI_STATE_WHY_P_WAPT))) {
   2018      0   stevel 		kreg_t pc;
   2019      0   stevel 
   2020      0   stevel 		(void) kmdb_dpi_get_register("pc", &pc);
   2021      0   stevel 
   2022      0   stevel 		for (bep = mdb_list_next(&t->t_active); bep != NULL;
   2023      0   stevel 		    bep = mdb_list_next(bep)) {
   2024      0   stevel 			if (kmt_bp_overlap(bep, pc)) {
   2025      0   stevel 				(void) bep->se_ops->se_disarm(t, bep);
   2026      0   stevel 				bep->se_state = MDB_TGT_SPEC_ACTIVE;
   2027      0   stevel 				break;
   2028      0   stevel 			}
   2029      0   stevel 		}
   2030      0   stevel 	}
   2031      0   stevel 
   2032      0   stevel 	kmdb_dpi_wapt_disarm(sep->se_data);
   2033      0   stevel 	if (kmt_step(t, tsp) == 0)
   2034      0   stevel 		status = kmt_status(t, tsp);
   2035      0   stevel 
   2036      0   stevel 	error = errno; /* save errno from step or status */
   2037      0   stevel 
   2038      0   stevel 	if (bep != NULL)
   2039      0   stevel 		mdb_tgt_sespec_arm_one(t, bep);
   2040      0   stevel 
   2041      0   stevel 	(void) set_errno(error);
   2042      0   stevel 	return (status);
   2043      0   stevel }
   2044      0   stevel 
   2045      0   stevel /*ARGSUSED*/
   2046      0   stevel static int
   2047      0   stevel kmt_wapt_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
   2048      0   stevel {
   2049      0   stevel 	return (kmdb_dpi_wapt_match(sep->se_data));
   2050      0   stevel }
   2051      0   stevel 
   2052      0   stevel static const mdb_se_ops_t kmt_wapt_ops = {
   2053      0   stevel 	kmt_wapt_ctor,		/* se_ctor */
   2054      0   stevel 	kmt_wapt_dtor,		/* se_dtor */
   2055      0   stevel 	kmt_wapt_info,		/* se_info */
   2056      0   stevel 	kmt_wapt_secmp,		/* se_secmp */
   2057      0   stevel 	kmt_wapt_vecmp,		/* se_vecmp */
   2058      0   stevel 	kmt_wapt_arm,		/* se_arm */
   2059      0   stevel 	kmt_wapt_disarm,	/* se_disarm */
   2060      0   stevel 	kmt_wapt_cont,		/* se_cont */
   2061      0   stevel 	kmt_wapt_match		/* se_match */
   2062      0   stevel };
   2063      0   stevel 
   2064      0   stevel /*ARGSUSED*/
   2065      0   stevel static int
   2066      0   stevel kmt_trap_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
   2067      0   stevel {
   2068      0   stevel 	sep->se_data = args; /* trap number */
   2069      0   stevel 
   2070      0   stevel 	return (0);
   2071      0   stevel }
   2072      0   stevel 
   2073      0   stevel /*ARGSUSED*/
   2074      0   stevel static char *
   2075      0   stevel kmt_trap_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep,
   2076      0   stevel     mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes)
   2077      0   stevel {
   2078      0   stevel 	const char *name;
   2079      0   stevel 	int trapnum;
   2080      0   stevel 
   2081      0   stevel 	if (vep != NULL)
   2082      0   stevel 		trapnum = (intptr_t)vep->ve_args;
   2083      0   stevel 	else
   2084      0   stevel 		trapnum = (intptr_t)sep->se_data;
   2085      0   stevel 
   2086      0   stevel 	if (trapnum == KMT_TRAP_ALL)
   2087      0   stevel 		name = "any trap";
   2088      0   stevel 	else if (trapnum == KMT_TRAP_NOTENUM)
   2089      0   stevel 		name = "miscellaneous trap";
   2090      0   stevel 	else
   2091      0   stevel 		name = kmt_trapname(trapnum);
   2092      0   stevel 
   2093      0   stevel 	(void) mdb_iob_snprintf(buf, nbytes, "single-step stop on %s", name);
   2094      0   stevel 
   2095      0   stevel 	return (buf);
   2096      0   stevel }
   2097      0   stevel 
   2098      0   stevel /*ARGSUSED2*/
   2099      0   stevel static int
   2100      0   stevel kmt_trap_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
   2101      0   stevel {
   2102      0   stevel 	int spectt = (intptr_t)sep->se_data;
   2103      0   stevel 	kmt_data_t *kmt = t->t_data;
   2104      0   stevel 	kreg_t tt;
   2105      0   stevel 
   2106      0   stevel 	(void) kmdb_dpi_get_register("tt", &tt);
   2107      0   stevel 
   2108      0   stevel 	switch (spectt) {
   2109      0   stevel 	case KMT_TRAP_ALL:
   2110      0   stevel 		return (1);
   2111      0   stevel 	case KMT_TRAP_NOTENUM:
   2112      0   stevel 		return (tt > kmt->kmt_trapmax ||
   2113      0   stevel 		    !BT_TEST(kmt->kmt_trapmap, tt));
   2114      0   stevel 	default:
   2115      0   stevel 		return (tt == spectt);
   2116      0   stevel 	}
   2117      0   stevel }
   2118      0   stevel 
   2119      0   stevel static const mdb_se_ops_t kmt_trap_ops = {
   2120      0   stevel 	kmt_trap_ctor,		/* se_ctor */
   2121      0   stevel 	no_se_dtor,		/* se_dtor */
   2122      0   stevel 	kmt_trap_info,		/* se_info */
   2123      0   stevel 	no_se_secmp,		/* se_secmp */
   2124      0   stevel 	no_se_vecmp,		/* se_vecmp */
   2125      0   stevel 	no_se_arm,		/* se_arm */
   2126      0   stevel 	no_se_disarm,		/* se_disarm */
   2127      0   stevel 	no_se_cont,		/* se_cont */
   2128      0   stevel 	kmt_trap_match		/* se_match */
   2129      0   stevel };
   2130      0   stevel 
   2131      0   stevel static void
   2132      0   stevel kmt_bparg_dtor(mdb_vespec_t *vep)
   2133      0   stevel {
   2134      0   stevel 	kmt_bparg_t *ka = vep->ve_args;
   2135      0   stevel 
   2136      0   stevel 	if (ka->ka_symbol != NULL)
   2137      0   stevel 		strfree(ka->ka_symbol);
   2138      0   stevel 
   2139      0   stevel 	if (ka->ka_defbp != NULL)
   2140      0   stevel 		kmt_defbp_delete(mdb.m_target, ka->ka_defbp);
   2141      0   stevel 
   2142      0   stevel 	mdb_free(ka, sizeof (kmt_bparg_t));
   2143      0   stevel }
   2144      0   stevel 
   2145      0   stevel static int
   2146      0   stevel kmt_add_vbrkpt(mdb_tgt_t *t, uintptr_t addr,
   2147      0   stevel     int spec_flags, mdb_tgt_se_f *func, void *data)
   2148      0   stevel {
   2149      0   stevel 	kmt_bparg_t *ka = mdb_alloc(sizeof (kmt_bparg_t), UM_SLEEP);
   2150      0   stevel 
   2151      0   stevel 	ka->ka_addr = addr;
   2152      0   stevel 	ka->ka_symbol = NULL;
   2153      0   stevel 	ka->ka_defbp = NULL;
   2154      0   stevel 
   2155      0   stevel 	return (mdb_tgt_vespec_insert(t, &kmt_brkpt_ops, spec_flags,
   2156      0   stevel 	    func, data, ka, kmt_bparg_dtor));
   2157      0   stevel }
   2158      0   stevel 
   2159      0   stevel static int
   2160      0   stevel kmt_add_sbrkpt(mdb_tgt_t *t, const char *fullname,
   2161      0   stevel     int spec_flags, mdb_tgt_se_f *func, void *data)
   2162      0   stevel {
   2163      0   stevel 	kmt_bparg_t *ka;
   2164      0   stevel 	kmt_defbp_t *dbp;
   2165      0   stevel 	GElf_Sym sym;
   2166      0   stevel 	char *tick, *objname, *symname;
   2167      0   stevel 	int serrno;
   2168      0   stevel 
   2169      0   stevel 	if ((tick = strchr(fullname, '`')) == fullname) {
   2170      0   stevel 		(void) set_errno(EMDB_NOOBJ);
   2171      0   stevel 		return (0);
   2172      0   stevel 	}
   2173      0   stevel 
   2174      0   stevel 	/*
   2175      0   stevel 	 * Deferred breakpoints are always scoped.  If we didn't find a tick,
   2176      0   stevel 	 * there's no scope.  We'll create a vbrkpt, but only if we can turn the
   2177      0   stevel 	 * provided string into an address.
   2178      0   stevel 	 */
   2179      0   stevel 	if (tick == NULL) {
   2180      0   stevel 		uintptr_t addr;
   2181      0   stevel 
   2182      0   stevel 		if (strisbasenum(fullname)) {
   2183      0   stevel 			addr = mdb_strtoull(fullname); /* a bare address */
   2184      0   stevel 		} else if (mdb_tgt_lookup_by_name(t, MDB_TGT_OBJ_EVERY,
   2185      0   stevel 		    fullname, &sym, NULL) < 0) {
   2186      0   stevel 			(void) set_errno(EMDB_NOSYM);
   2187      0   stevel 			return (0);
   2188      0   stevel 		} else {
   2189      0   stevel 			addr = (uintptr_t)sym.st_value; /* unscoped sym name */
   2190      0   stevel 		}
   2191      0   stevel 
   2192      0   stevel 		return (kmt_add_vbrkpt(t, addr, spec_flags, func, data));
   2193      0   stevel 	}
   2194      0   stevel 
   2195      0   stevel 	if (*(tick + 1) == '\0') {
   2196      0   stevel 		(void) set_errno(EMDB_NOSYM);
   2197      0   stevel 		return (0);
   2198      0   stevel 	}
   2199      0   stevel 
   2200      0   stevel 	objname = strndup(fullname, tick - fullname);
   2201      0   stevel 	symname = tick + 1;
   2202      0   stevel 
   2203      0   stevel 	if (mdb_tgt_lookup_by_name(t, objname, symname, NULL, NULL) < 0 &&
   2204      0   stevel 	    errno != EMDB_NOOBJ) {
   2205      0   stevel 		serrno = errno;
   2206      0   stevel 		strfree(objname);
   2207      0   stevel 
   2208      0   stevel 		(void) set_errno(serrno);
   2209      0   stevel 		return (0); /* errno is set for us */
   2210      0   stevel 	}
   2211      0   stevel 
   2212      0   stevel 	dbp = kmt_defbp_create(t, objname, symname);
   2213      0   stevel 	strfree(objname);
   2214      0   stevel 
   2215      0   stevel 	ka = mdb_alloc(sizeof (kmt_bparg_t), UM_SLEEP);
   2216      0   stevel 	ka->ka_symbol = strdup(fullname);
   2217      0   stevel 	ka->ka_addr = NULL;
   2218      0   stevel 	ka->ka_defbp = dbp;
   2219      0   stevel 
   2220      0   stevel 	return (mdb_tgt_vespec_insert(t, &kmt_brkpt_ops, spec_flags,
   2221   6473      edp 	    func, data, ka, kmt_bparg_dtor));
   2222      0   stevel }
   2223      0   stevel 
   2224      0   stevel static int
   2225      0   stevel kmt_wparg_overlap(const kmdb_wapt_t *wp1, const kmdb_wapt_t *wp2)
   2226      0   stevel {
   2227      0   stevel 	/* Assume the watchpoint spaces don't overlap */
   2228      0   stevel 	if (wp1->wp_type != wp2->wp_type)
   2229      0   stevel 		return (0);
   2230      0   stevel 
   2231      0   stevel 	if (wp2->wp_addr + wp2->wp_size <= wp1->wp_addr)
   2232      0   stevel 		return (0); /* no range overlap */
   2233      0   stevel 
   2234      0   stevel 	if (wp1->wp_addr + wp1->wp_size <= wp2->wp_addr)
   2235      0   stevel 		return (0); /* no range overlap */
   2236      0   stevel 
   2237      0   stevel 	return (wp1->wp_addr != wp2->wp_addr || wp1->wp_size != wp2->wp_size ||
   2238      0   stevel 	    wp1->wp_wflags != wp2->wp_wflags);
   2239      0   stevel }
   2240      0   stevel 
   2241      0   stevel static void
   2242      0   stevel kmt_wparg_dtor(mdb_vespec_t *vep)
   2243      0   stevel {
   2244      0   stevel 	mdb_free(vep->ve_args, sizeof (kmdb_wapt_t));
   2245      0   stevel }
   2246      0   stevel 
   2247      0   stevel static int
   2248      0   stevel kmt_add_wapt_common(mdb_tgt_t *t, uintptr_t addr, size_t len, uint_t wflags,
   2249      0   stevel     int spec_flags, mdb_tgt_se_f *func, void *data, int type)
   2250      0   stevel {
   2251      0   stevel 	kmdb_wapt_t *wp = mdb_alloc(sizeof (kmdb_wapt_t), UM_SLEEP);
   2252      0   stevel 	mdb_sespec_t *sep;
   2253      0   stevel 
   2254      0   stevel 	wp->wp_addr = addr;
   2255      0   stevel 	wp->wp_size = len;
   2256      0   stevel 	wp->wp_type = type;
   2257      0   stevel 	wp->wp_wflags = wflags;
   2258      0   stevel 
   2259      0   stevel 	if (kmdb_dpi_wapt_validate(wp) < 0)
   2260      0   stevel 		return (0); /* errno is set for us */
   2261      0   stevel 
   2262      0   stevel 	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
   2263      0   stevel 		if (sep->se_ops == &kmt_wapt_ops &&
   2264      0   stevel 		    mdb_list_next(&sep->se_velist) != NULL &&
   2265      0   stevel 		    kmt_wparg_overlap(wp, sep->se_data))
   2266      0   stevel 			goto wapt_dup;
   2267      0   stevel 	}
   2268      0   stevel 
   2269      0   stevel 	for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) {
   2270      0   stevel 		if (sep->se_ops == &kmt_wapt_ops && kmt_wparg_overlap(wp,
   2271      0   stevel 		    ((mdb_vespec_t *)mdb_list_next(&sep->se_velist))->ve_args))
   2272      0   stevel 			goto wapt_dup;
   2273      0   stevel 	}
   2274      0   stevel 
   2275      0   stevel 	return (mdb_tgt_vespec_insert(t, &kmt_wapt_ops, spec_flags,
   2276      0   stevel 	    func, data, wp, kmt_wparg_dtor));
   2277      0   stevel 
   2278      0   stevel wapt_dup:
   2279      0   stevel 	mdb_free(wp, sizeof (kmdb_wapt_t));
   2280      0   stevel 	(void) set_errno(EMDB_WPDUP);
   2281      0   stevel 	return (0);
   2282      0   stevel }
   2283      0   stevel 
   2284      0   stevel static int
   2285      0   stevel kmt_add_pwapt(mdb_tgt_t *t, physaddr_t addr, size_t len, uint_t wflags,
   2286      0   stevel     int spec_flags, mdb_tgt_se_f *func, void *data)
   2287      0   stevel {
   2288      0   stevel 	return (kmt_add_wapt_common(t, (uintptr_t)addr, len, wflags, spec_flags,
   2289      0   stevel 	    func, data, DPI_WAPT_TYPE_PHYS));
   2290      0   stevel }
   2291      0   stevel 
   2292      0   stevel static int
   2293      0   stevel kmt_add_vwapt(mdb_tgt_t *t, uintptr_t addr, size_t len, uint_t wflags,
   2294      0   stevel     int spec_flags, mdb_tgt_se_f *func, void *data)
   2295      0   stevel {
   2296      0   stevel 	return (kmt_add_wapt_common(t, addr, len, wflags, spec_flags, func,
   2297      0   stevel 	    data, DPI_WAPT_TYPE_VIRT));
   2298      0   stevel }
   2299      0   stevel 
   2300      0   stevel static int
   2301      0   stevel kmt_add_iowapt(mdb_tgt_t *t, uintptr_t addr, size_t len, uint_t wflags,
   2302      0   stevel     int spec_flags, mdb_tgt_se_f *func, void *data)
   2303      0   stevel {
   2304      0   stevel 	return (kmt_add_wapt_common(t, addr, len, wflags, spec_flags, func,
   2305      0   stevel 	    data, DPI_WAPT_TYPE_IO));
   2306      0   stevel }
   2307      0   stevel 
   2308      0   stevel static int
   2309      0   stevel kmt_add_trap(mdb_tgt_t *t, int trapnum, int spec_flags, mdb_tgt_se_f *func,
   2310      0   stevel     void *data)
   2311      0   stevel {
   2312      0   stevel 	kmt_data_t *kmt = t->t_data;
   2313      0   stevel 
   2314      0   stevel 	if (trapnum != KMT_TRAP_ALL && trapnum != KMT_TRAP_NOTENUM) {
   2315      0   stevel 		if (trapnum < 0 || trapnum > kmt->kmt_trapmax) {
   2316      0   stevel 			(void) set_errno(EMDB_BADFLTNUM);
   2317      0   stevel 			return (0);
   2318      0   stevel 		}
   2319      0   stevel 
   2320      0   stevel 		BT_SET(kmt->kmt_trapmap, trapnum);
   2321      0   stevel 	}
   2322      0   stevel 
   2323      0   stevel 	return (mdb_tgt_vespec_insert(t, &kmt_trap_ops, spec_flags, func, data,
   2324      0   stevel 	    (void *)(uintptr_t)trapnum, no_ve_dtor));
   2325      0   stevel }
   2326      0   stevel 
   2327      0   stevel /*ARGSUSED*/
   2328      0   stevel static uintmax_t
   2329      0   stevel kmt_cpuid_disc_get(const mdb_var_t *v)
   2330      0   stevel {
   2331      0   stevel 	return (kmdb_dpi_get_master_cpuid());
   2332      0   stevel }
   2333      0   stevel 
   2334      0   stevel static const mdb_nv_disc_t kmt_cpuid_disc = {
   2335      0   stevel 	NULL,
   2336      0   stevel 	kmt_cpuid_disc_get
   2337      0   stevel };
   2338      0   stevel 
   2339      0   stevel /*
   2340      0   stevel  * This routine executes while the kernel is running.
   2341      0   stevel  */
   2342      0   stevel void
   2343      0   stevel kmt_activate(mdb_tgt_t *t)
   2344      0   stevel {
   2345      0   stevel 	kmt_data_t *kmt = t->t_data;
   2346      0   stevel 
   2347      0   stevel 	mdb_prop_postmortem = FALSE;
   2348      0   stevel 	mdb_prop_kernel = TRUE;
   2349      0   stevel 
   2350      0   stevel 	(void) mdb_tgt_register_dcmds(t, &kmt_dcmds[0], MDB_MOD_FORCE);
   2351      0   stevel 	mdb_tgt_register_regvars(t, kmt->kmt_rds, &kmt_reg_disc, 0);
   2352   3446      mrj 
   2353   3446      mrj 	/*
   2354   3446      mrj 	 * Force load of the MDB krtld module, in case it's been rolled into
   2355   3446      mrj 	 * unix.
   2356   3446      mrj 	 */
   2357   3446      mrj 	(void) mdb_module_load(KMT_RTLD_NAME, MDB_MOD_SILENT | MDB_MOD_DEFER);
   2358      0   stevel }
   2359      0   stevel 
   2360      0   stevel static void
   2361      0   stevel kmt_destroy(mdb_tgt_t *t)
   2362      0   stevel {
   2363      0   stevel 	kmt_data_t *kmt = t->t_data;
   2364      0   stevel 	kmt_module_t *km, *pkm;
   2365      0   stevel 
   2366      0   stevel 	mdb_nv_destroy(&kmt->kmt_modules);
   2367      0   stevel 	for (km = mdb_list_prev(&kmt->kmt_modlist); km != NULL; km = pkm) {
   2368      0   stevel 		pkm = mdb_list_prev(km);
   2369      0   stevel 		mdb_free(km, sizeof (kmt_module_t));
   2370      0   stevel 	}
   2371      0   stevel 
   2372      0   stevel 	if (!kmt_defbp_lock)
   2373      0   stevel 		kmt_defbp_destroy_all();
   2374      0   stevel 
   2375      0   stevel 	if (kmt->kmt_trapmap != NULL)
   2376      0   stevel 		mdb_free(kmt->kmt_trapmap, BT_SIZEOFMAP(kmt->kmt_trapmax));
   2377      0   stevel 
   2378      0   stevel 	if (kmt->kmt_cpu != NULL)
   2379      0   stevel 		kmt_cpu_destroy(kmt->kmt_cpu);
   2380      0   stevel 
   2381      0   stevel 	if (kmt != NULL)
   2382      0   stevel 		mdb_free(kmt, sizeof (kmt_data_t));
   2383      0   stevel }
   2384      0   stevel 
   2385      0   stevel static const mdb_tgt_ops_t kmt_ops = {
   2386      0   stevel 	kmt_setflags,				/* t_setflags */
   2387      0   stevel 	(int (*)()) mdb_tgt_notsup,		/* t_setcontext */
   2388      0   stevel 	kmt_activate,				/* t_activate */
   2389      0   stevel 	(void (*)()) mdb_tgt_nop,		/* t_deactivate */
   2390      0   stevel 	kmt_periodic,				/* t_periodic */
   2391      0   stevel 	kmt_destroy,				/* t_destroy */
   2392      0   stevel 	kmt_name,				/* t_name */
   2393      0   stevel 	(const char *(*)()) mdb_conf_isa,	/* t_isa */
   2394      0   stevel 	kmt_platform,				/* t_platform */
   2395      0   stevel 	kmt_uname,				/* t_uname */
   2396      0   stevel 	kmt_dmodel,				/* t_dmodel */
   2397      0   stevel 	(ssize_t (*)()) mdb_tgt_notsup,		/* t_aread */
   2398      0   stevel 	(ssize_t (*)()) mdb_tgt_notsup,		/* t_awrite */
   2399      0   stevel 	kmt_read,				/* t_vread */
   2400      0   stevel 	kmt_write,				/* t_vwrite */
   2401      0   stevel 	kmt_pread,				/* t_pread */
   2402      0   stevel 	kmt_pwrite,				/* t_pwrite */
   2403      0   stevel 	kmt_read,				/* t_fread */
   2404      0   stevel 	kmt_write,				/* t_fwrite */
   2405      0   stevel 	kmt_ioread,				/* t_ioread */
   2406      0   stevel 	kmt_iowrite,				/* t_iowrite */
   2407      0   stevel 	kmt_vtop,				/* t_vtop */
   2408      0   stevel 	kmt_lookup_by_name,			/* t_lookup_by_name */
   2409      0   stevel 	kmt_lookup_by_addr,			/* t_lookup_by_addr */
   2410      0   stevel 	kmt_symbol_iter,			/* t_symbol_iter */
   2411      0   stevel 	kmt_mapping_iter,			/* t_mapping_iter */
   2412      0   stevel 	kmt_object_iter,			/* t_object_iter */
   2413      0   stevel 	kmt_addr_to_map,			/* t_addr_to_map */
   2414      0   stevel 	kmt_name_to_map,			/* t_name_to_map */
   2415      0   stevel 	kmt_addr_to_ctf,			/* t_addr_to_ctf */
   2416      0   stevel 	kmt_name_to_ctf,			/* t_name_to_ctf */
   2417      0   stevel 	kmt_status,				/* t_status */
   2418      0   stevel 	(int (*)()) mdb_tgt_notsup,		/* t_run */
   2419      0   stevel 	kmt_step,				/* t_step */
   2420      0   stevel 	kmt_step_out,				/* t_step_out */
   2421      0   stevel 	kmt_step_branch,			/* t_step_branch */
   2422      0   stevel 	kmt_next,				/* t_next */
   2423      0   stevel 	kmt_continue,				/* t_cont */
   2424      0   stevel 	(int (*)()) mdb_tgt_notsup,		/* t_signal */
   2425      0   stevel 	kmt_add_vbrkpt,				/* t_add_vbrkpt */
   2426      0   stevel 	kmt_add_sbrkpt,				/* t_add_sbrkpt */
   2427      0   stevel 	kmt_add_pwapt,				/* t_add_pwapt */
   2428      0   stevel 	kmt_add_vwapt,				/* t_add_vwapt */
   2429      0   stevel 	kmt_add_iowapt,				/* t_add_iowapt */
   2430      0   stevel 	(int (*)()) mdb_tgt_null,		/* t_add_sysenter */
   2431      0   stevel 	(int (*)()) mdb_tgt_null,		/* t_add_sysexit */
   2432      0   stevel 	(int (*)()) mdb_tgt_null,		/* t_add_signal */
   2433      0   stevel 	kmt_add_trap,				/* t_add_fault */
   2434      0   stevel 	kmt_getareg,				/* t_getareg */
   2435      0   stevel 	kmt_putareg,				/* t_putareg */
   2436   6473      edp 	(int (*)()) mdb_tgt_nop,		/* XXX t_stack_iter */
   2437   6473      edp 	(int (*)()) mdb_tgt_notsup		/* t_auxv */
   2438      0   stevel };
   2439      0   stevel 
   2440      0   stevel /*
   2441      0   stevel  * Called immediately upon resumption of the system after a step or continue.
   2442      0   stevel  * Allows us to synchronize kmt's view of the world with reality.
   2443      0   stevel  */
   2444      0   stevel /*ARGSUSED*/
   2445      0   stevel static void
   2446      0   stevel kmt_sync(mdb_tgt_t *t)
   2447      0   stevel {
   2448      0   stevel 	kmt_data_t *kmt = t->t_data;
   2449      0   stevel 	int symavail;
   2450      0   stevel 
   2451      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "synchronizing with kernel\n");
   2452      0   stevel 
   2453      0   stevel 	symavail = kmt->kmt_symavail;
   2454      0   stevel 	kmt->kmt_symavail = FALSE;
   2455      0   stevel 
   2456      0   stevel 	/*
   2457      0   stevel 	 * Resync our view of the world if the modules have changed, or if we
   2458      0   stevel 	 * didn't have any symbols coming into this function.  The latter will
   2459      0   stevel 	 * only happen on startup.
   2460      0   stevel 	 */
   2461      0   stevel 	if (kmdb_kdi_mods_changed() || !symavail)
   2462      0   stevel 		kmt_modlist_update(t);
   2463      0   stevel 
   2464      0   stevel 	/*
   2465      0   stevel 	 * It would be nice if we could run this less frequently, perhaps
   2466      0   stevel 	 * after a dvec-initiated trigger.
   2467      0   stevel 	 */
   2468      0   stevel 	kmdb_module_sync();
   2469      0   stevel 
   2470      0   stevel 	kmt->kmt_symavail = TRUE;
   2471      0   stevel 
   2472      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "synchronization complete\n");
   2473      0   stevel 
   2474      0   stevel 	kmt_defbp_prune();
   2475      0   stevel 
   2476      0   stevel 	if (kmt_defbp_num > 0 && kmt_defbp_bpspec == 0 &&
   2477      0   stevel 	    kmdb_kdi_dtrace_get_state() != KDI_DTSTATE_DTRACE_ACTIVE) {
   2478      0   stevel 		/*
   2479      0   stevel 		 * Deferred breakpoints were created while DTrace was active,
   2480      0   stevel 		 * and consequently the deferred breakpoint enabling mechanism
   2481      0   stevel 		 * wasn't activated.  Activate it now, and then try to activate
   2482      0   stevel 		 * the deferred breakpoints.  We do this so that we can catch
   2483      0   stevel 		 * the ones which may apply to modules that have been loaded
   2484      0   stevel 		 * while they were waiting for DTrace to deactivate.
   2485      0   stevel 		 */
   2486      0   stevel 		(void) kmt_defbp_activate(t);
   2487      0   stevel 		(void) mdb_tgt_sespec_activate_all(t);
   2488      0   stevel 	}
   2489      0   stevel 
   2490      0   stevel 	if (kmt->kmt_cpu_retry && ((kmt->kmt_cpu = kmt_cpu_create(t)) !=
   2491      0   stevel 	    NULL || errno != EAGAIN))
   2492      0   stevel 		kmt->kmt_cpu_retry = FALSE;
   2493      0   stevel 
   2494      0   stevel 	(void) mdb_tgt_status(t, &t->t_status);
   2495      0   stevel }
   2496      0   stevel 
   2497      0   stevel /*
   2498      0   stevel  * This routine executes while the kernel is running.
   2499      0   stevel  */
   2500      0   stevel /*ARGSUSED*/
   2501      0   stevel int
   2502      0   stevel kmdb_kvm_create(mdb_tgt_t *t, int argc, const char *argv[])
   2503      0   stevel {
   2504      0   stevel 	kmt_data_t *kmt;
   2505      0   stevel 
   2506      0   stevel 	if (argc != 0)
   2507      0   stevel 		return (set_errno(EINVAL));
   2508      0   stevel 
   2509      0   stevel 	kmt = mdb_zalloc(sizeof (kmt_data_t), UM_SLEEP);
   2510      0   stevel 	t->t_data = kmt;
   2511      0   stevel 	t->t_ops = &kmt_ops;
   2512      0   stevel 	t->t_flags |= MDB_TGT_F_RDWR;	/* kmdb is always r/w */
   2513      0   stevel 
   2514      0   stevel 	(void) mdb_nv_insert(&mdb.m_nv, "cpuid", &kmt_cpuid_disc, 0,
   2515      0   stevel 	    MDB_NV_PERSIST | MDB_NV_RDONLY);
   2516      0   stevel 
   2517      0   stevel 	(void) mdb_nv_create(&kmt->kmt_modules, UM_SLEEP);
   2518      0   stevel 
   2519      0   stevel 	kmt_init_isadep(t);
   2520      0   stevel 
   2521      0   stevel 	kmt->kmt_symavail = FALSE;
   2522      0   stevel 	kmt->kmt_cpu_retry = TRUE;
   2523      0   stevel 
   2524      0   stevel 	bzero(&kmt_defbp_list, sizeof (mdb_list_t));
   2525      0   stevel 
   2526      0   stevel 	return (0);
   2527      0   stevel 
   2528      0   stevel create_err:
   2529      0   stevel 	kmt_destroy(t);
   2530      0   stevel 
   2531      0   stevel 	return (-1);
   2532      0   stevel }
   2533      0   stevel 
   2534      0   stevel /*
   2535      0   stevel  * This routine is called once, when kmdb first has control of the world.
   2536      0   stevel  */
   2537      0   stevel void
   2538      0   stevel kmdb_kvm_startup(void)
   2539      0   stevel {
   2540   3446      mrj 	kmt_data_t *kmt = mdb.m_target->t_data;
   2541   3446      mrj 
   2542      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm startup\n");
   2543      0   stevel 
   2544      0   stevel 	kmt_sync(mdb.m_target);
   2545      0   stevel 	(void) mdb_module_load_builtin(KMT_MODULE);
   2546      0   stevel 	kmt_startup_isadep(mdb.m_target);
   2547      0   stevel 
   2548      0   stevel 	/*
   2549      0   stevel 	 * This is here because we need to write the deferred breakpoint
   2550      0   stevel 	 * breakpoint when the debugger starts.  Our normal r/o write routines
   2551      0   stevel 	 * don't work when the kernel is running, so we have to do it during
   2552      0   stevel 	 * startup.
   2553      0   stevel 	 */
   2554      0   stevel 	(void) mdb_tgt_sespec_activate_all(mdb.m_target);
   2555   3446      mrj 
   2556   3446      mrj 	kmt->kmt_rtld_name = KMT_RTLD_NAME;
   2557   3446      mrj 
   2558   3446      mrj 	if (kmt_module_by_name(kmt, KMT_RTLD_NAME) == NULL)
   2559   3446      mrj 		kmt->kmt_rtld_name = "unix";
   2560      0   stevel }
   2561      0   stevel 
   2562      0   stevel /*
   2563      0   stevel  * This routine is called after kmdb has loaded its initial set of modules.
   2564      0   stevel  */
   2565      0   stevel void
   2566      0   stevel kmdb_kvm_poststartup(void)
   2567      0   stevel {
   2568      0   stevel 	mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm post-startup\n");
   2569      0   stevel 
   2570      0   stevel 	(void) mdb_dis_select(kmt_def_dismode());
   2571      0   stevel }
   2572