--- trunk/src/debugger.c 2007/10/08 16:19:28 21 +++ trunk/src/debugger.c 2007/10/08 16:19:37 22 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2003-2006 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: debugger.c,v 1.125 2005/11/13 00:14:06 debug Exp $ + * $Id: debugger.c,v 1.132 2006/02/04 11:10:58 debug Exp $ * * Single-step debugger. * @@ -36,6 +36,8 @@ * * Add more functionality that already exists elsewhere in the emulator. * + * Call stack display? + * * More generic expression evaluator (for example + - * / between multiple * terms), including _TAB COMPLETION_ of symbols and register names! * @@ -474,7 +476,7 @@ */ static void debugger_cmd_device(struct machine *m, char *cmd_line) { - int i, j; + int i; struct memory *mem; struct cpu *c; @@ -507,44 +509,14 @@ device_dumplist(); } else if (strncmp(cmd_line, "add ", 4) == 0) { device_add(m, cmd_line+4); + } else if (strcmp(cmd_line, "consoles") == 0) { + console_debug_dump(m); } else if (strncmp(cmd_line, "remove ", 7) == 0) { i = atoi(cmd_line + 7); if (i==0 && cmd_line[7]!='0') { printf("Weird device number. Use 'device list'.\n"); } else memory_device_remove(m->memory, i); - } else if (strncmp(cmd_line, "state ", 6) == 0) { - i = atoi(cmd_line + 6); - if (i < 0 || i >= mem->n_mmapped_devices) { - printf("No devices with that id.\n"); - return; - } - - if (mem->dev_f_state[i] == NULL) { - printf("No state function has been implemented yet " - "for that device type.\n"); - return; - } - - for (j=0; ; j++) { - int type; - char *name; - void *data; - size_t len; - int res = mem->dev_f_state[i](c, mem, - mem->dev_extra[i], 0, j, &type, &name, &data, &len); - if (!res) - break; - printf("%2i:%30s = (", j, name); - switch (type) { - case DEVICE_STATE_TYPE_INT: - printf("int) %i", *((int *)data)); - break; - default: - printf("unknown)"); - } - printf("\n"); - } } else if (strcmp(cmd_line, "list") == 0) { if (mem->n_mmapped_devices == 0) printf("No memory-mapped devices in this machine.\n"); @@ -575,12 +547,11 @@ printf(" add name_and_params add a device to the current " "machine\n"); printf(" all list all registered devices\n"); + printf(" consoles list all slave consoles\n"); printf(" list list memory-mapped devices in the" " current machine\n"); printf(" remove x remove device nr x from the " "current machine\n"); - printf(" state x show state of device nr x in" - " the current machine\n"); } @@ -715,7 +686,7 @@ */ static void debugger_cmd_emuls(struct machine *m, char *cmd_line) { - int i, iadd = 4; + int i, iadd = DEBUG_INDENTATION; if (*cmd_line) { printf("syntax: emuls\n"); @@ -874,7 +845,7 @@ */ static void debugger_cmd_machine(struct machine *m, char *cmd_line) { - int iadd = 4; + int iadd = DEBUG_INDENTATION; if (*cmd_line) { printf("syntax: machine\n"); @@ -1083,7 +1054,6 @@ } /* here: q is the address, p is the data. */ - res = debugger_parse_name(m, q, 0, &addr); switch (res) { case NAME_PARSE_NOMATCH: @@ -1139,7 +1109,7 @@ printf("\n"); return; case 'h': - if ((data & 1) != 0) + if ((addr & 1) != 0) printf("WARNING: address isn't aligned\n"); if (m->cpus[0]->is_32bit) printf("0x%08x", (int)addr); @@ -1154,7 +1124,7 @@ printf("\n"); return; case 'w': - if ((data & 3) != 0) + if ((addr & 3) != 0) printf("WARNING: address isn't aligned\n"); if (m->cpus[0]->is_32bit) printf("0x%08x", (int)addr); @@ -1170,7 +1140,7 @@ printf("\n"); return; case 'd': - if ((data & 7) != 0) + if ((addr & 7) != 0) printf("WARNING: address isn't aligned\n"); if (m->cpus[0]->is_32bit) printf("0x%08x", (int)addr); @@ -1660,10 +1630,10 @@ */ static void debugger_cmd_help(struct machine *m, char *cmd_line) { - int i, max_name_len = 0, only_one = 0, only_one_match = 0; + int only_one = 0, only_one_match = 0; char *nlines_env = getenv("LINES"); - int nlines = atoi(nlines_env != NULL? nlines_env : "999999"); - int j, curlines; + int nlines = atoi(nlines_env != NULL? nlines_env : "999999"), curlines; + size_t i, j, max_name_len = 0; if (cmd_line[0] != '\0') { only_one = 1; @@ -1671,7 +1641,7 @@ i = 0; while (cmds[i].name != NULL) { - int a = strlen(cmds[i].name); + size_t a = strlen(cmds[i].name); if (cmds[i].args != NULL) a += 1 + strlen(cmds[i].args); if (a > max_name_len) @@ -1829,6 +1799,96 @@ /* + * debugger_execute_cmd(): + */ +void debugger_execute_cmd(char *cmd, int cmd_len) +{ + int i, n, i_match, matchlen; + + /* + * Is there a '=' on the command line? Then try to do an + * assignment. (Only if there is just one word, followed + * by the '=' sign. This makes it possible to use commands + * such as "device add name addr=xyz".) + */ + if (strchr(cmd, '=') != NULL) { + /* Count the nr of words: */ + int nw = 0, inword = 0; + char *p = cmd; + while (*p) { + if (*p == '=') + break; + if (*p != ' ') { + if (!inword) + nw ++; + inword = 1; + } else + inword = 0; + p++; + } + + if (nw == 1) { + debugger_assignment(debugger_machine, cmd); + return; + } + } + + i = 0; + while (cmds[i].name != NULL) + cmds[i++].tmp_flag = 0; + + /* How many chars in cmd to match against: */ + matchlen = 0; + while (isalpha((int)cmd[matchlen])) + matchlen ++; + + /* Check for a command name match: */ + n = i = i_match = 0; + while (cmds[i].name != NULL) { + if (strncasecmp(cmds[i].name, cmd, matchlen) == 0 + && cmds[i].f != NULL) { + cmds[i].tmp_flag = 1; + i_match = i; + n++; + } + i++; + } + + /* No match? */ + if (n == 0) { + printf("Unknown command '%s'. Type 'help' for help.\n", cmd); + return; + } + + /* More than one match? */ + if (n > 1) { + printf("Ambiguous command '%s': ", cmd); + i = 0; + while (cmds[i].name != NULL) { + if (cmds[i].tmp_flag) + printf(" %s", cmds[i].name); + i++; + } + printf("\n"); + return; + } + + /* Exactly one match: */ + if (cmds[i_match].f != NULL) { + char *p = cmd + matchlen; + /* Remove leading whitespace from the args... */ + while (*p != '\0' && *p == ' ') + p++; + + /* ... and run the command: */ + cmds[i_match].f(debugger_machine, p); + } else + printf("FATAL ERROR: internal error in debugger.c:" + " no handler for this command?\n"); +} + + +/* * debugger_readline(): * * Read a line from the terminal. @@ -2003,7 +2063,7 @@ j = 0; /* j = # of cmds printed */ while (cmds[i].name != NULL) { if (cmds[i].tmp_flag) { - int q; + size_t q; if (j == 0) printf(" "); printf("%s", @@ -2093,7 +2153,7 @@ */ void debugger(void) { - int i, n, i_match, matchlen, cmd_len; + int i, cmd_len; char *cmd; if (debugger_n_steps_left_before_interaction > 0) { @@ -2105,6 +2165,7 @@ * Clear all dyntrans translations, because otherwise things would * become to complex to keep in sync. */ + /* TODO: In all machines */ for (i=0; incpus; i++) if (debugger_machine->cpus[i]->translation_cache != NULL) cpu_create_or_reset_tc(debugger_machine->cpus[i]); @@ -2137,87 +2198,7 @@ repeat_cmd[0] = '\0'; } - /* - * Is there a '=' on the command line? Then try to do an - * assignment. (Only if there is just one word, followed - * by the '=' sign. This makes it possible to use commands - * such as "device add name addr=xyz".) - */ - if (strchr(cmd, '=') != NULL) { - /* Count the nr of words: */ - int nw = 0, inword = 0; - char *p = cmd; - while (*p) { - if (*p == '=') - break; - if (*p != ' ') { - if (!inword) - nw ++; - inword = 1; - } else - inword = 0; - p++; - } - - if (nw == 1) { - debugger_assignment(debugger_machine, cmd); - continue; - } - } - - i = 0; - while (cmds[i].name != NULL) - cmds[i++].tmp_flag = 0; - - /* How many chars in cmd to match against: */ - matchlen = 0; - while (isalpha((int)cmd[matchlen])) - matchlen ++; - - /* Check for a command name match: */ - n = i = i_match = 0; - while (cmds[i].name != NULL) { - if (strncasecmp(cmds[i].name, cmd, matchlen) == 0 - && cmds[i].f != NULL) { - cmds[i].tmp_flag = 1; - i_match = i; - n++; - } - i++; - } - - /* No match? */ - if (n == 0) { - printf("Unknown command '%s'. " - "Type 'help' for help.\n", cmd); - continue; - } - - /* More than one match? */ - if (n > 1) { - printf("Ambiguous command '%s': ", cmd); - i = 0; - while (cmds[i].name != NULL) { - if (cmds[i].tmp_flag) - printf(" %s", cmds[i].name); - i++; - } - printf("\n"); - continue; - } - - /* Exactly one match: */ - if (cmds[i_match].f != NULL) { - char *p = cmd + matchlen; - /* Remove leading whitespace from the args... */ - while (*p != '\0' && *p == ' ') - p++; - - /* ... and run the command: */ - cmds[i_match].f(debugger_machine, p); - } else - printf("FATAL ERROR: internal error in debugger.c:" - " no handler for this command?\n"); + debugger_execute_cmd(cmd, cmd_len); /* Special hack for the "step" command: */ if (exit_debugger == -1)