debug.c revision 1.2 1 1.2 andvar /* $NetBSD: debug.c,v 1.2 2021/08/17 22:00:33 andvar Exp $ */
2 1.1 christos
3 1.1 christos /*-
4 1.1 christos * Copyright (c) 1999 Takanori Watanabe
5 1.1 christos * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki (at) FreeBSD.org>
6 1.1 christos * All rights reserved.
7 1.1 christos *
8 1.1 christos * Redistribution and use in source and binary forms, with or without
9 1.1 christos * modification, are permitted provided that the following conditions
10 1.1 christos * are met:
11 1.1 christos * 1. Redistributions of source code must retain the above copyright
12 1.1 christos * notice, this list of conditions and the following disclaimer.
13 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 christos * notice, this list of conditions and the following disclaimer in the
15 1.1 christos * documentation and/or other materials provided with the distribution.
16 1.1 christos *
17 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 1.1 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 1.1 christos * SUCH DAMAGE.
28 1.1 christos *
29 1.1 christos * Id: debug.c,v 1.19 2000/08/16 18:15:00 iwasaki Exp
30 1.1 christos * $FreeBSD: src/usr.sbin/acpi/amldb/debug.c,v 1.3 2000/11/09 06:24:40 iwasaki Exp $
31 1.1 christos */
32 1.1 christos #include <sys/cdefs.h>
33 1.2 andvar __RCSID("$NetBSD: debug.c,v 1.2 2021/08/17 22:00:33 andvar Exp $");
34 1.1 christos
35 1.1 christos #include <sys/param.h>
36 1.1 christos
37 1.1 christos #include <acpi_common.h>
38 1.1 christos #include <aml/aml_name.h>
39 1.1 christos #include <aml/aml_amlmem.h>
40 1.1 christos #include <aml/aml_status.h>
41 1.1 christos #include <aml/aml_env.h>
42 1.1 christos #include <aml/aml_obj.h>
43 1.1 christos #include <aml/aml_evalobj.h>
44 1.1 christos #include <aml/aml_parse.h>
45 1.1 christos #include <aml/aml_region.h>
46 1.1 christos #include <aml/aml_store.h>
47 1.1 christos #include <aml/aml_common.h>
48 1.1 christos
49 1.1 christos #include <assert.h>
50 1.1 christos #include <err.h>
51 1.1 christos #include <stdio.h>
52 1.1 christos #include <stdlib.h>
53 1.1 christos #include <string.h>
54 1.1 christos #include <unistd.h>
55 1.1 christos
56 1.1 christos #include "debug.h"
57 1.1 christos
58 1.1 christos static int
59 1.1 christos print_named_object(struct aml_name *name, va_list ap)
60 1.1 christos {
61 1.1 christos
62 1.1 christos aml_print_curname(name);
63 1.1 christos printf("\n");
64 1.1 christos
65 1.1 christos return (0); /* always return success to continue the search */
66 1.1 christos }
67 1.1 christos
68 1.1 christos void
69 1.1 christos aml_dbgr(struct aml_environ *env1, struct aml_environ *env2)
70 1.1 christos {
71 1.1 christos #define CMDBUFLEN 512
72 1.1 christos #define ARGBUFLEN 512
73 1.1 christos static char lastcommand[CMDBUFLEN];
74 1.1 christos char commandline[CMDBUFLEN];
75 1.1 christos char argbuf[7][ARGBUFLEN];
76 1.1 christos char *ptr, *method;
77 1.1 christos char *np, *ep;
78 1.1 christos int i;
79 1.1 christos int argnum;
80 1.1 christos struct aml_name *name;
81 1.1 christos union aml_object argv[7], *retval;
82 1.1 christos
83 1.1 christos while (1) {
84 1.1 christos fputs("AML>", stderr);
85 1.1 christos fgets(commandline, 512, stdin);
86 1.1 christos commandline[512 - 1] = '\n'; /* safety */
87 1.1 christos if (feof(stdin)) {
88 1.1 christos commandline[0] = 'q';
89 1.1 christos }
90 1.1 christos if (commandline[0] == '\n') {
91 1.1 christos memcpy(commandline, lastcommand, sizeof commandline);
92 1.1 christos }
93 1.1 christos memcpy(lastcommand, commandline, sizeof commandline);
94 1.1 christos switch (commandline[0]) {
95 1.1 christos case 's':
96 1.1 christos if (env2 != NULL) {
97 1.1 christos env2->stat = aml_stat_step;
98 1.1 christos }
99 1.1 christos /* FALLTHROUGH */
100 1.1 christos case 'n':
101 1.1 christos env1->stat = aml_stat_step;
102 1.1 christos return;
103 1.1 christos case 'c':
104 1.1 christos env1->stat = aml_stat_none;
105 1.1 christos return;
106 1.1 christos case 'q':
107 1.1 christos env1->stat = aml_stat_panic;
108 1.1 christos return;
109 1.1 christos case 't':
110 1.1 christos /* NULL terminate */
111 1.1 christos ptr = &commandline[1];
112 1.1 christos while (ptr[0] != '\n')
113 1.1 christos ptr++;
114 1.1 christos ptr[0] = '\0';
115 1.1 christos
116 1.1 christos /* move pointer to object name */
117 1.1 christos ptr = &commandline[1];
118 1.1 christos while (ptr[0] == ' ')
119 1.1 christos ptr++;
120 1.1 christos
121 1.1 christos /* show current tree if no argument */
122 1.1 christos if (ptr[0] == '\0') {
123 1.1 christos aml_showtree(env1->curname, 0);
124 1.1 christos goto show_variables;
125 1.1 christos }
126 1.1 christos /* start from root? */
127 1.1 christos if (ptr[0] == '\\') {
128 1.1 christos if (ptr[1] == '\0') {
129 1.1 christos aml_showtree(aml_get_rootname(), 0);
130 1.1 christos goto show_variables;
131 1.1 christos }
132 1.1 christos if ((name = aml_find_from_namespace(aml_get_rootname(), ptr))) {
133 1.1 christos aml_showtree(name, 0);
134 1.1 christos goto show_variables;
135 1.1 christos }
136 1.1 christos }
137 1.1 christos if ((name = aml_find_from_namespace(env1->curname, ptr))) {
138 1.1 christos aml_showtree(name, 0);
139 1.1 christos }
140 1.1 christos show_variables:
141 1.1 christos for (i = 0; i < 7; i++) {
142 1.1 christos struct aml_name *tmp =
143 1.1 christos aml_local_stack_getArgX(NULL, i);
144 1.1 christos
145 1.1 christos if (tmp == NULL || tmp->property == NULL) {
146 1.1 christos break;
147 1.1 christos }
148 1.1 christos printf(" Arg%d ", i);
149 1.1 christos aml_showobject(tmp->property);
150 1.1 christos }
151 1.1 christos for (i = 0; i < 8; i++) {
152 1.1 christos struct aml_name *tmp =
153 1.1 christos aml_local_stack_getLocalX(i);
154 1.1 christos
155 1.1 christos if (tmp == NULL || tmp->property == NULL) {
156 1.1 christos continue;
157 1.1 christos }
158 1.1 christos printf(" Local%d ", i);
159 1.1 christos aml_showobject(tmp->property);
160 1.1 christos }
161 1.1 christos break;
162 1.1 christos case 'i':
163 1.1 christos aml_debug_prompt_reginput =
164 1.1 christos (aml_debug_prompt_reginput == 0) ? 1 : 0;
165 1.1 christos if (aml_debug_prompt_reginput)
166 1.1 christos fputs("REGION INPUT ON\n", stderr);
167 1.1 christos else
168 1.1 christos fputs("REGION INPUT OFF\n", stderr);
169 1.1 christos break;
170 1.1 christos case 'o':
171 1.1 christos aml_debug_prompt_regoutput =
172 1.1 christos (aml_debug_prompt_regoutput == 0) ? 1 : 0;
173 1.1 christos if (aml_debug_prompt_regoutput)
174 1.1 christos fputs("REGION OUTPUT ON\n", stderr);
175 1.1 christos else
176 1.1 christos fputs("REGION OUTPUT OFF\n", stderr);
177 1.1 christos break;
178 1.1 christos case 'm':
179 1.1 christos memman_statistics(aml_memman);
180 1.1 christos break;
181 1.1 christos case 'r':
182 1.1 christos /* NULL terminate */
183 1.1 christos ptr = &commandline[1];
184 1.1 christos while (ptr[0] != '\n')
185 1.1 christos ptr++;
186 1.1 christos ptr[0] = '\0';
187 1.1 christos
188 1.1 christos /* move pointer to method name */
189 1.1 christos ptr = &commandline[1];
190 1.1 christos while (ptr[0] == ' ')
191 1.1 christos ptr++;
192 1.1 christos
193 1.1 christos if (ptr[0] == '\0') {
194 1.1 christos break;
195 1.1 christos }
196 1.1 christos name = aml_find_from_namespace(aml_get_rootname(), ptr);
197 1.1 christos if (name == NULL) {
198 1.1 christos printf("%s:%d:aml_dbgr: not found name %s\n",
199 1.1 christos __FILE__, __LINE__, ptr);
200 1.1 christos break;
201 1.1 christos }
202 1.1 christos if (name->property == NULL ||
203 1.1 christos name->property->type != aml_t_method) {
204 1.1 christos printf("%s:%d:aml_dbgr: not method %s\n",
205 1.1 christos __FILE__, __LINE__, ptr);
206 1.1 christos break;
207 1.1 christos }
208 1.1 christos aml_showobject(name->property);
209 1.1 christos method = ptr;
210 1.1 christos
211 1.1 christos argnum = name->property->meth.argnum & 0x07;
212 1.1 christos if (argnum) {
213 1.1 christos fputs(" Enter argument values "
214 1.1 christos "(ex. number 1 / string foo). "
215 1.1 christos "'q' to quit.\n", stderr);
216 1.1 christos }
217 1.1 christos /* get and parse argument values */
218 1.1 christos for (i = 0; i < argnum; i++) {
219 1.1 christos retry:
220 1.1 christos fprintf(stderr, " Arg%d ? ", i);
221 1.1 christos if (read(0, argbuf[i], ARGBUFLEN) == 0) {
222 1.1 christos fputs("\n", stderr);
223 1.1 christos goto retry;
224 1.1 christos }
225 1.1 christos argbuf[i][ARGBUFLEN - 1] = '\n';
226 1.1 christos if (argbuf[i][0] == 'q') {
227 1.1 christos goto finish_execution;
228 1.1 christos }
229 1.1 christos if (argbuf[i][0] == '\n') {
230 1.1 christos goto retry;
231 1.1 christos }
232 1.1 christos /* move pointer to the value */
233 1.1 christos ptr = &argbuf[i][0];
234 1.1 christos while (ptr[0] != ' ' && ptr[0] != '\n') {
235 1.1 christos ptr++;
236 1.1 christos }
237 1.1 christos while (ptr[0] == ' ') {
238 1.1 christos ptr++;
239 1.1 christos }
240 1.1 christos if (ptr[0] == '\n') {
241 1.1 christos goto retry;
242 1.1 christos }
243 1.1 christos switch (argbuf[i][0]) {
244 1.1 christos case 'n':
245 1.1 christos argv[i].type = aml_t_num;
246 1.1 christos np = ptr;
247 1.1 christos if (ptr[0] == '0' &&
248 1.1 christos ptr[1] == 'x') {
249 1.1 christos argv[i].num.number = strtoq(ptr, &ep, 16);
250 1.1 christos } else {
251 1.1 christos argv[i].num.number = strtoq(ptr, &ep, 10);
252 1.1 christos }
253 1.1 christos if (np == ep) {
254 1.1 christos fputs("Wrong value for number.\n",
255 1.1 christos stderr);
256 1.1 christos goto retry;
257 1.1 christos }
258 1.1 christos break;
259 1.1 christos case 's':
260 1.1 christos argv[i].type = aml_t_string;
261 1.1 christos argv[i].str.needfree = 0;
262 1.1 christos argv[i].str.string = (u_int8_t *)ptr;
263 1.1 christos /* NULL ternimate */
264 1.1 christos while (ptr[0] != '\n') {
265 1.1 christos ptr++;
266 1.1 christos }
267 1.1 christos ptr[0] = '\0';
268 1.1 christos break;
269 1.1 christos default:
270 1.1 christos fputs("Invalid data type "
271 1.1 christos "(supports number or string only)\n",
272 1.1 christos stderr);
273 1.1 christos goto retry;
274 1.1 christos }
275 1.1 christos }
276 1.1 christos bzero(lastcommand, sizeof lastcommand);
277 1.1 christos fprintf(stderr, "==== Running %s. ====\n", method);
278 1.1 christos aml_local_stack_push(aml_local_stack_create());
279 1.1 christos retval = aml_invoke_method_by_name(method, argnum, argv);
280 1.1 christos aml_showobject(retval);
281 1.1 christos aml_local_stack_delete(aml_local_stack_pop());
282 1.1 christos fprintf(stderr, "==== %s finished. ====\n", method);
283 1.1 christos finish_execution:
284 1.1 christos break;
285 1.1 christos case 'f':
286 1.1 christos /* NULL terminate */
287 1.1 christos ptr = &commandline[1];
288 1.1 christos while (ptr[0] != '\n')
289 1.1 christos ptr++;
290 1.1 christos ptr[0] = '\0';
291 1.1 christos
292 1.1 christos /* move pointer to object name */
293 1.1 christos ptr = &commandline[1];
294 1.1 christos while (ptr[0] == ' ')
295 1.1 christos ptr++;
296 1.1 christos
297 1.1 christos aml_apply_foreach_found_objects(aml_get_rootname(),
298 1.1 christos ptr, print_named_object);
299 1.1 christos break;
300 1.1 christos case 'h':
301 1.1 christos fputs("s Single step\n"
302 1.1 christos "n Step program\n"
303 1.1 christos "c Continue program being debugged\n"
304 1.1 christos "q Quit method execution\n"
305 1.1 christos "t Show local name space tree and variables\n"
306 1.1 christos "i Toggle region input prompt\n"
307 1.1 christos "o Toggle region output prompt\n"
308 1.1 christos "m Show memory management statistics\n"
309 1.1 christos "r Run specified method\n"
310 1.1 christos "f Find named objects from namespace.\n"
311 1.2 andvar "h Show this message\n", stderr);
312 1.1 christos break;
313 1.1 christos }
314 1.1 christos }
315 1.1 christos }
316