xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_set.c (revision f11c6b60)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5186f7fbfSEdward Pilatowicz  * Common Development and Distribution License (the "License").
6186f7fbfSEdward Pilatowicz  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22186f7fbfSEdward Pilatowicz  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
27*f11c6b60SJohn Levon  * Copyright 2020 Joyent, Inc.
28f76ff24cSBryan Cantrill  */
29f76ff24cSBryan Cantrill 
30f76ff24cSBryan Cantrill /*
317c478bd9Sstevel@tonic-gate  * Support for ::set dcmd.  The +/-o option processing code is provided in a
327c478bd9Sstevel@tonic-gate  * stand-alone function so it can be used by the command-line option processing
337c478bd9Sstevel@tonic-gate  * code in mdb_main.c.  This facility provides an easy way for us to add more
347c478bd9Sstevel@tonic-gate  * configurable options without having to add a new dcmd each time.
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <mdb/mdb_target.h>
387c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
397c478bd9Sstevel@tonic-gate #include <mdb/mdb_string.h>
407c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h>
417c478bd9Sstevel@tonic-gate #include <mdb/mdb.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /*ARGSUSED*/
447c478bd9Sstevel@tonic-gate static int
opt_set_mflags(int enable,uint_t bits,const char * arg)457c478bd9Sstevel@tonic-gate opt_set_mflags(int enable, uint_t bits, const char *arg)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	mdb.m_flags = (mdb.m_flags & ~bits) | (bits & -enable);
487c478bd9Sstevel@tonic-gate 	return (1);
497c478bd9Sstevel@tonic-gate }
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /*ARGSUSED*/
527c478bd9Sstevel@tonic-gate static int
opt_set_tflags(int enable,uint_t bits,const char * arg)537c478bd9Sstevel@tonic-gate opt_set_tflags(int enable, uint_t bits, const char *arg)
547c478bd9Sstevel@tonic-gate {
557c478bd9Sstevel@tonic-gate 	mdb.m_tgtflags = (mdb.m_tgtflags & ~bits) | (bits & -enable);
567c478bd9Sstevel@tonic-gate 	return (1);
577c478bd9Sstevel@tonic-gate }
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate static int
opt_pager(int enable,uint_t bits,const char * arg)607c478bd9Sstevel@tonic-gate opt_pager(int enable, uint_t bits, const char *arg)
617c478bd9Sstevel@tonic-gate {
627c478bd9Sstevel@tonic-gate 	if (enable)
637c478bd9Sstevel@tonic-gate 		mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE);
647c478bd9Sstevel@tonic-gate 	else
657c478bd9Sstevel@tonic-gate 		mdb_iob_clrflags(mdb.m_out, MDB_IOB_PGENABLE);
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 	return (opt_set_mflags(enable, bits, arg));
687c478bd9Sstevel@tonic-gate }
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate static int
opt_adb(int enable,uint_t bits,const char * arg)717c478bd9Sstevel@tonic-gate opt_adb(int enable, uint_t bits, const char *arg)
727c478bd9Sstevel@tonic-gate {
737c478bd9Sstevel@tonic-gate 	if (enable)
747c478bd9Sstevel@tonic-gate 		(void) mdb_set_prompt("");
757c478bd9Sstevel@tonic-gate 	else if (mdb.m_promptlen == 0)
767c478bd9Sstevel@tonic-gate 		(void) mdb_set_prompt("> ");
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	(void) opt_pager(1 - enable, MDB_FL_PAGER, arg);
797c478bd9Sstevel@tonic-gate 	return (opt_set_mflags(enable, bits, arg));
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /*ARGSUSED*/
837c478bd9Sstevel@tonic-gate static int
opt_armemlim(int enable,uint_t bits,const char * arg)847c478bd9Sstevel@tonic-gate opt_armemlim(int enable, uint_t bits, const char *arg)
857c478bd9Sstevel@tonic-gate {
867c478bd9Sstevel@tonic-gate 	if (strisnum(arg)) {
877c478bd9Sstevel@tonic-gate 		mdb.m_armemlim = strtoi(arg);
887c478bd9Sstevel@tonic-gate 		return (1);
897c478bd9Sstevel@tonic-gate 	}
907c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "none") == 0) {
917c478bd9Sstevel@tonic-gate 		mdb.m_armemlim = MDB_ARR_NOLIMIT;
927c478bd9Sstevel@tonic-gate 		return (1);
937c478bd9Sstevel@tonic-gate 	}
947c478bd9Sstevel@tonic-gate 	return (0);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate /*ARGSUSED*/
987c478bd9Sstevel@tonic-gate static int
opt_arstrlim(int enable,uint_t bits,const char * arg)997c478bd9Sstevel@tonic-gate opt_arstrlim(int enable, uint_t bits, const char *arg)
1007c478bd9Sstevel@tonic-gate {
1017c478bd9Sstevel@tonic-gate 	if (strisnum(arg)) {
1027c478bd9Sstevel@tonic-gate 		mdb.m_arstrlim = strtoi(arg);
1037c478bd9Sstevel@tonic-gate 		return (1);
1047c478bd9Sstevel@tonic-gate 	}
1057c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "none") == 0) {
1067c478bd9Sstevel@tonic-gate 		mdb.m_arstrlim = MDB_ARR_NOLIMIT;
1077c478bd9Sstevel@tonic-gate 		return (1);
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 	return (0);
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1137c478bd9Sstevel@tonic-gate static int
opt_exec_mode(int enable,uint_t bits,const char * arg)1147c478bd9Sstevel@tonic-gate opt_exec_mode(int enable, uint_t bits, const char *arg)
1157c478bd9Sstevel@tonic-gate {
1167c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "ask") == 0) {
1177c478bd9Sstevel@tonic-gate 		mdb.m_execmode = MDB_EM_ASK;
1187c478bd9Sstevel@tonic-gate 		return (1);
1197c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "stop") == 0) {
1207c478bd9Sstevel@tonic-gate 		mdb.m_execmode = MDB_EM_STOP;
1217c478bd9Sstevel@tonic-gate 		return (1);
1227c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "follow") == 0) {
1237c478bd9Sstevel@tonic-gate 		mdb.m_execmode = MDB_EM_FOLLOW;
1247c478bd9Sstevel@tonic-gate 		return (1);
1257c478bd9Sstevel@tonic-gate 	}
1267c478bd9Sstevel@tonic-gate 	return (0);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1307c478bd9Sstevel@tonic-gate static int
opt_fork_mode(int enable,uint_t bits,const char * arg)1317c478bd9Sstevel@tonic-gate opt_fork_mode(int enable, uint_t bits, const char *arg)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate 	if (strcmp(arg, "ask") == 0) {
1347c478bd9Sstevel@tonic-gate 		mdb.m_forkmode = MDB_FM_ASK;
1357c478bd9Sstevel@tonic-gate 		return (1);
1367c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "parent") == 0) {
1377c478bd9Sstevel@tonic-gate 		mdb.m_forkmode = MDB_FM_PARENT;
1387c478bd9Sstevel@tonic-gate 		return (1);
1397c478bd9Sstevel@tonic-gate 	} else if (strcmp(arg, "child") == 0) {
1407c478bd9Sstevel@tonic-gate 		mdb.m_forkmode = MDB_FM_CHILD;
1417c478bd9Sstevel@tonic-gate 		return (1);
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 	return (0);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1477c478bd9Sstevel@tonic-gate static int
opt_set_term(int enable,uint_t bits,const char * arg)1487c478bd9Sstevel@tonic-gate opt_set_term(int enable, uint_t bits, const char *arg)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	mdb.m_termtype = strdup(arg);
1517c478bd9Sstevel@tonic-gate 	mdb.m_flags &= ~MDB_FL_TERMGUESS;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	return (1);
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate int
mdb_set_options(const char * s,int enable)1577c478bd9Sstevel@tonic-gate mdb_set_options(const char *s, int enable)
1587c478bd9Sstevel@tonic-gate {
1597c478bd9Sstevel@tonic-gate 	static const struct opdesc {
1607c478bd9Sstevel@tonic-gate 		const char *opt_name;
1617c478bd9Sstevel@tonic-gate 		int (*opt_func)(int, uint_t, const char *);
1627c478bd9Sstevel@tonic-gate 		uint_t opt_bits;
1637c478bd9Sstevel@tonic-gate 	} opdtab[] = {
1647c478bd9Sstevel@tonic-gate 		{ "adb", opt_adb, MDB_FL_REPLAST | MDB_FL_NOMODS | MDB_FL_ADB },
1657c478bd9Sstevel@tonic-gate 		{ "array_mem_limit", opt_armemlim, 0 },
1667c478bd9Sstevel@tonic-gate 		{ "array_str_limit", opt_arstrlim, 0 },
1677c478bd9Sstevel@tonic-gate 		{ "follow_exec_mode", opt_exec_mode, 0 },
1687c478bd9Sstevel@tonic-gate 		{ "follow_fork_mode", opt_fork_mode, 0 },
1697c478bd9Sstevel@tonic-gate 		{ "pager", opt_pager, MDB_FL_PAGER },
1707c478bd9Sstevel@tonic-gate 		{ "term", opt_set_term, 0 },
1717c478bd9Sstevel@tonic-gate 
172f76ff24cSBryan Cantrill 		{ "autowrap", opt_set_mflags, MDB_FL_AUTOWRAP },
1737c478bd9Sstevel@tonic-gate 		{ "ignoreeof", opt_set_mflags, MDB_FL_IGNEOF },
1747c478bd9Sstevel@tonic-gate 		{ "repeatlast", opt_set_mflags, MDB_FL_REPLAST },
1757c478bd9Sstevel@tonic-gate 		{ "latest", opt_set_mflags, MDB_FL_LATEST },
1767c478bd9Sstevel@tonic-gate 		{ "noctf", opt_set_mflags, MDB_FL_NOCTF },
1777c478bd9Sstevel@tonic-gate 		{ "nomods", opt_set_mflags, MDB_FL_NOMODS },
1787c478bd9Sstevel@tonic-gate 		{ "showlmid", opt_set_mflags, MDB_FL_SHOWLMID },
179186f7fbfSEdward Pilatowicz 		{ "lmraw", opt_set_mflags, MDB_FL_LMRAW },
1807c478bd9Sstevel@tonic-gate 		{ "stop_on_bpt_nosym", opt_set_mflags, MDB_FL_BPTNOSYMSTOP },
1817c478bd9Sstevel@tonic-gate 		{ "write_readback", opt_set_mflags, MDB_FL_READBACK },
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 		{ "allow_io_access", opt_set_tflags, MDB_TGT_F_ALLOWIO },
1847c478bd9Sstevel@tonic-gate 		{ "nostop", opt_set_tflags, MDB_TGT_F_NOSTOP },
1857c478bd9Sstevel@tonic-gate 		{ NULL, NULL, 0 }
1867c478bd9Sstevel@tonic-gate 	};
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	const struct opdesc *opp;
1897c478bd9Sstevel@tonic-gate 	char *buf = strdup(s);
1907c478bd9Sstevel@tonic-gate 	char *opt, *arg;
1917c478bd9Sstevel@tonic-gate 	int status = 1;
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 	for (opt = strtok(buf, ","); opt != NULL; opt = strtok(NULL, ",")) {
1947c478bd9Sstevel@tonic-gate 		if ((arg = strchr(opt, '=')) != NULL)
1957c478bd9Sstevel@tonic-gate 			*arg++ = '\0';
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 		for (opp = opdtab; opp->opt_name != NULL; opp++) {
1987c478bd9Sstevel@tonic-gate 			if (strcmp(opt, opp->opt_name) == 0) {
1997c478bd9Sstevel@tonic-gate 				if (opp->opt_bits != 0 && arg != NULL) {
2007c478bd9Sstevel@tonic-gate 					mdb_warn("option does not accept an "
2017c478bd9Sstevel@tonic-gate 					    "argument -- %s\n", opt);
2027c478bd9Sstevel@tonic-gate 					status = 0;
2037c478bd9Sstevel@tonic-gate 				} else if (opp->opt_bits == 0 && arg == NULL) {
2047c478bd9Sstevel@tonic-gate 					mdb_warn("option requires an argument "
2057c478bd9Sstevel@tonic-gate 					    "-- %s\n", opt);
2067c478bd9Sstevel@tonic-gate 					status = 0;
2077c478bd9Sstevel@tonic-gate 				} else if (opp->opt_func(enable != 0,
2087c478bd9Sstevel@tonic-gate 				    opp->opt_bits, arg) == 0) {
2097c478bd9Sstevel@tonic-gate 					mdb_warn("invalid argument for option "
2107c478bd9Sstevel@tonic-gate 					    "%s -- %s\n", opt, arg);
2117c478bd9Sstevel@tonic-gate 					status = 0;
2127c478bd9Sstevel@tonic-gate 				}
2137c478bd9Sstevel@tonic-gate 				break;
2147c478bd9Sstevel@tonic-gate 			}
2157c478bd9Sstevel@tonic-gate 		}
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 		if (opp->opt_name == NULL) {
2187c478bd9Sstevel@tonic-gate 			mdb_warn("invalid debugger option -- %s\n", opt);
2197c478bd9Sstevel@tonic-gate 			status = 0;
2207c478bd9Sstevel@tonic-gate 		}
2217c478bd9Sstevel@tonic-gate 	}
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	mdb_free(buf, strlen(s) + 1);
2247c478bd9Sstevel@tonic-gate 	return (status);
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate static void
print_path(const char ** path,int indent)2287c478bd9Sstevel@tonic-gate print_path(const char **path, int indent)
2297c478bd9Sstevel@tonic-gate {
2307c478bd9Sstevel@tonic-gate 	if (path != NULL && *path != NULL) {
2317c478bd9Sstevel@tonic-gate 		for (mdb_printf("%s\n", *path++); *path != NULL; path++)
2327c478bd9Sstevel@tonic-gate 			mdb_printf("%*s%s\n", indent, " ", *path);
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate #define	LABEL_INDENT	26
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate static void
print_properties(void)2407c478bd9Sstevel@tonic-gate print_properties(void)
2417c478bd9Sstevel@tonic-gate {
2427c478bd9Sstevel@tonic-gate 	int tflags = mdb_tgt_getflags(mdb.m_target);
2437c478bd9Sstevel@tonic-gate 	uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_AUTOWRAP;
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	mdb_iob_clrflags(mdb.m_out, MDB_IOB_AUTOWRAP);
2467c478bd9Sstevel@tonic-gate 	mdb_printf("\n  macro path: ");
2477c478bd9Sstevel@tonic-gate 	print_path(mdb.m_ipath, 14);
2487c478bd9Sstevel@tonic-gate 	mdb_printf(" module path: ");
2497c478bd9Sstevel@tonic-gate 	print_path(mdb.m_lpath, 14);
2507c478bd9Sstevel@tonic-gate 	mdb_iob_setflags(mdb.m_out, oflags);
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	mdb_printf("%*s %lr (%s)\n", LABEL_INDENT, "symbol matching distance:",
2537c478bd9Sstevel@tonic-gate 	    mdb.m_symdist, mdb.m_symdist ? "absolute mode" : "smart mode");
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	mdb_printf("%*s ", LABEL_INDENT, "array member print limit:");
2567c478bd9Sstevel@tonic-gate 	if (mdb.m_armemlim != MDB_ARR_NOLIMIT)
2577c478bd9Sstevel@tonic-gate 		mdb_printf("%u\n", mdb.m_armemlim);
2587c478bd9Sstevel@tonic-gate 	else
2597c478bd9Sstevel@tonic-gate 		mdb_printf("none\n");
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	mdb_printf(" array string print limit: ");
2627c478bd9Sstevel@tonic-gate 	if (mdb.m_arstrlim != MDB_ARR_NOLIMIT)
2637c478bd9Sstevel@tonic-gate 		mdb_printf("%u\n", mdb.m_arstrlim);
2647c478bd9Sstevel@tonic-gate 	else
2657c478bd9Sstevel@tonic-gate 		mdb_printf("none\n");
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	mdb_printf("%*s \"%s\"\n", LABEL_INDENT, "command prompt:",
2687c478bd9Sstevel@tonic-gate 	    mdb.m_prompt);
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	mdb_printf("%*s ", LABEL_INDENT, "debugger options:");
2717c478bd9Sstevel@tonic-gate 	(void) mdb_inc_indent(LABEL_INDENT + 1);
2727c478bd9Sstevel@tonic-gate 
273f76ff24cSBryan Cantrill 	/*
274f76ff24cSBryan Cantrill 	 * The ::set output implicitly relies on "autowrap" being enabled, so
275f76ff24cSBryan Cantrill 	 * we enable it for the duration of the command.
276f76ff24cSBryan Cantrill 	 */
277f76ff24cSBryan Cantrill 	oflags = mdb.m_flags;
278*f11c6b60SJohn Levon 	mdb_iob_set_autowrap(mdb.m_out);
279f76ff24cSBryan Cantrill 
2807c478bd9Sstevel@tonic-gate 	mdb_printf("follow_exec_mode=");
2817c478bd9Sstevel@tonic-gate 	switch (mdb.m_execmode) {
2827c478bd9Sstevel@tonic-gate 	case MDB_EM_ASK:
2837c478bd9Sstevel@tonic-gate 		mdb_printf("ask");
2847c478bd9Sstevel@tonic-gate 		break;
2857c478bd9Sstevel@tonic-gate 	case MDB_EM_STOP:
2867c478bd9Sstevel@tonic-gate 		mdb_printf("stop");
2877c478bd9Sstevel@tonic-gate 		break;
2887c478bd9Sstevel@tonic-gate 	case MDB_EM_FOLLOW:
2897c478bd9Sstevel@tonic-gate 		mdb_printf("follow");
2907c478bd9Sstevel@tonic-gate 		break;
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate #define	COMMAFLAG(name) { mdb_printf(", "); mdb_printf(name); }
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	COMMAFLAG("follow_fork_mode");
2967c478bd9Sstevel@tonic-gate 	switch (mdb.m_forkmode) {
2977c478bd9Sstevel@tonic-gate 	case MDB_FM_ASK:
2987c478bd9Sstevel@tonic-gate 		mdb_printf("ask");
2997c478bd9Sstevel@tonic-gate 		break;
3007c478bd9Sstevel@tonic-gate 	case MDB_FM_PARENT:
3017c478bd9Sstevel@tonic-gate 		mdb_printf("parent");
3027c478bd9Sstevel@tonic-gate 		break;
3037c478bd9Sstevel@tonic-gate 	case MDB_FM_CHILD:
3047c478bd9Sstevel@tonic-gate 		mdb_printf("child");
3057c478bd9Sstevel@tonic-gate 		break;
3067c478bd9Sstevel@tonic-gate 	}
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_ADB)
3097c478bd9Sstevel@tonic-gate 		COMMAFLAG("adb");
310f76ff24cSBryan Cantrill 	if (oflags & MDB_FL_AUTOWRAP)
311f76ff24cSBryan Cantrill 		COMMAFLAG("autowrap");
3127c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_IGNEOF)
3137c478bd9Sstevel@tonic-gate 		COMMAFLAG("ignoreeof");
314186f7fbfSEdward Pilatowicz 	if (mdb.m_flags & MDB_FL_LMRAW)
315186f7fbfSEdward Pilatowicz 		COMMAFLAG("lmraw");
3167c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_PAGER)
3177c478bd9Sstevel@tonic-gate 		COMMAFLAG("pager");
3187c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_REPLAST)
3197c478bd9Sstevel@tonic-gate 		COMMAFLAG("repeatlast");
3207c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_SHOWLMID)
3217c478bd9Sstevel@tonic-gate 		COMMAFLAG("showlmid");
3227c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_BPTNOSYMSTOP)
3237c478bd9Sstevel@tonic-gate 		COMMAFLAG("stop_on_bpt_nosym");
3247c478bd9Sstevel@tonic-gate 	if (mdb.m_flags & MDB_FL_READBACK)
3257c478bd9Sstevel@tonic-gate 		COMMAFLAG("write_readback");
3267c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
3277c478bd9Sstevel@tonic-gate 	(void) mdb_dec_indent(LABEL_INDENT + 1);
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	mdb_printf("%*s ", LABEL_INDENT, "target options:");
3307c478bd9Sstevel@tonic-gate 	(void) mdb_inc_indent(LABEL_INDENT + 1);
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_RDWR)
3337c478bd9Sstevel@tonic-gate 		mdb_printf("read-write");
3347c478bd9Sstevel@tonic-gate 	else
3357c478bd9Sstevel@tonic-gate 		mdb_printf("read-only");
3367c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_ALLOWIO)
3377c478bd9Sstevel@tonic-gate 		COMMAFLAG("allow-io-access");
3387c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_FORCE)
3397c478bd9Sstevel@tonic-gate 		COMMAFLAG("force-attach");
3407c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_PRELOAD)
3417c478bd9Sstevel@tonic-gate 		COMMAFLAG("preload-syms");
3427c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_NOLOAD)
3437c478bd9Sstevel@tonic-gate 		COMMAFLAG("no-load-objs");
3447c478bd9Sstevel@tonic-gate 	if (tflags & MDB_TGT_F_NOSTOP)
3457c478bd9Sstevel@tonic-gate 		COMMAFLAG("no-stop");
3467c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
3477c478bd9Sstevel@tonic-gate 	(void) mdb_dec_indent(LABEL_INDENT + 1);
348f76ff24cSBryan Cantrill 
349f76ff24cSBryan Cantrill 	mdb.m_flags = oflags;
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3537c478bd9Sstevel@tonic-gate int
cmd_set(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3547c478bd9Sstevel@tonic-gate cmd_set(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3557c478bd9Sstevel@tonic-gate {
3567c478bd9Sstevel@tonic-gate 	const char *opt_I = NULL, *opt_L = NULL, *opt_P = NULL, *opt_o = NULL;
3577c478bd9Sstevel@tonic-gate 	const char *opt_plus_o = NULL, *opt_D = NULL;
3587c478bd9Sstevel@tonic-gate 	uint_t opt_w = FALSE, opt_plus_w = FALSE, opt_W = FALSE;
3597c478bd9Sstevel@tonic-gate 	uint_t opt_plus_W = FALSE, opt_F = FALSE;
3607c478bd9Sstevel@tonic-gate 	uintptr_t opt_s = (uintptr_t)(long)-1;
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	int tflags = 0;
3637c478bd9Sstevel@tonic-gate 	int i;
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC)
3667c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 	/*
3697c478bd9Sstevel@tonic-gate 	 * If no options are specified, print out the current set of target
3707c478bd9Sstevel@tonic-gate 	 * and debugger properties that can be modified with ::set.
3717c478bd9Sstevel@tonic-gate 	 */
3727c478bd9Sstevel@tonic-gate 	if (argc == 0) {
3737c478bd9Sstevel@tonic-gate 		print_properties();
3747c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
3757c478bd9Sstevel@tonic-gate 	}
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 	while ((i = mdb_getopts(argc, argv,
3787c478bd9Sstevel@tonic-gate 	    'F', MDB_OPT_SETBITS, TRUE, &opt_F,
3797c478bd9Sstevel@tonic-gate 	    'I', MDB_OPT_STR, &opt_I,
3807c478bd9Sstevel@tonic-gate 	    'L', MDB_OPT_STR, &opt_L,
3817c478bd9Sstevel@tonic-gate 	    'P', MDB_OPT_STR, &opt_P,
3827c478bd9Sstevel@tonic-gate 	    'o', MDB_OPT_STR, &opt_o,
3837c478bd9Sstevel@tonic-gate 	    's', MDB_OPT_UINTPTR, &opt_s,
3847c478bd9Sstevel@tonic-gate 	    'w', MDB_OPT_SETBITS, TRUE, &opt_w,
3857c478bd9Sstevel@tonic-gate 	    'W', MDB_OPT_SETBITS, TRUE, &opt_W,
3867c478bd9Sstevel@tonic-gate 	    'D', MDB_OPT_STR, &opt_D, NULL)) != argc) {
3877c478bd9Sstevel@tonic-gate 		uint_t n = 1;
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 		argv += i; /* skip past args we processed */
3907c478bd9Sstevel@tonic-gate 		argc -= i; /* adjust argc */
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 		if (argv[0].a_type != MDB_TYPE_STRING)
3937c478bd9Sstevel@tonic-gate 			return (DCMD_USAGE);
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 		if (strcmp(argv->a_un.a_str, "+W") == 0)
3967c478bd9Sstevel@tonic-gate 			opt_plus_W = TRUE;
3977c478bd9Sstevel@tonic-gate 		else if (strcmp(argv->a_un.a_str, "+w") == 0)
3987c478bd9Sstevel@tonic-gate 			opt_plus_w = TRUE;
3997c478bd9Sstevel@tonic-gate 		else if (strcmp(argv->a_un.a_str, "+o") == 0 &&
4007c478bd9Sstevel@tonic-gate 		    argc >= 2 && argv[1].a_type == MDB_TYPE_STRING) {
4017c478bd9Sstevel@tonic-gate 			opt_plus_o = argv[1].a_un.a_str;
4027c478bd9Sstevel@tonic-gate 			n = 2;
4037c478bd9Sstevel@tonic-gate 		} else
4047c478bd9Sstevel@tonic-gate 			return (DCMD_USAGE);
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 		/* remove the flag and possible argument */
4077c478bd9Sstevel@tonic-gate 		argv += n;
4087c478bd9Sstevel@tonic-gate 		argc -= n;
4097c478bd9Sstevel@tonic-gate 	}
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	if ((opt_w && opt_plus_w) || (opt_W && opt_plus_W))
4127c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	/*
4157c478bd9Sstevel@tonic-gate 	 * Handle -w, -/+W and -F first: as these options modify the target,
4167c478bd9Sstevel@tonic-gate 	 * they are the only ::set changes that can potentially fail.  We'll
4177c478bd9Sstevel@tonic-gate 	 * use these flags to modify a copy of the target's t_flags, which we'll
4187c478bd9Sstevel@tonic-gate 	 * then pass to the target's setflags op.  This allows the target to
4197c478bd9Sstevel@tonic-gate 	 * detect newly-set and newly-cleared flags by comparing the passed
4207c478bd9Sstevel@tonic-gate 	 * value to the current t_flags.
4217c478bd9Sstevel@tonic-gate 	 */
4227c478bd9Sstevel@tonic-gate 	tflags = mdb_tgt_getflags(mdb.m_target);
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	if (opt_w)
4257c478bd9Sstevel@tonic-gate 		tflags |= MDB_TGT_F_RDWR;
4267c478bd9Sstevel@tonic-gate 	if (opt_plus_w)
4277c478bd9Sstevel@tonic-gate 		tflags &= ~MDB_TGT_F_RDWR;
4287c478bd9Sstevel@tonic-gate 	if (opt_W)
4297c478bd9Sstevel@tonic-gate 		tflags |= MDB_TGT_F_ALLOWIO;
4307c478bd9Sstevel@tonic-gate 	if (opt_plus_W)
4317c478bd9Sstevel@tonic-gate 		tflags &= ~MDB_TGT_F_ALLOWIO;
4327c478bd9Sstevel@tonic-gate 	if (opt_F)
4337c478bd9Sstevel@tonic-gate 		tflags |= MDB_TGT_F_FORCE;
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	if (tflags != mdb_tgt_getflags(mdb.m_target) &&
4367c478bd9Sstevel@tonic-gate 	    mdb_tgt_setflags(mdb.m_target, tflags) == -1)
4377c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 	/*
4407c478bd9Sstevel@tonic-gate 	 * Now handle everything that either can't fail or we don't care if
4417c478bd9Sstevel@tonic-gate 	 * it does.  Note that we handle +/-o first in case another option
4427c478bd9Sstevel@tonic-gate 	 * overrides a change made implicity by a +/-o argument (e.g. -P).
4437c478bd9Sstevel@tonic-gate 	 */
4447c478bd9Sstevel@tonic-gate 	if (opt_o != NULL)
4457c478bd9Sstevel@tonic-gate 		(void) mdb_set_options(opt_o, TRUE);
4467c478bd9Sstevel@tonic-gate 	if (opt_plus_o != NULL)
4477c478bd9Sstevel@tonic-gate 		(void) mdb_set_options(opt_plus_o, FALSE);
4487c478bd9Sstevel@tonic-gate 	if (opt_I != NULL) {
4497c478bd9Sstevel@tonic-gate #ifdef _KMDB
4507c478bd9Sstevel@tonic-gate 		mdb_warn("macro path cannot be set under kmdb\n");
4517c478bd9Sstevel@tonic-gate #else
4527c478bd9Sstevel@tonic-gate 		mdb_set_ipath(opt_I);
4537c478bd9Sstevel@tonic-gate #endif
4547c478bd9Sstevel@tonic-gate 	}
4557c478bd9Sstevel@tonic-gate 	if (opt_L != NULL)
4567c478bd9Sstevel@tonic-gate 		mdb_set_lpath(opt_L);
4577c478bd9Sstevel@tonic-gate 	if (opt_P != NULL)
4587c478bd9Sstevel@tonic-gate 		(void) mdb_set_prompt(opt_P);
4597c478bd9Sstevel@tonic-gate 	if (opt_s != (uintptr_t)-1)
4607c478bd9Sstevel@tonic-gate 		mdb.m_symdist = (size_t)opt_s;
4617c478bd9Sstevel@tonic-gate 	if (opt_D != NULL && (i = mdb_dstr2mode(opt_D)) != MDB_DBG_HELP)
4627c478bd9Sstevel@tonic-gate 		mdb_dmode((uint_t)i);
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
4657c478bd9Sstevel@tonic-gate }
466