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