xref: /netbsd-src/usr.sbin/acpitools/amldb/debug.c (revision 2e0bf311b34bf9507e08ee74157213840e9994d3)
1*2e0bf311Sandvar /*	$NetBSD: debug.c,v 1.2 2021/08/17 22:00:33 andvar Exp $	*/
253e202c1Schristos 
353e202c1Schristos /*-
453e202c1Schristos  * Copyright (c) 1999 Takanori Watanabe
553e202c1Schristos  * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
653e202c1Schristos  * All rights reserved.
753e202c1Schristos  *
853e202c1Schristos  * Redistribution and use in source and binary forms, with or without
953e202c1Schristos  * modification, are permitted provided that the following conditions
1053e202c1Schristos  * are met:
1153e202c1Schristos  * 1. Redistributions of source code must retain the above copyright
1253e202c1Schristos  *    notice, this list of conditions and the following disclaimer.
1353e202c1Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1453e202c1Schristos  *    notice, this list of conditions and the following disclaimer in the
1553e202c1Schristos  *    documentation and/or other materials provided with the distribution.
1653e202c1Schristos  *
1753e202c1Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1853e202c1Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1953e202c1Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2053e202c1Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2153e202c1Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2253e202c1Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2353e202c1Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2453e202c1Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2553e202c1Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2653e202c1Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2753e202c1Schristos  * SUCH DAMAGE.
2853e202c1Schristos  *
2953e202c1Schristos  *	Id: debug.c,v 1.19 2000/08/16 18:15:00 iwasaki Exp
3053e202c1Schristos  *	$FreeBSD: src/usr.sbin/acpi/amldb/debug.c,v 1.3 2000/11/09 06:24:40 iwasaki Exp $
3153e202c1Schristos  */
3253e202c1Schristos #include <sys/cdefs.h>
33*2e0bf311Sandvar __RCSID("$NetBSD: debug.c,v 1.2 2021/08/17 22:00:33 andvar Exp $");
3453e202c1Schristos 
3553e202c1Schristos #include <sys/param.h>
3653e202c1Schristos 
3753e202c1Schristos #include <acpi_common.h>
3853e202c1Schristos #include <aml/aml_name.h>
3953e202c1Schristos #include <aml/aml_amlmem.h>
4053e202c1Schristos #include <aml/aml_status.h>
4153e202c1Schristos #include <aml/aml_env.h>
4253e202c1Schristos #include <aml/aml_obj.h>
4353e202c1Schristos #include <aml/aml_evalobj.h>
4453e202c1Schristos #include <aml/aml_parse.h>
4553e202c1Schristos #include <aml/aml_region.h>
4653e202c1Schristos #include <aml/aml_store.h>
4753e202c1Schristos #include <aml/aml_common.h>
4853e202c1Schristos 
4953e202c1Schristos #include <assert.h>
5053e202c1Schristos #include <err.h>
5153e202c1Schristos #include <stdio.h>
5253e202c1Schristos #include <stdlib.h>
5353e202c1Schristos #include <string.h>
5453e202c1Schristos #include <unistd.h>
5553e202c1Schristos 
5653e202c1Schristos #include "debug.h"
5753e202c1Schristos 
5853e202c1Schristos static int
print_named_object(struct aml_name * name,va_list ap)5953e202c1Schristos print_named_object(struct aml_name *name, va_list ap)
6053e202c1Schristos {
6153e202c1Schristos 
6253e202c1Schristos 	aml_print_curname(name);
6353e202c1Schristos 	printf("\n");
6453e202c1Schristos 
6553e202c1Schristos 	return (0);	/* always return success to continue the search */
6653e202c1Schristos }
6753e202c1Schristos 
6853e202c1Schristos void
aml_dbgr(struct aml_environ * env1,struct aml_environ * env2)6953e202c1Schristos aml_dbgr(struct aml_environ *env1, struct aml_environ *env2)
7053e202c1Schristos {
7153e202c1Schristos #define CMDBUFLEN	512
7253e202c1Schristos #define ARGBUFLEN	512
7353e202c1Schristos 	static	char lastcommand[CMDBUFLEN];
7453e202c1Schristos 	char	commandline[CMDBUFLEN];
7553e202c1Schristos 	char	argbuf[7][ARGBUFLEN];
7653e202c1Schristos 	char	*ptr, *method;
7753e202c1Schristos 	char	*np, *ep;
7853e202c1Schristos 	int 	i;
7953e202c1Schristos 	int	argnum;
8053e202c1Schristos 	struct	aml_name *name;
8153e202c1Schristos 	union	aml_object argv[7], *retval;
8253e202c1Schristos 
8353e202c1Schristos 	while (1) {
8453e202c1Schristos 		fputs("AML>", stderr);
8553e202c1Schristos 		fgets(commandline, 512, stdin);
8653e202c1Schristos 		commandline[512 - 1] = '\n';	/* safety */
8753e202c1Schristos 		if (feof(stdin)) {
8853e202c1Schristos 			commandline[0] = 'q';
8953e202c1Schristos 		}
9053e202c1Schristos 		if (commandline[0] == '\n') {
9153e202c1Schristos 			memcpy(commandline, lastcommand, sizeof commandline);
9253e202c1Schristos 		}
9353e202c1Schristos 		memcpy(lastcommand, commandline, sizeof commandline);
9453e202c1Schristos 		switch (commandline[0]) {
9553e202c1Schristos 		case 's':
9653e202c1Schristos 			if (env2 != NULL) {
9753e202c1Schristos 				env2->stat = aml_stat_step;
9853e202c1Schristos 			}
9953e202c1Schristos 			/* FALLTHROUGH */
10053e202c1Schristos 		case 'n':
10153e202c1Schristos 			env1->stat = aml_stat_step;
10253e202c1Schristos 			return;
10353e202c1Schristos 		case 'c':
10453e202c1Schristos 			env1->stat = aml_stat_none;
10553e202c1Schristos 			return;
10653e202c1Schristos 		case 'q':
10753e202c1Schristos 			env1->stat = aml_stat_panic;
10853e202c1Schristos 			return;
10953e202c1Schristos 		case 't':
11053e202c1Schristos 			/* NULL terminate */
11153e202c1Schristos 			ptr = &commandline[1];
11253e202c1Schristos 			while (ptr[0] != '\n')
11353e202c1Schristos 				ptr++;
11453e202c1Schristos 			ptr[0] = '\0';
11553e202c1Schristos 
11653e202c1Schristos 			/* move pointer to object name */
11753e202c1Schristos 			ptr = &commandline[1];
11853e202c1Schristos 			while (ptr[0] == ' ')
11953e202c1Schristos 				ptr++;
12053e202c1Schristos 
12153e202c1Schristos 			/* show current tree if no argument */
12253e202c1Schristos 			if (ptr[0] == '\0') {
12353e202c1Schristos 				aml_showtree(env1->curname, 0);
12453e202c1Schristos 				goto show_variables;
12553e202c1Schristos 			}
12653e202c1Schristos 			/* start from root? */
12753e202c1Schristos 			if (ptr[0] == '\\') {
12853e202c1Schristos 				if (ptr[1] == '\0') {
12953e202c1Schristos 					aml_showtree(aml_get_rootname(), 0);
13053e202c1Schristos 					goto show_variables;
13153e202c1Schristos 				}
13253e202c1Schristos 				if ((name = aml_find_from_namespace(aml_get_rootname(), ptr))) {
13353e202c1Schristos 					aml_showtree(name, 0);
13453e202c1Schristos 					goto show_variables;
13553e202c1Schristos 				}
13653e202c1Schristos 			}
13753e202c1Schristos 			if ((name = aml_find_from_namespace(env1->curname, ptr))) {
13853e202c1Schristos 				aml_showtree(name, 0);
13953e202c1Schristos 			}
14053e202c1Schristos show_variables:
14153e202c1Schristos 			for (i = 0; i < 7; i++) {
14253e202c1Schristos 				struct aml_name *tmp =
14353e202c1Schristos 				aml_local_stack_getArgX(NULL, i);
14453e202c1Schristos 
14553e202c1Schristos 				if (tmp == NULL || tmp->property == NULL) {
14653e202c1Schristos 					break;
14753e202c1Schristos 				}
14853e202c1Schristos 				printf("  Arg%d    ", i);
14953e202c1Schristos 				aml_showobject(tmp->property);
15053e202c1Schristos 			}
15153e202c1Schristos 			for (i = 0; i < 8; i++) {
15253e202c1Schristos 				struct aml_name *tmp =
15353e202c1Schristos 				aml_local_stack_getLocalX(i);
15453e202c1Schristos 
15553e202c1Schristos 				if (tmp == NULL || tmp->property == NULL) {
15653e202c1Schristos 					continue;
15753e202c1Schristos 				}
15853e202c1Schristos 				printf("  Local%d  ", i);
15953e202c1Schristos 				aml_showobject(tmp->property);
16053e202c1Schristos 			}
16153e202c1Schristos 			break;
16253e202c1Schristos 		case 'i':
16353e202c1Schristos 			aml_debug_prompt_reginput =
16453e202c1Schristos 			    (aml_debug_prompt_reginput == 0) ? 1 : 0;
16553e202c1Schristos 			if (aml_debug_prompt_reginput)
16653e202c1Schristos 				fputs("REGION INPUT ON\n", stderr);
16753e202c1Schristos 			else
16853e202c1Schristos 				fputs("REGION INPUT OFF\n", stderr);
16953e202c1Schristos 			break;
17053e202c1Schristos 		case 'o':
17153e202c1Schristos 			aml_debug_prompt_regoutput =
17253e202c1Schristos 			    (aml_debug_prompt_regoutput == 0) ? 1 : 0;
17353e202c1Schristos 			if (aml_debug_prompt_regoutput)
17453e202c1Schristos 				fputs("REGION OUTPUT ON\n", stderr);
17553e202c1Schristos 			else
17653e202c1Schristos 				fputs("REGION OUTPUT OFF\n", stderr);
17753e202c1Schristos 			break;
17853e202c1Schristos 		case 'm':
17953e202c1Schristos 			memman_statistics(aml_memman);
18053e202c1Schristos 			break;
18153e202c1Schristos 		case 'r':
18253e202c1Schristos 			/* NULL terminate */
18353e202c1Schristos 			ptr = &commandline[1];
18453e202c1Schristos 			while (ptr[0] != '\n')
18553e202c1Schristos 				ptr++;
18653e202c1Schristos 			ptr[0] = '\0';
18753e202c1Schristos 
18853e202c1Schristos 			/* move pointer to method name */
18953e202c1Schristos 			ptr = &commandline[1];
19053e202c1Schristos 			while (ptr[0] == ' ')
19153e202c1Schristos 				ptr++;
19253e202c1Schristos 
19353e202c1Schristos 			if (ptr[0] == '\0') {
19453e202c1Schristos 				break;
19553e202c1Schristos 			}
19653e202c1Schristos 			name = aml_find_from_namespace(aml_get_rootname(), ptr);
19753e202c1Schristos 			if (name == NULL) {
19853e202c1Schristos 				printf("%s:%d:aml_dbgr: not found name %s\n",
19953e202c1Schristos 				    __FILE__, __LINE__, ptr);
20053e202c1Schristos 				break;
20153e202c1Schristos 			}
20253e202c1Schristos 			if (name->property == NULL ||
20353e202c1Schristos 			    name->property->type != aml_t_method) {
20453e202c1Schristos 				printf("%s:%d:aml_dbgr: not method %s\n",
20553e202c1Schristos 				    __FILE__, __LINE__, ptr);
20653e202c1Schristos 				break;
20753e202c1Schristos 			}
20853e202c1Schristos 			aml_showobject(name->property);
20953e202c1Schristos 			method = ptr;
21053e202c1Schristos 
21153e202c1Schristos 			argnum = name->property->meth.argnum & 0x07;
21253e202c1Schristos 			if (argnum) {
21353e202c1Schristos 				fputs("  Enter argument values "
21453e202c1Schristos 				      "(ex. number 1 / string foo). "
21553e202c1Schristos 				      "'q' to quit.\n", stderr);
21653e202c1Schristos 			}
21753e202c1Schristos 			/* get and parse argument values */
21853e202c1Schristos 			for (i = 0; i < argnum; i++) {
21953e202c1Schristos retry:
22053e202c1Schristos 				fprintf(stderr, "  Arg%d ? ", i);
22153e202c1Schristos 				if (read(0, argbuf[i], ARGBUFLEN) == 0) {
22253e202c1Schristos 					fputs("\n", stderr);
22353e202c1Schristos 					goto retry;
22453e202c1Schristos 				}
22553e202c1Schristos 				argbuf[i][ARGBUFLEN - 1] = '\n';
22653e202c1Schristos 				if (argbuf[i][0] == 'q') {
22753e202c1Schristos 					goto finish_execution;
22853e202c1Schristos 				}
22953e202c1Schristos 				if (argbuf[i][0] == '\n') {
23053e202c1Schristos 					goto retry;
23153e202c1Schristos 				}
23253e202c1Schristos 				/* move pointer to the value */
23353e202c1Schristos 				ptr = &argbuf[i][0];
23453e202c1Schristos 				while (ptr[0] != ' ' && ptr[0] != '\n') {
23553e202c1Schristos 					ptr++;
23653e202c1Schristos 				}
23753e202c1Schristos 				while (ptr[0] == ' ') {
23853e202c1Schristos 					ptr++;
23953e202c1Schristos 				}
24053e202c1Schristos 				if (ptr[0] == '\n') {
24153e202c1Schristos 					goto retry;
24253e202c1Schristos 				}
24353e202c1Schristos 				switch (argbuf[i][0]) {
24453e202c1Schristos 				case 'n':
24553e202c1Schristos 					argv[i].type = aml_t_num;
24653e202c1Schristos 					np = ptr;
24753e202c1Schristos 					if (ptr[0] == '0' &&
24853e202c1Schristos 					    ptr[1] == 'x') {
24953e202c1Schristos 						argv[i].num.number = strtoq(ptr, &ep, 16);
25053e202c1Schristos 					} else {
25153e202c1Schristos 						argv[i].num.number = strtoq(ptr, &ep, 10);
25253e202c1Schristos 					}
25353e202c1Schristos 					if (np == ep) {
25453e202c1Schristos 						fputs("Wrong value for number.\n",
25553e202c1Schristos 						    stderr);
25653e202c1Schristos 						goto retry;
25753e202c1Schristos 					}
25853e202c1Schristos 					break;
25953e202c1Schristos 				case 's':
26053e202c1Schristos 					argv[i].type = aml_t_string;
26153e202c1Schristos 					argv[i].str.needfree = 0;
26253e202c1Schristos 					argv[i].str.string = (u_int8_t *)ptr;
26353e202c1Schristos 					/* NULL ternimate */
26453e202c1Schristos 					while (ptr[0] != '\n') {
26553e202c1Schristos 						ptr++;
26653e202c1Schristos 					}
26753e202c1Schristos 					ptr[0] = '\0';
26853e202c1Schristos 					break;
26953e202c1Schristos 				default:
27053e202c1Schristos 					fputs("Invalid data type "
27153e202c1Schristos 					      "(supports number or string only)\n",
27253e202c1Schristos 					    stderr);
27353e202c1Schristos 					goto retry;
27453e202c1Schristos 				}
27553e202c1Schristos 			}
27653e202c1Schristos 			bzero(lastcommand, sizeof lastcommand);
27753e202c1Schristos 			fprintf(stderr, "==== Running %s. ====\n", method);
27853e202c1Schristos 			aml_local_stack_push(aml_local_stack_create());
27953e202c1Schristos 			retval = aml_invoke_method_by_name(method, argnum, argv);
28053e202c1Schristos 			aml_showobject(retval);
28153e202c1Schristos 			aml_local_stack_delete(aml_local_stack_pop());
28253e202c1Schristos 			fprintf(stderr, "==== %s finished. ====\n", method);
28353e202c1Schristos finish_execution:
28453e202c1Schristos 			break;
28553e202c1Schristos 		case 'f':
28653e202c1Schristos 			/* NULL terminate */
28753e202c1Schristos 			ptr = &commandline[1];
28853e202c1Schristos 			while (ptr[0] != '\n')
28953e202c1Schristos 				ptr++;
29053e202c1Schristos 			ptr[0] = '\0';
29153e202c1Schristos 
29253e202c1Schristos 			/* move pointer to object name */
29353e202c1Schristos 			ptr = &commandline[1];
29453e202c1Schristos 			while (ptr[0] == ' ')
29553e202c1Schristos 				ptr++;
29653e202c1Schristos 
29753e202c1Schristos 			aml_apply_foreach_found_objects(aml_get_rootname(),
29853e202c1Schristos 			    ptr, print_named_object);
29953e202c1Schristos 			break;
30053e202c1Schristos 		case 'h':
30153e202c1Schristos 			fputs("s	Single step\n"
30253e202c1Schristos 			      "n	Step program\n"
30353e202c1Schristos 			      "c	Continue program being debugged\n"
30453e202c1Schristos 			      "q	Quit method execution\n"
30553e202c1Schristos 			      "t	Show local name space tree and variables\n"
30653e202c1Schristos 			      "i	Toggle region input prompt\n"
30753e202c1Schristos 			      "o	Toggle region output prompt\n"
30853e202c1Schristos 			      "m	Show memory management statistics\n"
30953e202c1Schristos 			      "r	Run specified method\n"
31053e202c1Schristos 			      "f	Find named objects from namespace.\n"
311*2e0bf311Sandvar 			      "h	Show this message\n", stderr);
31253e202c1Schristos 			break;
31353e202c1Schristos 		}
31453e202c1Schristos 	}
31553e202c1Schristos }
316