25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: debugger_cmds.c,v 1.5 2006/06/24 19:52:28 debug Exp $ |
* $Id: debugger_cmds.c,v 1.8 2006/10/14 02:30:12 debug Exp $ |
29 |
* |
* |
30 |
* Debugger commands. Included from debugger.c. |
* Debugger commands. Included from debugger.c. |
31 |
*/ |
*/ |
111 |
|
|
112 |
i = m->n_breakpoints; |
i = m->n_breakpoints; |
113 |
|
|
114 |
res = debugger_parse_name(m, cmd_line + 4, 0, &tmp); |
res = debugger_parse_expression(m, cmd_line + 4, 0, &tmp); |
115 |
if (!res) { |
if (!res) { |
116 |
printf("Couldn't parse '%s'\n", cmd_line + 4); |
printf("Couldn't parse '%s'\n", cmd_line + 4); |
117 |
return; |
return; |
208 |
|
|
209 |
for (i=0; i<mem->n_mmapped_devices; i++) { |
for (i=0; i<mem->n_mmapped_devices; i++) { |
210 |
printf("%2i: %25s @ 0x%011"PRIx64", len = 0x%"PRIx64, |
printf("%2i: %25s @ 0x%011"PRIx64", len = 0x%"PRIx64, |
211 |
i, mem->dev_name[i], |
i, mem->devices[i].name, |
212 |
(uint64_t) mem->dev_baseaddr[i], |
(uint64_t) mem->devices[i].baseaddr, |
213 |
(uint64_t) mem->dev_length[i]); |
(uint64_t) mem->devices[i].length); |
214 |
|
|
215 |
if (mem->dev_flags[i]) { |
if (mem->devices[i].flags) { |
216 |
printf(" ("); |
printf(" ("); |
217 |
if (mem->dev_flags[i] & DM_DYNTRANS_OK) |
if (mem->devices[i].flags & DM_DYNTRANS_OK) |
218 |
printf("DYNTRANS R"); |
printf("DYNTRANS R"); |
219 |
if (mem->dev_flags[i] & DM_DYNTRANS_WRITE_OK) |
if (mem->devices[i].flags &DM_DYNTRANS_WRITE_OK) |
220 |
printf("+W"); |
printf("+W"); |
221 |
printf(")"); |
printf(")"); |
222 |
} |
} |
264 |
p = strchr(tmps, ' '); |
p = strchr(tmps, ' '); |
265 |
if (p != NULL) |
if (p != NULL) |
266 |
*p = '\0'; |
*p = '\0'; |
267 |
r = debugger_parse_name(m, tmps, 0, &tmp); |
r = debugger_parse_expression(m, tmps, 0, &tmp); |
268 |
free(tmps); |
free(tmps); |
269 |
|
|
270 |
if (r == NAME_PARSE_NOMATCH || r == NAME_PARSE_MULTIPLE) { |
if (r == PARSE_NOMATCH || r == PARSE_MULTIPLE) { |
271 |
printf("Unparsable address: %s\n", cmd_line); |
printf("Unparsable address: %s\n", cmd_line); |
272 |
return; |
return; |
273 |
} else { |
} else { |
277 |
p = strchr(cmd_line, ' '); |
p = strchr(cmd_line, ' '); |
278 |
} |
} |
279 |
|
|
280 |
|
if (m->cpus == NULL) { |
281 |
|
printf("No cpus (?)\n"); |
282 |
|
return; |
283 |
|
} |
284 |
|
c = m->cpus[m->bootstrap_cpu]; |
285 |
|
if (c == NULL) { |
286 |
|
printf("m->cpus[m->bootstrap_cpu] = NULL\n"); |
287 |
|
return; |
288 |
|
} |
289 |
|
mem = m->cpus[m->bootstrap_cpu]->mem; |
290 |
|
|
291 |
addr_start = last_dump_addr; |
addr_start = last_dump_addr; |
292 |
|
|
293 |
if (addr_start == MAGIC_UNTOUCHED) { |
if (addr_start == MAGIC_UNTOUCHED) |
294 |
uint64_t tmp; |
addr_start = c->pc; |
|
int match_register = 0; |
|
|
cpu_register_match(m, "pc", 0, &tmp, &match_register); |
|
|
if (match_register) { |
|
|
addr_start = tmp; |
|
|
} else { |
|
|
printf("No starting address.\n"); |
|
|
return; |
|
|
} |
|
|
} |
|
295 |
|
|
296 |
addr_end = addr_start + 16 * 16; |
addr_end = addr_start + 16 * 16; |
297 |
|
|
299 |
if (p != NULL) { |
if (p != NULL) { |
300 |
while (*p == ' ' && *p) |
while (*p == ' ' && *p) |
301 |
p++; |
p++; |
302 |
r = debugger_parse_name(m, p, 0, &addr_end); |
r = debugger_parse_expression(m, p, 0, &addr_end); |
303 |
if (r == NAME_PARSE_NOMATCH || r == NAME_PARSE_MULTIPLE) { |
if (r == PARSE_NOMATCH || r == PARSE_MULTIPLE) { |
304 |
printf("Unparsable address: %s\n", cmd_line); |
printf("Unparsable address: %s\n", cmd_line); |
305 |
return; |
return; |
306 |
} |
} |
307 |
} |
} |
308 |
|
|
|
if (m->cpus == NULL) { |
|
|
printf("No cpus (?)\n"); |
|
|
return; |
|
|
} |
|
|
c = m->cpus[m->bootstrap_cpu]; |
|
|
if (c == NULL) { |
|
|
printf("m->cpus[m->bootstrap_cpu] = NULL\n"); |
|
|
return; |
|
|
} |
|
|
mem = m->cpus[m->bootstrap_cpu]->mem; |
|
|
|
|
309 |
addr = addr_start & ~0xf; |
addr = addr_start & ~0xf; |
310 |
|
|
311 |
ctrl_c = 0; |
ctrl_c = 0; |
390 |
/* |
/* |
391 |
* debugger_cmd_focus(): |
* debugger_cmd_focus(): |
392 |
* |
* |
393 |
* Changes focus to specific machine (in a specific emulation). |
* Changes focus to specific cpu, in a specific machine (in a specific |
394 |
|
* emulation). |
395 |
*/ |
*/ |
396 |
static void debugger_cmd_focus(struct machine *m, char *cmd_line) |
static void debugger_cmd_focus(struct machine *m, char *cmd_line) |
397 |
{ |
{ |
398 |
int x = -1, y = -1; |
int x = -1, y = -1, z = -1; |
399 |
char *p; |
char *p, *p2; |
400 |
|
|
401 |
if (!cmd_line[0]) { |
if (!cmd_line[0]) { |
402 |
printf("syntax: focus x[,y]\n"); |
printf("syntax: focus x[,y,[,z]]\n"); |
403 |
printf("where x and y are integers as reported by the" |
printf("where x (cpu id), y (machine number), and z (emul " |
404 |
" 'emuls' command\n"); |
"number) are integers as\nreported by the 'emuls'" |
405 |
|
" command.\n"); |
406 |
goto print_current_focus_and_return; |
goto print_current_focus_and_return; |
407 |
} |
} |
408 |
|
|
409 |
x = atoi(cmd_line); |
x = atoi(cmd_line); |
410 |
p = strchr(cmd_line, ','); |
p = strchr(cmd_line, ','); |
411 |
if (p == cmd_line) { |
if (p == cmd_line) { |
412 |
printf("No machine number specified?\n"); |
printf("No cpu number specified?\n"); |
|
printf("syntax: focus x[,y]\n"); |
|
413 |
return; |
return; |
414 |
} |
} |
415 |
|
|
416 |
if (p != NULL) |
if (p != NULL) { |
417 |
y = atoi(p + 1); |
y = atoi(p+1); |
418 |
|
p2 = strchr(p+1, ','); |
419 |
|
if (p2 == p+1) { |
420 |
|
printf("No machine number specified?\n"); |
421 |
|
return; |
422 |
|
} |
423 |
|
|
424 |
|
if (p2 != NULL) |
425 |
|
z = atoi(p2 + 1); |
426 |
|
} |
427 |
|
|
428 |
if (y != -1) { |
if (z != -1) { |
429 |
/* Change emul: */ |
/* Change emul: */ |
430 |
if (y < 0 || y >= debugger_n_emuls) { |
if (z < 0 || z >= debugger_n_emuls) { |
431 |
printf("Invalid emul number: %i\n", y); |
printf("Invalid emul number: %i\n", z); |
432 |
return; |
return; |
433 |
} |
} |
434 |
|
|
435 |
debugger_emul = debugger_emuls[y]; |
debugger_cur_emul = z; |
436 |
|
debugger_emul = debugger_emuls[z]; |
437 |
|
|
438 |
/* This is just in case the machine change below fails... */ |
/* This is just in case the machine change below fails... */ |
439 |
debugger_machine = debugger_emul->machines[0]; |
debugger_machine = debugger_emul->machines[0]; |
440 |
} |
} |
441 |
|
|
442 |
/* Change machine: */ |
if (y != -1) { |
443 |
if (x < 0 || x >= debugger_emul->n_machines) { |
/* Change machine: */ |
444 |
printf("Invalid machine number: %i\n", x); |
if (y < 0 || y >= debugger_emul->n_machines) { |
445 |
|
printf("Invalid machine number: %i\n", y); |
446 |
|
return; |
447 |
|
} |
448 |
|
|
449 |
|
debugger_cur_machine = y; |
450 |
|
debugger_machine = debugger_emul->machines[y]; |
451 |
|
} |
452 |
|
|
453 |
|
/* Change cpu: */ |
454 |
|
if (x < 0 || x >= debugger_machine->ncpus) { |
455 |
|
printf("Invalid cpu number: %i\n", x); |
456 |
return; |
return; |
457 |
} |
} |
458 |
|
|
459 |
debugger_machine = debugger_emul->machines[x]; |
debugger_cur_cpu = x; |
460 |
|
|
461 |
print_current_focus_and_return: |
print_current_focus_and_return: |
462 |
printf("current emul: \"%s\"\n", debugger_emul->name == NULL? |
if (debugger_n_emuls > 1) |
463 |
"(no name)" : debugger_emul->name); |
printf("current emul (%i): \"%s\"\n", |
464 |
printf("current machine: \"%s\"\n", debugger_machine->name == NULL? |
debugger_cur_emul, debugger_emul->name == NULL? |
465 |
"(no name)" : debugger_machine->name); |
"(no name)" : debugger_emul->name); |
466 |
|
|
467 |
|
if (debugger_emul->n_machines > 1) |
468 |
|
printf("current machine (%i): \"%s\"\n", |
469 |
|
debugger_cur_machine, debugger_machine->name == NULL? |
470 |
|
"(no name)" : debugger_machine->name); |
471 |
|
|
472 |
|
printf("current cpu (%i)\n", debugger_cur_cpu); |
473 |
} |
} |
474 |
|
|
475 |
|
|
657 |
return; |
return; |
658 |
} |
} |
659 |
|
|
660 |
res = debugger_parse_name(m, cmd_line, 0, &tmp); |
res = debugger_parse_expression(m, cmd_line, 0, &tmp); |
661 |
switch (res) { |
switch (res) { |
662 |
case NAME_PARSE_NOMATCH: |
case PARSE_NOMATCH: |
663 |
printf("No match.\n"); |
printf("No match.\n"); |
664 |
break; |
break; |
665 |
case NAME_PARSE_MULTIPLE: |
case PARSE_MULTIPLE: |
666 |
printf("Multiple matches. Try prefixing with %%, $, or @.\n"); |
printf("Multiple matches. Try prefixing with %%, $, or @.\n"); |
667 |
break; |
break; |
668 |
case NAME_PARSE_REGISTER: |
case PARSE_SETTINGS: |
669 |
printf("%s = 0x%"PRIx64"\n", cmd_line, (uint64_t)tmp); |
printf("%s = 0x%"PRIx64"\n", cmd_line, (uint64_t)tmp); |
670 |
break; |
break; |
671 |
case NAME_PARSE_SYMBOL: |
case PARSE_SYMBOL: |
672 |
if (m->cpus[0]->is_32bit) |
if (m->cpus[0]->is_32bit) |
673 |
printf("%s = 0x%08"PRIx32"\n", cmd_line, (uint32_t)tmp); |
printf("%s = 0x%08"PRIx32"\n", cmd_line, (uint32_t)tmp); |
674 |
else |
else |
675 |
printf("%s = 0x%016"PRIx64"\n", cmd_line,(uint64_t)tmp); |
printf("%s = 0x%016"PRIx64"\n", cmd_line,(uint64_t)tmp); |
676 |
break; |
break; |
677 |
case NAME_PARSE_NUMBER: |
case PARSE_NUMBER: |
678 |
printf("0x%"PRIx64"\n", (uint64_t) tmp); |
printf("0x%"PRIx64"\n", (uint64_t) tmp); |
679 |
break; |
break; |
680 |
} |
} |
742 |
} |
} |
743 |
|
|
744 |
/* here: q is the address, p is the data. */ |
/* here: q is the address, p is the data. */ |
745 |
res = debugger_parse_name(m, q, 0, &addr); |
res = debugger_parse_expression(m, q, 0, &addr); |
746 |
switch (res) { |
switch (res) { |
747 |
case NAME_PARSE_NOMATCH: |
case PARSE_NOMATCH: |
748 |
printf("Couldn't parse the address.\n"); |
printf("Couldn't parse the address.\n"); |
749 |
return; |
return; |
750 |
case NAME_PARSE_MULTIPLE: |
case PARSE_MULTIPLE: |
751 |
printf("Multiple matches for the address." |
printf("Multiple matches for the address." |
752 |
" Try prefixing with %%, $, or @.\n"); |
" Try prefixing with %%, $, or @.\n"); |
753 |
return; |
return; |
754 |
case NAME_PARSE_REGISTER: |
case PARSE_SETTINGS: |
755 |
case NAME_PARSE_SYMBOL: |
case PARSE_SYMBOL: |
756 |
case NAME_PARSE_NUMBER: |
case PARSE_NUMBER: |
757 |
break; |
break; |
758 |
default: |
default: |
759 |
printf("INTERNAL ERROR in debugger.c.\n"); |
printf("INTERNAL ERROR in debugger.c.\n"); |
760 |
return; |
return; |
761 |
} |
} |
762 |
|
|
763 |
res = debugger_parse_name(m, p, 0, &data); |
res = debugger_parse_expression(m, p, 0, &data); |
764 |
switch (res) { |
switch (res) { |
765 |
case NAME_PARSE_NOMATCH: |
case PARSE_NOMATCH: |
766 |
printf("Couldn't parse the data.\n"); |
printf("Couldn't parse the data.\n"); |
767 |
return; |
return; |
768 |
case NAME_PARSE_MULTIPLE: |
case PARSE_MULTIPLE: |
769 |
printf("Multiple matches for the data value." |
printf("Multiple matches for the data value." |
770 |
" Try prefixing with %%, $, or @.\n"); |
" Try prefixing with %%, $, or @.\n"); |
771 |
return; |
return; |
772 |
case NAME_PARSE_REGISTER: |
case PARSE_SETTINGS: |
773 |
case NAME_PARSE_SYMBOL: |
case PARSE_SYMBOL: |
774 |
case NAME_PARSE_NUMBER: |
case PARSE_NUMBER: |
775 |
break; |
break; |
776 |
default: |
default: |
777 |
printf("INTERNAL ERROR in debugger.c.\n"); |
printf("INTERNAL ERROR in debugger.c.\n"); |
945 |
*/ |
*/ |
946 |
static void debugger_cmd_reg(struct machine *m, char *cmd_line) |
static void debugger_cmd_reg(struct machine *m, char *cmd_line) |
947 |
{ |
{ |
948 |
int i, cpuid = -1, coprocnr = -1; |
int cpuid = debugger_cur_cpu, coprocnr = -1; |
949 |
int gprs, coprocs; |
int gprs, coprocs; |
950 |
char *p; |
char *p; |
951 |
|
|
971 |
gprs = (coprocnr == -1)? 1 : 0; |
gprs = (coprocnr == -1)? 1 : 0; |
972 |
coprocs = (coprocnr == -1)? 0x0 : (1 << coprocnr); |
coprocs = (coprocnr == -1)? 0x0 : (1 << coprocnr); |
973 |
|
|
974 |
for (i=0; i<m->ncpus; i++) |
cpu_register_dump(m, m->cpus[cpuid], gprs, coprocs); |
|
if (cpuid == -1 || i == cpuid) |
|
|
cpu_register_dump(m, m->cpus[i], gprs, coprocs); |
|
975 |
} |
} |
976 |
|
|
977 |
|
|
1108 |
p = strchr(tmps, ' '); |
p = strchr(tmps, ' '); |
1109 |
if (p != NULL) |
if (p != NULL) |
1110 |
*p = '\0'; |
*p = '\0'; |
1111 |
r = debugger_parse_name(m, tmps, 0, &tmp); |
r = debugger_parse_expression(m, tmps, 0, &tmp); |
1112 |
free(tmps); |
free(tmps); |
1113 |
|
|
1114 |
if (r == NAME_PARSE_NOMATCH || r == NAME_PARSE_MULTIPLE) { |
if (r == PARSE_NOMATCH || r == PARSE_MULTIPLE) { |
1115 |
printf("Unparsable address: %s\n", cmd_line); |
printf("Unparsable address: %s\n", cmd_line); |
1116 |
return; |
return; |
1117 |
} else { |
} else { |
1121 |
p = strchr(cmd_line, ' '); |
p = strchr(cmd_line, ' '); |
1122 |
} |
} |
1123 |
|
|
1124 |
|
if (m->cpus == NULL) { |
1125 |
|
printf("No cpus (?)\n"); |
1126 |
|
return; |
1127 |
|
} |
1128 |
|
c = m->cpus[m->bootstrap_cpu]; |
1129 |
|
if (c == NULL) { |
1130 |
|
printf("m->cpus[m->bootstrap_cpu] = NULL\n"); |
1131 |
|
return; |
1132 |
|
} |
1133 |
|
mem = m->cpus[m->bootstrap_cpu]->mem; |
1134 |
|
|
1135 |
addr_start = last_unasm_addr; |
addr_start = last_unasm_addr; |
1136 |
|
|
1137 |
if (addr_start == MAGIC_UNTOUCHED) { |
if (addr_start == MAGIC_UNTOUCHED) |
1138 |
uint64_t tmp; |
addr_start = c->pc; |
|
int match_register = 0; |
|
|
cpu_register_match(m, "pc", 0, &tmp, &match_register); |
|
|
if (match_register) { |
|
|
addr_start = tmp; |
|
|
} else { |
|
|
printf("No starting address.\n"); |
|
|
return; |
|
|
} |
|
|
} |
|
1139 |
|
|
1140 |
addr_end = addr_start + 1000; |
addr_end = addr_start + 1000; |
1141 |
|
|
1143 |
if (p != NULL) { |
if (p != NULL) { |
1144 |
while (*p == ' ' && *p) |
while (*p == ' ' && *p) |
1145 |
p++; |
p++; |
1146 |
r = debugger_parse_name(m, p, 0, &addr_end); |
r = debugger_parse_expression(m, p, 0, &addr_end); |
1147 |
if (r == NAME_PARSE_NOMATCH || r == NAME_PARSE_MULTIPLE) { |
if (r == PARSE_NOMATCH || r == PARSE_MULTIPLE) { |
1148 |
printf("Unparsable address: %s\n", cmd_line); |
printf("Unparsable address: %s\n", cmd_line); |
1149 |
return; |
return; |
1150 |
} |
} |
1151 |
} else |
} else |
1152 |
lines_left = 20; |
lines_left = 20; |
1153 |
|
|
|
if (m->cpus == NULL) { |
|
|
printf("No cpus (?)\n"); |
|
|
return; |
|
|
} |
|
|
c = m->cpus[m->bootstrap_cpu]; |
|
|
if (c == NULL) { |
|
|
printf("m->cpus[m->bootstrap_cpu] = NULL\n"); |
|
|
return; |
|
|
} |
|
|
mem = m->cpus[m->bootstrap_cpu]->mem; |
|
|
|
|
1154 |
addr = addr_start; |
addr = addr_start; |
1155 |
|
|
1156 |
ctrl_c = 0; |
ctrl_c = 0; |
1246 |
{ "emuls", "", 0, debugger_cmd_emuls, |
{ "emuls", "", 0, debugger_cmd_emuls, |
1247 |
"print a summary of all current emuls" }, |
"print a summary of all current emuls" }, |
1248 |
|
|
1249 |
{ "focus", "x[,y]", 0, debugger_cmd_focus, |
{ "focus", "x[,y[,z]]", 0, debugger_cmd_focus, |
1250 |
"changes focus to machine x (in emul y)" }, |
"changes focus to cpu x, machine x, emul z" }, |
1251 |
|
|
1252 |
{ "help", "", 0, debugger_cmd_help, |
{ "help", "", 0, debugger_cmd_help, |
1253 |
"print this help message" }, |
"print this help message" }, |
1404 |
curlines = 0; |
curlines = 0; |
1405 |
} |
} |
1406 |
|
|
1407 |
printf("\nIn generic assignments, x must be a register, and expr can be" |
printf("\nIn generic assignments, x must be a register or other " |
1408 |
" a register, a\nnumeric value, or a symbol name (+ an optional " |
"writable settings\nvariable, and expr can contain registers/" |
1409 |
"numeric offset). In case there\nare multiple matches (i.e. a " |
"settings, numeric values, or symbol\nnames, in combination with" |
1410 |
"symbol that has the same name as a register), you\nmay add a " |
" parenthesis and + - * / %% ^ | operators.\nIn case there are" |
1411 |
"prefix character as a hint: '%%' for registers, '@' for symbols," |
" multiple matches (i.e. a symbol that has the same name as a\n" |
1412 |
" and\n'$' for numeric values. Use 0x for hexadecimal values.\n"); |
"register), you may add a prefix character as a hint: '#' for" |
1413 |
|
" registers, '@'\nfor symbols, and '$' for numeric values. Use" |
1414 |
|
" 0x for hexadecimal values.\n"); |
1415 |
} |
} |
1416 |
|
|