Home | History | Annotate | Line # | Download | only in amldb
      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