|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1991 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: */ ! 52: /* ! 53: * Author: David B. Golub, Carnegie Mellon University ! 54: * Date: 7/90 ! 55: */ ! 56: ! 57: /* ! 58: * Command dispatcher. ! 59: */ ! 60: #include <cpus.h> ! 61: #include <dipc.h> ! 62: #include <dipc_timer.h> ! 63: #include <xkmachkernel.h> ! 64: #include <norma_vm.h> ! 65: #ifdef AT386 ! 66: #include <norma_scsi.h> ! 67: #endif /* AT386 */ ! 68: ! 69: #include <mach/boolean.h> ! 70: #include <string.h> ! 71: #include <machine/db_machdep.h> ! 72: ! 73: #if defined(__alpha) ! 74: # include <kdebug.h> ! 75: # if KDEBUG ! 76: # include <machine/kdebug.h> ! 77: # endif ! 78: #endif /* defined(__alpha) */ ! 79: ! 80: #include <ddb/db_lex.h> ! 81: #include <ddb/db_output.h> ! 82: #include <ddb/db_break.h> ! 83: #include <ddb/db_command.h> ! 84: #include <ddb/db_cond.h> ! 85: #include <ddb/db_examine.h> ! 86: #include <ddb/db_expr.h> ! 87: #include <ppc/db_low_trace.h> ! 88: #include <ddb/db_macro.h> ! 89: #include <ddb/db_print.h> ! 90: #include <ddb/db_run.h> ! 91: #include <ddb/db_task_thread.h> ! 92: #include <ddb/db_variables.h> ! 93: #include <ddb/db_watch.h> ! 94: #include <ddb/db_write_cmd.h> ! 95: #include <ddb/tr.h> ! 96: ! 97: #include <machine/setjmp.h> ! 98: #include <kern/thread.h> ! 99: ! 100: #include <kern/misc_protos.h> ! 101: #include <vm/vm_print.h> ! 102: #include <ipc/ipc_print.h> ! 103: #include <kern/kern_print.h> ! 104: #include <machine/db_machdep.h> /* For db_stack_trace_cmd(). */ ! 105: #include <kern/zalloc.h> /* For db_show_one_zone, db_show_all_zones. */ ! 106: #include <kern/lock.h> /* For db_show_all_slocks(). */ ! 107: ! 108: #if DIPC_TIMER ! 109: #include <dipc/dipc_timer.h> ! 110: #endif /* DIPC_TIMER */ ! 111: ! 112: #if NORMA_VM ! 113: #include <xmm/xmm_obj.h> ! 114: #endif /* NORMA_VM */ ! 115: ! 116: /* ! 117: * Exported global variables ! 118: */ ! 119: boolean_t db_cmd_loop_done; ! 120: jmp_buf_t *db_recover = 0; ! 121: db_addr_t db_dot; ! 122: db_addr_t db_last_addr; ! 123: db_addr_t db_prev; ! 124: db_addr_t db_next; ! 125: ! 126: /* ! 127: * if 'ed' style: 'dot' is set at start of last item printed, ! 128: * and '+' points to next line. ! 129: * Otherwise: 'dot' points to next item, '..' points to last. ! 130: */ ! 131: boolean_t db_ed_style = TRUE; ! 132: ! 133: /* ! 134: * Results of command search. ! 135: */ ! 136: #define CMD_UNIQUE 0 ! 137: #define CMD_FOUND 1 ! 138: #define CMD_NONE 2 ! 139: #define CMD_AMBIGUOUS 3 ! 140: #define CMD_HELP 4 ! 141: ! 142: /* Prototypes for functions local to this file. XXX -- should be static! ! 143: */ ! 144: ! 145: void db_command( ! 146: struct db_command **last_cmdp, /* IN_OUT */ ! 147: db_expr_t *last_countp, /* IN_OUT */ ! 148: char *last_modifp, /* IN_OUT */ ! 149: struct db_command *cmd_table); ! 150: ! 151: void db_help_cmd(void); ! 152: ! 153: void db_output_prompt(void); ! 154: ! 155: void db_fncall(void); ! 156: ! 157: void db_cmd_list(struct db_command *table); ! 158: ! 159: int db_cmd_search( ! 160: char * name, ! 161: struct db_command * table, ! 162: struct db_command ** cmdp); /* out */ ! 163: ! 164: void db_command_list( ! 165: struct db_command **last_cmdp, /* IN_OUT */ ! 166: db_expr_t *last_countp, /* IN_OUT */ ! 167: char *last_modifp, /* IN_OUT */ ! 168: struct db_command *cmd_table); ! 169: ! 170: ! 171: ! 172: /* ! 173: * Search for command prefix. ! 174: */ ! 175: int ! 176: db_cmd_search( ! 177: char * name, ! 178: struct db_command * table, ! 179: struct db_command ** cmdp) /* out */ ! 180: { ! 181: struct db_command *cmd; ! 182: int result = CMD_NONE; ! 183: ! 184: for (cmd = table; cmd->name != 0; cmd++) { ! 185: register char *lp; ! 186: register char *rp; ! 187: register int c; ! 188: ! 189: lp = name; ! 190: rp = cmd->name; ! 191: while ((c = *lp) == *rp) { ! 192: if (c == 0) { ! 193: /* complete match */ ! 194: *cmdp = cmd; ! 195: return (CMD_UNIQUE); ! 196: } ! 197: lp++; ! 198: rp++; ! 199: } ! 200: if (c == 0) { ! 201: /* end of name, not end of command - ! 202: partial match */ ! 203: if (result == CMD_FOUND) { ! 204: result = CMD_AMBIGUOUS; ! 205: /* but keep looking for a full match - ! 206: this lets us match single letters */ ! 207: } ! 208: else { ! 209: *cmdp = cmd; ! 210: result = CMD_FOUND; ! 211: } ! 212: } ! 213: } ! 214: if (result == CMD_NONE) { ! 215: /* check for 'help' */ ! 216: if (!strncmp(name, "help", strlen(name))) ! 217: result = CMD_HELP; ! 218: } ! 219: return (result); ! 220: } ! 221: ! 222: void ! 223: db_cmd_list(struct db_command *table) ! 224: { ! 225: register struct db_command *new; ! 226: register struct db_command *old; ! 227: register struct db_command *cur; ! 228: unsigned int l; ! 229: unsigned int len; ! 230: ! 231: len = 1; ! 232: for (cur = table; cur->name != 0; cur++) ! 233: if ((l = strlen(cur->name)) >= len) ! 234: len = l + 1; ! 235: ! 236: old = (struct db_command *)0; ! 237: for (;;) { ! 238: new = (struct db_command *)0; ! 239: for (cur = table; cur->name != 0; cur++) ! 240: if ((new == (struct db_command *)0 || ! 241: strcmp(cur->name, new->name) < 0) && ! 242: (old == (struct db_command *)0 || ! 243: strcmp(cur->name, old->name) > 0)) ! 244: new = cur; ! 245: if (new == (struct db_command *)0) ! 246: return; ! 247: db_reserve_output_position(len); ! 248: db_printf("%-*s", len, new->name); ! 249: old = new; ! 250: } ! 251: } ! 252: ! 253: void ! 254: db_command( ! 255: struct db_command **last_cmdp, /* IN_OUT */ ! 256: db_expr_t *last_countp, /* IN_OUT */ ! 257: char *last_modifp, /* IN_OUT */ ! 258: struct db_command *cmd_table) ! 259: { ! 260: struct db_command *cmd; ! 261: int t; ! 262: char modif[TOK_STRING_SIZE]; ! 263: char *modifp = &modif[0]; ! 264: db_expr_t addr, count; ! 265: boolean_t have_addr; ! 266: int result; ! 267: ! 268: t = db_read_token(); ! 269: if (t == tEOL || t == tSEMI_COLON) { ! 270: /* empty line repeats last command, at 'next' */ ! 271: cmd = *last_cmdp; ! 272: count = *last_countp; ! 273: modifp = last_modifp; ! 274: addr = (db_expr_t)db_next; ! 275: have_addr = FALSE; ! 276: if (t == tSEMI_COLON) ! 277: db_unread_token(t); ! 278: } ! 279: else if (t == tEXCL) { ! 280: db_fncall(); ! 281: return; ! 282: } ! 283: else if (t != tIDENT) { ! 284: db_printf("?\n"); ! 285: db_flush_lex(); ! 286: return; ! 287: } ! 288: else { ! 289: /* ! 290: * Search for command ! 291: */ ! 292: while (cmd_table) { ! 293: result = db_cmd_search(db_tok_string, ! 294: cmd_table, ! 295: &cmd); ! 296: switch (result) { ! 297: case CMD_NONE: ! 298: if (db_exec_macro(db_tok_string) == 0) ! 299: return; ! 300: db_printf("No such command \"%s\"\n", db_tok_string); ! 301: db_flush_lex(); ! 302: return; ! 303: case CMD_AMBIGUOUS: ! 304: db_printf("Ambiguous\n"); ! 305: db_flush_lex(); ! 306: return; ! 307: case CMD_HELP: ! 308: db_cmd_list(cmd_table); ! 309: db_flush_lex(); ! 310: return; ! 311: default: ! 312: break; ! 313: } ! 314: if ((cmd_table = cmd->more) != 0) { ! 315: t = db_read_token(); ! 316: if (t != tIDENT) { ! 317: db_cmd_list(cmd_table); ! 318: db_flush_lex(); ! 319: return; ! 320: } ! 321: } ! 322: } ! 323: ! 324: if ((cmd->flag & CS_OWN) == 0) { ! 325: /* ! 326: * Standard syntax: ! 327: * command [/modifier] [addr] [,count] ! 328: */ ! 329: t = db_read_token(); ! 330: if (t == tSLASH) { ! 331: t = db_read_token(); ! 332: if (t != tIDENT) { ! 333: db_printf("Bad modifier \"/%s\"\n", db_tok_string); ! 334: db_flush_lex(); ! 335: return; ! 336: } ! 337: strcpy(modif, db_tok_string); ! 338: } ! 339: else { ! 340: db_unread_token(t); ! 341: modif[0] = '\0'; ! 342: } ! 343: ! 344: if (db_expression(&addr)) { ! 345: db_dot = (db_addr_t) addr; ! 346: db_last_addr = db_dot; ! 347: have_addr = TRUE; ! 348: } ! 349: else { ! 350: addr = (db_expr_t) db_dot; ! 351: have_addr = FALSE; ! 352: } ! 353: t = db_read_token(); ! 354: if (t == tCOMMA) { ! 355: if (!db_expression(&count)) { ! 356: db_printf("Count missing after ','\n"); ! 357: db_flush_lex(); ! 358: return; ! 359: } ! 360: } ! 361: else { ! 362: db_unread_token(t); ! 363: count = -1; ! 364: } ! 365: } ! 366: } ! 367: if (cmd != 0) { ! 368: /* ! 369: * Execute the command. ! 370: */ ! 371: (*cmd->fcn)(addr, have_addr, count, modifp); ! 372: ! 373: if (cmd->flag & CS_SET_DOT) { ! 374: /* ! 375: * If command changes dot, set dot to ! 376: * previous address displayed (if 'ed' style). ! 377: */ ! 378: if (db_ed_style) { ! 379: db_dot = db_prev; ! 380: } ! 381: else { ! 382: db_dot = db_next; ! 383: } ! 384: } ! 385: else { ! 386: /* ! 387: * If command does not change dot, ! 388: * set 'next' location to be the same. ! 389: */ ! 390: db_next = db_dot; ! 391: } ! 392: } ! 393: *last_cmdp = cmd; ! 394: *last_countp = count; ! 395: strcpy(last_modifp, modifp); ! 396: } ! 397: ! 398: void ! 399: db_command_list( ! 400: struct db_command **last_cmdp, /* IN_OUT */ ! 401: db_expr_t *last_countp, /* IN_OUT */ ! 402: char *last_modifp, /* IN_OUT */ ! 403: struct db_command *cmd_table) ! 404: { ! 405: do { ! 406: db_command(last_cmdp, last_countp, last_modifp, cmd_table); ! 407: db_skip_to_eol(); ! 408: } while (db_read_token() == tSEMI_COLON && db_cmd_loop_done == 0); ! 409: } ! 410: ! 411: ! 412: extern void db_system_stats(void); ! 413: ! 414: #if XKMACHKERNEL ! 415: extern void db_show_net_memory(void); ! 416: ! 417: struct db_command db_show_net_cmds[] = { ! 418: { "memory", (db_func)db_show_net_memory, 0, 0 }, ! 419: }; ! 420: #endif /* XKMACHKERNEL */ ! 421: ! 422: #if DIPC ! 423: extern void db_dipc_stats(void), db_dipc_memory(void), ! 424: db_dipc_port_deads(void), db_dipc_port_table(void), ! 425: db_dipc_msg_progress(void), db_dipc_special_ports(void), ! 426: db_dipc_port_table_proxies(void), ! 427: db_dipc_port_table_principals(void), db_dipc_port_get(void); ! 428: ! 429: extern void db_show_kkt_handle(void), db_show_kkt_request(void), ! 430: db_show_kkt_channel(void), db_show_kkt(void), ! 431: db_show_kkt_node_map(void); ! 432: #if PARAGON860 ! 433: extern void db_show_kkt_transmit(void), db_show_kkt_transport(void); ! 434: #endif /* PARAGON860 */ ! 435: #if NORMA_SCSI ! 436: extern void db_show_kkt_node(void), db_show_kkt_msg(void), ! 437: db_show_kkt_event(void); ! 438: #endif /* NORMA_SCSI */ ! 439: ! 440: struct db_command db_dipc_port_cmds[] = { ! 441: { "dead", (db_func)db_dipc_port_deads, 0, 0 }, ! 442: { "principals", (db_func)db_dipc_port_table_principals, 0, 0 }, ! 443: { "proxies", (db_func)db_dipc_port_table_proxies, 0, 0 }, ! 444: { "special", (db_func)db_dipc_special_ports, 0, 0 }, ! 445: { "table", (db_func)db_dipc_port_table, 0, 0 }, ! 446: { "uid", (db_func)db_dipc_port_get, 0, 0 }, ! 447: { (char *)0 } ! 448: }; ! 449: ! 450: struct db_command db_dipc_cmds[] = { ! 451: { "port", 0, 0, db_dipc_port_cmds }, ! 452: { "memory", (db_func)db_dipc_memory, 0, 0 }, ! 453: { "message_progress",(db_func)db_dipc_msg_progress, 0, 0 }, ! 454: { "mp", (db_func)db_dipc_msg_progress, 0, 0 }, ! 455: { "stats", (db_func)db_dipc_stats, 0, 0 }, ! 456: { (char *)0 } ! 457: }; ! 458: ! 459: struct db_command db_show_kkt_cmds[] = { ! 460: { "handle", (db_func)db_show_kkt_handle, 0, 0 }, ! 461: { "request", (db_func)db_show_kkt_request, 0, 0 }, ! 462: { "channel", (db_func)db_show_kkt_channel, 0, 0 }, ! 463: { "stats", (db_func)db_show_kkt, 0, 0 }, ! 464: { "map", (db_func)db_show_kkt_node_map, 0, 0 }, ! 465: #if PARAGON860 ! 466: { "transmit", (db_func)db_show_kkt_transmit, 0, 0 }, ! 467: { "transport", (db_func)db_show_kkt_transport, 0, 0 }, ! 468: #endif /* PARAGON860 */ ! 469: #if NORMA_SCSI ! 470: { "node", (db_func)db_show_kkt_node, 0, 0 }, ! 471: { "msg", (db_func)db_show_kkt_msg, 0, 0 }, ! 472: { "event", (db_func)db_show_kkt_event, 0, 0 }, ! 473: #endif /* NORMA_SCSI */ ! 474: { (char *)0 } ! 475: }; ! 476: #endif /*DIPC*/ ! 477: ! 478: struct db_command db_show_all_cmds[] = { ! 479: #if USLOCK_DEBUG ! 480: { "slocks", (db_func) db_show_all_slocks, 0, 0 }, ! 481: #endif /* USLOCK_DEBUG */ ! 482: #if DIPC_TIMER ! 483: { "timers", (db_func)db_timer_print, 0, 0 }, ! 484: #endif /* DIPC_TIMER */ ! 485: { "acts", db_show_all_acts, 0, 0 }, ! 486: { "spaces", db_show_all_spaces, 0, 0 }, ! 487: { "tasks", db_show_all_acts, 0, 0 }, ! 488: /* temporary alias for sanity preservation */ ! 489: { "threads", db_show_all_acts, 0, 0 }, ! 490: { "zones", db_show_all_zones, 0, 0 }, ! 491: { "vmtask", db_show_all_task_vm, 0, 0 }, ! 492: { (char *)0 } ! 493: }; ! 494: ! 495: /* XXX */ ! 496: ! 497: extern void db_show_thread_log(void); ! 498: extern void db_show_one_lock(lock_t*); ! 499: extern void db_show_etap_log(db_expr_t, int, db_expr_t, char *); ! 500: ! 501: struct db_command db_show_cmds[] = { ! 502: { "all", 0, 0, db_show_all_cmds }, ! 503: #if DIPC ! 504: { "dipc", 0, 0, db_dipc_cmds }, ! 505: { "kkt", 0, 0, db_show_kkt_cmds }, ! 506: #endif /* DIPC */ ! 507: #if XKMACHKERNEL ! 508: { "net", 0, 0, db_show_net_cmds }, ! 509: #endif /* XKMACHKERNEL */ ! 510: { "registers", db_show_regs, 0, 0 }, ! 511: { "variables", (db_func) db_show_variable, CS_OWN, 0 }, ! 512: { "breaks", (db_func) db_listbreak_cmd, 0, 0 }, ! 513: { "watches", (db_func) db_listwatch_cmd, 0, 0 }, ! 514: { "task", db_show_one_task, 0, 0 }, ! 515: { "act", db_show_one_act, 0, 0 }, ! 516: { "shuttle", db_show_shuttle, 0, 0 }, ! 517: #if 0 ! 518: { "thread", db_show_one_thread, 0, 0 }, ! 519: #endif ! 520: { "vmtask", db_show_one_task_vm, 0, 0 }, ! 521: { "macro", (db_func) db_show_macro, CS_OWN, 0 }, ! 522: { "runq", (db_func) db_show_runq, 0, 0 }, ! 523: { "map", (db_func) vm_map_print, 0, 0 }, ! 524: { "object", (db_func) vm_object_print, 0, 0 }, ! 525: { "page", (db_func) vm_page_print, 0, 0 }, ! 526: { "copy", (db_func) vm_map_copy_print, 0, 0 }, ! 527: { "port", (db_func) ipc_port_print, 0, 0 }, ! 528: { "pset", (db_func) ipc_pset_print, 0, 0 }, ! 529: { "kmsg", (db_func) ipc_kmsg_print, 0, 0 }, ! 530: { "msg", (db_func) ipc_msg_print, 0, 0 }, ! 531: { "ipc_port", db_show_port_id, 0, 0 }, ! 532: { "lock", (db_func)db_show_one_lock, 0, 0 }, ! 533: #if NORMA_VM ! 534: { "xmm_obj", (db_func) xmm_obj_print, 0, 0 }, ! 535: { "xmm_reply", (db_func) xmm_reply_print, 0, 0 }, ! 536: #endif /* NORMA_VM */ ! 537: #if TRACE_BUFFER ! 538: { "tr", db_show_tr, 0, 0 }, ! 539: #endif /* TRACE_BUFFER */ ! 540: { "space", db_show_one_space, 0, 0 }, ! 541: { "system", (db_func) db_system_stats, 0, 0 }, ! 542: #if DIPC_TIMER ! 543: { "timer", (db_func)db_show_one_timer, 0, 0 }, ! 544: #endif /* DIPC_TIMER */ ! 545: { "zone", db_show_one_zone, 0, 0 }, ! 546: { "simple_lock", db_show_one_simple_lock, 0, 0 }, ! 547: #if !NORMA_IPC ! 548: { "mutex", db_show_one_mutex, 0, 0 }, ! 549: #endif /* !NORMA_IPC */ ! 550: { "thread_log", (db_func)db_show_thread_log, 0, 0 }, ! 551: { "subsystem", db_show_subsystem, 0, 0 }, ! 552: { "shuttle", db_show_shuttle, 0, 0 }, ! 553: { "etap_log", db_show_etap_log, 0, 0 }, ! 554: { (char *)0, } ! 555: }; ! 556: ! 557: #if NCPUS > 1 ! 558: #define db_switch_cpu kdb_on ! 559: extern void db_switch_cpu(int); ! 560: #endif /* NCPUS > 1 */ ! 561: ! 562: struct db_command db_command_table[] = { ! 563: #if DB_MACHINE_COMMANDS ! 564: ! 565: /* this must be the first entry, if it exists */ ! 566: { "machine", 0, 0, 0 }, ! 567: #endif ! 568: { "print", (db_func) db_print_cmd, CS_OWN, 0 }, ! 569: { "examine", db_examine_cmd, CS_MORE|CS_SET_DOT, 0 }, ! 570: { "x", db_examine_cmd, CS_MORE|CS_SET_DOT, 0 }, ! 571: { "xf", db_examine_forward, CS_SET_DOT, 0 }, ! 572: { "xb", db_examine_backward, CS_SET_DOT, 0 }, ! 573: { "search", (db_func) db_search_cmd, CS_OWN|CS_SET_DOT, 0 }, ! 574: { "set", (db_func) db_set_cmd, CS_OWN, 0 }, ! 575: { "write", db_write_cmd, CS_MORE|CS_SET_DOT, 0 }, ! 576: { "w", db_write_cmd, CS_MORE|CS_SET_DOT, 0 }, ! 577: { "delete", (db_func) db_delete_cmd, CS_OWN, 0 }, ! 578: { "d", (db_func) db_delete_cmd, CS_OWN, 0 }, ! 579: { "break", db_breakpoint_cmd, CS_MORE, 0 }, ! 580: { "dwatch", db_deletewatch_cmd, CS_MORE, 0 }, ! 581: { "watch", db_watchpoint_cmd, CS_MORE, 0 }, ! 582: { "step", db_single_step_cmd, 0, 0 }, ! 583: { "s", db_single_step_cmd, 0, 0 }, ! 584: { "continue", db_continue_cmd, 0, 0 }, ! 585: { "c", db_continue_cmd, 0, 0 }, ! 586: { "gdb", db_continue_gdb, 0, 0 }, ! 587: { "until", db_trace_until_call_cmd, 0, 0 }, ! 588: ! 589: /* As per request of DNoveck, CR1550, leave this disabled */ ! 590: #if 0 /* until CR1440 is fixed, to avoid toe-stubbing */ ! 591: { "next", db_trace_until_matching_cmd, 0, 0 }, ! 592: #endif ! 593: { "match", db_trace_until_matching_cmd, 0 , 0 }, ! 594: { "trace", db_stack_trace_cmd, 0, 0 }, ! 595: { "cond", (db_func) db_cond_cmd, CS_OWN, 0 }, ! 596: { "call", (db_func) db_fncall, CS_OWN, 0 }, ! 597: { "macro", (db_func) db_def_macro_cmd, CS_OWN, 0 }, ! 598: { "dmacro", (db_func) db_del_macro_cmd, CS_OWN, 0 }, ! 599: { "show", 0, 0, db_show_cmds }, ! 600: #if NCPUS > 1 ! 601: { "cpu", (db_func) db_switch_cpu, 0, 0 }, ! 602: #endif /* NCPUS > 1 */ ! 603: { "reboot", (db_func) db_reboot, 0, 0 }, ! 604: #if defined(__ppc__) ! 605: { "lt", db_low_trace, CS_MORE|CS_SET_DOT, 0 }, ! 606: { "dl", db_display_long, CS_MORE|CS_SET_DOT, 0 }, ! 607: { "dr", db_display_real, CS_MORE|CS_SET_DOT, 0 }, ! 608: { "dv", db_display_virtual, CS_MORE|CS_SET_DOT, 0 }, ! 609: { "dm", db_display_mappings, CS_MORE|CS_SET_DOT, 0 }, ! 610: { "dp", db_display_phys, CS_MORE|CS_SET_DOT, 0 }, ! 611: { "ds", db_display_save, CS_MORE|CS_SET_DOT, 0 }, ! 612: { "dx", db_display_xregs, CS_MORE|CS_SET_DOT, 0 }, ! 613: #endif ! 614: { (char *)0, } ! 615: }; ! 616: ! 617: /* this function should be called to install the machine dependent ! 618: commands. It should be called before the debugger is enabled */ ! 619: void db_machine_commands_install(struct db_command *ptr) ! 620: { ! 621: db_command_table[0].more = ptr; ! 622: return; ! 623: } ! 624: ! 625: ! 626: struct db_command *db_last_command = 0; ! 627: db_expr_t db_last_count = 0; ! 628: char db_last_modifier[TOK_STRING_SIZE] = { '\0' }; ! 629: ! 630: void ! 631: db_help_cmd(void) ! 632: { ! 633: struct db_command *cmd = db_command_table; ! 634: ! 635: while (cmd->name != 0) { ! 636: db_printf("%-12s", cmd->name); ! 637: db_end_line(); ! 638: cmd++; ! 639: } ! 640: } ! 641: ! 642: int (*ddb_display)(void); ! 643: ! 644: void ! 645: db_command_loop(void) ! 646: { ! 647: jmp_buf_t db_jmpbuf; ! 648: jmp_buf_t *prev = db_recover; ! 649: extern int db_output_line; ! 650: extern int db_macro_level; ! 651: extern int db_indent; ! 652: ! 653: /* ! 654: * Initialize 'prev' and 'next' to dot. ! 655: */ ! 656: db_prev = db_dot; ! 657: db_next = db_dot; ! 658: ! 659: if (ddb_display) ! 660: (*ddb_display)(); ! 661: ! 662: db_cmd_loop_done = 0; ! 663: while (!db_cmd_loop_done) { ! 664: (void) _setjmp(db_recover = &db_jmpbuf); ! 665: db_macro_level = 0; ! 666: if (db_print_position() != 0) ! 667: db_printf("\n"); ! 668: db_output_line = 0; ! 669: db_indent = 0; ! 670: db_reset_more(); ! 671: db_output_prompt(); ! 672: ! 673: (void) db_read_line("!!"); ! 674: db_command_list(&db_last_command, &db_last_count, ! 675: db_last_modifier, db_command_table); ! 676: } ! 677: ! 678: db_recover = prev; ! 679: } ! 680: ! 681: boolean_t ! 682: db_exec_cmd_nest( ! 683: char *cmd, ! 684: int size) ! 685: { ! 686: struct db_lex_context lex_context; ! 687: ! 688: db_cmd_loop_done = 0; ! 689: if (cmd) { ! 690: db_save_lex_context(&lex_context); ! 691: db_switch_input(cmd, size); ! 692: } ! 693: db_command_list(&db_last_command, &db_last_count, ! 694: db_last_modifier, db_command_table); ! 695: if (cmd) ! 696: db_restore_lex_context(&lex_context); ! 697: return(db_cmd_loop_done == 0); ! 698: } ! 699: ! 700: void ! 701: db_error(char *s) ! 702: { ! 703: extern int db_macro_level; ! 704: ! 705: #if defined(__alpha) ! 706: # if KDEBUG ! 707: extern boolean_t kdebug_mode; ! 708: if (kdebug_mode) { ! 709: if (s) kprintf(DBG_DEBUG, s); ! 710: return; ! 711: } ! 712: # endif /* KDEBUG */ ! 713: #endif /* defined(__alpha) */ ! 714: ! 715: db_macro_level = 0; ! 716: if (db_recover) { ! 717: if (s > (char *)1) ! 718: db_printf(s); ! 719: db_flush_lex(); ! 720: _longjmp(db_recover, (s == (char *)1) ? 2 : 1); ! 721: } ! 722: else ! 723: { ! 724: if (s > (char *)1) ! 725: db_printf(s); ! 726: panic("db_error"); ! 727: } ! 728: } ! 729: ! 730: ! 731: /* ! 732: * Call random function: ! 733: * !expr(arg,arg,arg) ! 734: */ ! 735: void ! 736: db_fncall(void) ! 737: { ! 738: db_expr_t fn_addr; ! 739: #define MAXARGS 11 ! 740: db_expr_t args[MAXARGS]; ! 741: int nargs = 0; ! 742: db_expr_t retval; ! 743: db_expr_t (*func)(db_expr_t, ...); ! 744: int t; ! 745: ! 746: if (!db_expression(&fn_addr)) { ! 747: db_printf("Bad function \"%s\"\n", db_tok_string); ! 748: db_flush_lex(); ! 749: return; ! 750: } ! 751: func = (db_expr_t (*) (db_expr_t, ...)) fn_addr; ! 752: ! 753: t = db_read_token(); ! 754: if (t == tLPAREN) { ! 755: if (db_expression(&args[0])) { ! 756: nargs++; ! 757: while ((t = db_read_token()) == tCOMMA) { ! 758: if (nargs == MAXARGS) { ! 759: db_printf("Too many arguments\n"); ! 760: db_flush_lex(); ! 761: return; ! 762: } ! 763: if (!db_expression(&args[nargs])) { ! 764: db_printf("Argument missing\n"); ! 765: db_flush_lex(); ! 766: return; ! 767: } ! 768: nargs++; ! 769: } ! 770: db_unread_token(t); ! 771: } ! 772: if (db_read_token() != tRPAREN) { ! 773: db_printf("?\n"); ! 774: db_flush_lex(); ! 775: return; ! 776: } ! 777: } ! 778: while (nargs < MAXARGS) { ! 779: args[nargs++] = 0; ! 780: } ! 781: ! 782: retval = (*func)(args[0], args[1], args[2], args[3], args[4], ! 783: args[5], args[6], args[7], args[8], args[9] ); ! 784: db_printf(" %#n\n", retval); ! 785: } ! 786: ! 787: boolean_t ! 788: db_option( ! 789: char *modif, ! 790: int option) ! 791: { ! 792: register char *p; ! 793: ! 794: for (p = modif; *p; p++) ! 795: if (*p == option) ! 796: return(TRUE); ! 797: return(FALSE); ! 798: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.