xref: /netbsd-src/sys/ddb/db_variables.c (revision 7c7c171d130af9949261bc7dce2150a03c3d239c)
1 /*	$NetBSD: db_variables.c,v 1.12 1998/01/31 04:14:48 ross 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@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 int	db_radix;
52 extern int	db_max_width;
53 extern int	db_tab_stop_width;
54 extern int	db_max_line;
55 
56 static int	db_rw_internal_variable __P((struct db_variable *, db_expr_t *,
57 		    int));
58 
59 /* XXX must all be ints for sysctl. */
60 struct db_variable db_vars[] = {
61 	{ "radix",	(long *)&db_radix,	db_rw_internal_variable },
62 	{ "maxoff",	(long *)&db_maxoff,	db_rw_internal_variable },
63 	{ "maxwidth",	(long *)&db_max_width,	db_rw_internal_variable },
64 	{ "tabstops",	(long *)&db_tab_stop_width, db_rw_internal_variable },
65 	{ "lines",	(long *)&db_max_line,	db_rw_internal_variable },
66 	{ "onpanic",	(long *)&db_onpanic,	db_rw_internal_variable },
67 };
68 struct db_variable *db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
69 
70 /*
71  * ddb command line access to the DDB variables defined above.
72  */
73 static int
74 db_rw_internal_variable(vp, valp, rw)
75 	struct db_variable *vp;
76 	db_expr_t *valp;
77 	int rw;
78 {
79 
80 	if (rw == DB_VAR_GET) {
81 		*valp = *(int *)vp->valuep;
82 	} else {
83 		*(int *)vp->valuep = *valp;
84 	}
85 	return (0);
86 }
87 
88 /*
89  * sysctl(3) access to the DDB variables defined above.
90  */
91 int
92 ddb_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
93 	int	*name;
94 	u_int	namelen;
95 	void	*oldp;
96 	size_t	*oldlenp;
97 	void	*newp;
98 	size_t	newlen;
99 	struct proc *p;
100 {
101 
102 	/* All sysctl names at this level are terminal. */
103 	if (namelen != 1)
104 		return (ENOTDIR);
105 
106 	switch (name[0]) {
107 	case DDBCTL_RADIX:
108 		return (sysctl_int(oldp, oldlenp, newp, newlen, &db_radix));
109 
110 	case DDBCTL_MAXOFF:
111 		return (sysctl_int(oldp, oldlenp, newp, newlen, &db_maxoff));
112 
113 	case DDBCTL_MAXWIDTH:
114 		return (sysctl_int(oldp, oldlenp, newp, newlen,
115 		    &db_max_width));
116 
117 	case DDBCTL_TABSTOPS:
118 		return (sysctl_int(oldp, oldlenp, newp, newlen,
119 		    &db_tab_stop_width));
120 
121 	case DDBCTL_LINES:
122 		return (sysctl_int(oldp, oldlenp, newp, newlen, &db_max_line));
123 
124 	case DDBCTL_ONPANIC:
125 		return (sysctl_int(oldp, oldlenp, newp, newlen, &db_onpanic));
126 	}
127 
128 	return (EOPNOTSUPP);
129 }
130 
131 int
132 db_find_variable(varp)
133 	struct db_variable	**varp;
134 {
135 	int	t;
136 	struct db_variable *vp;
137 
138 	t = db_read_token();
139 	if (t == tIDENT) {
140 	    for (vp = db_vars; vp < db_evars; vp++) {
141 		if (!strcmp(db_tok_string, vp->name)) {
142 		    *varp = vp;
143 		    return (1);
144 		}
145 	    }
146 	    for (vp = db_regs; vp < db_eregs; vp++) {
147 		if (!strcmp(db_tok_string, vp->name)) {
148 		    *varp = vp;
149 		    return (1);
150 		}
151 	    }
152 	}
153 	db_error("Unknown variable\n");
154 	/*NOTREACHED*/
155 	return 0;
156 }
157 
158 int
159 db_get_variable(valuep)
160 	db_expr_t	*valuep;
161 {
162 	struct db_variable *vp;
163 
164 	if (!db_find_variable(&vp))
165 	    return (0);
166 
167 	db_read_variable(vp, valuep);
168 
169 	return (1);
170 }
171 
172 int
173 db_set_variable(value)
174 	db_expr_t	value;
175 {
176 	struct db_variable *vp;
177 
178 	if (!db_find_variable(&vp))
179 	    return (0);
180 
181 	db_write_variable(vp, &value);
182 
183 	return (1);
184 }
185 
186 
187 void
188 db_read_variable(vp, valuep)
189 	struct db_variable *vp;
190 	db_expr_t	*valuep;
191 {
192 	int	(*func) __P((struct db_variable *, db_expr_t *, int)) = vp->fcn;
193 
194 	if (func == FCN_NULL)
195 	    *valuep = *(vp->valuep);
196 	else
197 	    (*func)(vp, valuep, DB_VAR_GET);
198 }
199 
200 void
201 db_write_variable(vp, valuep)
202 	struct db_variable *vp;
203 	db_expr_t	*valuep;
204 {
205 	int	(*func) __P((struct db_variable *, db_expr_t *, int)) = vp->fcn;
206 
207 	if (func == FCN_NULL)
208 	    *(vp->valuep) = *valuep;
209 	else
210 	    (*func)(vp, valuep, DB_VAR_SET);
211 }
212 
213 /*ARGSUSED*/
214 void
215 db_set_cmd(addr, have_addr, count, modif)
216 	db_expr_t	addr;
217 	int		have_addr;
218 	db_expr_t	count;
219 	char *		modif;
220 {
221 	db_expr_t	value;
222 	struct db_variable *vp;
223 	int	t;
224 
225 	t = db_read_token();
226 	if (t != tDOLLAR) {
227 	    db_error("Unknown variable\n");
228 	    /*NOTREACHED*/
229 	}
230 	if (!db_find_variable(&vp)) {
231 	    db_error("Unknown variable\n");
232 	    /*NOTREACHED*/
233 	}
234 
235 	t = db_read_token();
236 	if (t != tEQ)
237 	    db_unread_token(t);
238 
239 	if (!db_expression(&value)) {
240 	    db_error("No value\n");
241 	    /*NOTREACHED*/
242 	}
243 	if (db_read_token() != tEOL) {
244 	    db_error("?\n");
245 	    /*NOTREACHED*/
246 	}
247 
248 	db_write_variable(vp, &value);
249 }
250