No empty .Rs/.Re
[netbsd-mini2440.git] / sys / ddb / db_variables.c
blob40597cfea70b54f173df9d136547c6a3195392a6
1 /* $NetBSD: db_variables.c,v 1.41 2009/03/07 22:02:17 ad Exp $ */
3 /*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 * Carnegie Mellon requests users of this software to return to
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: db_variables.c,v 1.41 2009/03/07 22:02:17 ad Exp $");
32 #ifdef _KERNEL_OPT
33 #include "opt_ddbparam.h"
34 #endif
36 #include <sys/param.h>
37 #include <sys/proc.h>
38 #include <uvm/uvm_extern.h>
39 #include <sys/sysctl.h>
41 #include <ddb/ddb.h>
42 #include <ddb/ddbvar.h>
45 * If this is non-zero, the DDB will be entered when the system
46 * panics. Initialize it so that it's patchable.
48 #ifndef DDB_ONPANIC
49 #define DDB_ONPANIC 1
50 #endif
51 int db_onpanic = DDB_ONPANIC;
54 * Can DDB can be entered from the console?
56 #ifndef DDB_FROMCONSOLE
57 #define DDB_FROMCONSOLE 1
58 #endif
59 int db_fromconsole = DDB_FROMCONSOLE;
62 * Output DDB output to the message buffer?
64 #ifndef DDB_TEE_MSGBUF
65 #define DDB_TEE_MSGBUF 0
66 #endif
67 int db_tee_msgbuf = DDB_TEE_MSGBUF;
70 static int db_rw_internal_variable(const struct db_variable *, db_expr_t *,
71 int);
72 static int db_find_variable(const struct db_variable **);
74 /* XXX must all be ints for sysctl. */
75 const struct db_variable db_vars[] = {
76 { "radix", (void *)&db_radix, db_rw_internal_variable, NULL },
77 { "maxoff", (void *)&db_maxoff, db_rw_internal_variable, NULL },
78 { "maxwidth", (void *)&db_max_width, db_rw_internal_variable, NULL },
79 { "tabstops", (void *)&db_tab_stop_width, db_rw_internal_variable, NULL },
80 { "lines", (void *)&db_max_line, db_rw_internal_variable, NULL },
81 { "onpanic", (void *)&db_onpanic, db_rw_internal_variable, NULL },
82 { "fromconsole", (void *)&db_fromconsole, db_rw_internal_variable, NULL },
83 { "tee_msgbuf", (void *)&db_tee_msgbuf, db_rw_internal_variable, NULL },
85 const struct db_variable * const db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
88 * ddb command line access to the DDB variables defined above.
90 static int
91 db_rw_internal_variable(const struct db_variable *vp, db_expr_t *valp, int rw)
94 if (rw == DB_VAR_GET)
95 *valp = *(int *)vp->valuep;
96 else
97 *(int *)vp->valuep = *valp;
98 return (0);
102 * sysctl(3) access to the DDB variables defined above.
104 #ifdef _KERNEL
105 SYSCTL_SETUP(sysctl_ddb_setup, "sysctl ddb subtree setup")
108 sysctl_createv(clog, 0, NULL, NULL,
109 CTLFLAG_PERMANENT,
110 CTLTYPE_NODE, "ddb", NULL,
111 NULL, 0, NULL, 0,
112 CTL_DDB, CTL_EOL);
114 sysctl_createv(clog, 0, NULL, NULL,
115 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
116 CTLTYPE_INT, "radix",
117 SYSCTL_DESCR("Input and output radix"),
118 NULL, 0, &db_radix, 0,
119 CTL_DDB, DDBCTL_RADIX, CTL_EOL);
120 sysctl_createv(clog, 0, NULL, NULL,
121 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
122 CTLTYPE_INT, "maxoff",
123 SYSCTL_DESCR("Maximum symbol offset"),
124 NULL, 0, &db_maxoff, 0,
125 CTL_DDB, DDBCTL_MAXOFF, CTL_EOL);
126 sysctl_createv(clog, 0, NULL, NULL,
127 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
128 CTLTYPE_INT, "maxwidth",
129 SYSCTL_DESCR("Maximum output line width"),
130 NULL, 0, &db_max_width, 0,
131 CTL_DDB, DDBCTL_MAXWIDTH, CTL_EOL);
132 sysctl_createv(clog, 0, NULL, NULL,
133 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
134 CTLTYPE_INT, "lines",
135 SYSCTL_DESCR("Number of display lines"),
136 NULL, 0, &db_max_line, 0,
137 CTL_DDB, DDBCTL_LINES, CTL_EOL);
138 sysctl_createv(clog, 0, NULL, NULL,
139 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
140 CTLTYPE_INT, "tabstops",
141 SYSCTL_DESCR("Output tab width"),
142 NULL, 0, &db_tab_stop_width, 0,
143 CTL_DDB, DDBCTL_TABSTOPS, CTL_EOL);
144 sysctl_createv(clog, 0, NULL, NULL,
145 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
146 CTLTYPE_INT, "onpanic",
147 SYSCTL_DESCR("Whether to enter ddb on a kernel panic"),
148 NULL, 0, &db_onpanic, 0,
149 CTL_DDB, DDBCTL_ONPANIC, CTL_EOL);
150 sysctl_createv(clog, 0, NULL, NULL,
151 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
152 CTLTYPE_INT, "fromconsole",
153 SYSCTL_DESCR("Whether ddb can be entered from the "
154 "console"),
155 NULL, 0, &db_fromconsole, 0,
156 CTL_DDB, DDBCTL_FROMCONSOLE, CTL_EOL);
157 sysctl_createv(clog, 0, NULL, NULL,
158 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
159 CTLTYPE_INT, "tee_msgbuf",
160 SYSCTL_DESCR("Whether to tee ddb output to the msgbuf"),
161 NULL, 0, &db_tee_msgbuf, 0,
162 CTL_DDB, CTL_CREATE, CTL_EOL);
164 sysctl_createv(clog, 0, NULL, NULL,
165 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
166 CTLTYPE_STRING, "commandonenter",
167 SYSCTL_DESCR("Command to be executed on each ddb enter"),
168 NULL, 0, &db_cmd_on_enter, DB_LINE_MAXLEN,
169 CTL_DDB, CTL_CREATE, CTL_EOL);
171 #endif /* _KERNEL */
174 db_find_variable(const struct db_variable **varp)
176 int t;
177 const struct db_variable *vp;
179 t = db_read_token();
180 if (t == tIDENT) {
181 for (vp = db_vars; vp < db_evars; vp++) {
182 if (!strcmp(db_tok_string, vp->name)) {
183 *varp = vp;
184 return (1);
187 for (vp = db_regs; vp < db_eregs; vp++) {
188 if (!strcmp(db_tok_string, vp->name)) {
189 *varp = vp;
190 return (1);
194 db_error("Unknown variable\n");
195 /*NOTREACHED*/
196 return 0;
200 db_get_variable(db_expr_t *valuep)
202 const struct db_variable *vp;
204 if (!db_find_variable(&vp))
205 return (0);
207 db_read_variable(vp, valuep);
209 return (1);
213 db_set_variable(db_expr_t value)
215 const struct db_variable *vp;
217 if (!db_find_variable(&vp))
218 return (0);
220 db_write_variable(vp, &value);
222 return (1);
226 void
227 db_read_variable(const struct db_variable *vp, db_expr_t *valuep)
229 int (*func)(const struct db_variable *, db_expr_t *, int) = vp->fcn;
231 if (func == FCN_NULL)
232 *valuep = *(vp->valuep);
233 else
234 (*func)(vp, valuep, DB_VAR_GET);
237 void
238 db_write_variable(const struct db_variable *vp, db_expr_t *valuep)
240 int (*func)(const struct db_variable *, db_expr_t *, int) = vp->fcn;
242 if (func == FCN_NULL)
243 *(vp->valuep) = *valuep;
244 else
245 (*func)(vp, valuep, DB_VAR_SET);
248 /*ARGSUSED*/
249 void
250 db_set_cmd(db_expr_t addr, bool have_addr,
251 db_expr_t count, const char *modif)
253 db_expr_t value;
254 db_expr_t old_value;
255 const struct db_variable *vp = NULL; /* XXX: GCC */
256 int t;
258 t = db_read_token();
259 if (t != tDOLLAR) {
260 db_error("Unknown variable\n");
261 /*NOTREACHED*/
263 if (!db_find_variable(&vp)) {
264 db_error("Unknown variable\n");
265 /*NOTREACHED*/
268 t = db_read_token();
269 if (t != tEQ)
270 db_unread_token(t);
272 if (!db_expression(&value)) {
273 db_error("No value\n");
274 /*NOTREACHED*/
276 if (db_read_token() != tEOL) {
277 db_error("?\n");
278 /*NOTREACHED*/
281 db_read_variable(vp, &old_value);
282 db_printf("$%s\t\t%s = ", vp->name, db_num_to_str(old_value));
283 db_printf("%s\n", db_num_to_str(value));
284 db_write_variable(vp, &value);