comparison debug.c @ 2214:7591c67b8d1e

Support for loading symbols in debugger for use during name resolution and disassembly
author Michael Pavone <pavone@retrodev.com>
date Mon, 29 Aug 2022 23:01:46 -0700
parents 3809a0bd680e
children 4e27c36f947c
comparison
equal deleted inserted replaced
2213:53411df7fc71 2214:7591c67b8d1e
623 uint32_t right; 623 uint32_t right;
624 switch(e->type) 624 switch(e->type)
625 { 625 {
626 case EXPR_SCALAR: 626 case EXPR_SCALAR:
627 if (e->op.type == TOKEN_NAME) { 627 if (e->op.type == TOKEN_NAME) {
628 return root->resolve(root, e->op.v.str, out); 628 if (root->resolve(root, e->op.v.str, out)) {
629 return 1;
630 }
631 tern_val v;
632 if (tern_find(root->symbols, e->op.v.str, &v)) {
633 *out = v.intval;
634 return 1;
635 }
636 return 0;
629 } else { 637 } else {
630 *out = e->op.v.num; 638 *out = e->op.v.num;
631 return 1; 639 return 1;
632 } 640 }
633 case EXPR_UNARY: 641 case EXPR_UNARY:
1652 (*target)->condition = NULL; 1660 (*target)->condition = NULL;
1653 } 1661 }
1654 return 1; 1662 return 1;
1655 } 1663 }
1656 1664
1665 static void symbol_max_len(char *key, tern_val val, uint8_t valtype, void *data)
1666 {
1667 size_t *max_len = data;
1668 size_t len = strlen(key);
1669 if (len > *max_len) {
1670 *max_len = len;
1671 }
1672 }
1673
1674 static void print_symbol(char *key, tern_val val, uint8_t valtype, void *data)
1675 {
1676 size_t *padding = data;
1677 size_t len = strlen(key);
1678 fputs(key, stdout);
1679 while (len < *padding)
1680 {
1681 putchar(' ');
1682 len++;
1683 }
1684 printf("%X\n", (uint32_t)val.intval);
1685 }
1686
1687 static uint8_t cmd_symbols(debug_root *root, parsed_command *cmd)
1688 {
1689 char *filename = cmd->raw ? strip_ws(cmd->raw) : NULL;
1690 if (filename && *filename) {
1691 FILE *f = fopen(filename, "r");
1692 if (!f) {
1693 fprintf(stderr, "Failed to open %s for reading\n", filename);
1694 return 1;
1695 }
1696 char linebuf[1024];
1697 while (fgets(linebuf, sizeof(linebuf), f))
1698 {
1699 char *line = strip_ws(linebuf);
1700 if (*line) {
1701 char *end;
1702 uint32_t address = strtol(line, &end, 16);
1703 if (end != line) {
1704 if (*end == '=') {
1705 char *name = strip_ws(end + 1);
1706 add_label(root->disasm, name, address);
1707 root->symbols = tern_insert_int(root->symbols, name, address);
1708 }
1709 }
1710 }
1711 }
1712 } else {
1713 size_t max_len = 0;
1714 tern_foreach(root->symbols, symbol_max_len, &max_len);
1715 max_len += 2;
1716 tern_foreach(root->symbols, print_symbol, &max_len);
1717 }
1718 return 1;
1719 }
1720
1657 static uint8_t cmd_delete_m68k(debug_root *root, parsed_command *cmd) 1721 static uint8_t cmd_delete_m68k(debug_root *root, parsed_command *cmd)
1658 { 1722 {
1659 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value); 1723 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value);
1660 if (!*this_bp) { 1724 if (!*this_bp) {
1661 fprintf(stderr, "Breakpoint %d does not exist\n", cmd->args[0].value); 1725 fprintf(stderr, "Breakpoint %d does not exist\n", cmd->args[0].value);
2114 .impl = cmd_while, 2178 .impl = cmd_while,
2115 .min_args = 1, 2179 .min_args = 1,
2116 .max_args = 1, 2180 .max_args = 1,
2117 .has_block = 1, 2181 .has_block = 1,
2118 .accepts_else = 1 2182 .accepts_else = 1
2183 },
2184 {
2185 .names = (const char *[]){
2186 "symbols", NULL
2187 },
2188 .usage = "symbols [FILENAME]",
2189 .desc = "Loads a list of symbols from the file indicated by FILENAME or lists currently loaded symbols if FILENAME is omitted",
2190 .impl = cmd_symbols,
2191 .min_args = 0,
2192 .max_args = 1,
2193 .raw_args = 1
2119 } 2194 }
2120 }; 2195 };
2121 #define NUM_COMMON (sizeof(common_commands)/sizeof(*common_commands)) 2196 #define NUM_COMMON (sizeof(common_commands)/sizeof(*common_commands))
2122 2197
2123 command_def m68k_commands[] = { 2198 command_def m68k_commands[] = {
2601 root->commands = tern_insert_ptr(root->commands, defs[i].names[j], defs + i); 2676 root->commands = tern_insert_ptr(root->commands, defs[i].names[j], defs + i);
2602 } 2677 }
2603 } 2678 }
2604 } 2679 }
2605 2680
2681 static void symbol_map(char *key, tern_val val, uint8_t valtype, void *data)
2682 {
2683 debug_root *root = data;
2684 label_def *label = val.ptrval;
2685 for (uint32_t i = 0; i < label->num_labels; i++)
2686 {
2687 root->symbols = tern_insert_int(root->symbols, label->labels[i], label->full_address);
2688 }
2689 }
2690
2606 debug_root *find_m68k_root(m68k_context *context) 2691 debug_root *find_m68k_root(m68k_context *context)
2607 { 2692 {
2608 debug_root *root = find_root(context); 2693 debug_root *root = find_root(context);
2609 if (root && !root->commands) { 2694 if (root && !root->commands) {
2610 add_commands(root, common_commands, NUM_COMMON); 2695 add_commands(root, common_commands, NUM_COMMON);
2611 add_commands(root, m68k_commands, NUM_68K); 2696 add_commands(root, m68k_commands, NUM_68K);
2612 root->read_mem = read_m68k; 2697 root->read_mem = read_m68k;
2613 root->write_mem = write_m68k; 2698 root->write_mem = write_m68k;
2614 root->set = set_m68k; 2699 root->set = set_m68k;
2700 root->disasm = create_68000_disasm();
2615 switch (current_system->type) 2701 switch (current_system->type)
2616 { 2702 {
2617 case SYSTEM_GENESIS: 2703 case SYSTEM_GENESIS:
2618 case SYSTEM_SEGACD: 2704 case SYSTEM_SEGACD:
2619 //check if this is the main CPU 2705 //check if this is the main CPU
2620 if (context->system == current_system) { 2706 if (context->system == current_system) {
2621 root->resolve = resolve_genesis; 2707 root->resolve = resolve_genesis;
2622 add_commands(root, genesis_commands, NUM_GENESIS); 2708 add_commands(root, genesis_commands, NUM_GENESIS);
2623 if (current_system->type == SYSTEM_SEGACD) { 2709 if (current_system->type == SYSTEM_SEGACD) {
2710 add_segacd_maincpu_labels(root->disasm);
2624 add_commands(root, scd_main_commands, NUM_SCD_MAIN); 2711 add_commands(root, scd_main_commands, NUM_SCD_MAIN);
2625 } 2712 }
2626 break; 2713 break;
2627 } else { 2714 } else {
2715 add_segacd_subcpu_labels(root->disasm);
2628 add_commands(root, scd_sub_commands, NUM_SCD_SUB); 2716 add_commands(root, scd_sub_commands, NUM_SCD_SUB);
2629 } 2717 }
2630 default: 2718 default:
2631 root->resolve = resolve_m68k; 2719 root->resolve = resolve_m68k;
2632 } 2720 }
2721 tern_foreach(root->disasm->labels, symbol_map, root);
2633 } 2722 }
2634 return root; 2723 return root;
2635 } 2724 }
2636 2725
2637 #ifndef NO_Z80 2726 #ifndef NO_Z80
3291 { 3380 {
3292 eval_expr(root, cur->args[i].parsed, &cur->args[i].value); 3381 eval_expr(root, cur->args[i].parsed, &cur->args[i].value);
3293 do_print(root, format_str, cur->args[i].raw, cur->args[i].value); 3382 do_print(root, format_str, cur->args[i].raw, cur->args[i].value);
3294 } 3383 }
3295 } 3384 }
3296 m68k_disasm(&inst, input_buf); 3385 m68k_disasm_labels(&inst, input_buf, root->disasm);
3297 printf("%X: %s\n", address, input_buf); 3386 printf("%X: %s\n", address, input_buf);
3298 debugger_repl(root); 3387 debugger_repl(root);
3299 return; 3388 return;
3300 } 3389 }