db_variables.c revision 1.9 1 /* $NetBSD: db_variables.c,v 1.9 1997/01/09 05:37:02 thorpej Exp $ */
2
3 /*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
7 *
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.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
27 */
28
29 #include <sys/param.h>
30 #include <sys/proc.h>
31 #include <vm/vm.h>
32 #include <sys/sysctl.h>
33
34 #include <machine/db_machdep.h>
35
36 #include <ddb/db_lex.h>
37 #include <ddb/db_variables.h>
38 #include <ddb/db_command.h>
39 #include <ddb/db_sym.h>
40 #include <ddb/db_extern.h>
41
42 /*
43 * If this is non-zero, the DDB will be entered when the system
44 * panics. Initialize it so that it's patchable.
45 */
46 #ifndef DDB_ONPANIC
47 #define DDB_ONPANIC 1
48 #endif
49 int db_onpanic = DDB_ONPANIC;
50
51 extern unsigned int db_maxoff;
52
53 extern int db_radix;
54 extern int db_max_width;
55 extern int db_tab_stop_width;
56 extern int db_max_line;
57
58 struct db_variable db_vars[] = {
59 { "radix", &db_radix, FCN_NULL },
60 { "maxoff", (int *)&db_maxoff, FCN_NULL },
61 { "maxwidth", &db_max_width, FCN_NULL },
62 { "tabstops", &db_tab_stop_width, FCN_NULL },
63 { "lines", &db_max_line, FCN_NULL },
64 { "onpanic", &db_onpanic, FCN_NULL },
65 };
66 struct db_variable *db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
67
68 /*
69 * sysctl(3) access to the DDB variables defined above.
70 */
71 int
72 ddb_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
73 int *name;
74 u_int namelen;
75 void *oldp;
76 size_t *oldlenp;
77 void *newp;
78 size_t newlen;
79 struct proc *p;
80 {
81
82 /* All sysctl names at this level are terminal. */
83 if (namelen != 1)
84 return (ENOTDIR);
85
86 switch (name[0]) {
87 case DDBCTL_RADIX:
88 return (sysctl_int(oldp, oldlenp, newp, newlen, &db_radix));
89
90 case DDBCTL_MAXOFF:
91 return (sysctl_int(oldp, oldlenp, newp, newlen,
92 (int *)db_maxoff));
93
94 case DDBCTL_MAXWIDTH:
95 return (sysctl_int(oldp, oldlenp, newp, newlen,
96 &db_max_width));
97
98 case DDBCTL_TABSTOPS:
99 return (sysctl_int(oldp, oldlenp, newp, newlen,
100 &db_tab_stop_width));
101
102 case DDBCTL_LINES:
103 return (sysctl_int(oldp, oldlenp, newp, newlen, &db_max_line));
104
105 case DDBCTL_ONPANIC:
106 return (sysctl_int(oldp, oldlenp, newp, newlen, &db_onpanic));
107 }
108
109 return (EOPNOTSUPP);
110 }
111
112 int
113 db_find_variable(varp)
114 struct db_variable **varp;
115 {
116 int t;
117 struct db_variable *vp;
118
119 t = db_read_token();
120 if (t == tIDENT) {
121 for (vp = db_vars; vp < db_evars; vp++) {
122 if (!strcmp(db_tok_string, vp->name)) {
123 *varp = vp;
124 return (1);
125 }
126 }
127 for (vp = db_regs; vp < db_eregs; vp++) {
128 if (!strcmp(db_tok_string, vp->name)) {
129 *varp = vp;
130 return (1);
131 }
132 }
133 }
134 db_error("Unknown variable\n");
135 /*NOTREACHED*/
136 return 0;
137 }
138
139 int
140 db_get_variable(valuep)
141 db_expr_t *valuep;
142 {
143 struct db_variable *vp;
144
145 if (!db_find_variable(&vp))
146 return (0);
147
148 db_read_variable(vp, valuep);
149
150 return (1);
151 }
152
153 int
154 db_set_variable(value)
155 db_expr_t value;
156 {
157 struct db_variable *vp;
158
159 if (!db_find_variable(&vp))
160 return (0);
161
162 db_write_variable(vp, &value);
163
164 return (1);
165 }
166
167
168 void
169 db_read_variable(vp, valuep)
170 struct db_variable *vp;
171 db_expr_t *valuep;
172 {
173 int (*func) __P((struct db_variable *, db_expr_t *, int)) = vp->fcn;
174
175 if (func == FCN_NULL)
176 *valuep = *(vp->valuep);
177 else
178 (*func)(vp, valuep, DB_VAR_GET);
179 }
180
181 void
182 db_write_variable(vp, valuep)
183 struct db_variable *vp;
184 db_expr_t *valuep;
185 {
186 int (*func) __P((struct db_variable *, db_expr_t *, int)) = vp->fcn;
187
188 if (func == FCN_NULL)
189 *(vp->valuep) = *valuep;
190 else
191 (*func)(vp, valuep, DB_VAR_SET);
192 }
193
194 /*ARGSUSED*/
195 void
196 db_set_cmd(addr, have_addr, count, modif)
197 db_expr_t addr;
198 int have_addr;
199 db_expr_t count;
200 char * modif;
201 {
202 db_expr_t value;
203 struct db_variable *vp;
204 int t;
205
206 t = db_read_token();
207 if (t != tDOLLAR) {
208 db_error("Unknown variable\n");
209 /*NOTREACHED*/
210 }
211 if (!db_find_variable(&vp)) {
212 db_error("Unknown variable\n");
213 /*NOTREACHED*/
214 }
215
216 t = db_read_token();
217 if (t != tEQ)
218 db_unread_token(t);
219
220 if (!db_expression(&value)) {
221 db_error("No value\n");
222 /*NOTREACHED*/
223 }
224 if (db_read_token() != tEOL) {
225 db_error("?\n");
226 /*NOTREACHED*/
227 }
228
229 db_write_variable(vp, &value);
230 }
231