1 |
/* |
/* |
2 |
* Copyright (C) 2004-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2004-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: debugger_cmds.c,v 1.4 2006/06/16 18:31:26 debug Exp $ |
* $Id: debugger_cmds.c,v 1.12 2007/06/15 17:02:39 debug Exp $ |
29 |
* |
* |
30 |
* Debugger commands. Included from debugger.c. |
* Debugger commands. Included from debugger.c. |
31 |
*/ |
*/ |
62 |
} |
} |
63 |
|
|
64 |
if (strcmp(cmd_line, "show") == 0) { |
if (strcmp(cmd_line, "show") == 0) { |
65 |
if (m->n_breakpoints == 0) |
if (m->breakpoints.n == 0) |
66 |
printf("No breakpoints set.\n"); |
printf("No breakpoints set.\n"); |
67 |
for (i=0; i<m->n_breakpoints; i++) |
for (i=0; i<m->breakpoints.n; i++) |
68 |
show_breakpoint(m, i); |
show_breakpoint(m, i); |
69 |
return; |
return; |
70 |
} |
} |
72 |
if (strncmp(cmd_line, "delete ", 7) == 0) { |
if (strncmp(cmd_line, "delete ", 7) == 0) { |
73 |
int x = atoi(cmd_line + 7); |
int x = atoi(cmd_line + 7); |
74 |
|
|
75 |
if (m->n_breakpoints == 0) { |
if (m->breakpoints.n == 0) { |
76 |
printf("No breakpoints set.\n"); |
printf("No breakpoints set.\n"); |
77 |
return; |
return; |
78 |
} |
} |
79 |
if (x < 0 || x >= m->n_breakpoints) { |
if (x < 0 || x > m->breakpoints.n) { |
80 |
printf("Invalid breakpoint nr %i. Use 'breakpoint " |
printf("Invalid breakpoint nr %i. Use 'breakpoint " |
81 |
"show' to see the current breakpoints.\n", x); |
"show' to see the current breakpoints.\n", x); |
82 |
return; |
return; |
83 |
} |
} |
84 |
|
|
85 |
free(m->breakpoint_string[x]); |
free(m->breakpoints.string[x]); |
86 |
|
|
87 |
for (i=x; i<m->n_breakpoints-1; i++) { |
for (i=x; i<m->breakpoints.n-1; i++) { |
88 |
m->breakpoint_addr[i] = m->breakpoint_addr[i+1]; |
m->breakpoints.addr[i] = m->breakpoints.addr[i+1]; |
89 |
m->breakpoint_string[i] = m->breakpoint_string[i+1]; |
m->breakpoints.string[i] = m->breakpoints.string[i+1]; |
|
m->breakpoint_flags[i] = m->breakpoint_flags[i+1]; |
|
90 |
} |
} |
91 |
m->n_breakpoints --; |
m->breakpoints.n --; |
92 |
|
|
93 |
/* Clear translations: */ |
/* Clear translations: */ |
94 |
for (i=0; i<m->ncpus; i++) |
for (i=0; i<m->ncpus; i++) |
101 |
uint64_t tmp; |
uint64_t tmp; |
102 |
size_t breakpoint_buf_len; |
size_t breakpoint_buf_len; |
103 |
|
|
104 |
if (m->n_breakpoints >= MAX_BREAKPOINTS) { |
i = m->breakpoints.n; |
|
printf("Too many breakpoints. (You need to recompile" |
|
|
" gxemul to increase this. Max = %i.)\n", |
|
|
MAX_BREAKPOINTS); |
|
|
return; |
|
|
} |
|
|
|
|
|
i = m->n_breakpoints; |
|
105 |
|
|
106 |
res = debugger_parse_name(m, cmd_line + 4, 0, &tmp); |
res = debugger_parse_expression(m, cmd_line + 4, 0, &tmp); |
107 |
if (!res) { |
if (!res) { |
108 |
printf("Couldn't parse '%s'\n", cmd_line + 4); |
printf("Couldn't parse '%s'\n", cmd_line + 4); |
109 |
return; |
return; |
110 |
} |
} |
111 |
|
|
112 |
|
CHECK_ALLOCATION(m->breakpoints.string = realloc( |
113 |
|
m->breakpoints.string, sizeof(char *) * |
114 |
|
(m->breakpoints.n + 1))); |
115 |
|
CHECK_ALLOCATION(m->breakpoints.addr = realloc( |
116 |
|
m->breakpoints.addr, sizeof(uint64_t) * |
117 |
|
(m->breakpoints.n + 1))); |
118 |
|
|
119 |
breakpoint_buf_len = strlen(cmd_line+4) + 1; |
breakpoint_buf_len = strlen(cmd_line+4) + 1; |
120 |
m->breakpoint_string[i] = malloc(breakpoint_buf_len); |
|
121 |
if (m->breakpoint_string[i] == NULL) { |
CHECK_ALLOCATION(m->breakpoints.string[i] = |
122 |
printf("out of memory in debugger_cmd_breakpoint()\n"); |
malloc(breakpoint_buf_len)); |
123 |
exit(1); |
strlcpy(m->breakpoints.string[i], cmd_line+4, |
|
} |
|
|
strlcpy(m->breakpoint_string[i], cmd_line+4, |
|
124 |
breakpoint_buf_len); |
breakpoint_buf_len); |
125 |
m->breakpoint_addr[i] = tmp; |
m->breakpoints.addr[i] = tmp; |
|
m->breakpoint_flags[i] = 0; |
|
126 |
|
|
127 |
m->n_breakpoints ++; |
m->breakpoints.n ++; |
128 |
show_breakpoint(m, i); |
show_breakpoint(m, i); |
129 |
|
|
130 |
/* Clear translations: */ |
/* Clear translations: */ |
204 |
|
|
205 |
for (i=0; i<mem->n_mmapped_devices; i++) { |
for (i=0; i<mem->n_mmapped_devices; i++) { |
206 |
printf("%2i: %25s @ 0x%011"PRIx64", len = 0x%"PRIx64, |
printf("%2i: %25s @ 0x%011"PRIx64", len = 0x%"PRIx64, |
207 |
i, mem->dev_name[i], |
i, mem->devices[i].name, |
208 |
(uint64_t) mem->dev_baseaddr[i], |
(uint64_t) mem->devices[i].baseaddr, |
209 |
(uint64_t) mem->dev_length[i]); |
(uint64_t) mem->devices[i].length); |
210 |
|
|
211 |
if (mem->dev_flags[i]) { |
if (mem->devices[i].flags) { |
212 |
printf(" ("); |
printf(" ("); |
213 |
if (mem->dev_flags[i] & DM_DYNTRANS_OK) |
if (mem->devices[i].flags & DM_DYNTRANS_OK) |
214 |
printf("DYNTRANS R"); |
printf("DYNTRANS R"); |
215 |
if (mem->dev_flags[i] & DM_DYNTRANS_WRITE_OK) |
if (mem->devices[i].flags &DM_DYNTRANS_WRITE_OK) |
216 |
printf("+W"); |
printf("+W"); |
217 |
printf(")"); |
printf(")"); |
218 |
} |
} |
254 |
|
|
255 |
if (cmd_line[0] != '\0') { |
if (cmd_line[0] != '\0') { |
256 |
uint64_t tmp; |
uint64_t tmp; |
257 |
char *tmps = strdup(cmd_line); |
char *tmps; |
258 |
|
|
259 |
|
CHECK_ALLOCATION(tmps = strdup(cmd_line)); |
260 |
|
|
261 |
/* addr: */ |
/* addr: */ |
262 |
p = strchr(tmps, ' '); |
p = strchr(tmps, ' '); |
263 |
if (p != NULL) |
if (p != NULL) |
264 |
*p = '\0'; |
*p = '\0'; |
265 |
r = debugger_parse_name(m, tmps, 0, &tmp); |
r = debugger_parse_expression(m, tmps, 0, &tmp); |
266 |
free(tmps); |
free(tmps); |
267 |
|
|
268 |
if (r == NAME_PARSE_NOMATCH || r == NAME_PARSE_MULTIPLE) { |
if (r == PARSE_NOMATCH || r == PARSE_MULTIPLE) { |
269 |
printf("Unparsable address: %s\n", cmd_line); |
printf("Unparsable address: %s\n", cmd_line); |
270 |
return; |
return; |
271 |
} else { |
} else { |
275 |
p = strchr(cmd_line, ' '); |
p = strchr(cmd_line, ' '); |
276 |
} |
} |
277 |
|
|
278 |
|
if (m->cpus == NULL) { |
279 |
|
printf("No cpus (?)\n"); |
280 |
|
return; |
281 |
|
} |
282 |
|
c = m->cpus[m->bootstrap_cpu]; |
283 |
|
if (c == NULL) { |
284 |
|
printf("m->cpus[m->bootstrap_cpu] = NULL\n"); |
285 |
|
return; |
286 |
|
} |
287 |
|
mem = m->cpus[m->bootstrap_cpu]->mem; |
288 |
|
|
289 |
addr_start = last_dump_addr; |
addr_start = last_dump_addr; |
290 |
|
|
291 |
if (addr_start == MAGIC_UNTOUCHED) { |
if (addr_start == MAGIC_UNTOUCHED) |
292 |
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; |
|
|
} |
|
|
} |
|
293 |
|
|
294 |
addr_end = addr_start + 16 * 16; |
addr_end = addr_start + 16 * 16; |
295 |
|
|
297 |
if (p != NULL) { |
if (p != NULL) { |
298 |
while (*p == ' ' && *p) |
while (*p == ' ' && *p) |
299 |
p++; |
p++; |
300 |
r = debugger_parse_name(m, p, 0, &addr_end); |
r = debugger_parse_expression(m, p, 0, &addr_end); |
301 |
if (r == NAME_PARSE_NOMATCH || r == NAME_PARSE_MULTIPLE) { |
if (r == PARSE_NOMATCH || r == PARSE_MULTIPLE) { |
302 |
printf("Unparsable address: %s\n", cmd_line); |
printf("Unparsable address: %s\n", cmd_line); |
303 |
return; |
return; |
304 |
} |
} |
305 |
} |
} |
306 |
|
|
|
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; |
|
|
|
|
307 |
addr = addr_start & ~0xf; |
addr = addr_start & ~0xf; |
308 |
|
|
309 |
ctrl_c = 0; |
ctrl_c = 0; |
388 |
/* |
/* |
389 |
* debugger_cmd_focus(): |
* debugger_cmd_focus(): |
390 |
* |
* |
391 |
* Changes focus to specific machine (in a specific emulation). |
* Changes focus to specific cpu, in a specific machine (in a specific |
392 |
|
* emulation). |
393 |
*/ |
*/ |
394 |
static void debugger_cmd_focus(struct machine *m, char *cmd_line) |
static void debugger_cmd_focus(struct machine *m, char *cmd_line) |
395 |
{ |
{ |
396 |
int x = -1, y = -1; |
int x = -1, y = -1, z = -1; |
397 |
char *p; |
char *p, *p2; |
398 |
|
|
399 |
if (!cmd_line[0]) { |
if (!cmd_line[0]) { |
400 |
printf("syntax: focus x[,y]\n"); |
printf("syntax: focus x[,y,[,z]]\n"); |
401 |
printf("where x and y are integers as reported by the" |
printf("where x (cpu id), y (machine number), and z (emul " |
402 |
" 'emuls' command\n"); |
"number) are integers as\nreported by the 'emuls'" |
403 |
|
" command.\n"); |
404 |
goto print_current_focus_and_return; |
goto print_current_focus_and_return; |
405 |
} |
} |
406 |
|
|
407 |
x = atoi(cmd_line); |
x = atoi(cmd_line); |
408 |
p = strchr(cmd_line, ','); |
p = strchr(cmd_line, ','); |
409 |
if (p == cmd_line) { |
if (p == cmd_line) { |
410 |
printf("No machine number specified?\n"); |
printf("No cpu number specified?\n"); |
|
printf("syntax: focus x[,y]\n"); |
|
411 |
return; |
return; |
412 |
} |
} |
413 |
|
|
414 |
if (p != NULL) |
if (p != NULL) { |
415 |
y = atoi(p + 1); |
y = atoi(p+1); |
416 |
|
p2 = strchr(p+1, ','); |
417 |
|
if (p2 == p+1) { |
418 |
|
printf("No machine number specified?\n"); |
419 |
|
return; |
420 |
|
} |
421 |
|
|
422 |
|
if (p2 != NULL) |
423 |
|
z = atoi(p2 + 1); |
424 |
|
} |
425 |
|
|
426 |
if (y != -1) { |
if (z != -1) { |
427 |
/* Change emul: */ |
/* Change emul: */ |
428 |
if (y < 0 || y >= debugger_n_emuls) { |
if (z < 0 || z >= debugger_n_emuls) { |
429 |
printf("Invalid emul number: %i\n", y); |
printf("Invalid emul number: %i\n", z); |
430 |
return; |
return; |
431 |
} |
} |
432 |
|
|
433 |
debugger_emul = debugger_emuls[y]; |
debugger_cur_emul = z; |
434 |
|
debugger_emul = debugger_emuls[z]; |
435 |
|
|
436 |
/* This is just in case the machine change below fails... */ |
/* This is just in case the machine change below fails... */ |
437 |
debugger_machine = debugger_emul->machines[0]; |
debugger_machine = debugger_emul->machines[0]; |
438 |
} |
} |
439 |
|
|
440 |
/* Change machine: */ |
if (y != -1) { |
441 |
if (x < 0 || x >= debugger_emul->n_machines) { |
/* Change machine: */ |
442 |
printf("Invalid machine number: %i\n", x); |
if (y < 0 || y >= debugger_emul->n_machines) { |
443 |
|
printf("Invalid machine number: %i\n", y); |
444 |
|
return; |
445 |
|
} |
446 |
|
|
447 |
|
debugger_cur_machine = y; |
448 |
|
debugger_machine = debugger_emul->machines[y]; |
449 |
|
} |
450 |
|
|
451 |
|
/* Change cpu: */ |
452 |
|
if (x < 0 || x >= debugger_machine->ncpus) { |
453 |
|
printf("Invalid cpu number: %i\n", x); |
454 |
return; |
return; |
455 |
} |
} |
456 |
|
|
457 |
debugger_machine = debugger_emul->machines[x]; |
debugger_cur_cpu = x; |
458 |
|
|
459 |
print_current_focus_and_return: |
print_current_focus_and_return: |
460 |
printf("current emul: \"%s\"\n", debugger_emul->name == NULL? |
if (debugger_n_emuls > 1) |
461 |
"(no name)" : debugger_emul->name); |
printf("current emul (%i): \"%s\"\n", |
462 |
printf("current machine: \"%s\"\n", debugger_machine->name == NULL? |
debugger_cur_emul, debugger_emul->name == NULL? |
463 |
"(no name)" : debugger_machine->name); |
"(no name)" : debugger_emul->name); |
464 |
|
|
465 |
|
if (debugger_emul->n_machines > 1) |
466 |
|
printf("current machine (%i): \"%s\"\n", |
467 |
|
debugger_cur_machine, debugger_machine->name == NULL? |
468 |
|
"(no name)" : debugger_machine->name); |
469 |
|
|
470 |
|
printf("current cpu (%i)\n", debugger_cur_cpu); |
471 |
} |
} |
472 |
|
|
473 |
|
|
655 |
return; |
return; |
656 |
} |
} |
657 |
|
|
658 |
res = debugger_parse_name(m, cmd_line, 0, &tmp); |
res = debugger_parse_expression(m, cmd_line, 0, &tmp); |
659 |
switch (res) { |
switch (res) { |
660 |
case NAME_PARSE_NOMATCH: |
case PARSE_NOMATCH: |
661 |
printf("No match.\n"); |
printf("No match.\n"); |
662 |
break; |
break; |
663 |
case NAME_PARSE_MULTIPLE: |
case PARSE_MULTIPLE: |
664 |
printf("Multiple matches. Try prefixing with %%, $, or @.\n"); |
printf("Multiple matches. Try prefixing with %%, $, or @.\n"); |
665 |
break; |
break; |
666 |
case NAME_PARSE_REGISTER: |
case PARSE_SETTINGS: |
667 |
printf("%s = 0x%"PRIx64"\n", cmd_line, (uint64_t)tmp); |
printf("%s = 0x%"PRIx64"\n", cmd_line, (uint64_t)tmp); |
668 |
break; |
break; |
669 |
case NAME_PARSE_SYMBOL: |
case PARSE_SYMBOL: |
670 |
if (m->cpus[0]->is_32bit) |
if (m->cpus[0]->is_32bit) |
671 |
printf("%s = 0x%08"PRIx32"\n", cmd_line, (uint32_t)tmp); |
printf("%s = 0x%08"PRIx32"\n", cmd_line, (uint32_t)tmp); |
672 |
else |
else |
673 |
printf("%s = 0x%016"PRIx64"\n", cmd_line,(uint64_t)tmp); |
printf("%s = 0x%016"PRIx64"\n", cmd_line,(uint64_t)tmp); |
674 |
break; |
break; |
675 |
case NAME_PARSE_NUMBER: |
case PARSE_NUMBER: |
676 |
printf("0x%"PRIx64"\n", (uint64_t) tmp); |
printf("0x%"PRIx64"\n", (uint64_t) tmp); |
677 |
break; |
break; |
678 |
} |
} |
740 |
} |
} |
741 |
|
|
742 |
/* here: q is the address, p is the data. */ |
/* here: q is the address, p is the data. */ |
743 |
res = debugger_parse_name(m, q, 0, &addr); |
res = debugger_parse_expression(m, q, 0, &addr); |
744 |
switch (res) { |
switch (res) { |
745 |
case NAME_PARSE_NOMATCH: |
case PARSE_NOMATCH: |
746 |
printf("Couldn't parse the address.\n"); |
printf("Couldn't parse the address.\n"); |
747 |
return; |
return; |
748 |
case NAME_PARSE_MULTIPLE: |
case PARSE_MULTIPLE: |
749 |
printf("Multiple matches for the address." |
printf("Multiple matches for the address." |
750 |
" Try prefixing with %%, $, or @.\n"); |
" Try prefixing with %%, $, or @.\n"); |
751 |
return; |
return; |
752 |
case NAME_PARSE_REGISTER: |
case PARSE_SETTINGS: |
753 |
case NAME_PARSE_SYMBOL: |
case PARSE_SYMBOL: |
754 |
case NAME_PARSE_NUMBER: |
case PARSE_NUMBER: |
755 |
break; |
break; |
756 |
default: |
default: |
757 |
printf("INTERNAL ERROR in debugger.c.\n"); |
printf("INTERNAL ERROR in debugger.c.\n"); |
758 |
return; |
return; |
759 |
} |
} |
760 |
|
|
761 |
res = debugger_parse_name(m, p, 0, &data); |
res = debugger_parse_expression(m, p, 0, &data); |
762 |
switch (res) { |
switch (res) { |
763 |
case NAME_PARSE_NOMATCH: |
case PARSE_NOMATCH: |
764 |
printf("Couldn't parse the data.\n"); |
printf("Couldn't parse the data.\n"); |
765 |
return; |
return; |
766 |
case NAME_PARSE_MULTIPLE: |
case PARSE_MULTIPLE: |
767 |
printf("Multiple matches for the data value." |
printf("Multiple matches for the data value." |
768 |
" Try prefixing with %%, $, or @.\n"); |
" Try prefixing with %%, $, or @.\n"); |
769 |
return; |
return; |
770 |
case NAME_PARSE_REGISTER: |
case PARSE_SETTINGS: |
771 |
case NAME_PARSE_SYMBOL: |
case PARSE_SYMBOL: |
772 |
case NAME_PARSE_NUMBER: |
case PARSE_NUMBER: |
773 |
break; |
break; |
774 |
default: |
default: |
775 |
printf("INTERNAL ERROR in debugger.c.\n"); |
printf("INTERNAL ERROR in debugger.c.\n"); |
919 |
} |
} |
920 |
|
|
921 |
for (i=0; i<debugger_n_emuls; i++) { |
for (i=0; i<debugger_n_emuls; i++) { |
922 |
single_step = 0; |
single_step = NOT_SINGLE_STEPPING; |
923 |
|
|
924 |
e = debugger_emuls[i]; |
e = debugger_emuls[i]; |
925 |
force_debugger_at_exit = 0; |
force_debugger_at_exit = 0; |
943 |
*/ |
*/ |
944 |
static void debugger_cmd_reg(struct machine *m, char *cmd_line) |
static void debugger_cmd_reg(struct machine *m, char *cmd_line) |
945 |
{ |
{ |
946 |
int i, cpuid = -1, coprocnr = -1; |
int cpuid = debugger_cur_cpu, coprocnr = -1; |
947 |
int gprs, coprocs; |
int gprs, coprocs; |
948 |
char *p; |
char *p; |
949 |
|
|
969 |
gprs = (coprocnr == -1)? 1 : 0; |
gprs = (coprocnr == -1)? 1 : 0; |
970 |
coprocs = (coprocnr == -1)? 0x0 : (1 << coprocnr); |
coprocs = (coprocnr == -1)? 0x0 : (1 << coprocnr); |
971 |
|
|
972 |
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); |
|
973 |
} |
} |
974 |
|
|
975 |
|
|
1100 |
|
|
1101 |
if (cmd_line[0] != '\0') { |
if (cmd_line[0] != '\0') { |
1102 |
uint64_t tmp; |
uint64_t tmp; |
1103 |
char *tmps = strdup(cmd_line); |
char *tmps; |
1104 |
|
|
1105 |
|
CHECK_ALLOCATION(tmps = strdup(cmd_line)); |
1106 |
|
|
1107 |
/* addr: */ |
/* addr: */ |
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 |
|
|