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