xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_set.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate  * Support for ::set dcmd.  The +/-o option processing code is provided in a
31*7c478bd9Sstevel@tonic-gate  * stand-alone function so it can be used by the command-line option processing
32*7c478bd9Sstevel@tonic-gate  * code in mdb_main.c.  This facility provides an easy way for us to add more
33*7c478bd9Sstevel@tonic-gate  * configurable options without having to add a new dcmd each time.
34*7c478bd9Sstevel@tonic-gate  */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_target.h>
37*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
38*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_string.h>
39*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h>
40*7c478bd9Sstevel@tonic-gate #include <mdb/mdb.h>
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
43*7c478bd9Sstevel@tonic-gate static int
44*7c478bd9Sstevel@tonic-gate opt_set_mflags(int enable, uint_t bits, const char *arg)
45*7c478bd9Sstevel@tonic-gate {
46*7c478bd9Sstevel@tonic-gate 	mdb.m_flags = (mdb.m_flags & ~bits) | (bits & -enable);
47*7c478bd9Sstevel@tonic-gate 	return (1);
48*7c478bd9Sstevel@tonic-gate }
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
51*7c478bd9Sstevel@tonic-gate static int
52*7c478bd9Sstevel@tonic-gate opt_set_tflags(int enable, uint_t bits, const char *arg)
53*7c478bd9Sstevel@tonic-gate {
54*7c478bd9Sstevel@tonic-gate 	mdb.m_tgtflags = (mdb.m_tgtflags & ~bits) | (bits & -enable);
55*7c478bd9Sstevel@tonic-gate 	return (1);
56*7c478bd9Sstevel@tonic-gate }
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate static int
59*7c478bd9Sstevel@tonic-gate opt_pager(int enable, uint_t bits, const char *arg)
60*7c478bd9Sstevel@tonic-gate {
61*7c478bd9Sstevel@tonic-gate 	if (enable)
62*7c478bd9Sstevel@tonic-gate 		mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE);
63*7c478bd9Sstevel@tonic-gate 	else
64*7c478bd9Sstevel@tonic-gate 		mdb_iob_clrflags(mdb.m_out, MDB_IOB_PGENABLE);
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	return (opt_set_mflags(enable, bits, arg));
67*7c478bd9Sstevel@tonic-gate }
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate static int
70*7c478bd9Sstevel@tonic-gate opt_adb(int enable, uint_t bits, const char *arg)
71*7c478bd9Sstevel@tonic-gate {
72*7c478bd9Sstevel@tonic-gate 	if (enable)
73*7c478bd9Sstevel@tonic-gate 		(void) mdb_set_prompt("");
74*7c478bd9Sstevel@tonic-gate 	else if (mdb.m_promptlen == 0)
75*7c478bd9Sstevel@tonic-gate 		(void) mdb_set_prompt("> ");
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 	(void) opt_pager(1 - enable, MDB_FL_PAGER, arg);
78*7c478bd9Sstevel@tonic-gate 	return (opt_set_mflags(enable, bits, arg));
79*7c478bd9Sstevel@tonic-gate }
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
82*7c478bd9Sstevel@tonic-gate static int
83*7c478bd9Sstevel@tonic-gate opt_armemlim(int enable, uint_t bits, const char *arg)
84*7c478bd9Sstevel@tonic-gate {
85*7c478bd9Sstevel@tonic-gate 	if (strisnum(arg)) {
86*7c478bd9Sstevel@tonic-gate 		mdb.m_armemlim = strtoi(arg);
87*7c478bd9Sstevel@tonic-gate 		return (1);
88*7c478bd9Sstevel@tonic-gate 	}
89*7c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "none") == 0) {
90*7c478bd9Sstevel@tonic-gate 		mdb.m_armemlim = MDB_ARR_NOLIMIT;
91*7c478bd9Sstevel@tonic-gate 		return (1);
92*7c478bd9Sstevel@tonic-gate 	}
93*7c478bd9Sstevel@tonic-gate 	return (0);
94*7c478bd9Sstevel@tonic-gate }
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
97*7c478bd9Sstevel@tonic-gate static int
98*7c478bd9Sstevel@tonic-gate opt_arstrlim(int enable, uint_t bits, const char *arg)
99*7c478bd9Sstevel@tonic-gate {
100*7c478bd9Sstevel@tonic-gate 	if (strisnum(arg)) {
101*7c478bd9Sstevel@tonic-gate 		mdb.m_arstrlim = strtoi(arg);
102*7c478bd9Sstevel@tonic-gate 		return (1);
103*7c478bd9Sstevel@tonic-gate 	}
104*7c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "none") == 0) {
105*7c478bd9Sstevel@tonic-gate 		mdb.m_arstrlim = MDB_ARR_NOLIMIT;
106*7c478bd9Sstevel@tonic-gate 		return (1);
107*7c478bd9Sstevel@tonic-gate 	}
108*7c478bd9Sstevel@tonic-gate 	return (0);
109*7c478bd9Sstevel@tonic-gate }
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
112*7c478bd9Sstevel@tonic-gate static int
113*7c478bd9Sstevel@tonic-gate opt_exec_mode(int enable, uint_t bits, const char *arg)
114*7c478bd9Sstevel@tonic-gate {
115*7c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "ask") == 0) {
116*7c478bd9Sstevel@tonic-gate 		mdb.m_execmode = MDB_EM_ASK;
117*7c478bd9Sstevel@tonic-gate 		return (1);
118*7c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "stop") == 0) {
119*7c478bd9Sstevel@tonic-gate 		mdb.m_execmode = MDB_EM_STOP;
120*7c478bd9Sstevel@tonic-gate 		return (1);
121*7c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "follow") == 0) {
122*7c478bd9Sstevel@tonic-gate 		mdb.m_execmode = MDB_EM_FOLLOW;
123*7c478bd9Sstevel@tonic-gate 		return (1);
124*7c478bd9Sstevel@tonic-gate 	}
125*7c478bd9Sstevel@tonic-gate 	return (0);
126*7c478bd9Sstevel@tonic-gate }
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
129*7c478bd9Sstevel@tonic-gate static int
130*7c478bd9Sstevel@tonic-gate opt_fork_mode(int enable, uint_t bits, const char *arg)
131*7c478bd9Sstevel@tonic-gate {
132*7c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "ask") == 0) {
133*7c478bd9Sstevel@tonic-gate 		mdb.m_forkmode = MDB_FM_ASK;
134*7c478bd9Sstevel@tonic-gate 		return (1);
135*7c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "parent") == 0) {
136*7c478bd9Sstevel@tonic-gate 		mdb.m_forkmode = MDB_FM_PARENT;
137*7c478bd9Sstevel@tonic-gate 		return (1);
138*7c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "child") == 0) {
139*7c478bd9Sstevel@tonic-gate 		mdb.m_forkmode = MDB_FM_CHILD;
140*7c478bd9Sstevel@tonic-gate 		return (1);
141*7c478bd9Sstevel@tonic-gate 	}
142*7c478bd9Sstevel@tonic-gate 	return (0);
143*7c478bd9Sstevel@tonic-gate }
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
146*7c478bd9Sstevel@tonic-gate static int
147*7c478bd9Sstevel@tonic-gate opt_set_term(int enable, uint_t bits, const char *arg)
148*7c478bd9Sstevel@tonic-gate {
149*7c478bd9Sstevel@tonic-gate 	mdb.m_termtype = strdup(arg);
150*7c478bd9Sstevel@tonic-gate 	mdb.m_flags &= ~MDB_FL_TERMGUESS;
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	return (1);
153*7c478bd9Sstevel@tonic-gate }
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate int
156*7c478bd9Sstevel@tonic-gate mdb_set_options(const char *s, int enable)
157*7c478bd9Sstevel@tonic-gate {
158*7c478bd9Sstevel@tonic-gate 	static const struct opdesc {
159*7c478bd9Sstevel@tonic-gate 		const char *opt_name;
160*7c478bd9Sstevel@tonic-gate 		int (*opt_func)(int, uint_t, const char *);
161*7c478bd9Sstevel@tonic-gate 		uint_t opt_bits;
162*7c478bd9Sstevel@tonic-gate 	} opdtab[] = {
163*7c478bd9Sstevel@tonic-gate 		{ "adb", opt_adb, MDB_FL_REPLAST | MDB_FL_NOMODS | MDB_FL_ADB },
164*7c478bd9Sstevel@tonic-gate 		{ "array_mem_limit", opt_armemlim, 0 },
165*7c478bd9Sstevel@tonic-gate 		{ "array_str_limit", opt_arstrlim, 0 },
166*7c478bd9Sstevel@tonic-gate 		{ "follow_exec_mode", opt_exec_mode, 0 },
167*7c478bd9Sstevel@tonic-gate 		{ "follow_fork_mode", opt_fork_mode, 0 },
168*7c478bd9Sstevel@tonic-gate 		{ "pager", opt_pager, MDB_FL_PAGER },
169*7c478bd9Sstevel@tonic-gate 		{ "term", opt_set_term, 0 },
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate 		{ "ignoreeof", opt_set_mflags, MDB_FL_IGNEOF },
172*7c478bd9Sstevel@tonic-gate 		{ "repeatlast", opt_set_mflags, MDB_FL_REPLAST },
173*7c478bd9Sstevel@tonic-gate 		{ "latest", opt_set_mflags, MDB_FL_LATEST },
174*7c478bd9Sstevel@tonic-gate 		{ "noctf", opt_set_mflags, MDB_FL_NOCTF },
175*7c478bd9Sstevel@tonic-gate 		{ "nomods", opt_set_mflags, MDB_FL_NOMODS },
176*7c478bd9Sstevel@tonic-gate 		{ "showlmid", opt_set_mflags, MDB_FL_SHOWLMID },
177*7c478bd9Sstevel@tonic-gate 		{ "stop_on_bpt_nosym", opt_set_mflags, MDB_FL_BPTNOSYMSTOP },
178*7c478bd9Sstevel@tonic-gate 		{ "write_readback", opt_set_mflags, MDB_FL_READBACK },
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 		{ "allow_io_access", opt_set_tflags, MDB_TGT_F_ALLOWIO },
181*7c478bd9Sstevel@tonic-gate 		{ "nostop", opt_set_tflags, MDB_TGT_F_NOSTOP },
182*7c478bd9Sstevel@tonic-gate 		{ NULL, NULL, 0 }
183*7c478bd9Sstevel@tonic-gate 	};
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate 	const struct opdesc *opp;
186*7c478bd9Sstevel@tonic-gate 	char *buf = strdup(s);
187*7c478bd9Sstevel@tonic-gate 	char *opt, *arg;
188*7c478bd9Sstevel@tonic-gate 	int status = 1;
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 	for (opt = strtok(buf, ","); opt != NULL; opt = strtok(NULL, ",")) {
191*7c478bd9Sstevel@tonic-gate 		if ((arg = strchr(opt, '=')) != NULL)
192*7c478bd9Sstevel@tonic-gate 			*arg++ = '\0';
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate 		for (opp = opdtab; opp->opt_name != NULL; opp++) {
195*7c478bd9Sstevel@tonic-gate 			if (strcmp(opt, opp->opt_name) == 0) {
196*7c478bd9Sstevel@tonic-gate 				if (opp->opt_bits != 0 && arg != NULL) {
197*7c478bd9Sstevel@tonic-gate 					mdb_warn("option does not accept an "
198*7c478bd9Sstevel@tonic-gate 					    "argument -- %s\n", opt);
199*7c478bd9Sstevel@tonic-gate 					status = 0;
200*7c478bd9Sstevel@tonic-gate 				} else if (opp->opt_bits == 0 && arg == NULL) {
201*7c478bd9Sstevel@tonic-gate 					mdb_warn("option requires an argument "
202*7c478bd9Sstevel@tonic-gate 					    "-- %s\n", opt);
203*7c478bd9Sstevel@tonic-gate 					status = 0;
204*7c478bd9Sstevel@tonic-gate 				} else if (opp->opt_func(enable != 0,
205*7c478bd9Sstevel@tonic-gate 				    opp->opt_bits, arg) == 0) {
206*7c478bd9Sstevel@tonic-gate 					mdb_warn("invalid argument for option "
207*7c478bd9Sstevel@tonic-gate 					    "%s -- %s\n", opt, arg);
208*7c478bd9Sstevel@tonic-gate 					status = 0;
209*7c478bd9Sstevel@tonic-gate 				}
210*7c478bd9Sstevel@tonic-gate 				break;
211*7c478bd9Sstevel@tonic-gate 			}
212*7c478bd9Sstevel@tonic-gate 		}
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 		if (opp->opt_name == NULL) {
215*7c478bd9Sstevel@tonic-gate 			mdb_warn("invalid debugger option -- %s\n", opt);
216*7c478bd9Sstevel@tonic-gate 			status = 0;
217*7c478bd9Sstevel@tonic-gate 		}
218*7c478bd9Sstevel@tonic-gate 	}
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	mdb_free(buf, strlen(s) + 1);
221*7c478bd9Sstevel@tonic-gate 	return (status);
222*7c478bd9Sstevel@tonic-gate }
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate static void
225*7c478bd9Sstevel@tonic-gate print_path(const char **path, int indent)
226*7c478bd9Sstevel@tonic-gate {
227*7c478bd9Sstevel@tonic-gate 	if (path != NULL && *path != NULL) {
228*7c478bd9Sstevel@tonic-gate 		for (mdb_printf("%s\n", *path++); *path != NULL; path++)
229*7c478bd9Sstevel@tonic-gate 			mdb_printf("%*s%s\n", indent, " ", *path);
230*7c478bd9Sstevel@tonic-gate 	}
231*7c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
232*7c478bd9Sstevel@tonic-gate }
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate #define	LABEL_INDENT	26
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate static void
237*7c478bd9Sstevel@tonic-gate print_properties(void)
238*7c478bd9Sstevel@tonic-gate {
239*7c478bd9Sstevel@tonic-gate 	int tflags = mdb_tgt_getflags(mdb.m_target);
240*7c478bd9Sstevel@tonic-gate 	uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_AUTOWRAP;
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 	mdb_iob_clrflags(mdb.m_out, MDB_IOB_AUTOWRAP);
243*7c478bd9Sstevel@tonic-gate 	mdb_printf("\n  macro path: ");
244*7c478bd9Sstevel@tonic-gate 	print_path(mdb.m_ipath, 14);
245*7c478bd9Sstevel@tonic-gate 	mdb_printf(" module path: ");
246*7c478bd9Sstevel@tonic-gate 	print_path(mdb.m_lpath, 14);
247*7c478bd9Sstevel@tonic-gate 	mdb_iob_setflags(mdb.m_out, oflags);
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 	mdb_printf("%*s %lr (%s)\n", LABEL_INDENT, "symbol matching distance:",
250*7c478bd9Sstevel@tonic-gate 	    mdb.m_symdist, mdb.m_symdist ? "absolute mode" : "smart mode");
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate 	mdb_printf("%*s ", LABEL_INDENT, "array member print limit:");
253*7c478bd9Sstevel@tonic-gate 	if (mdb.m_armemlim != MDB_ARR_NOLIMIT)
254*7c478bd9Sstevel@tonic-gate 		mdb_printf("%u\n", mdb.m_armemlim);
255*7c478bd9Sstevel@tonic-gate 	else
256*7c478bd9Sstevel@tonic-gate 		mdb_printf("none\n");
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 	mdb_printf(" array string print limit: ");
259*7c478bd9Sstevel@tonic-gate 	if (mdb.m_arstrlim != MDB_ARR_NOLIMIT)
260*7c478bd9Sstevel@tonic-gate 		mdb_printf("%u\n", mdb.m_arstrlim);
261*7c478bd9Sstevel@tonic-gate 	else
262*7c478bd9Sstevel@tonic-gate 		mdb_printf("none\n");
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 	mdb_printf("%*s \"%s\"\n", LABEL_INDENT, "command prompt:",
265*7c478bd9Sstevel@tonic-gate 	    mdb.m_prompt);
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	mdb_printf("%*s ", LABEL_INDENT, "debugger options:");
268*7c478bd9Sstevel@tonic-gate 	(void) mdb_inc_indent(LABEL_INDENT + 1);
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 	mdb_printf("follow_exec_mode=");
271*7c478bd9Sstevel@tonic-gate 	switch (mdb.m_execmode) {
272*7c478bd9Sstevel@tonic-gate 	case MDB_EM_ASK:
273*7c478bd9Sstevel@tonic-gate 		mdb_printf("ask");
274*7c478bd9Sstevel@tonic-gate 		break;
275*7c478bd9Sstevel@tonic-gate 	case MDB_EM_STOP:
276*7c478bd9Sstevel@tonic-gate 		mdb_printf("stop");
277*7c478bd9Sstevel@tonic-gate 		break;
278*7c478bd9Sstevel@tonic-gate 	case MDB_EM_FOLLOW:
279*7c478bd9Sstevel@tonic-gate 		mdb_printf("follow");
280*7c478bd9Sstevel@tonic-gate 		break;
281*7c478bd9Sstevel@tonic-gate 	}
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate #define	COMMAFLAG(name) { mdb_printf(", "); mdb_printf(name); }
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 	COMMAFLAG("follow_fork_mode");
286*7c478bd9Sstevel@tonic-gate 	switch (mdb.m_forkmode) {
287*7c478bd9Sstevel@tonic-gate 	case MDB_FM_ASK:
288*7c478bd9Sstevel@tonic-gate 		mdb_printf("ask");
289*7c478bd9Sstevel@tonic-gate 		break;
290*7c478bd9Sstevel@tonic-gate 	case MDB_FM_PARENT:
291*7c478bd9Sstevel@tonic-gate 		mdb_printf("parent");
292*7c478bd9Sstevel@tonic-gate 		break;
293*7c478bd9Sstevel@tonic-gate 	case MDB_FM_CHILD:
294*7c478bd9Sstevel@tonic-gate 		mdb_printf("child");
295*7c478bd9Sstevel@tonic-gate 		break;
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_ADB)
299*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("adb");
300*7c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_IGNEOF)
301*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("ignoreeof");
302*7c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_PAGER)
303*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("pager");
304*7c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_REPLAST)
305*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("repeatlast");
306*7c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_SHOWLMID)
307*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("showlmid");
308*7c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_BPTNOSYMSTOP)
309*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("stop_on_bpt_nosym");
310*7c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_READBACK)
311*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("write_readback");
312*7c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
313*7c478bd9Sstevel@tonic-gate 	(void) mdb_dec_indent(LABEL_INDENT + 1);
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 	mdb_printf("%*s ", LABEL_INDENT, "target options:");
316*7c478bd9Sstevel@tonic-gate 	(void) mdb_inc_indent(LABEL_INDENT + 1);
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_RDWR)
319*7c478bd9Sstevel@tonic-gate 		mdb_printf("read-write");
320*7c478bd9Sstevel@tonic-gate 	else
321*7c478bd9Sstevel@tonic-gate 		mdb_printf("read-only");
322*7c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_ALLOWIO)
323*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("allow-io-access");
324*7c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_FORCE)
325*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("force-attach");
326*7c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_PRELOAD)
327*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("preload-syms");
328*7c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_NOLOAD)
329*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("no-load-objs");
330*7c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_NOSTOP)
331*7c478bd9Sstevel@tonic-gate 		COMMAFLAG("no-stop");
332*7c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
333*7c478bd9Sstevel@tonic-gate 	(void) mdb_dec_indent(LABEL_INDENT + 1);
334*7c478bd9Sstevel@tonic-gate }
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
337*7c478bd9Sstevel@tonic-gate int
338*7c478bd9Sstevel@tonic-gate cmd_set(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
339*7c478bd9Sstevel@tonic-gate {
340*7c478bd9Sstevel@tonic-gate 	const char *opt_I = NULL, *opt_L = NULL, *opt_P = NULL, *opt_o = NULL;
341*7c478bd9Sstevel@tonic-gate 	const char *opt_plus_o = NULL, *opt_D = NULL;
342*7c478bd9Sstevel@tonic-gate 	uint_t opt_w = FALSE, opt_plus_w = FALSE, opt_W = FALSE;
343*7c478bd9Sstevel@tonic-gate 	uint_t opt_plus_W = FALSE, opt_F = FALSE;
344*7c478bd9Sstevel@tonic-gate 	uintptr_t opt_s = (uintptr_t)(long)-1;
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 	int tflags = 0;
347*7c478bd9Sstevel@tonic-gate 	int i;
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC)
350*7c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate 	/*
353*7c478bd9Sstevel@tonic-gate 	 * If no options are specified, print out the current set of target
354*7c478bd9Sstevel@tonic-gate 	 * and debugger properties that can be modified with ::set.
355*7c478bd9Sstevel@tonic-gate 	 */
356*7c478bd9Sstevel@tonic-gate 	if (argc == 0) {
357*7c478bd9Sstevel@tonic-gate 		print_properties();
358*7c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
359*7c478bd9Sstevel@tonic-gate 	}
360*7c478bd9Sstevel@tonic-gate 
361*7c478bd9Sstevel@tonic-gate 	while ((i = mdb_getopts(argc, argv,
362*7c478bd9Sstevel@tonic-gate 	    'F', MDB_OPT_SETBITS, TRUE, &opt_F,
363*7c478bd9Sstevel@tonic-gate 	    'I', MDB_OPT_STR, &opt_I,
364*7c478bd9Sstevel@tonic-gate 	    'L', MDB_OPT_STR, &opt_L,
365*7c478bd9Sstevel@tonic-gate 	    'P', MDB_OPT_STR, &opt_P,
366*7c478bd9Sstevel@tonic-gate 	    'o', MDB_OPT_STR, &opt_o,
367*7c478bd9Sstevel@tonic-gate 	    's', MDB_OPT_UINTPTR, &opt_s,
368*7c478bd9Sstevel@tonic-gate 	    'w', MDB_OPT_SETBITS, TRUE, &opt_w,
369*7c478bd9Sstevel@tonic-gate 	    'W', MDB_OPT_SETBITS, TRUE, &opt_W,
370*7c478bd9Sstevel@tonic-gate 	    'D', MDB_OPT_STR, &opt_D, NULL)) != argc) {
371*7c478bd9Sstevel@tonic-gate 		uint_t n = 1;
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 		argv += i; /* skip past args we processed */
374*7c478bd9Sstevel@tonic-gate 		argc -= i; /* adjust argc */
375*7c478bd9Sstevel@tonic-gate 
376*7c478bd9Sstevel@tonic-gate 		if (argv[0].a_type != MDB_TYPE_STRING)
377*7c478bd9Sstevel@tonic-gate 			return (DCMD_USAGE);
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 		if (strcmp(argv->a_un.a_str, "+W") == 0)
380*7c478bd9Sstevel@tonic-gate 			opt_plus_W = TRUE;
381*7c478bd9Sstevel@tonic-gate 		else if (strcmp(argv->a_un.a_str, "+w") == 0)
382*7c478bd9Sstevel@tonic-gate 			opt_plus_w = TRUE;
383*7c478bd9Sstevel@tonic-gate 		else if (strcmp(argv->a_un.a_str, "+o") == 0 &&
384*7c478bd9Sstevel@tonic-gate 		    argc >= 2 && argv[1].a_type == MDB_TYPE_STRING) {
385*7c478bd9Sstevel@tonic-gate 			opt_plus_o = argv[1].a_un.a_str;
386*7c478bd9Sstevel@tonic-gate 			n = 2;
387*7c478bd9Sstevel@tonic-gate 		} else
388*7c478bd9Sstevel@tonic-gate 			return (DCMD_USAGE);
389*7c478bd9Sstevel@tonic-gate 
390*7c478bd9Sstevel@tonic-gate 		/* remove the flag and possible argument */
391*7c478bd9Sstevel@tonic-gate 		argv += n;
392*7c478bd9Sstevel@tonic-gate 		argc -= n;
393*7c478bd9Sstevel@tonic-gate 	}
394*7c478bd9Sstevel@tonic-gate 
395*7c478bd9Sstevel@tonic-gate 	if ((opt_w && opt_plus_w) || (opt_W && opt_plus_W))
396*7c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 	/*
399*7c478bd9Sstevel@tonic-gate 	 * Handle -w, -/+W and -F first: as these options modify the target,
400*7c478bd9Sstevel@tonic-gate 	 * they are the only ::set changes that can potentially fail.  We'll
401*7c478bd9Sstevel@tonic-gate 	 * use these flags to modify a copy of the target's t_flags, which we'll
402*7c478bd9Sstevel@tonic-gate 	 * then pass to the target's setflags op.  This allows the target to
403*7c478bd9Sstevel@tonic-gate 	 * detect newly-set and newly-cleared flags by comparing the passed
404*7c478bd9Sstevel@tonic-gate 	 * value to the current t_flags.
405*7c478bd9Sstevel@tonic-gate 	 */
406*7c478bd9Sstevel@tonic-gate 	tflags = mdb_tgt_getflags(mdb.m_target);
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate 	if (opt_w)
409*7c478bd9Sstevel@tonic-gate 		tflags |= MDB_TGT_F_RDWR;
410*7c478bd9Sstevel@tonic-gate 	if (opt_plus_w)
411*7c478bd9Sstevel@tonic-gate 		tflags &= ~MDB_TGT_F_RDWR;
412*7c478bd9Sstevel@tonic-gate 	if (opt_W)
413*7c478bd9Sstevel@tonic-gate 		tflags |= MDB_TGT_F_ALLOWIO;
414*7c478bd9Sstevel@tonic-gate 	if (opt_plus_W)
415*7c478bd9Sstevel@tonic-gate 		tflags &= ~MDB_TGT_F_ALLOWIO;
416*7c478bd9Sstevel@tonic-gate 	if (opt_F)
417*7c478bd9Sstevel@tonic-gate 		tflags |= MDB_TGT_F_FORCE;
418*7c478bd9Sstevel@tonic-gate 
419*7c478bd9Sstevel@tonic-gate 	if (tflags != mdb_tgt_getflags(mdb.m_target) &&
420*7c478bd9Sstevel@tonic-gate 	    mdb_tgt_setflags(mdb.m_target, tflags) == -1)
421*7c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate 	/*
424*7c478bd9Sstevel@tonic-gate 	 * Now handle everything that either can't fail or we don't care if
425*7c478bd9Sstevel@tonic-gate 	 * it does.  Note that we handle +/-o first in case another option
426*7c478bd9Sstevel@tonic-gate 	 * overrides a change made implicity by a +/-o argument (e.g. -P).
427*7c478bd9Sstevel@tonic-gate 	 */
428*7c478bd9Sstevel@tonic-gate 	if (opt_o != NULL)
429*7c478bd9Sstevel@tonic-gate 		(void) mdb_set_options(opt_o, TRUE);
430*7c478bd9Sstevel@tonic-gate 	if (opt_plus_o != NULL)
431*7c478bd9Sstevel@tonic-gate 		(void) mdb_set_options(opt_plus_o, FALSE);
432*7c478bd9Sstevel@tonic-gate 	if (opt_I != NULL) {
433*7c478bd9Sstevel@tonic-gate #ifdef _KMDB
434*7c478bd9Sstevel@tonic-gate 		mdb_warn("macro path cannot be set under kmdb\n");
435*7c478bd9Sstevel@tonic-gate #else
436*7c478bd9Sstevel@tonic-gate 		mdb_set_ipath(opt_I);
437*7c478bd9Sstevel@tonic-gate #endif
438*7c478bd9Sstevel@tonic-gate 	}
439*7c478bd9Sstevel@tonic-gate 	if (opt_L != NULL)
440*7c478bd9Sstevel@tonic-gate 		mdb_set_lpath(opt_L);
441*7c478bd9Sstevel@tonic-gate 	if (opt_P != NULL)
442*7c478bd9Sstevel@tonic-gate 		(void) mdb_set_prompt(opt_P);
443*7c478bd9Sstevel@tonic-gate 	if (opt_s != (uintptr_t)-1)
444*7c478bd9Sstevel@tonic-gate 		mdb.m_symdist = (size_t)opt_s;
445*7c478bd9Sstevel@tonic-gate 	if (opt_D != NULL && (i = mdb_dstr2mode(opt_D)) != MDB_DBG_HELP)
446*7c478bd9Sstevel@tonic-gate 		mdb_dmode((uint_t)i);
447*7c478bd9Sstevel@tonic-gate 
448*7c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
449*7c478bd9Sstevel@tonic-gate }
450