1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Copyright 2018 Joyent, Inc.
26 */
27
28/*
29 * MDB Target Layer
30 *
31 * The *target* is the program being inspected by the debugger.  The MDB target
32 * layer provides a set of functions that insulate common debugger code,
33 * including the MDB Module API, from the implementation details of how the
34 * debugger accesses information from a given target.  Each target exports a
35 * standard set of properties, including one or more address  spaces, one or
36 * more symbol tables, a set of load objects, and a set of threads that can be
37 * examined using the interfaces in <mdb/mdb_target.h>.  This technique has
38 * been employed successfully in other debuggers, including [1], primarily
39 * to improve portability, although the term "target" often refers to the
40 * encapsulation of architectural or operating system-specific details.  The
41 * target abstraction is useful for MDB because it allows us to easily extend
42 * the debugger to examine a variety of different program forms.  Primarily,
43 * the target functions validate input arguments and then call an appropriate
44 * function in the target ops vector, defined in <mdb/mdb_target_impl.h>.
45 * However, this interface layer provides a very high level of flexibility for
46 * separating the debugger interface from instrumentation details.  Experience
47 * has shown this kind of design can facilitate separating out debugger
48 * instrumentation into an external agent [2] and enable the development of
49 * advanced instrumentation frameworks [3].  We want MDB to be an ideal
50 * extensible framework for the development of such applications.
51 *
52 * Aside from a set of wrapper functions, the target layer also provides event
53 * management for targets that represent live executing programs.  Our model of
54 * events is also extensible, and is based upon work in [3] and [4].  We define
55 * a *software event* as a state transition in the target program (for example,
56 * the transition of the program counter to a location of interest) that is
57 * observed by the debugger or its agent.  A *software event specifier* is a
58 * description of a class of software events that is used by the debugger to
59 * instrument the target so that the corresponding software events can be
60 * observed.  In MDB, software event specifiers are represented by the
61 * mdb_sespec_t structure, defined in <mdb/mdb_target_impl.h>.  As the user,
62 * the internal debugger code, and MDB modules may all wish to observe software
63 * events and receive appropriate notification and callbacks, we do not expose
64 * software event specifiers directly as part of the user interface.  Instead,
65 * clients of the target layer request that events be observed by creating
66 * new *virtual event specifiers*.  Each virtual specifier is named by a unique
67 * non-zero integer (the VID), and is represented by a mdb_vespec_t structure.
68 * One or more virtual specifiers are then associated with each underlying
69 * software event specifier.  This design enforces the constraint that the
70 * target must only insert one set of instrumentation, regardless of how many
71 * times the target layer was asked to trace a given event.  For example, if
72 * multiple clients request a breakpoint at a particular address, the virtual
73 * specifiers will map to the same sespec, ensuring that only one breakpoint
74 * trap instruction is actually planted at the given target address.  When no
75 * virtual specifiers refer to an sespec, it is no longer needed and can be
76 * removed, along with the corresponding instrumentation.
77 *
78 * The following state transition diagram illustrates the life cycle of a
79 * software event specifier and example transitions:
80 *
81 *                                         cont/
82 *     +--------+   delete   +--------+    stop    +-------+
83 *    (|( DEAD )|) <------- (  ACTIVE  ) <------> (  ARMED  )
84 *     +--------+            +--------+            +-------+
85 *          ^   load/unload  ^        ^   failure/     |
86 *   delete |        object /          \  reset        | failure
87 *          |              v            v              |
88 *          |      +--------+          +-------+       |
89 *          +---- (   IDLE   )        (   ERR   ) <----+
90 *          |      +--------+          +-------+
91 *          |                              |
92 *          +------------------------------+
93 *
94 * The MDB execution control model is based upon the synchronous debugging
95 * model exported by Solaris proc(4).  A target program is set running or the
96 * debugger is attached to a running target.  On ISTOP (stop on event of
97 * interest), one target thread is selected as the representative.  The
98 * algorithm for selecting the representative is target-specific, but we assume
99 * that if an observed software event has occurred, the target will select the
100 * thread that triggered the state transition of interest.  The other threads
101 * are stopped in sympathy with the representative as soon as possible.  Prior
102 * to continuing the target, we plant our instrumentation, transitioning event
103 * specifiers from the ACTIVE to the ARMED state, and then back again when the
104 * target stops.  We then query each active event specifier to learn which ones
105 * are matched, and then invoke the callbacks associated with their vespecs.
106 * If an OS error occurs while attempting to arm or disarm a specifier, the
107 * specifier is transitioned to the ERROR state; we will attempt to arm it
108 * again at the next continue.  If no target process is under our control or
109 * if an event is not currently applicable (e.g. a deferred breakpoint on an
110 * object that is not yet loaded), it remains in the IDLE state.  The target
111 * implementation should intercept object load events and then transition the
112 * specifier to the ACTIVE state when the corresponding object is loaded.
113 *
114 * To simplify the debugger implementation and allow targets to easily provide
115 * new types of observable events, most of the event specifier management is
116 * done by the target layer.  Each software event specifier provides an ops
117 * vector of subroutines that the target layer can call to perform the
118 * various state transitions described above.  The target maintains two lists
119 * of mdb_sespec_t's: the t_idle list (IDLE state) and the t_active list
120 * (ACTIVE, ARMED, and ERROR states).  Each mdb_sespec_t maintains a list of
121 * associated mdb_vespec_t's.  If an sespec is IDLE or ERROR, its se_errno
122 * field will have an errno value specifying the reason for its inactivity.
123 * The vespec stores the client's callback function and private data, and the
124 * arguments used to construct the sespec.  All objects are reference counted
125 * so we can destroy an object when it is no longer needed.  The mdb_sespec_t
126 * invariants for the respective states are as follows:
127 *
128 *   IDLE: on t_idle list, se_data == NULL, se_errno != 0, se_ctor not called
129 * ACTIVE: on t_active list, se_data valid, se_errno == 0, se_ctor called
130 *  ARMED: on t_active list, se_data valid, se_errno == 0, se_ctor called
131 *  ERROR: on t_active list, se_data valid, se_errno != 0, se_ctor called
132 *
133 * Additional commentary on specific state transitions and issues involving
134 * event management can be found below near the target layer functions.
135 *
136 * References
137 *
138 * [1] John Gilmore, "Working in GDB", Technical Report, Cygnus Support,
139 *     1.84 edition, 1994.
140 *
141 * [2] David R. Hanson and Mukund Raghavachari, "A Machine-Independent
142 *     Debugger", Software--Practice and Experience, 26(11), 1277-1299(1996).
143 *
144 * [3] Michael W. Shapiro, "RDB: A System for Incremental Replay Debugging",
145 *     Technical Report CS-97-12, Department of Computer Science,
146 *     Brown University.
147 *
148 * [4] Daniel B. Price, "New Techniques for Replay Debugging", Technical
149 *     Report CS-98-05, Department of Computer Science, Brown University.
150 */
151
152#include <mdb/mdb_target_impl.h>
153#include <mdb/mdb_debug.h>
154#include <mdb/mdb_modapi.h>
155#include <mdb/mdb_err.h>
156#include <mdb/mdb_callb.h>
157#include <mdb/mdb_gelf.h>
158#include <mdb/mdb_io_impl.h>
159#include <mdb/mdb_string.h>
160#include <mdb/mdb_signal.h>
161#include <mdb/mdb_frame.h>
162#include <mdb/mdb.h>
163
164#include <sys/stat.h>
165#include <sys/param.h>
166#include <sys/signal.h>
167#include <strings.h>
168#include <stdlib.h>
169#include <errno.h>
170
171/*
172 * Define convenience macros for referencing the set of vespec flag bits that
173 * are preserved by the target implementation, and the set of bits that
174 * determine automatic ve_hits == ve_limit behavior.
175 */
176#define	T_IMPL_BITS	\
177	(MDB_TGT_SPEC_INTERNAL | MDB_TGT_SPEC_SILENT | MDB_TGT_SPEC_MATCHED | \
178	MDB_TGT_SPEC_DELETED)
179
180#define	T_AUTO_BITS	\
181	(MDB_TGT_SPEC_AUTOSTOP | MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS)
182
183/*
184 * Define convenience macro for referencing target flag pending continue bits.
185 */
186#define	T_CONT_BITS	\
187	(MDB_TGT_F_STEP | MDB_TGT_F_STEP_OUT | MDB_TGT_F_NEXT | MDB_TGT_F_CONT)
188
189mdb_tgt_t *
190mdb_tgt_create(mdb_tgt_ctor_f *ctor, int flags, int argc, const char *argv[])
191{
192	mdb_module_t *mp;
193	mdb_tgt_t *t;
194
195	if (flags & ~MDB_TGT_F_ALL) {
196		(void) set_errno(EINVAL);
197		return (NULL);
198	}
199
200	t = mdb_zalloc(sizeof (mdb_tgt_t), UM_SLEEP);
201	mdb_list_append(&mdb.m_tgtlist, t);
202
203	t->t_module = &mdb.m_rmod;
204	t->t_matched = T_SE_END;
205	t->t_flags = flags;
206	t->t_vepos = 1;
207	t->t_veneg = 1;
208
209	for (mp = mdb.m_mhead; mp != NULL; mp = mp->mod_next) {
210		if (ctor == mp->mod_tgt_ctor) {
211			t->t_module = mp;
212			break;
213		}
214	}
215
216	if (ctor(t, argc, argv) != 0) {
217		mdb_list_delete(&mdb.m_tgtlist, t);
218		mdb_free(t, sizeof (mdb_tgt_t));
219		return (NULL);
220	}
221
222	mdb_dprintf(MDB_DBG_TGT, "t_create %s (%p)\n",
223	    t->t_module->mod_name, (void *)t);
224
225	(void) t->t_ops->t_status(t, &t->t_status);
226	return (t);
227}
228
229int
230mdb_tgt_getflags(mdb_tgt_t *t)
231{
232	return (t->t_flags);
233}
234
235int
236mdb_tgt_setflags(mdb_tgt_t *t, int flags)
237{
238	if (flags & ~MDB_TGT_F_ALL)
239		return (set_errno(EINVAL));
240
241	return (t->t_ops->t_setflags(t, flags));
242}
243
244int
245mdb_tgt_setcontext(mdb_tgt_t *t, void *context)
246{
247	return (t->t_ops->t_setcontext(t, context));
248}
249
250/*ARGSUSED*/
251static int
252tgt_delete_vespec(mdb_tgt_t *t, void *private, int vid, void *data)
253{
254	(void) mdb_tgt_vespec_delete(t, vid);
255	return (0);
256}
257
258void
259mdb_tgt_destroy(mdb_tgt_t *t)
260{
261	mdb_xdata_t *xdp, *nxdp;
262
263	if (mdb.m_target == t) {
264		mdb_dprintf(MDB_DBG_TGT, "t_deactivate %s (%p)\n",
265		    t->t_module->mod_name, (void *)t);
266		t->t_ops->t_deactivate(t);
267		mdb.m_target = NULL;
268	}
269
270	mdb_dprintf(MDB_DBG_TGT, "t_destroy %s (%p)\n",
271	    t->t_module->mod_name, (void *)t);
272
273	for (xdp = mdb_list_next(&t->t_xdlist); xdp != NULL; xdp = nxdp) {
274		nxdp = mdb_list_next(xdp);
275		mdb_list_delete(&t->t_xdlist, xdp);
276		mdb_free(xdp, sizeof (mdb_xdata_t));
277	}
278
279	mdb_tgt_sespec_idle_all(t, EBUSY, TRUE);
280	(void) mdb_tgt_vespec_iter(t, tgt_delete_vespec, NULL);
281	t->t_ops->t_destroy(t);
282
283	mdb_list_delete(&mdb.m_tgtlist, t);
284	mdb_free(t, sizeof (mdb_tgt_t));
285
286	if (mdb.m_target == NULL)
287		mdb_tgt_activate(mdb_list_prev(&mdb.m_tgtlist));
288}
289
290void
291mdb_tgt_activate(mdb_tgt_t *t)
292{
293	mdb_tgt_t *otgt = mdb.m_target;
294
295	if (mdb.m_target != NULL) {
296		mdb_dprintf(MDB_DBG_TGT, "t_deactivate %s (%p)\n",
297		    mdb.m_target->t_module->mod_name, (void *)mdb.m_target);
298		mdb.m_target->t_ops->t_deactivate(mdb.m_target);
299	}
300
301	if ((mdb.m_target = t) != NULL) {
302		const char *v = strstr(mdb.m_root, "%V");
303
304		mdb_dprintf(MDB_DBG_TGT, "t_activate %s (%p)\n",
305		    t->t_module->mod_name, (void *)t);
306
307		/*
308		 * If the root was explicitly set with -R and contains %V,
309		 * expand it like a path.  If the resulting directory is
310		 * not present, then replace %V with "latest" and re-evaluate.
311		 */
312		if (v != NULL) {
313			char old_root[MAXPATHLEN];
314			const char **p;
315#ifndef _KMDB
316			struct stat s;
317#endif
318			size_t len;
319
320			p = mdb_path_alloc(mdb.m_root, &len);
321			(void) strcpy(old_root, mdb.m_root);
322			(void) strncpy(mdb.m_root, p[0], MAXPATHLEN);
323			mdb.m_root[MAXPATHLEN - 1] = '\0';
324			mdb_path_free(p, len);
325
326#ifndef _KMDB
327			if (stat(mdb.m_root, &s) == -1 && errno == ENOENT) {
328				mdb.m_flags |= MDB_FL_LATEST;
329				p = mdb_path_alloc(old_root, &len);
330				(void) strncpy(mdb.m_root, p[0], MAXPATHLEN);
331				mdb.m_root[MAXPATHLEN - 1] = '\0';
332				mdb_path_free(p, len);
333			}
334#endif
335		}
336
337		/*
338		 * Re-evaluate the macro and dmod paths now that we have the
339		 * new target set and m_root figured out.
340		 */
341		if (otgt == NULL) {
342			mdb_set_ipath(mdb.m_ipathstr);
343			mdb_set_lpath(mdb.m_lpathstr);
344		}
345
346		t->t_ops->t_activate(t);
347	}
348}
349
350void
351mdb_tgt_periodic(mdb_tgt_t *t)
352{
353	t->t_ops->t_periodic(t);
354}
355
356const char *
357mdb_tgt_name(mdb_tgt_t *t)
358{
359	return (t->t_ops->t_name(t));
360}
361
362const char *
363mdb_tgt_isa(mdb_tgt_t *t)
364{
365	return (t->t_ops->t_isa(t));
366}
367
368const char *
369mdb_tgt_platform(mdb_tgt_t *t)
370{
371	return (t->t_ops->t_platform(t));
372}
373
374int
375mdb_tgt_uname(mdb_tgt_t *t, struct utsname *utsp)
376{
377	return (t->t_ops->t_uname(t, utsp));
378}
379
380int
381mdb_tgt_dmodel(mdb_tgt_t *t)
382{
383	return (t->t_ops->t_dmodel(t));
384}
385
386int
387mdb_tgt_auxv(mdb_tgt_t *t, const auxv_t **auxvp)
388{
389	return (t->t_ops->t_auxv(t, auxvp));
390}
391
392ssize_t
393mdb_tgt_aread(mdb_tgt_t *t, mdb_tgt_as_t as,
394    void *buf, size_t n, mdb_tgt_addr_t addr)
395{
396	if (t->t_flags & MDB_TGT_F_ASIO)
397		return (t->t_ops->t_aread(t, as, buf, n, addr));
398
399	switch ((uintptr_t)as) {
400	case (uintptr_t)MDB_TGT_AS_VIRT:
401	case (uintptr_t)MDB_TGT_AS_VIRT_I:
402	case (uintptr_t)MDB_TGT_AS_VIRT_S:
403		return (t->t_ops->t_vread(t, buf, n, addr));
404	case (uintptr_t)MDB_TGT_AS_PHYS:
405		return (t->t_ops->t_pread(t, buf, n, addr));
406	case (uintptr_t)MDB_TGT_AS_FILE:
407		return (t->t_ops->t_fread(t, buf, n, addr));
408	case (uintptr_t)MDB_TGT_AS_IO:
409		return (t->t_ops->t_ioread(t, buf, n, addr));
410	}
411	return (t->t_ops->t_aread(t, as, buf, n, addr));
412}
413
414ssize_t
415mdb_tgt_awrite(mdb_tgt_t *t, mdb_tgt_as_t as,
416    const void *buf, size_t n, mdb_tgt_addr_t addr)
417{
418	if (!(t->t_flags & MDB_TGT_F_RDWR))
419		return (set_errno(EMDB_TGTRDONLY));
420
421	if (t->t_flags & MDB_TGT_F_ASIO)
422		return (t->t_ops->t_awrite(t, as, buf, n, addr));
423
424	switch ((uintptr_t)as) {
425	case (uintptr_t)MDB_TGT_AS_VIRT:
426	case (uintptr_t)MDB_TGT_AS_VIRT_I:
427	case (uintptr_t)MDB_TGT_AS_VIRT_S:
428		return (t->t_ops->t_vwrite(t, buf, n, addr));
429	case (uintptr_t)MDB_TGT_AS_PHYS:
430		return (t->t_ops->t_pwrite(t, buf, n, addr));
431	case (uintptr_t)MDB_TGT_AS_FILE:
432		return (t->t_ops->t_fwrite(t, buf, n, addr));
433	case (uintptr_t)MDB_TGT_AS_IO:
434		return (t->t_ops->t_iowrite(t, buf, n, addr));
435	}
436	return (t->t_ops->t_awrite(t, as, buf, n, addr));
437}
438
439ssize_t
440mdb_tgt_vread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr)
441{
442	return (t->t_ops->t_vread(t, buf, n, addr));
443}
444
445ssize_t
446mdb_tgt_vwrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr)
447{
448	if (t->t_flags & MDB_TGT_F_RDWR)
449		return (t->t_ops->t_vwrite(t, buf, n, addr));
450
451	return (set_errno(EMDB_TGTRDONLY));
452}
453
454ssize_t
455mdb_tgt_pread(mdb_tgt_t *t, void *buf, size_t n, physaddr_t addr)
456{
457	return (t->t_ops->t_pread(t, buf, n, addr));
458}
459
460ssize_t
461mdb_tgt_pwrite(mdb_tgt_t *t, const void *buf, size_t n, physaddr_t addr)
462{
463	if (t->t_flags & MDB_TGT_F_RDWR)
464		return (t->t_ops->t_pwrite(t, buf, n, addr));
465
466	return (set_errno(EMDB_TGTRDONLY));
467}
468
469ssize_t
470mdb_tgt_fread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr)
471{
472	return (t->t_ops->t_fread(t, buf, n, addr));
473}
474
475ssize_t
476mdb_tgt_fwrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr)
477{
478	if (t->t_flags & MDB_TGT_F_RDWR)
479		return (t->t_ops->t_fwrite(t, buf, n, addr));
480
481	return (set_errno(EMDB_TGTRDONLY));
482}
483
484ssize_t
485mdb_tgt_ioread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr)
486{
487	return (t->t_ops->t_ioread(t, buf, n, addr));
488}
489
490ssize_t
491mdb_tgt_iowrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr)
492{
493	if (t->t_flags & MDB_TGT_F_RDWR)
494		return (t->t_ops->t_iowrite(t, buf, n, addr));
495
496	return (set_errno(EMDB_TGTRDONLY));
497}
498
499int
500mdb_tgt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap)
501{
502	return (t->t_ops->t_vtop(t, as, va, pap));
503}
504
505ssize_t
506mdb_tgt_readstr(mdb_tgt_t *t, mdb_tgt_as_t as, char *buf,
507    size_t nbytes, mdb_tgt_addr_t addr)
508{
509	ssize_t n, nread = mdb_tgt_aread(t, as, buf, nbytes, addr);
510	char *p;
511
512	if (nread >= 0) {
513		if ((p = memchr(buf, '\0', nread)) != NULL)
514			nread = (size_t)(p - buf);
515		goto done;
516	}
517
518	nread = 0;
519	p = &buf[0];
520
521	while (nread < nbytes && (n = mdb_tgt_aread(t, as, p, 1, addr)) == 1) {
522		if (*p == '\0')
523			return (nread);
524		nread++;
525		addr++;
526		p++;
527	}
528
529	if (nread == 0 && n == -1)
530		return (-1); /* If we can't even read a byte, return -1 */
531
532done:
533	if (nbytes != 0)
534		buf[MIN(nread, nbytes - 1)] = '\0';
535
536	return (nread);
537}
538
539ssize_t
540mdb_tgt_writestr(mdb_tgt_t *t, mdb_tgt_as_t as,
541    const char *buf, mdb_tgt_addr_t addr)
542{
543	ssize_t nwritten = mdb_tgt_awrite(t, as, buf, strlen(buf) + 1, addr);
544	return (nwritten > 0 ? nwritten - 1 : nwritten);
545}
546
547int
548mdb_tgt_lookup_by_name(mdb_tgt_t *t, const char *obj,
549    const char *name, GElf_Sym *symp, mdb_syminfo_t *sip)
550{
551	mdb_syminfo_t info;
552	GElf_Sym sym;
553	uint_t id;
554
555	if (name == NULL || t == NULL)
556		return (set_errno(EINVAL));
557
558	if (obj == MDB_TGT_OBJ_EVERY &&
559	    mdb_gelf_symtab_lookup_by_name(mdb.m_prsym, name, &sym, &id) == 0) {
560		info.sym_table = MDB_TGT_PRVSYM;
561		info.sym_id = id;
562		goto found;
563	}
564
565	if (t->t_ops->t_lookup_by_name(t, obj, name, &sym, &info) == 0)
566		goto found;
567
568	return (-1);
569
570found:
571	if (symp != NULL)
572		*symp = sym;
573	if (sip != NULL)
574		*sip = info;
575	return (0);
576}
577
578int
579mdb_tgt_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags,
580    char *buf, size_t len, GElf_Sym *symp, mdb_syminfo_t *sip)
581{
582	mdb_syminfo_t info;
583	GElf_Sym sym;
584
585	if (t == NULL)
586		return (set_errno(EINVAL));
587
588	if (t->t_ops->t_lookup_by_addr(t, addr, flags,
589	    buf, len, &sym, &info) == 0) {
590		if (symp != NULL)
591			*symp = sym;
592		if (sip != NULL)
593			*sip = info;
594		return (0);
595	}
596
597	return (-1);
598}
599
600/*
601 * The mdb_tgt_lookup_by_scope function is a convenience routine for code that
602 * wants to look up a scoped symbol name such as "object`symbol".  It is
603 * implemented as a simple wrapper around mdb_tgt_lookup_by_name.  Note that
604 * we split on the *last* occurrence of "`", so the object name itself may
605 * contain additional scopes whose evaluation is left to the target.  This
606 * allows targets to implement additional scopes, such as source files,
607 * function names, link map identifiers, etc.
608 */
609int
610mdb_tgt_lookup_by_scope(mdb_tgt_t *t, const char *s, GElf_Sym *symp,
611    mdb_syminfo_t *sip)
612{
613	const char *object = MDB_TGT_OBJ_EVERY;
614	const char *name = s;
615	char buf[MDB_TGT_SYM_NAMLEN];
616
617	if (t == NULL)
618		return (set_errno(EINVAL));
619
620	if (strchr(name, '`') != NULL) {
621
622		(void) strncpy(buf, s, sizeof (buf));
623		buf[sizeof (buf) - 1] = '\0';
624		name = buf;
625
626		if ((s = strrsplit(buf, '`')) != NULL) {
627			object = buf;
628			name = s;
629			if (*object == '\0')
630				return (set_errno(EMDB_NOOBJ));
631			if (*name == '\0')
632				return (set_errno(EMDB_NOSYM));
633		}
634	}
635
636	return (mdb_tgt_lookup_by_name(t, object, name, symp, sip));
637}
638
639int
640mdb_tgt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which,
641    uint_t type, mdb_tgt_sym_f *cb, void *p)
642{
643	if ((which != MDB_TGT_SYMTAB && which != MDB_TGT_DYNSYM) ||
644	    (type & ~(MDB_TGT_BIND_ANY | MDB_TGT_TYPE_ANY)) != 0)
645		return (set_errno(EINVAL));
646
647	return (t->t_ops->t_symbol_iter(t, obj, which, type, cb, p));
648}
649
650ssize_t
651mdb_tgt_readsym(mdb_tgt_t *t, mdb_tgt_as_t as, void *buf, size_t nbytes,
652    const char *obj, const char *name)
653{
654	GElf_Sym sym;
655
656	if (mdb_tgt_lookup_by_name(t, obj, name, &sym, NULL) == 0)
657		return (mdb_tgt_aread(t, as, buf, nbytes, sym.st_value));
658
659	return (-1);
660}
661
662ssize_t
663mdb_tgt_writesym(mdb_tgt_t *t, mdb_tgt_as_t as, const void *buf,
664    size_t nbytes, const char *obj, const char *name)
665{
666	GElf_Sym sym;
667
668	if (mdb_tgt_lookup_by_name(t, obj, name, &sym, NULL) == 0)
669		return (mdb_tgt_awrite(t, as, buf, nbytes, sym.st_value));
670
671	return (-1);
672}
673
674int
675mdb_tgt_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *cb, void *p)
676{
677	return (t->t_ops->t_mapping_iter(t, cb, p));
678}
679
680int
681mdb_tgt_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *cb, void *p)
682{
683	return (t->t_ops->t_object_iter(t, cb, p));
684}
685
686const mdb_map_t *
687mdb_tgt_addr_to_map(mdb_tgt_t *t, uintptr_t addr)
688{
689	return (t->t_ops->t_addr_to_map(t, addr));
690}
691
692const mdb_map_t *
693mdb_tgt_name_to_map(mdb_tgt_t *t, const char *name)
694{
695	return (t->t_ops->t_name_to_map(t, name));
696}
697
698struct ctf_file *
699mdb_tgt_addr_to_ctf(mdb_tgt_t *t, uintptr_t addr)
700{
701	return (t->t_ops->t_addr_to_ctf(t, addr));
702}
703
704struct ctf_file *
705mdb_tgt_name_to_ctf(mdb_tgt_t *t, const char *name)
706{
707	return (t->t_ops->t_name_to_ctf(t, name));
708}
709
710/*
711 * Return the latest target status.  We just copy out our cached copy.  The
712 * status only needs to change when the target is run, stepped, or continued.
713 */
714int
715mdb_tgt_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
716{
717	uint_t dstop = (t->t_status.st_flags & MDB_TGT_DSTOP);
718	uint_t istop = (t->t_status.st_flags & MDB_TGT_ISTOP);
719	uint_t state = t->t_status.st_state;
720
721	if (tsp == NULL)
722		return (set_errno(EINVAL));
723
724	/*
725	 * If we're called with the address of the target's internal status,
726	 * then call down to update it; otherwise copy out the saved status.
727	 */
728	if (tsp == &t->t_status && t->t_ops->t_status(t, &t->t_status) != 0)
729		return (-1); /* errno is set for us */
730
731	/*
732	 * Assert that our state is valid before returning it.  The state must
733	 * be valid, and DSTOP and ISTOP cannot be set simultaneously.  ISTOP
734	 * is only valid when stopped.  DSTOP is only valid when running or
735	 * stopped.  If any test fails, abort the debugger.
736	 */
737	if (state > MDB_TGT_LOST)
738		fail("invalid target state (%u)\n", state);
739	if (state != MDB_TGT_STOPPED && istop)
740		fail("target state is (%u) and ISTOP is set\n", state);
741	if (state != MDB_TGT_STOPPED && state != MDB_TGT_RUNNING && dstop)
742		fail("target state is (%u) and DSTOP is set\n", state);
743	if (istop && dstop)
744		fail("target has ISTOP and DSTOP set simultaneously\n");
745
746	if (tsp != &t->t_status)
747		bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t));
748
749	return (0);
750}
751
752/*
753 * For the given sespec, scan its list of vespecs for ones that are marked
754 * temporary and delete them.  We use the same method as vespec_delete below.
755 */
756/*ARGSUSED*/
757void
758mdb_tgt_sespec_prune_one(mdb_tgt_t *t, mdb_sespec_t *sep)
759{
760	mdb_vespec_t *vep, *nvep;
761
762	for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) {
763		nvep = mdb_list_next(vep);
764
765		if ((vep->ve_flags & (MDB_TGT_SPEC_DELETED |
766		    MDB_TGT_SPEC_TEMPORARY)) == MDB_TGT_SPEC_TEMPORARY) {
767			vep->ve_flags |= MDB_TGT_SPEC_DELETED;
768			mdb_tgt_vespec_rele(t, vep);
769		}
770	}
771}
772
773/*
774 * Prune each sespec on the active list of temporary vespecs.  This function
775 * is called, for example, after the target finishes a continue operation.
776 */
777void
778mdb_tgt_sespec_prune_all(mdb_tgt_t *t)
779{
780	mdb_sespec_t *sep, *nsep;
781
782	for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) {
783		nsep = mdb_list_next(sep);
784		mdb_tgt_sespec_prune_one(t, sep);
785	}
786}
787
788/*
789 * Transition the given sespec to the IDLE state.  We invoke the destructor,
790 * and then move the sespec from the active list to the idle list.
791 */
792void
793mdb_tgt_sespec_idle_one(mdb_tgt_t *t, mdb_sespec_t *sep, int reason)
794{
795	ASSERT(sep->se_state != MDB_TGT_SPEC_IDLE);
796
797	if (sep->se_state == MDB_TGT_SPEC_ARMED)
798		(void) sep->se_ops->se_disarm(t, sep);
799
800	sep->se_ops->se_dtor(t, sep);
801	sep->se_data = NULL;
802
803	sep->se_state = MDB_TGT_SPEC_IDLE;
804	sep->se_errno = reason;
805
806	mdb_list_delete(&t->t_active, sep);
807	mdb_list_append(&t->t_idle, sep);
808
809	mdb_tgt_sespec_prune_one(t, sep);
810}
811
812/*
813 * Transition each sespec on the active list to the IDLE state.  This function
814 * is called, for example, after the target terminates execution.
815 */
816void
817mdb_tgt_sespec_idle_all(mdb_tgt_t *t, int reason, int clear_matched)
818{
819	mdb_sespec_t *sep, *nsep;
820	mdb_vespec_t *vep;
821
822	while ((sep = t->t_matched) != T_SE_END && clear_matched) {
823		for (vep = mdb_list_next(&sep->se_velist); vep != NULL; ) {
824			vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED;
825			vep = mdb_list_next(vep);
826		}
827
828		t->t_matched = sep->se_matched;
829		sep->se_matched = NULL;
830		mdb_tgt_sespec_rele(t, sep);
831	}
832
833	for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) {
834		nsep = mdb_list_next(sep);
835		mdb_tgt_sespec_idle_one(t, sep, reason);
836	}
837}
838
839/*
840 * Attempt to transition the given sespec from the IDLE to ACTIVE state.  We
841 * do this by invoking se_ctor -- if this fails, we save the reason in se_errno
842 * and return -1 with errno set.  One strange case we need to deal with here is
843 * the possibility that a given vespec is sitting on the idle list with its
844 * corresponding sespec, but it is actually a duplicate of another sespec on the
845 * active list.  This can happen if the sespec is associated with a
846 * MDB_TGT_SPEC_DISABLED vespec that was just enabled, and is now ready to be
847 * activated.  A more interesting reason this situation might arise is the case
848 * where a virtual address breakpoint is set at an address just mmap'ed by
849 * dlmopen.  Since no symbol table information is available for this mapping
850 * yet, a pre-existing deferred symbolic breakpoint may already exist for this
851 * address, but it is on the idle list.  When the symbol table is ready and the
852 * DLACTIVITY event occurs, we now discover that the virtual address obtained by
853 * evaluating the symbolic breakpoint matches the explicit virtual address of
854 * the active virtual breakpoint.  To resolve this conflict in either case, we
855 * destroy the idle sespec, and attach its list of vespecs to the existing
856 * active sespec.
857 */
858int
859mdb_tgt_sespec_activate_one(mdb_tgt_t *t, mdb_sespec_t *sep)
860{
861	mdb_vespec_t *vep = mdb_list_next(&sep->se_velist);
862
863	mdb_vespec_t *nvep;
864	mdb_sespec_t *dup;
865
866	ASSERT(sep->se_state == MDB_TGT_SPEC_IDLE);
867	ASSERT(vep != NULL);
868
869	if (vep->ve_flags & MDB_TGT_SPEC_DISABLED)
870		return (0); /* cannot be activated while disabled bit set */
871
872	/*
873	 * First search the active list for an existing, duplicate sespec to
874	 * handle the special case described above.
875	 */
876	for (dup = mdb_list_next(&t->t_active); dup; dup = mdb_list_next(dup)) {
877		if (dup->se_ops == sep->se_ops &&
878		    dup->se_ops->se_secmp(t, dup, vep->ve_args)) {
879			ASSERT(dup != sep);
880			break;
881		}
882	}
883
884	/*
885	 * If a duplicate is found, destroy the existing, idle sespec, and
886	 * attach all of its vespecs to the duplicate sespec.
887	 */
888	if (dup != NULL) {
889		for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) {
890			mdb_dprintf(MDB_DBG_TGT, "merge [ %d ] to sespec %p\n",
891			    vep->ve_id, (void *)dup);
892
893			if (dup->se_matched != NULL)
894				vep->ve_flags |= MDB_TGT_SPEC_MATCHED;
895
896			nvep = mdb_list_next(vep);
897			vep->ve_hits = 0;
898
899			mdb_list_delete(&sep->se_velist, vep);
900			mdb_tgt_sespec_rele(t, sep);
901
902			mdb_list_append(&dup->se_velist, vep);
903			mdb_tgt_sespec_hold(t, dup);
904			vep->ve_se = dup;
905		}
906
907		mdb_dprintf(MDB_DBG_TGT, "merged idle sespec %p with %p\n",
908		    (void *)sep, (void *)dup);
909		return (0);
910	}
911
912	/*
913	 * If no duplicate is found, call the sespec's constructor.  If this
914	 * is successful, move the sespec to the active list.
915	 */
916	if (sep->se_ops->se_ctor(t, sep, vep->ve_args) < 0) {
917		sep->se_errno = errno;
918		sep->se_data = NULL;
919
920		return (-1);
921	}
922
923	for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) {
924		nvep = mdb_list_next(vep);
925		vep->ve_hits = 0;
926	}
927	mdb_list_delete(&t->t_idle, sep);
928	mdb_list_append(&t->t_active, sep);
929	sep->se_state = MDB_TGT_SPEC_ACTIVE;
930	sep->se_errno = 0;
931
932	return (0);
933}
934
935/*
936 * Transition each sespec on the idle list to the ACTIVE state.  This function
937 * is called, for example, after the target's t_run() function returns.  If
938 * the se_ctor() function fails, the specifier is not yet applicable; it will
939 * remain on the idle list and can be activated later.
940 *
941 * Returns 1 if there weren't any unexpected activation failures; 0 if there
942 * were.
943 */
944int
945mdb_tgt_sespec_activate_all(mdb_tgt_t *t)
946{
947	mdb_sespec_t *sep, *nsep;
948	int rc = 1;
949
950	for (sep = mdb_list_next(&t->t_idle); sep != NULL; sep = nsep) {
951		nsep = mdb_list_next(sep);
952
953		if (mdb_tgt_sespec_activate_one(t, sep) < 0 &&
954		    sep->se_errno != EMDB_NOOBJ)
955			rc = 0;
956	}
957
958	return (rc);
959}
960
961/*
962 * Transition the given sespec to the ARMED state.  Note that we attempt to
963 * re-arm sespecs previously in the ERROR state.  If se_arm() fails the sespec
964 * transitions to the ERROR state but stays on the active list.
965 */
966void
967mdb_tgt_sespec_arm_one(mdb_tgt_t *t, mdb_sespec_t *sep)
968{
969	ASSERT(sep->se_state != MDB_TGT_SPEC_IDLE);
970
971	if (sep->se_state == MDB_TGT_SPEC_ARMED)
972		return; /* do not arm sespecs more than once */
973
974	if (sep->se_ops->se_arm(t, sep) == -1) {
975		sep->se_state = MDB_TGT_SPEC_ERROR;
976		sep->se_errno = errno;
977	} else {
978		sep->se_state = MDB_TGT_SPEC_ARMED;
979		sep->se_errno = 0;
980	}
981}
982
983/*
984 * Transition each sespec on the active list (except matched specs) to the
985 * ARMED state.  This function is called prior to continuing the target.
986 */
987void
988mdb_tgt_sespec_arm_all(mdb_tgt_t *t)
989{
990	mdb_sespec_t *sep, *nsep;
991
992	for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) {
993		nsep = mdb_list_next(sep);
994		if (sep->se_matched == NULL)
995			mdb_tgt_sespec_arm_one(t, sep);
996	}
997}
998
999/*
1000 * Transition each sespec on the active list that is in the ARMED state to
1001 * the ACTIVE state.  If se_disarm() fails, the sespec is transitioned to
1002 * the ERROR state instead, but left on the active list.
1003 */
1004static void
1005tgt_disarm_sespecs(mdb_tgt_t *t)
1006{
1007	mdb_sespec_t *sep;
1008
1009	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
1010		if (sep->se_state != MDB_TGT_SPEC_ARMED)
1011			continue; /* do not disarm if in ERROR state */
1012
1013		if (sep->se_ops->se_disarm(t, sep) == -1) {
1014			sep->se_state = MDB_TGT_SPEC_ERROR;
1015			sep->se_errno = errno;
1016		} else {
1017			sep->se_state = MDB_TGT_SPEC_ACTIVE;
1018			sep->se_errno = 0;
1019		}
1020	}
1021}
1022
1023/*
1024 * Determine if the software event that triggered the most recent stop matches
1025 * any of the active event specifiers.  If 'all' is TRUE, we consider all
1026 * sespecs in our search.   If 'all' is FALSE, we only consider ARMED sespecs.
1027 * If we successfully match an event, we add it to the t_matched list and
1028 * place an additional hold on it.
1029 */
1030static mdb_sespec_t *
1031tgt_match_sespecs(mdb_tgt_t *t, int all)
1032{
1033	mdb_sespec_t *sep;
1034
1035	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
1036		if (all == FALSE && sep->se_state != MDB_TGT_SPEC_ARMED)
1037			continue; /* restrict search to ARMED sespecs */
1038
1039		if (sep->se_state != MDB_TGT_SPEC_ERROR &&
1040		    sep->se_ops->se_match(t, sep, &t->t_status)) {
1041			mdb_dprintf(MDB_DBG_TGT, "match se %p\n", (void *)sep);
1042			mdb_tgt_sespec_hold(t, sep);
1043			sep->se_matched = t->t_matched;
1044			t->t_matched = sep;
1045		}
1046	}
1047
1048	return (t->t_matched);
1049}
1050
1051/*
1052 * This function provides the low-level target continue algorithm.  We proceed
1053 * in three phases: (1) we arm the active sespecs, except the specs matched at
1054 * the time we last stopped, (2) we call se_cont() on any matched sespecs to
1055 * step over these event transitions, and then arm the corresponding sespecs,
1056 * and (3) we call the appropriate low-level continue routine.  Once the
1057 * target stops again, we determine which sespecs were matched, and invoke the
1058 * appropriate vespec callbacks and perform other vespec maintenance.
1059 */
1060static int
1061tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp,
1062    int (*t_cont)(mdb_tgt_t *, mdb_tgt_status_t *))
1063{
1064	mdb_var_t *hitv = mdb_nv_lookup(&mdb.m_nv, "hits");
1065	uintptr_t pc = t->t_status.st_pc;
1066	int error = 0;
1067
1068	mdb_sespec_t *sep, *nsep, *matched;
1069	mdb_vespec_t *vep, *nvep;
1070	uintptr_t addr;
1071
1072	uint_t cbits = 0;	/* union of pending continue bits */
1073	uint_t ncont = 0;	/* # of callbacks that requested cont */
1074	uint_t n = 0;		/* # of callbacks */
1075
1076	/*
1077	 * If the target is undead, dead, or lost, we no longer allow continue.
1078	 * This effectively forces the user to use ::kill or ::run after death.
1079	 */
1080	if (t->t_status.st_state == MDB_TGT_UNDEAD)
1081		return (set_errno(EMDB_TGTZOMB));
1082	if (t->t_status.st_state == MDB_TGT_DEAD)
1083		return (set_errno(EMDB_TGTCORE));
1084	if (t->t_status.st_state == MDB_TGT_LOST)
1085		return (set_errno(EMDB_TGTLOST));
1086
1087	/*
1088	 * If any of single-step, step-over, or step-out is pending, it takes
1089	 * precedence over an explicit or pending continue, because these are
1090	 * all different specialized forms of continue.
1091	 */
1092	if (t->t_flags & MDB_TGT_F_STEP)
1093		t_cont = t->t_ops->t_step;
1094	else if (t->t_flags & MDB_TGT_F_NEXT)
1095		t_cont = t->t_ops->t_step;
1096	else if (t->t_flags & MDB_TGT_F_STEP_OUT)
1097		t_cont = t->t_ops->t_cont;
1098
1099	/*
1100	 * To handle step-over, we ask the target to find the address past the
1101	 * next control transfer instruction.  If an address is found, we plant
1102	 * a temporary breakpoint there and continue; otherwise just step.
1103	 */
1104	if ((t->t_flags & MDB_TGT_F_NEXT) && !(t->t_flags & MDB_TGT_F_STEP)) {
1105		if (t->t_ops->t_next(t, &addr) == -1 || mdb_tgt_add_vbrkpt(t,
1106		    addr, MDB_TGT_SPEC_HIDDEN | MDB_TGT_SPEC_TEMPORARY,
1107		    no_se_f, NULL) == 0) {
1108			mdb_dprintf(MDB_DBG_TGT, "next falling back to step: "
1109			    "%s\n", mdb_strerror(errno));
1110		} else
1111			t_cont = t->t_ops->t_cont;
1112	}
1113
1114	/*
1115	 * To handle step-out, we ask the target to find the return address of
1116	 * the current frame, plant a temporary breakpoint there, and continue.
1117	 */
1118	if (t->t_flags & MDB_TGT_F_STEP_OUT) {
1119		if (t->t_ops->t_step_out(t, &addr) == -1)
1120			return (-1); /* errno is set for us */
1121
1122		if (mdb_tgt_add_vbrkpt(t, addr, MDB_TGT_SPEC_HIDDEN |
1123		    MDB_TGT_SPEC_TEMPORARY, no_se_f, NULL) == 0)
1124			return (-1); /* errno is set for us */
1125	}
1126
1127	(void) mdb_signal_block(SIGHUP);
1128	(void) mdb_signal_block(SIGTERM);
1129	mdb_intr_disable();
1130
1131	t->t_flags &= ~T_CONT_BITS;
1132	t->t_flags |= MDB_TGT_F_BUSY;
1133	mdb_tgt_sespec_arm_all(t);
1134
1135	ASSERT(t->t_matched != NULL);
1136	matched = t->t_matched;
1137	t->t_matched = T_SE_END;
1138
1139	if (mdb.m_term != NULL)
1140		IOP_SUSPEND(mdb.m_term);
1141
1142	/*
1143	 * Iterate over the matched sespec list, performing autostop processing
1144	 * and clearing the matched bit for each associated vespec.  We then
1145	 * invoke each sespec's se_cont callback in order to continue past
1146	 * the corresponding event.  If the matched list has more than one
1147	 * sespec, we assume that the se_cont callbacks are non-interfering.
1148	 */
1149	for (sep = matched; sep != T_SE_END; sep = sep->se_matched) {
1150		for (vep = mdb_list_next(&sep->se_velist); vep != NULL; ) {
1151			if ((vep->ve_flags & MDB_TGT_SPEC_AUTOSTOP) &&
1152			    (vep->ve_limit && vep->ve_hits == vep->ve_limit))
1153				vep->ve_hits = 0;
1154
1155			vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED;
1156			vep = mdb_list_next(vep);
1157		}
1158
1159		if (sep->se_ops->se_cont(t, sep, &t->t_status) == -1) {
1160			error = errno ? errno : -1;
1161			tgt_disarm_sespecs(t);
1162			break;
1163		}
1164
1165		if (!(t->t_status.st_flags & MDB_TGT_ISTOP)) {
1166			tgt_disarm_sespecs(t);
1167			if (t->t_status.st_state == MDB_TGT_UNDEAD)
1168				mdb_tgt_sespec_idle_all(t, EMDB_TGTZOMB, TRUE);
1169			else if (t->t_status.st_state == MDB_TGT_LOST)
1170				mdb_tgt_sespec_idle_all(t, EMDB_TGTLOST, TRUE);
1171			break;
1172		}
1173	}
1174
1175	/*
1176	 * Clear the se_matched field for each matched sespec, and drop the
1177	 * reference count since the sespec is no longer on the matched list.
1178	 */
1179	for (sep = matched; sep != T_SE_END; sep = nsep) {
1180		nsep = sep->se_matched;
1181		sep->se_matched = NULL;
1182		mdb_tgt_sespec_rele(t, sep);
1183	}
1184
1185	/*
1186	 * If the matched list was non-empty, see if we hit another event while
1187	 * performing se_cont() processing.  If so, don't bother continuing any
1188	 * further.  If not, arm the sespecs on the old matched list by calling
1189	 * mdb_tgt_sespec_arm_all() again and then continue by calling t_cont.
1190	 */
1191	if (matched != T_SE_END) {
1192		if (error != 0 || !(t->t_status.st_flags & MDB_TGT_ISTOP))
1193			goto out; /* abort now if se_cont() failed */
1194
1195		if ((t->t_matched = tgt_match_sespecs(t, FALSE)) != T_SE_END) {
1196			tgt_disarm_sespecs(t);
1197			goto out;
1198		}
1199
1200		mdb_tgt_sespec_arm_all(t);
1201	}
1202
1203	if (t_cont != t->t_ops->t_step || pc == t->t_status.st_pc) {
1204		if (t_cont(t, &t->t_status) != 0)
1205			error = errno ? errno : -1;
1206	}
1207
1208	tgt_disarm_sespecs(t);
1209
1210	if (t->t_flags & MDB_TGT_F_UNLOAD)
1211		longjmp(mdb.m_frame->f_pcb, MDB_ERR_QUIT);
1212
1213	if (t->t_status.st_state == MDB_TGT_UNDEAD)
1214		mdb_tgt_sespec_idle_all(t, EMDB_TGTZOMB, TRUE);
1215	else if (t->t_status.st_state == MDB_TGT_LOST)
1216		mdb_tgt_sespec_idle_all(t, EMDB_TGTLOST, TRUE);
1217	else if (t->t_status.st_flags & MDB_TGT_ISTOP)
1218		t->t_matched = tgt_match_sespecs(t, TRUE);
1219out:
1220	if (mdb.m_term != NULL)
1221		IOP_RESUME(mdb.m_term);
1222
1223	(void) mdb_signal_unblock(SIGTERM);
1224	(void) mdb_signal_unblock(SIGHUP);
1225	mdb_intr_enable();
1226
1227	for (sep = t->t_matched; sep != T_SE_END; sep = sep->se_matched) {
1228		/*
1229		 * When we invoke a ve_callback, it may in turn request that the
1230		 * target continue immediately after callback processing is
1231		 * complete.  We only allow this to occur if *all* callbacks
1232		 * agree to continue.  To implement this behavior, we keep a
1233		 * count (ncont) of such requests, and only apply the cumulative
1234		 * continue bits (cbits) to the target if ncont is equal to the
1235		 * total number of callbacks that are invoked (n).
1236		 */
1237		for (vep = mdb_list_next(&sep->se_velist);
1238		    vep != NULL; vep = nvep, n++) {
1239			/*
1240			 * Place an extra hold on the current vespec and pick
1241			 * up the next pointer before invoking the callback: we
1242			 * must be prepared for the vespec to be deleted or
1243			 * moved to a different list by the callback.
1244			 */
1245			mdb_tgt_vespec_hold(t, vep);
1246			nvep = mdb_list_next(vep);
1247
1248			vep->ve_flags |= MDB_TGT_SPEC_MATCHED;
1249			vep->ve_hits++;
1250
1251			mdb_nv_set_value(mdb.m_dot, t->t_status.st_pc);
1252			mdb_nv_set_value(hitv, vep->ve_hits);
1253
1254			ASSERT((t->t_flags & T_CONT_BITS) == 0);
1255			vep->ve_callback(t, vep->ve_id, vep->ve_data);
1256
1257			ncont += (t->t_flags & T_CONT_BITS) != 0;
1258			cbits |= (t->t_flags & T_CONT_BITS);
1259			t->t_flags &= ~T_CONT_BITS;
1260
1261			if (vep->ve_limit && vep->ve_hits == vep->ve_limit) {
1262				if (vep->ve_flags & MDB_TGT_SPEC_AUTODEL)
1263					(void) mdb_tgt_vespec_delete(t,
1264					    vep->ve_id);
1265				else if (vep->ve_flags & MDB_TGT_SPEC_AUTODIS)
1266					(void) mdb_tgt_vespec_disable(t,
1267					    vep->ve_id);
1268			}
1269
1270			if (vep->ve_limit && vep->ve_hits < vep->ve_limit) {
1271				if (vep->ve_flags & MDB_TGT_SPEC_AUTOSTOP)
1272					(void) mdb_tgt_continue(t, NULL);
1273			}
1274
1275			mdb_tgt_vespec_rele(t, vep);
1276		}
1277	}
1278
1279	if (t->t_matched != T_SE_END && ncont == n)
1280		t->t_flags |= cbits; /* apply continues (see above) */
1281
1282	mdb_tgt_sespec_prune_all(t);
1283
1284	t->t_status.st_flags &= ~MDB_TGT_BUSY;
1285	t->t_flags &= ~MDB_TGT_F_BUSY;
1286
1287	if (tsp != NULL)
1288		bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t));
1289
1290	if (error != 0)
1291		return (set_errno(error));
1292
1293	return (0);
1294}
1295
1296/*
1297 * This function is the common glue that connects the high-level target layer
1298 * continue functions (e.g. step and cont below) with the low-level
1299 * tgt_continue() function above.  Since vespec callbacks may perform any
1300 * actions, including attempting to continue the target itself, we must be
1301 * prepared to be called while the target is still marked F_BUSY.  In this
1302 * case, we just set a pending bit and return.  When we return from the call
1303 * to tgt_continue() that made us busy into the tgt_request_continue() call
1304 * that is still on the stack, we will loop around and call tgt_continue()
1305 * again.  This allows vespecs to continue the target without recursion.
1306 */
1307static int
1308tgt_request_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp, uint_t tflag,
1309    int (*t_cont)(mdb_tgt_t *, mdb_tgt_status_t *))
1310{
1311	mdb_tgt_spec_desc_t desc;
1312	mdb_sespec_t *sep;
1313	char buf[BUFSIZ];
1314	int status;
1315
1316	if (t->t_flags & MDB_TGT_F_BUSY) {
1317		t->t_flags |= tflag;
1318		return (0);
1319	}
1320
1321	do {
1322		status = tgt_continue(t, tsp, t_cont);
1323	} while (status == 0 && (t->t_flags & T_CONT_BITS));
1324
1325	if (status == 0) {
1326		for (sep = t->t_matched; sep != T_SE_END;
1327		    sep = sep->se_matched) {
1328			mdb_vespec_t *vep;
1329
1330			for (vep = mdb_list_next(&sep->se_velist); vep;
1331			    vep = mdb_list_next(vep)) {
1332				if (vep->ve_flags & MDB_TGT_SPEC_SILENT)
1333					continue;
1334				warn("%s\n", sep->se_ops->se_info(t, sep,
1335				    vep, &desc, buf, sizeof (buf)));
1336			}
1337		}
1338
1339		mdb_callb_fire(MDB_CALLB_STCHG);
1340	}
1341
1342	t->t_flags &= ~T_CONT_BITS;
1343	return (status);
1344}
1345
1346/*
1347 * Restart target execution: we rely upon the underlying target implementation
1348 * to do most of the work for us.  In particular, we assume it will properly
1349 * preserve the state of our event lists if the run fails for some reason,
1350 * and that it will reset all events to the IDLE state if the run succeeds.
1351 * If it is successful, we attempt to activate all of the idle sespecs.  The
1352 * t_run() operation is defined to leave the target stopped at the earliest
1353 * possible point in execution, and then return control to the debugger,
1354 * awaiting a step or continue operation to set it running again.
1355 */
1356int
1357mdb_tgt_run(mdb_tgt_t *t, int argc, const mdb_arg_t *argv)
1358{
1359	int i;
1360
1361	for (i = 0; i < argc; i++) {
1362		if (argv->a_type != MDB_TYPE_STRING)
1363			return (set_errno(EINVAL));
1364	}
1365
1366	if (t->t_ops->t_run(t, argc, argv) == -1)
1367		return (-1); /* errno is set for us */
1368
1369	t->t_flags &= ~T_CONT_BITS;
1370	(void) mdb_tgt_sespec_activate_all(t);
1371
1372	if (mdb.m_term != NULL)
1373		IOP_CTL(mdb.m_term, MDB_IOC_CTTY, NULL);
1374
1375	return (0);
1376}
1377
1378int
1379mdb_tgt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1380{
1381	return (tgt_request_continue(t, tsp, MDB_TGT_F_STEP, t->t_ops->t_step));
1382}
1383
1384int
1385mdb_tgt_step_out(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1386{
1387	t->t_flags |= MDB_TGT_F_STEP_OUT; /* set flag even if tgt not busy */
1388	return (tgt_request_continue(t, tsp, 0, t->t_ops->t_cont));
1389}
1390
1391int
1392mdb_tgt_next(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1393{
1394	t->t_flags |= MDB_TGT_F_NEXT; /* set flag even if tgt not busy */
1395	return (tgt_request_continue(t, tsp, 0, t->t_ops->t_step));
1396}
1397
1398int
1399mdb_tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1400{
1401	return (tgt_request_continue(t, tsp, MDB_TGT_F_CONT, t->t_ops->t_cont));
1402}
1403
1404int
1405mdb_tgt_signal(mdb_tgt_t *t, int sig)
1406{
1407	return (t->t_ops->t_signal(t, sig));
1408}
1409
1410void *
1411mdb_tgt_vespec_data(mdb_tgt_t *t, int vid)
1412{
1413	mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, vid);
1414
1415	if (vep == NULL) {
1416		(void) set_errno(EMDB_NOSESPEC);
1417		return (NULL);
1418	}
1419
1420	return (vep->ve_data);
1421}
1422
1423/*
1424 * Return a structured description and comment string for the given vespec.
1425 * We fill in the common information from the vespec, and then call down to
1426 * the underlying sespec to provide the comment string and modify any
1427 * event type-specific information.
1428 */
1429char *
1430mdb_tgt_vespec_info(mdb_tgt_t *t, int vid, mdb_tgt_spec_desc_t *sp,
1431    char *buf, size_t nbytes)
1432{
1433	mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, vid);
1434
1435	mdb_tgt_spec_desc_t desc;
1436	mdb_sespec_t *sep;
1437
1438	if (vep == NULL) {
1439		if (sp != NULL)
1440			bzero(sp, sizeof (mdb_tgt_spec_desc_t));
1441		(void) set_errno(EMDB_NOSESPEC);
1442		return (NULL);
1443	}
1444
1445	if (sp == NULL)
1446		sp = &desc;
1447
1448	sep = vep->ve_se;
1449
1450	sp->spec_id = vep->ve_id;
1451	sp->spec_flags = vep->ve_flags;
1452	sp->spec_hits = vep->ve_hits;
1453	sp->spec_limit = vep->ve_limit;
1454	sp->spec_state = sep->se_state;
1455	sp->spec_errno = sep->se_errno;
1456	sp->spec_base = 0;
1457	sp->spec_size = 0;
1458	sp->spec_data = vep->ve_data;
1459
1460	return (sep->se_ops->se_info(t, sep, vep, sp, buf, nbytes));
1461}
1462
1463/*
1464 * Qsort callback for sorting vespecs by VID, used below.
1465 */
1466static int
1467tgt_vespec_compare(const mdb_vespec_t **lp, const mdb_vespec_t **rp)
1468{
1469	return ((*lp)->ve_id - (*rp)->ve_id);
1470}
1471
1472/*
1473 * Iterate over all vespecs and call the specified callback function with the
1474 * corresponding VID and caller data pointer.  We want the callback function
1475 * to see a consistent, sorted snapshot of the vespecs, and allow the callback
1476 * to take actions such as deleting the vespec itself, so we cannot simply
1477 * iterate over the lists.  Instead, we pre-allocate an array of vespec
1478 * pointers, fill it in and place an additional hold on each vespec, and then
1479 * sort it.  After the callback has been executed on each vespec in the
1480 * sorted array, we remove our hold and free the temporary array.
1481 */
1482int
1483mdb_tgt_vespec_iter(mdb_tgt_t *t, mdb_tgt_vespec_f *func, void *p)
1484{
1485	mdb_vespec_t **veps, **vepp, **vend;
1486	mdb_vespec_t *vep, *nvep;
1487	mdb_sespec_t *sep;
1488
1489	uint_t vecnt = t->t_vecnt;
1490
1491	veps = mdb_alloc(sizeof (mdb_vespec_t *) * vecnt, UM_SLEEP);
1492	vend = veps + vecnt;
1493	vepp = veps;
1494
1495	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
1496		for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) {
1497			mdb_tgt_vespec_hold(t, vep);
1498			nvep = mdb_list_next(vep);
1499			*vepp++ = vep;
1500		}
1501	}
1502
1503	for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) {
1504		for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) {
1505			mdb_tgt_vespec_hold(t, vep);
1506			nvep = mdb_list_next(vep);
1507			*vepp++ = vep;
1508		}
1509	}
1510
1511	if (vepp != vend) {
1512		fail("target has %u vespecs on list but vecnt shows %u\n",
1513		    (uint_t)(vepp - veps), vecnt);
1514	}
1515
1516	qsort(veps, vecnt, sizeof (mdb_vespec_t *),
1517	    (int (*)(const void *, const void *))tgt_vespec_compare);
1518
1519	for (vepp = veps; vepp < vend; vepp++) {
1520		if (func(t, p, (*vepp)->ve_id, (*vepp)->ve_data) != 0)
1521			break;
1522	}
1523
1524	for (vepp = veps; vepp < vend; vepp++)
1525		mdb_tgt_vespec_rele(t, *vepp);
1526
1527	mdb_free(veps, sizeof (mdb_vespec_t *) * vecnt);
1528	return (0);
1529}
1530
1531/*
1532 * Reset the vespec flags, match limit, and callback data to the specified
1533 * values.  We silently correct invalid parameters, except for the VID.
1534 * The caller is required to query the existing properties and pass back
1535 * the existing values for any properties that should not be modified.
1536 * If the callback data is modified, the caller is responsible for cleaning
1537 * up any state associated with the previous value.
1538 */
1539int
1540mdb_tgt_vespec_modify(mdb_tgt_t *t, int id, uint_t flags,
1541    uint_t limit, void *data)
1542{
1543	mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id);
1544
1545	if (vep == NULL)
1546		return (set_errno(EMDB_NOSESPEC));
1547
1548	/*
1549	 * If the value of the MDB_TGT_SPEC_DISABLED bit is changing, call the
1550	 * appropriate vespec function to do the enable/disable work.
1551	 */
1552	if ((flags & MDB_TGT_SPEC_DISABLED) !=
1553	    (vep->ve_flags & MDB_TGT_SPEC_DISABLED)) {
1554		if (flags & MDB_TGT_SPEC_DISABLED)
1555			(void) mdb_tgt_vespec_disable(t, id);
1556		else
1557			(void) mdb_tgt_vespec_enable(t, id);
1558	}
1559
1560	/*
1561	 * Make that only one MDB_TGT_SPEC_AUTO* bit is set in the new flags
1562	 * value: extra bits are cleared according to order of precedence.
1563	 */
1564	if (flags & MDB_TGT_SPEC_AUTOSTOP)
1565		flags &= ~(MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS);
1566	else if (flags & MDB_TGT_SPEC_AUTODEL)
1567		flags &= ~MDB_TGT_SPEC_AUTODIS;
1568
1569	/*
1570	 * The TEMPORARY property always takes precedence over STICKY.
1571	 */
1572	if (flags & MDB_TGT_SPEC_TEMPORARY)
1573		flags &= ~MDB_TGT_SPEC_STICKY;
1574
1575	/*
1576	 * If any MDB_TGT_SPEC_AUTO* bits are changing, reset the hit count
1577	 * back to zero and clear all of the old auto bits.
1578	 */
1579	if ((flags & T_AUTO_BITS) != (vep->ve_flags & T_AUTO_BITS)) {
1580		vep->ve_flags &= ~T_AUTO_BITS;
1581		vep->ve_hits = 0;
1582	}
1583
1584	vep->ve_flags = (vep->ve_flags & T_IMPL_BITS) | (flags & ~T_IMPL_BITS);
1585	vep->ve_data = data;
1586
1587	/*
1588	 * If any MDB_TGT_SPEC_AUTO* flags are set, make sure the limit is at
1589	 * least one.  If none are set, reset it back to zero.
1590	 */
1591	if (vep->ve_flags & T_AUTO_BITS)
1592		vep->ve_limit = MAX(limit, 1);
1593	else
1594		vep->ve_limit = 0;
1595
1596	/*
1597	 * As a convenience, we allow the caller to specify SPEC_DELETED in
1598	 * the flags field as indication that the event should be deleted.
1599	 */
1600	if (flags & MDB_TGT_SPEC_DELETED)
1601		(void) mdb_tgt_vespec_delete(t, id);
1602
1603	return (0);
1604}
1605
1606/*
1607 * Remove the user disabled bit from the specified vespec, and attempt to
1608 * activate the underlying sespec and move it to the active list if possible.
1609 */
1610int
1611mdb_tgt_vespec_enable(mdb_tgt_t *t, int id)
1612{
1613	mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id);
1614
1615	if (vep == NULL)
1616		return (set_errno(EMDB_NOSESPEC));
1617
1618	if (vep->ve_flags & MDB_TGT_SPEC_DISABLED) {
1619		ASSERT(mdb_list_next(vep) == NULL);
1620		vep->ve_flags &= ~MDB_TGT_SPEC_DISABLED;
1621		if (mdb_tgt_sespec_activate_one(t, vep->ve_se) < 0)
1622			return (-1); /* errno is set for us */
1623	}
1624
1625	return (0);
1626}
1627
1628/*
1629 * Set the user disabled bit on the specified vespec, and move it to the idle
1630 * list.  If the vespec is not alone with its sespec or if it is a currently
1631 * matched event, we must always create a new idle sespec and move the vespec
1632 * there.  If the vespec was alone and active, we can simply idle the sespec.
1633 */
1634int
1635mdb_tgt_vespec_disable(mdb_tgt_t *t, int id)
1636{
1637	mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id);
1638	mdb_sespec_t *sep;
1639
1640	if (vep == NULL)
1641		return (set_errno(EMDB_NOSESPEC));
1642
1643	if (vep->ve_flags & MDB_TGT_SPEC_DISABLED)
1644		return (0); /* already disabled */
1645
1646	if (mdb_list_prev(vep) != NULL || mdb_list_next(vep) != NULL ||
1647	    vep->ve_se->se_matched != NULL) {
1648
1649		sep = mdb_tgt_sespec_insert(t, vep->ve_se->se_ops, &t->t_idle);
1650
1651		mdb_list_delete(&vep->ve_se->se_velist, vep);
1652		mdb_tgt_sespec_rele(t, vep->ve_se);
1653
1654		mdb_list_append(&sep->se_velist, vep);
1655		mdb_tgt_sespec_hold(t, sep);
1656
1657		vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED;
1658		vep->ve_se = sep;
1659
1660	} else if (vep->ve_se->se_state != MDB_TGT_SPEC_IDLE)
1661		mdb_tgt_sespec_idle_one(t, vep->ve_se, EMDB_SPECDIS);
1662
1663	vep->ve_flags |= MDB_TGT_SPEC_DISABLED;
1664	return (0);
1665}
1666
1667/*
1668 * Delete the given vespec.  We use the MDB_TGT_SPEC_DELETED flag to ensure that
1669 * multiple calls to mdb_tgt_vespec_delete to not attempt to decrement the
1670 * reference count on the vespec more than once.  This is because the vespec
1671 * may remain referenced if it is currently held by another routine (e.g.
1672 * vespec_iter), and so the user could attempt to delete it more than once
1673 * since it reference count will be >= 2 prior to the first delete call.
1674 */
1675int
1676mdb_tgt_vespec_delete(mdb_tgt_t *t, int id)
1677{
1678	mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id);
1679
1680	if (vep == NULL)
1681		return (set_errno(EMDB_NOSESPEC));
1682
1683	if (vep->ve_flags & MDB_TGT_SPEC_DELETED)
1684		return (set_errno(EBUSY));
1685
1686	vep->ve_flags |= MDB_TGT_SPEC_DELETED;
1687	mdb_tgt_vespec_rele(t, vep);
1688	return (0);
1689}
1690
1691int
1692mdb_tgt_add_vbrkpt(mdb_tgt_t *t, uintptr_t addr,
1693    int spec_flags, mdb_tgt_se_f *func, void *p)
1694{
1695	return (t->t_ops->t_add_vbrkpt(t, addr, spec_flags, func, p));
1696}
1697
1698int
1699mdb_tgt_add_sbrkpt(mdb_tgt_t *t, const char *symbol,
1700    int spec_flags, mdb_tgt_se_f *func, void *p)
1701{
1702	return (t->t_ops->t_add_sbrkpt(t, symbol, spec_flags, func, p));
1703}
1704
1705int
1706mdb_tgt_add_pwapt(mdb_tgt_t *t, physaddr_t pa, size_t n, uint_t flags,
1707    int spec_flags, mdb_tgt_se_f *func, void *p)
1708{
1709	if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) {
1710		(void) set_errno(EINVAL);
1711		return (0);
1712	}
1713
1714	if (pa + n < pa) {
1715		(void) set_errno(EMDB_WPRANGE);
1716		return (0);
1717	}
1718
1719	return (t->t_ops->t_add_pwapt(t, pa, n, flags, spec_flags, func, p));
1720}
1721
1722int
1723mdb_tgt_add_vwapt(mdb_tgt_t *t, uintptr_t va, size_t n, uint_t flags,
1724    int spec_flags, mdb_tgt_se_f *func, void *p)
1725{
1726	if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) {
1727		(void) set_errno(EINVAL);
1728		return (0);
1729	}
1730
1731	if (va + n < va) {
1732		(void) set_errno(EMDB_WPRANGE);
1733		return (0);
1734	}
1735
1736	return (t->t_ops->t_add_vwapt(t, va, n, flags, spec_flags, func, p));
1737}
1738
1739int
1740mdb_tgt_add_iowapt(mdb_tgt_t *t, uintptr_t addr, size_t n, uint_t flags,
1741    int spec_flags, mdb_tgt_se_f *func, void *p)
1742{
1743	if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) {
1744		(void) set_errno(EINVAL);
1745		return (0);
1746	}
1747
1748	if (addr + n < addr) {
1749		(void) set_errno(EMDB_WPRANGE);
1750		return (0);
1751	}
1752
1753	return (t->t_ops->t_add_iowapt(t, addr, n, flags, spec_flags, func, p));
1754}
1755
1756int
1757mdb_tgt_add_sysenter(mdb_tgt_t *t, int sysnum,
1758    int spec_flags, mdb_tgt_se_f *func, void *p)
1759{
1760	return (t->t_ops->t_add_sysenter(t, sysnum, spec_flags, func, p));
1761}
1762
1763int
1764mdb_tgt_add_sysexit(mdb_tgt_t *t, int sysnum,
1765    int spec_flags, mdb_tgt_se_f *func, void *p)
1766{
1767	return (t->t_ops->t_add_sysexit(t, sysnum, spec_flags, func, p));
1768}
1769
1770int
1771mdb_tgt_add_signal(mdb_tgt_t *t, int sig,
1772    int spec_flags, mdb_tgt_se_f *func, void *p)
1773{
1774	return (t->t_ops->t_add_signal(t, sig, spec_flags, func, p));
1775}
1776
1777int
1778mdb_tgt_add_fault(mdb_tgt_t *t, int flt,
1779    int spec_flags, mdb_tgt_se_f *func, void *p)
1780{
1781	return (t->t_ops->t_add_fault(t, flt, spec_flags, func, p));
1782}
1783
1784int
1785mdb_tgt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid,
1786    const char *rname, mdb_tgt_reg_t *rp)
1787{
1788	return (t->t_ops->t_getareg(t, tid, rname, rp));
1789}
1790
1791int
1792mdb_tgt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid,
1793    const char *rname, mdb_tgt_reg_t r)
1794{
1795	return (t->t_ops->t_putareg(t, tid, rname, r));
1796}
1797
1798int
1799mdb_tgt_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gregs,
1800    mdb_tgt_stack_f *cb, void *p)
1801{
1802	return (t->t_ops->t_stack_iter(t, gregs, cb, p));
1803}
1804
1805int
1806mdb_tgt_xdata_iter(mdb_tgt_t *t, mdb_tgt_xdata_f *func, void *private)
1807{
1808	mdb_xdata_t *xdp;
1809
1810	for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) {
1811		if (func(private, xdp->xd_name, xdp->xd_desc,
1812		    xdp->xd_copy(t, NULL, 0)) != 0)
1813			break;
1814	}
1815
1816	return (0);
1817}
1818
1819ssize_t
1820mdb_tgt_getxdata(mdb_tgt_t *t, const char *name, void *buf, size_t nbytes)
1821{
1822	mdb_xdata_t *xdp;
1823
1824	for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) {
1825		if (strcmp(xdp->xd_name, name) == 0)
1826			return (xdp->xd_copy(t, buf, nbytes));
1827	}
1828
1829	return (set_errno(ENODATA));
1830}
1831
1832long
1833mdb_tgt_notsup()
1834{
1835	return (set_errno(EMDB_TGTNOTSUP));
1836}
1837
1838void *
1839mdb_tgt_null()
1840{
1841	(void) set_errno(EMDB_TGTNOTSUP);
1842	return (NULL);
1843}
1844
1845long
1846mdb_tgt_nop()
1847{
1848	return (0L);
1849}
1850
1851int
1852mdb_tgt_xdata_insert(mdb_tgt_t *t, const char *name, const char *desc,
1853    ssize_t (*copy)(mdb_tgt_t *, void *, size_t))
1854{
1855	mdb_xdata_t *xdp;
1856
1857	for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) {
1858		if (strcmp(xdp->xd_name, name) == 0)
1859			return (set_errno(EMDB_XDEXISTS));
1860	}
1861
1862	xdp = mdb_alloc(sizeof (mdb_xdata_t), UM_SLEEP);
1863	mdb_list_append(&t->t_xdlist, xdp);
1864
1865	xdp->xd_name = name;
1866	xdp->xd_desc = desc;
1867	xdp->xd_copy = copy;
1868
1869	return (0);
1870}
1871
1872int
1873mdb_tgt_xdata_delete(mdb_tgt_t *t, const char *name)
1874{
1875	mdb_xdata_t *xdp;
1876
1877	for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) {
1878		if (strcmp(xdp->xd_name, name) == 0) {
1879			mdb_list_delete(&t->t_xdlist, xdp);
1880			mdb_free(xdp, sizeof (mdb_xdata_t));
1881			return (0);
1882		}
1883	}
1884
1885	return (set_errno(EMDB_NOXD));
1886}
1887
1888int
1889mdb_tgt_sym_match(const GElf_Sym *sym, uint_t mask)
1890{
1891#if STT_NUM != (STT_TLS + 1)
1892#error "STT_NUM has grown. update mdb_tgt_sym_match()"
1893#endif
1894
1895	uchar_t s_bind = GELF_ST_BIND(sym->st_info);
1896	uchar_t s_type = GELF_ST_TYPE(sym->st_info);
1897
1898	/*
1899	 * In case you haven't already guessed, this relies on the bitmask
1900	 * used by <mdb/mdb_target.h> and <libproc.h> for encoding symbol
1901	 * type and binding matching the order of STB and STT constants
1902	 * in <sys/elf.h>.  Changes to ELF must maintain binary
1903	 * compatibility, so I think this is reasonably fair game.
1904	 */
1905	if (s_bind < STB_NUM && s_type < STT_NUM) {
1906		uint_t type = (1 << (s_type + 8)) | (1 << s_bind);
1907		return ((type & ~mask) == 0);
1908	}
1909
1910	return (0); /* Unknown binding or type; fail to match */
1911}
1912
1913void
1914mdb_tgt_elf_export(mdb_gelf_file_t *gf)
1915{
1916	GElf_Xword d = 0, t = 0;
1917	GElf_Addr b = 0, e = 0;
1918	uint32_t m = 0;
1919	mdb_var_t *v;
1920
1921	/*
1922	 * Reset legacy adb variables based on the specified ELF object file
1923	 * provided by the target.  We define these variables:
1924	 *
1925	 * b - the address of the data segment (first writeable Phdr)
1926	 * d - the size of the data segment
1927	 * e - the address of the entry point
1928	 * m - the magic number identifying the file
1929	 * t - the address of the text segment (first executable Phdr)
1930	 */
1931	if (gf != NULL) {
1932		const GElf_Phdr *text = NULL, *data = NULL;
1933		size_t i;
1934
1935		e = gf->gf_ehdr.e_entry;
1936		bcopy(&gf->gf_ehdr.e_ident[EI_MAG0], &m, sizeof (m));
1937
1938		for (i = 0; i < gf->gf_npload; i++) {
1939			if (text == NULL && (gf->gf_phdrs[i].p_flags & PF_X))
1940				text = &gf->gf_phdrs[i];
1941			if (data == NULL && (gf->gf_phdrs[i].p_flags & PF_W))
1942				data = &gf->gf_phdrs[i];
1943		}
1944
1945		if (text != NULL)
1946			t = text->p_memsz;
1947		if (data != NULL) {
1948			b = data->p_vaddr;
1949			d = data->p_memsz;
1950		}
1951	}
1952
1953	if ((v = mdb_nv_lookup(&mdb.m_nv, "b")) != NULL)
1954		mdb_nv_set_value(v, b);
1955	if ((v = mdb_nv_lookup(&mdb.m_nv, "d")) != NULL)
1956		mdb_nv_set_value(v, d);
1957	if ((v = mdb_nv_lookup(&mdb.m_nv, "e")) != NULL)
1958		mdb_nv_set_value(v, e);
1959	if ((v = mdb_nv_lookup(&mdb.m_nv, "m")) != NULL)
1960		mdb_nv_set_value(v, m);
1961	if ((v = mdb_nv_lookup(&mdb.m_nv, "t")) != NULL)
1962		mdb_nv_set_value(v, t);
1963}
1964
1965/*ARGSUSED*/
1966void
1967mdb_tgt_sespec_hold(mdb_tgt_t *t, mdb_sespec_t *sep)
1968{
1969	sep->se_refs++;
1970	ASSERT(sep->se_refs != 0);
1971}
1972
1973void
1974mdb_tgt_sespec_rele(mdb_tgt_t *t, mdb_sespec_t *sep)
1975{
1976	ASSERT(sep->se_refs != 0);
1977
1978	if (--sep->se_refs == 0) {
1979		mdb_dprintf(MDB_DBG_TGT, "destroying sespec %p\n", (void *)sep);
1980		ASSERT(mdb_list_next(&sep->se_velist) == NULL);
1981
1982		if (sep->se_state != MDB_TGT_SPEC_IDLE) {
1983			sep->se_ops->se_dtor(t, sep);
1984			mdb_list_delete(&t->t_active, sep);
1985		} else
1986			mdb_list_delete(&t->t_idle, sep);
1987
1988		mdb_free(sep, sizeof (mdb_sespec_t));
1989	}
1990}
1991
1992mdb_sespec_t *
1993mdb_tgt_sespec_insert(mdb_tgt_t *t, const mdb_se_ops_t *ops, mdb_list_t *list)
1994{
1995	mdb_sespec_t *sep = mdb_zalloc(sizeof (mdb_sespec_t), UM_SLEEP);
1996
1997	if (list == &t->t_active)
1998		sep->se_state = MDB_TGT_SPEC_ACTIVE;
1999	else
2000		sep->se_state = MDB_TGT_SPEC_IDLE;
2001
2002	mdb_list_append(list, sep);
2003	sep->se_ops = ops;
2004	return (sep);
2005}
2006
2007mdb_sespec_t *
2008mdb_tgt_sespec_lookup_active(mdb_tgt_t *t, const mdb_se_ops_t *ops, void *args)
2009{
2010	mdb_sespec_t *sep;
2011
2012	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
2013		if (sep->se_ops == ops && sep->se_ops->se_secmp(t, sep, args))
2014			break;
2015	}
2016
2017	return (sep);
2018}
2019
2020mdb_sespec_t *
2021mdb_tgt_sespec_lookup_idle(mdb_tgt_t *t, const mdb_se_ops_t *ops, void *args)
2022{
2023	mdb_sespec_t *sep;
2024
2025	for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) {
2026		if (sep->se_ops == ops && sep->se_ops->se_vecmp(t,
2027		    mdb_list_next(&sep->se_velist), args))
2028			break;
2029	}
2030
2031	return (sep);
2032}
2033
2034/*ARGSUSED*/
2035void
2036mdb_tgt_vespec_hold(mdb_tgt_t *t, mdb_vespec_t *vep)
2037{
2038	vep->ve_refs++;
2039	ASSERT(vep->ve_refs != 0);
2040}
2041
2042void
2043mdb_tgt_vespec_rele(mdb_tgt_t *t, mdb_vespec_t *vep)
2044{
2045	ASSERT(vep->ve_refs != 0);
2046
2047	if (--vep->ve_refs == 0) {
2048		/*
2049		 * Remove this vespec from the sespec's velist and decrement
2050		 * the reference count on the sespec.
2051		 */
2052		mdb_list_delete(&vep->ve_se->se_velist, vep);
2053		mdb_tgt_sespec_rele(t, vep->ve_se);
2054
2055		/*
2056		 * If we are deleting the most recently assigned VID, reset
2057		 * t_vepos or t_veneg as appropriate to re-use that number.
2058		 * This could be enhanced to re-use any free number by
2059		 * maintaining a bitmap or hash of the allocated IDs.
2060		 */
2061		if (vep->ve_id > 0 && t->t_vepos == vep->ve_id + 1)
2062			t->t_vepos = vep->ve_id;
2063		else if (vep->ve_id < 0 && t->t_veneg == -vep->ve_id + 1)
2064			t->t_veneg = -vep->ve_id;
2065
2066		/*
2067		 * Call the destructor to clean up ve_args, and then free
2068		 * the actual vespec structure.
2069		 */
2070		vep->ve_dtor(vep);
2071		mdb_free(vep, sizeof (mdb_vespec_t));
2072
2073		ASSERT(t->t_vecnt != 0);
2074		t->t_vecnt--;
2075	}
2076}
2077
2078int
2079mdb_tgt_vespec_insert(mdb_tgt_t *t, const mdb_se_ops_t *ops, int flags,
2080    mdb_tgt_se_f *func, void *data, void *args, void (*dtor)(mdb_vespec_t *))
2081{
2082	mdb_vespec_t *vep = mdb_zalloc(sizeof (mdb_vespec_t), UM_SLEEP);
2083
2084	int id, mult, *seqp;
2085	mdb_sespec_t *sep;
2086
2087	/*
2088	 * Make that only one MDB_TGT_SPEC_AUTO* bit is set in the new flags
2089	 * value: extra bits are cleared according to order of precedence.
2090	 */
2091	if (flags & MDB_TGT_SPEC_AUTOSTOP)
2092		flags &= ~(MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS);
2093	else if (flags & MDB_TGT_SPEC_AUTODEL)
2094		flags &= ~MDB_TGT_SPEC_AUTODIS;
2095
2096	/*
2097	 * The TEMPORARY property always takes precedence over STICKY.
2098	 */
2099	if (flags & MDB_TGT_SPEC_TEMPORARY)
2100		flags &= ~MDB_TGT_SPEC_STICKY;
2101
2102	/*
2103	 * Find a matching sespec or create a new one on the appropriate list.
2104	 * We always create a new sespec if the vespec is created disabled.
2105	 */
2106	if (flags & MDB_TGT_SPEC_DISABLED)
2107		sep = mdb_tgt_sespec_insert(t, ops, &t->t_idle);
2108	else if ((sep = mdb_tgt_sespec_lookup_active(t, ops, args)) == NULL &&
2109	    (sep = mdb_tgt_sespec_lookup_idle(t, ops, args)) == NULL)
2110		sep = mdb_tgt_sespec_insert(t, ops, &t->t_active);
2111
2112	/*
2113	 * Generate a new ID for the vespec.  Increasing positive integers are
2114	 * assigned to visible vespecs; decreasing negative integers are
2115	 * assigned to hidden vespecs.  The target saves our most recent choice.
2116	 */
2117	if (flags & MDB_TGT_SPEC_INTERNAL) {
2118		seqp = &t->t_veneg;
2119		mult = -1;
2120	} else {
2121		seqp = &t->t_vepos;
2122		mult = 1;
2123	}
2124
2125	id = *seqp;
2126
2127	while (mdb_tgt_vespec_lookup(t, id * mult) != NULL)
2128		id = MAX(id + 1, 1);
2129
2130	*seqp = MAX(id + 1, 1);
2131
2132	vep->ve_id = id * mult;
2133	vep->ve_flags = flags & ~(MDB_TGT_SPEC_MATCHED | MDB_TGT_SPEC_DELETED);
2134	vep->ve_se = sep;
2135	vep->ve_callback = func;
2136	vep->ve_data = data;
2137	vep->ve_args = args;
2138	vep->ve_dtor = dtor;
2139
2140	mdb_list_append(&sep->se_velist, vep);
2141	mdb_tgt_sespec_hold(t, sep);
2142
2143	mdb_tgt_vespec_hold(t, vep);
2144	t->t_vecnt++;
2145
2146	/*
2147	 * If this vespec is the first reference to the sespec and it's active,
2148	 * then it is newly created and we should attempt to initialize it.
2149	 * If se_ctor fails, then move the sespec back to the idle list.
2150	 */
2151	if (sep->se_refs == 1 && sep->se_state == MDB_TGT_SPEC_ACTIVE &&
2152	    sep->se_ops->se_ctor(t, sep, vep->ve_args) == -1) {
2153
2154		mdb_list_delete(&t->t_active, sep);
2155		mdb_list_append(&t->t_idle, sep);
2156
2157		sep->se_state = MDB_TGT_SPEC_IDLE;
2158		sep->se_errno = errno;
2159		sep->se_data = NULL;
2160	}
2161
2162	/*
2163	 * If the sespec is active and the target is currently running (because
2164	 * we grabbed it using PGRAB_NOSTOP), then go ahead and attempt to arm
2165	 * the sespec so it will take effect immediately.
2166	 */
2167	if (sep->se_state == MDB_TGT_SPEC_ACTIVE &&
2168	    t->t_status.st_state == MDB_TGT_RUNNING)
2169		mdb_tgt_sespec_arm_one(t, sep);
2170
2171	mdb_dprintf(MDB_DBG_TGT, "inserted [ %d ] sep=%p refs=%u state=%d\n",
2172	    vep->ve_id, (void *)sep, sep->se_refs, sep->se_state);
2173
2174	return (vep->ve_id);
2175}
2176
2177/*
2178 * Search the target's active, idle, and disabled lists for the vespec matching
2179 * the specified VID, and return a pointer to it, or NULL if no match is found.
2180 */
2181mdb_vespec_t *
2182mdb_tgt_vespec_lookup(mdb_tgt_t *t, int vid)
2183{
2184	mdb_sespec_t *sep;
2185	mdb_vespec_t *vep;
2186
2187	if (vid == 0)
2188		return (NULL); /* 0 is never a valid VID */
2189
2190	for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) {
2191		for (vep = mdb_list_next(&sep->se_velist); vep;
2192		    vep = mdb_list_next(vep)) {
2193			if (vep->ve_id == vid)
2194				return (vep);
2195		}
2196	}
2197
2198	for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) {
2199		for (vep = mdb_list_next(&sep->se_velist); vep;
2200		    vep = mdb_list_next(vep)) {
2201			if (vep->ve_id == vid)
2202				return (vep);
2203		}
2204	}
2205
2206	return (NULL);
2207}
2208
2209/*ARGSUSED*/
2210void
2211no_ve_dtor(mdb_vespec_t *vep)
2212{
2213	/* default destructor does nothing */
2214}
2215
2216/*ARGSUSED*/
2217void
2218no_se_f(mdb_tgt_t *t, int vid, void *data)
2219{
2220	/* default callback does nothing */
2221}
2222
2223/*ARGSUSED*/
2224void
2225no_se_dtor(mdb_tgt_t *t, mdb_sespec_t *sep)
2226{
2227	/* default destructor does nothing */
2228}
2229
2230/*ARGSUSED*/
2231int
2232no_se_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args)
2233{
2234	return (sep->se_data == args);
2235}
2236
2237/*ARGSUSED*/
2238int
2239no_se_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args)
2240{
2241	return (vep->ve_args == args);
2242}
2243
2244/*ARGSUSED*/
2245int
2246no_se_arm(mdb_tgt_t *t, mdb_sespec_t *sep)
2247{
2248	return (0); /* return success */
2249}
2250
2251/*ARGSUSED*/
2252int
2253no_se_disarm(mdb_tgt_t *t, mdb_sespec_t *sep)
2254{
2255	return (0); /* return success */
2256}
2257
2258/*ARGSUSED*/
2259int
2260no_se_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp)
2261{
2262	if (tsp != &t->t_status)
2263		bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t));
2264
2265	return (0); /* return success */
2266}
2267
2268int
2269mdb_tgt_register_dcmds(mdb_tgt_t *t, const mdb_dcmd_t *dcp, int flags)
2270{
2271	int fail = 0;
2272
2273	for (; dcp->dc_name != NULL; dcp++) {
2274		if (mdb_module_add_dcmd(t->t_module, dcp, flags) == -1) {
2275			warn("failed to add dcmd %s", dcp->dc_name);
2276			fail++;
2277		}
2278	}
2279
2280	return (fail > 0 ? -1 : 0);
2281}
2282
2283int
2284mdb_tgt_register_walkers(mdb_tgt_t *t, const mdb_walker_t *wp, int flags)
2285{
2286	int fail = 0;
2287
2288	for (; wp->walk_name != NULL; wp++) {
2289		if (mdb_module_add_walker(t->t_module, wp, flags) == -1) {
2290			warn("failed to add walk %s", wp->walk_name);
2291			fail++;
2292		}
2293	}
2294
2295	return (fail > 0 ? -1 : 0);
2296}
2297
2298void
2299mdb_tgt_register_regvars(mdb_tgt_t *t, const mdb_tgt_regdesc_t *rdp,
2300    const mdb_nv_disc_t *disc, int flags)
2301{
2302	for (; rdp->rd_name != NULL; rdp++) {
2303		if (!(rdp->rd_flags & MDB_TGT_R_EXPORT))
2304			continue; /* Don't export register as a variable */
2305
2306		if (rdp->rd_flags & MDB_TGT_R_RDONLY)
2307			flags |= MDB_NV_RDONLY;
2308
2309		(void) mdb_nv_insert(&mdb.m_nv, rdp->rd_name, disc,
2310		    (uintptr_t)t, MDB_NV_PERSIST | flags);
2311	}
2312}
2313