/[gxemul]/trunk/src/debugger.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/debugger.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: debugger.c,v 1.98 2005/03/20 20:27:26 debug Exp $   *  $Id: debugger.c,v 1.122 2005/08/11 09:43:40 debug Exp $
29   *   *
30   *  Single-step debugger.   *  Single-step debugger.
31   *   *
# Line 54  Line 54 
54  #include <string.h>  #include <string.h>
55  #include <unistd.h>  #include <unistd.h>
56    
57    #include "bintrans.h"
58  #include "console.h"  #include "console.h"
59  #include "cpu.h"  #include "cpu.h"
60  #include "device.h"  #include "device.h"
# Line 81  volatile int single_step = 0; Line 82  volatile int single_step = 0;
82  int force_debugger_at_exit = 0;  int force_debugger_at_exit = 0;
83  int show_opcode_statistics = 0;  int show_opcode_statistics = 0;
84    
85    volatile int single_step_breakpoint = 0;
86    int debugger_n_steps_left_before_interaction = 0;
87    
88  int old_instruction_trace = 0;  int old_instruction_trace = 0;
89  int old_quiet_mode = 0;  int old_quiet_mode = 0;
90  int old_show_trace_tree = 0;  int old_show_trace_tree = 0;
# Line 98  static struct emul *debugger_emul; Line 102  static struct emul *debugger_emul;
102  static struct machine *debugger_machine;  static struct machine *debugger_machine;
103    
104  static int exit_debugger;  static int exit_debugger;
 static int n_steps_left_before_interaction = 0;  
105    
106  #define MAX_CMD_LEN             70  #define MAX_CMD_BUFLEN          72
107  #define N_PREVIOUS_CMDS         150  #define N_PREVIOUS_CMDS         150
108  static char *last_cmd[N_PREVIOUS_CMDS];  static char *last_cmd[N_PREVIOUS_CMDS];
109  static int last_cmd_index;  static int last_cmd_index;
110    
111  static char repeat_cmd[MAX_CMD_LEN + 1];  static char repeat_cmd[MAX_CMD_BUFLEN];
112    
113  #define MAGIC_UNTOUCHED         0x98ca76c2ffcc0011ULL  #define MAGIC_UNTOUCHED         0x98ca76c2ffcc0011ULL
114    
# Line 114  static uint64_t last_unasm_addr = MAGIC_ Line 117  static uint64_t last_unasm_addr = MAGIC_
117    
118    
119  /*  /*
120     *  debugger_readchar():
121     *
122     *  TODO: This uses up 100% CPU, maybe that isn't too good. The usleep() call
123     *        might make it a tiny bit nicer on other running processes, but it
124     *        is still very ugly.
125     */
126    char debugger_readchar(void)
127    {
128            int ch;
129            while ((ch = console_readchar(MAIN_CONSOLE)) < 0) {
130                    x11_check_event(debugger_emuls, debugger_n_emuls);
131                    usleep(1);
132            }
133            return ch;
134    }
135    
136    
137    /*
138   *  debugger_activate():   *  debugger_activate():
139   *   *
140   *  This is a signal handler for CTRL-C.  It shouldn't be called directly,   *  This is a signal handler for CTRL-C.  It shouldn't be called directly,
# Line 127  void debugger_activate(int x) Line 148  void debugger_activate(int x)
148          if (single_step) {          if (single_step) {
149                  /*  Already in the debugger. Do nothing.  */                  /*  Already in the debugger. Do nothing.  */
150                  int i;                  int i;
151                  for (i=0; i<MAX_CMD_LEN+1; i++)                  for (i=0; i<MAX_CMD_BUFLEN; i++)
152                          console_makeavail(MAIN_CONSOLE, '\b');                          console_makeavail(MAIN_CONSOLE, '\b');
153                  console_makeavail(MAIN_CONSOLE, ' ');                  console_makeavail(MAIN_CONSOLE, ' ');
154                  console_makeavail(MAIN_CONSOLE, '\n');                  console_makeavail(MAIN_CONSOLE, '\n');
# Line 197  static int debugger_parse_name(struct ma Line 218  static int debugger_parse_name(struct ma
218          }          }
219    
220          /*  Warn about non-signextended values:  */          /*  Warn about non-signextended values:  */
221          if (writeflag &&          if (writeflag) {
222              ((*valuep) >> 32) == 0 && (*valuep) & 0x80000000ULL)                  if (m->cpus[0]->is_32bit) {
223                  printf("WARNING: The value is not sign-extended. "                          /*  Automagically sign-extend.  TODO: Is this good?  */
224                      "Is this what you intended?\n");                          if (((*valuep) >> 32) == 0 && (*valuep) & 0x80000000ULL)
225                                    (*valuep) |= 0xffffffff00000000ULL;
226                    } else {
227                            if (((*valuep) >> 32) == 0 && (*valuep) & 0x80000000ULL)
228                                    printf("WARNING: The value is not sign-extende"
229                                        "d. Is this what you intended?\n");
230                    }
231            }
232    
233          skip_register = name[0] == '$' || name[0] == '@';          skip_register = name[0] == '$' || name[0] == '@';
234          skip_numeric  = name[0] == '%' || name[0] == '@';          skip_numeric  = name[0] == '%' || name[0] == '@';
# Line 233  static int debugger_parse_name(struct ma Line 261  static int debugger_parse_name(struct ma
261                          fprintf(stderr, "out of memory in debugger\n");                          fprintf(stderr, "out of memory in debugger\n");
262                          exit(1);                          exit(1);
263                  }                  }
264                  strcpy(sn, name);                  strlcpy(sn, name, strlen(name)+1);
265    
266                  /*  Is there a '+' in there? Then treat that as an offset:  */                  /*  Is there a '+' in there? Then treat that as an offset:  */
267                  p = strchr(sn, '+');                  p = strchr(sn, '+');
# Line 273  static int debugger_parse_name(struct ma Line 301  static int debugger_parse_name(struct ma
301   */   */
302  static void show_breakpoint(struct machine *m, int i)  static void show_breakpoint(struct machine *m, int i)
303  {  {
304          printf("%3i: 0x%016llx", i,          printf("%3i: 0x", i);
305              (long long)m->breakpoint_addr[i]);          if (m->cpus[0]->is_32bit)
306                    printf("%08x", (int)m->breakpoint_addr[i]);
307            else
308                    printf("%016llx", (long long)m->breakpoint_addr[i]);
309          if (m->breakpoint_string[i] != NULL)          if (m->breakpoint_string[i] != NULL)
310                  printf(" (%s)", m->breakpoint_string[i]);                  printf(" (%s)", m->breakpoint_string[i]);
311          if (m->breakpoint_flags[i])          if (m->breakpoint_flags[i])
# Line 336  static void debugger_cmd_breakpoint(stru Line 367  static void debugger_cmd_breakpoint(stru
367                          m->breakpoint_flags[i]  = m->breakpoint_flags[i+1];                          m->breakpoint_flags[i]  = m->breakpoint_flags[i+1];
368                  }                  }
369                  m->n_breakpoints --;                  m->n_breakpoints --;
370    
371                    /*  Clear translations:  */
372                    for (i=0; i<m->ncpus; i++)
373                            if (m->cpus[i]->translation_cache != NULL)
374                                    cpu_create_or_reset_tc(m->cpus[i]);
375                  return;                  return;
376          }          }
377    
378          if (strncmp(cmd_line, "add ", 4) == 0) {          if (strncmp(cmd_line, "add ", 4) == 0) {
379                  uint64_t tmp;                  uint64_t tmp;
380                    size_t breakpoint_buf_len;
381    
382                  if (m->n_breakpoints >= MAX_BREAKPOINTS) {                  if (m->n_breakpoints >= MAX_BREAKPOINTS) {
383                          printf("Too many breakpoints. (You need to recompile"                          printf("Too many breakpoints. (You need to recompile"
# Line 357  static void debugger_cmd_breakpoint(stru Line 394  static void debugger_cmd_breakpoint(stru
394                          return;                          return;
395                  }                  }
396    
397                  m->breakpoint_string[i] = malloc(strlen(cmd_line+4) + 1);                  breakpoint_buf_len = strlen(cmd_line+4) + 1;
398                    m->breakpoint_string[i] = malloc(breakpoint_buf_len);
399                  if (m->breakpoint_string[i] == NULL) {                  if (m->breakpoint_string[i] == NULL) {
400                          printf("out of memory in debugger_cmd_breakpoint()\n");                          printf("out of memory in debugger_cmd_breakpoint()\n");
401                          exit(1);                          exit(1);
402                  }                  }
403                  strcpy(m->breakpoint_string[i], cmd_line+4);                  strlcpy(m->breakpoint_string[i], cmd_line+4,
404                        breakpoint_buf_len);
405                  m->breakpoint_addr[i] = tmp;                  m->breakpoint_addr[i] = tmp;
406                  m->breakpoint_flags[i] = 0;                  m->breakpoint_flags[i] = 0;
407    
408                  m->n_breakpoints ++;                  m->n_breakpoints ++;
409                  show_breakpoint(m, i);                  show_breakpoint(m, i);
410    
411                    /*  Clear translations:  */
412                    for (i=0; i<m->ncpus; i++)
413                            if (m->cpus[i]->translation_cache != NULL)
414                                    cpu_create_or_reset_tc(m->cpus[i]);
415                  return;                  return;
416          }          }
417    
# Line 380  static void debugger_cmd_breakpoint(stru Line 424  static void debugger_cmd_breakpoint(stru
424   */   */
425  static void debugger_cmd_bintrans(struct machine *m, char *cmd_line)  static void debugger_cmd_bintrans(struct machine *m, char *cmd_line)
426  {  {
427            int i;
428    
429          if (*cmd_line == '\0')          if (*cmd_line == '\0')
430                  goto printstate;                  goto printstate;
431    
# Line 393  static void debugger_cmd_bintrans(struct Line 439  static void debugger_cmd_bintrans(struct
439                  cmd_line++;                  cmd_line++;
440    
441          /*  Note: len 3 and 4, to include the NUL char.  */          /*  Note: len 3 and 4, to include the NUL char.  */
442          if (strncasecmp(cmd_line, "on", 3) == 0)          if (strncasecmp(cmd_line, "on", 3) == 0) {
443                  m->bintrans_enable = 1;                  m->bintrans_enable = 1;
444          else if (strncasecmp(cmd_line, "off", 4) == 0)                  for (i=0; i<m->ncpus; i++)
445                            bintrans_restart(m->cpus[i]);
446            } else if (strncasecmp(cmd_line, "off", 4) == 0)
447                  m->bintrans_enable = 0;                  m->bintrans_enable = 0;
448          else          else
449                  printf("syntax: bintrans [on|off]\n");                  printf("syntax: bintrans [on|off]\n");
# Line 508  static void debugger_cmd_device(struct m Line 556  static void debugger_cmd_device(struct m
556                              (long long)mem->dev_length[i]);                              (long long)mem->dev_length[i]);
557                          if (mem->dev_flags[i]) {                          if (mem->dev_flags[i]) {
558                                  printf(" (");                                  printf(" (");
559                                  if (mem->dev_flags[i] & MEM_BINTRANS_OK)                                  if (mem->dev_flags[i] & MEM_DYNTRANS_OK)
560                                          printf("BINTRANS R");                                          printf("DYNTRANS R");
561                                  if (mem->dev_flags[i] & MEM_BINTRANS_WRITE_OK)                                  if (mem->dev_flags[i] & MEM_DYNTRANS_WRITE_OK)
562                                          printf("+W");                                          printf("+W");
563                                  printf(")");                                  printf(")");
564                          }                          }
# Line 620  static void debugger_cmd_dump(struct mac Line 668  static void debugger_cmd_dump(struct mac
668                  r = c->memory_rw(c, mem, addr, &buf[0], sizeof(buf),                  r = c->memory_rw(c, mem, addr, &buf[0], sizeof(buf),
669                      MEM_READ, CACHE_NONE | NO_EXCEPTIONS);                      MEM_READ, CACHE_NONE | NO_EXCEPTIONS);
670    
671                  printf("0x%016llx  ", (long long)addr);                  if (c->is_32bit)
672                            printf("0x%08x  ", (int)addr);
673                    else
674                            printf("0x%016llx  ", (long long)addr);
675    
676                  if (r == MEMORY_ACCESS_FAILED)                  if (r == MEMORY_ACCESS_FAILED)
677                          printf("(memory access failed)\n");                          printf("(memory access failed)\n");
# Line 653  static void debugger_cmd_dump(struct mac Line 704  static void debugger_cmd_dump(struct mac
704    
705          last_dump_addr = addr_end;          last_dump_addr = addr_end;
706    
707          strcpy(repeat_cmd, "dump");          strlcpy(repeat_cmd, "dump", MAX_CMD_BUFLEN);
708  }  }
709    
710    
# Line 795  static void debugger_cmd_lookup(struct m Line 846  static void debugger_cmd_lookup(struct m
846                          printf("lookup for '%s' failed\n", cmd_line);                          printf("lookup for '%s' failed\n", cmd_line);
847                          return;                          return;
848                  }                  }
849                  printf("%s = 0x%016llx\n", cmd_line, (long long)newaddr);                  printf("%s = 0x", cmd_line);
850                    if (m->cpus[0]->is_32bit)
851                            printf("%08x\n", (int)newaddr);
852                    else
853                            printf("%016llx\n", (long long)newaddr);
854                  return;                  return;
855          }          }
856    
857          symbol = get_symbol_name(&m->symbol_context, addr, &offset);          symbol = get_symbol_name(&m->symbol_context, addr, &offset);
858    
859          if (symbol != NULL)          if (symbol != NULL) {
860                  printf("0x%016llx = %s\n", (long long)addr, symbol);                  if (m->cpus[0]->is_32bit)
861          else                          printf("0x%08x", (int)addr);
862                    else
863                            printf("0x%016llx", (long long)addr);
864                    printf(" = %s\n", symbol);
865            } else
866                  printf("lookup for '%s' failed\n", cmd_line);                  printf("lookup for '%s' failed\n", cmd_line);
867  }  }
868    
# Line 830  static void debugger_cmd_machine(struct Line 889  static void debugger_cmd_machine(struct
889    
890    
891  /*  /*
892     *  debugger_cmd_ninstrs():
893     */
894    static void debugger_cmd_ninstrs(struct machine *m, char *cmd_line)
895    {
896            int toggle = 1;
897            int previous_mode = m->show_nr_of_instructions;
898    
899            if (cmd_line[0] != '\0') {
900                    while (cmd_line[0] != '\0' && cmd_line[0] == ' ')
901                            cmd_line ++;
902                    switch (cmd_line[0]) {
903                    case '0':
904                            toggle = 0;
905                            m->show_nr_of_instructions = 0;
906                            break;
907                    case '1':
908                            toggle = 0;
909                            m->show_nr_of_instructions = 1;
910                            break;
911                    case 'o':
912                    case 'O':
913                            toggle = 0;
914                            switch (cmd_line[1]) {
915                            case 'n':
916                            case 'N':
917                                    m->show_nr_of_instructions = 1;
918                                    break;
919                            default:
920                                    m->show_nr_of_instructions = 0;
921                            }
922                            break;
923                    default:
924                            printf("syntax: trace [on|off]\n");
925                            return;
926                    }
927            }
928    
929            if (toggle)
930                    m->show_nr_of_instructions = !m->show_nr_of_instructions;
931    
932            printf("show_nr_of_instructions = %s",
933                m->show_nr_of_instructions? "ON" : "OFF");
934            if (m->show_nr_of_instructions != previous_mode)
935                    printf("  (was: %s)", previous_mode? "ON" : "OFF");
936            printf("\n");
937    }
938    
939    
940    /*
941   *  debugger_cmd_opcodestats():   *  debugger_cmd_opcodestats():
942   */   */
943  static void debugger_cmd_opcodestats(struct machine *m, char *cmd_line)  static void debugger_cmd_opcodestats(struct machine *m, char *cmd_line)
# Line 899  static void debugger_cmd_print(struct ma Line 1007  static void debugger_cmd_print(struct ma
1007                  printf("Multiple matches. Try prefixing with %%, $, or @.\n");                  printf("Multiple matches. Try prefixing with %%, $, or @.\n");
1008                  break;                  break;
1009          case NAME_PARSE_REGISTER:          case NAME_PARSE_REGISTER:
1010                    printf("%s = 0x%llx\n", cmd_line, (long long)tmp);
1011                    break;
1012          case NAME_PARSE_SYMBOL:          case NAME_PARSE_SYMBOL:
1013                  printf("%s = 0x%016llx\n", cmd_line, (long long)tmp);                  if (m->cpus[0]->is_32bit)
1014                            printf("%s = 0x%08x\n", cmd_line, (int)tmp);
1015                    else
1016                            printf("%s = 0x%016llx\n", cmd_line, (long long)tmp);
1017                  break;                  break;
1018          case NAME_PARSE_NUMBER:          case NAME_PARSE_NUMBER:
1019                  printf("0x%016llx\n", (long long)tmp);                  printf("0x%llx\n", (long long)tmp);
1020                  break;                  break;
1021          }          }
1022  }  }
# Line 1012  static void debugger_cmd_put(struct mach Line 1125  static void debugger_cmd_put(struct mach
1125          switch (put_type) {          switch (put_type) {
1126          case 'b':          case 'b':
1127                  a_byte = data;                  a_byte = data;
1128                  printf("0x%016llx: %02x", (long long)addr, a_byte);                  if (m->cpus[0]->is_32bit)
1129                            printf("0x%08x", (int)addr);
1130                    else
1131                            printf("0x%016llx", (long long)addr);
1132                    printf(": %02x", a_byte);
1133                  if (data > 255)                  if (data > 255)
1134                          printf(" (NOTE: truncating %0llx)", (long long)data);                          printf(" (NOTE: truncating %0llx)", (long long)data);
1135                  res = m->cpus[0]->memory_rw(m->cpus[0], m->cpus[0]->mem, addr,                  res = m->cpus[0]->memory_rw(m->cpus[0], m->cpus[0]->mem, addr,
# Line 1024  static void debugger_cmd_put(struct mach Line 1141  static void debugger_cmd_put(struct mach
1141          case 'h':          case 'h':
1142                  if ((data & 1) != 0)                  if ((data & 1) != 0)
1143                          printf("WARNING: address isn't aligned\n");                          printf("WARNING: address isn't aligned\n");
1144                  printf("0x%016llx: %04x", (long long)addr, (int)data);                  if (m->cpus[0]->is_32bit)
1145                            printf("0x%08x", (int)addr);
1146                    else
1147                            printf("0x%016llx", (long long)addr);
1148                    printf(": %04x", (int)data);
1149                  if (data > 0xffff)                  if (data > 0xffff)
1150                          printf(" (NOTE: truncating %0llx)", (long long)data);                          printf(" (NOTE: truncating %0llx)", (long long)data);
1151                  res = store_16bit_word(m->cpus[0], addr, data);                  res = store_16bit_word(m->cpus[0], addr, data);
# Line 1035  static void debugger_cmd_put(struct mach Line 1156  static void debugger_cmd_put(struct mach
1156          case 'w':          case 'w':
1157                  if ((data & 3) != 0)                  if ((data & 3) != 0)
1158                          printf("WARNING: address isn't aligned\n");                          printf("WARNING: address isn't aligned\n");
1159                  printf("0x%016llx: %08x", (long long)addr, (int)data);                  if (m->cpus[0]->is_32bit)
1160                            printf("0x%08x", (int)addr);
1161                    else
1162                            printf("0x%016llx", (long long)addr);
1163                    printf(": %08x", (int)data);
1164                  if (data > 0xffffffff && (data >> 32) != 0                  if (data > 0xffffffff && (data >> 32) != 0
1165                      && (data >> 32) != 0xffffffff)                      && (data >> 32) != 0xffffffff)
1166                          printf(" (NOTE: truncating %0llx)", (long long)data);                          printf(" (NOTE: truncating %0llx)", (long long)data);
# Line 1047  static void debugger_cmd_put(struct mach Line 1172  static void debugger_cmd_put(struct mach
1172          case 'd':          case 'd':
1173                  if ((data & 7) != 0)                  if ((data & 7) != 0)
1174                          printf("WARNING: address isn't aligned\n");                          printf("WARNING: address isn't aligned\n");
1175                  printf("0x%016llx: %016llx", (long long)addr, (long long)data);                  if (m->cpus[0]->is_32bit)
1176                            printf("0x%08x", (int)addr);
1177                    else
1178                            printf("0x%016llx", (long long)addr);
1179                    printf(": %016llx", (long long)data);
1180                  res = store_64bit_word(m->cpus[0], addr, data);                  res = store_64bit_word(m->cpus[0], addr, data);
1181                  if (!res)                  if (!res)
1182                          printf("  FAILED!\n");                          printf("  FAILED!\n");
# Line 1197  static void debugger_cmd_step(struct mac Line 1326  static void debugger_cmd_step(struct mac
1326                  }                  }
1327          }          }
1328    
1329          n_steps_left_before_interaction = n - 1;          debugger_n_steps_left_before_interaction = n - 1;
1330    
1331          /*  Special hack, see debugger() for more info.  */          /*  Special hack, see debugger() for more info.  */
1332          exit_debugger = -1;          exit_debugger = -1;
1333    
1334          strcpy(repeat_cmd, "step");          strlcpy(repeat_cmd, "step", MAX_CMD_BUFLEN);
1335  }  }
1336    
1337    
# Line 1249  static void debugger_cmd_tlbdump(struct Line 1378  static void debugger_cmd_tlbdump(struct
1378   */   */
1379  static void debugger_cmd_trace(struct machine *m, char *cmd_line)  static void debugger_cmd_trace(struct machine *m, char *cmd_line)
1380  {  {
1381          if (*cmd_line) {          int i, toggle = 1;
1382                  printf("syntax: trace\n");          int previous_mode = old_show_trace_tree;
1383                  return;  
1384            if (cmd_line[0] != '\0') {
1385                    while (cmd_line[0] != '\0' && cmd_line[0] == ' ')
1386                            cmd_line ++;
1387                    switch (cmd_line[0]) {
1388                    case '0':
1389                            toggle = 0;
1390                            old_show_trace_tree = 0;
1391                            break;
1392                    case '1':
1393                            toggle = 0;
1394                            old_show_trace_tree = 1;
1395                            break;
1396                    case 'o':
1397                    case 'O':
1398                            toggle = 0;
1399                            switch (cmd_line[1]) {
1400                            case 'n':
1401                            case 'N':
1402                                    old_show_trace_tree = 1;
1403                                    break;
1404                            default:
1405                                    old_show_trace_tree = 0;
1406                            }
1407                            break;
1408                    default:
1409                            printf("syntax: trace [on|off]\n");
1410                            return;
1411                    }
1412          }          }
1413    
1414          old_show_trace_tree = 1 - old_show_trace_tree;          if (toggle)
1415          printf("show_trace_tree = %s\n", old_show_trace_tree? "ON" : "OFF");                  old_show_trace_tree = 1 - old_show_trace_tree;
1416    
1417            printf("show_trace_tree = %s", old_show_trace_tree? "ON" : "OFF");
1418            if (old_show_trace_tree != previous_mode)
1419                    printf("  (was: %s)", previous_mode? "ON" : "OFF");
1420            printf("\n");
1421    
1422          if (m->bintrans_enable && old_show_trace_tree)          if (m->bintrans_enable && old_show_trace_tree)
1423                  printf("NOTE: the trace tree functionality doesn't "                  printf("NOTE: the trace tree functionality doesn't "
1424                      "work very well with bintrans!\n");                      "work very well with bintrans!\n");
1425    
1426          /*  TODO: how to preserve quiet_mode?  */          /*  Clear translations:  */
1427          old_quiet_mode = 0;          for (i=0; i<m->ncpus; i++)
1428          printf("quiet_mode = %s\n", old_quiet_mode? "ON" : "OFF");                  if (m->cpus[i]->translation_cache != NULL)
1429                            cpu_create_or_reset_tc(m->cpus[i]);
1430  }  }
1431    
1432    
# Line 1344  static void debugger_cmd_unassemble(stru Line 1507  static void debugger_cmd_unassemble(stru
1507    
1508          addr = addr_start;          addr = addr_start;
1509    
         if ((addr & 3) != 0)  
                 printf("WARNING! You entered an unaligned address.\n");  
   
1510          ctrl_c = 0;          ctrl_c = 0;
1511    
1512          while (addr < addr_end) {          while (addr < addr_end) {
1513                  int i, len;                  unsigned int i, len;
1514                  unsigned char buf[25];  /*  TODO: How long can an                  unsigned char buf[17];  /*  TODO: How long can an
1515                                              instruction be, on weird archs?  */                                              instruction be, on weird archs?  */
1516                  memset(buf, 0, sizeof(buf));                  memset(buf, 0, sizeof(buf));
1517    
# Line 1377  static void debugger_cmd_unassemble(stru Line 1537  static void debugger_cmd_unassemble(stru
1537    
1538          last_unasm_addr = addr;          last_unasm_addr = addr;
1539    
1540          strcpy(repeat_cmd, "unassemble");          strlcpy(repeat_cmd, "unassemble", MAX_CMD_BUFLEN);
1541  }  }
1542    
1543    
# Line 1444  static struct cmd cmds[] = { Line 1604  static struct cmd cmds[] = {
1604          { "machine", "", 0, debugger_cmd_machine,          { "machine", "", 0, debugger_cmd_machine,
1605                  "print a summary of the current machine" },                  "print a summary of the current machine" },
1606    
1607            { "ninstrs", "[on|off]", 0, debugger_cmd_ninstrs,
1608                    "toggle (set or unset) show_nr_of_instructions" },
1609    
1610          { "opcodestats", "", 0, debugger_cmd_opcodestats,          { "opcodestats", "", 0, debugger_cmd_opcodestats,
1611                  "show opcode statistics" },                  "show opcode statistics" },
1612    
# Line 1474  static struct cmd cmds[] = { Line 1637  static struct cmd cmds[] = {
1637          { "tlbdump", "[cpuid][,r]", 0, debugger_cmd_tlbdump,          { "tlbdump", "[cpuid][,r]", 0, debugger_cmd_tlbdump,
1638                  "dump TLB contents (add ',r' for raw data)" },                  "dump TLB contents (add ',r' for raw data)" },
1639    
1640          { "trace", "", 0, debugger_cmd_trace,          { "trace", "[on|off]", 0, debugger_cmd_trace,
1641                  "toggle show_trace_tree on or off" },                  "toggle show_trace_tree on or off" },
1642    
1643          { "unassemble", "[addr [endaddr]]", 0, debugger_cmd_unassemble,          { "unassemble", "[addr [endaddr]]", 0, debugger_cmd_unassemble,
# Line 1483  static struct cmd cmds[] = { Line 1646  static struct cmd cmds[] = {
1646          { "version", "", 0, debugger_cmd_version,          { "version", "", 0, debugger_cmd_version,
1647                  "print version information" },                  "print version information" },
1648    
1649            /*  Note: NULL handler.  */
1650            { "x = expr", "", 0, NULL, "generic assignment" },
1651    
1652          { NULL, NULL, 0, NULL, NULL }          { NULL, NULL, 0, NULL, NULL }
1653  };  };
1654    
# Line 1494  static struct cmd cmds[] = { Line 1660  static struct cmd cmds[] = {
1660   *   *
1661   *  NOTE: This is placed after the cmds[] array, because it needs to   *  NOTE: This is placed after the cmds[] array, because it needs to
1662   *  access it.   *  access it.
1663     *
1664     *  TODO: Command completion (ie just type "help s" for "help step").
1665   */   */
1666  static void debugger_cmd_help(struct machine *m, char *cmd_line)  static void debugger_cmd_help(struct machine *m, char *cmd_line)
1667  {  {
1668          int i, j, max_name_len = 0;          int i, max_name_len = 0, only_one = 0, only_one_match = 0;
1669            char *nlines_env = getenv("LINES");
1670            int nlines = atoi(nlines_env != NULL? nlines_env : "999999");
1671            int j, curlines;
1672    
1673            if (cmd_line[0] != '\0') {
1674                    only_one = 1;
1675            }
1676    
1677          i = 0;          i = 0;
1678          while (cmds[i].name != NULL) {          while (cmds[i].name != NULL) {
# Line 1509  static void debugger_cmd_help(struct mac Line 1684  static void debugger_cmd_help(struct mac
1684                  i++;                  i++;
1685          }          }
1686    
1687          printf("Available commands:\n");          curlines = 0;
1688            if (!only_one) {
1689                    printf("Available commands:\n");
1690                    curlines++;
1691            }
1692    
1693          i = 0;          i = 0;
1694          while (cmds[i].name != NULL) {          while (cmds[i].name != NULL) {
1695                  char buf[100];                  char buf[100];
1696                  snprintf(buf, sizeof(buf), "%s", cmds[i].name);                  snprintf(buf, sizeof(buf), "%s", cmds[i].name);
1697    
1698                    if (only_one) {
1699                            if (strcmp(cmds[i].name, cmd_line) != 0) {
1700                                    i++;
1701                                    continue;
1702                            }
1703                            only_one_match = 1;
1704                    }
1705    
1706                  if (cmds[i].args != NULL)                  if (cmds[i].args != NULL)
1707                          snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),                          snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
1708                              " %s", cmds[i].args);                              " %s", cmds[i].args);
# Line 1528  static void debugger_cmd_help(struct mac Line 1716  static void debugger_cmd_help(struct mac
1716    
1717                  printf("   %s\n", cmds[i].description);                  printf("   %s\n", cmds[i].description);
1718                  i++;                  i++;
1719    
1720                    curlines ++;
1721                    if (curlines >= nlines - 1) {
1722                            char ch;
1723                            printf("-- more --"); fflush(stdout);
1724                            ch = debugger_readchar();
1725                            printf("\n");
1726                            if (ch == 'q' || ch == 'Q')
1727                                    return;
1728                            curlines = 0;
1729                    }
1730            }
1731    
1732            if (only_one) {
1733                    if (!only_one_match)
1734                            printf("%s: no such command\n", cmd_line);
1735                    return;
1736          }          }
1737    
1738          printf("Generic assignments:   x = expr\n");          /*  TODO: generalize/refactor  */
1739          printf("where x must be a register, and expr can be a register, a "          curlines += 8;
1740              "numeric value, or\na symbol name (+ an optional numeric offset)."          if (curlines > nlines - 1) {
1741              " In case there are multiple\nmatches (ie a symbol that has the "                  char ch;
1742              "same name as a register), you may add a\nprefix character as a "                  printf("-- more --"); fflush(stdout);
1743              "hint: '%%' for registers, '@' for symbols, and\n'$' for numeric"                  ch = debugger_readchar();
1744              " values. Use 0x for hexadecimal values.\n");                  printf("\n");
1745                    if (ch == 'q' || ch == 'Q')
1746                            return;
1747                    curlines = 0;
1748            }
1749    
1750            printf("\nIn generic assignments, x must be a register, and expr can be"
1751                " a register, a\nnumeric value, or a symbol name (+ an optional "
1752                "numeric offset). In case there\nare multiple matches (i.e. a "
1753                "symbol that has the same name as a register), you\nmay add a "
1754                "prefix character as a hint: '%%' for registers, '@' for symbols,"
1755                " and\n'$' for numeric values. Use 0x for hexadecimal values.\n");
1756  }  }
1757    
1758    
# Line 1553  void debugger_assignment(struct machine Line 1769  void debugger_assignment(struct machine
1769          char *left, *right;          char *left, *right;
1770          int res_left, res_right;          int res_left, res_right;
1771          uint64_t tmp;          uint64_t tmp;
1772            uint64_t old_pc = m->cpus[0]->pc;       /*  TODO: multiple cpus?  */
1773    
1774          left  = malloc(strlen(cmd) + 1);          left  = malloc(MAX_CMD_BUFLEN);
1775          if (left == NULL) {          if (left == NULL) {
1776                  fprintf(stderr, "out of memory in debugger_assignment()\n");                  fprintf(stderr, "out of memory in debugger_assignment()\n");
1777                  exit(1);                  exit(1);
1778          }          }
1779          strcpy(left, cmd);          strlcpy(left, cmd, MAX_CMD_BUFLEN);
1780          right = strchr(left, '=');          right = strchr(left, '=');
1781          if (right == NULL) {          if (right == NULL) {
1782                  fprintf(stderr, "internal error in the debugger\n");                  fprintf(stderr, "internal error in the debugger\n");
# Line 1603  void debugger_assignment(struct machine Line 1820  void debugger_assignment(struct machine
1820                  }                  }
1821          }          }
1822    
1823            /*
1824             *  If the PC has changed, then release any breakpoint we were
1825             *  currently stopped at.
1826             *
1827             *  TODO: multiple cpus?
1828             */
1829            if (old_pc != m->cpus[0]->pc)
1830                    single_step_breakpoint = 0;
1831    
1832          free(left);          free(left);
1833  }  }
1834    
# Line 1627  static char *debugger_readline(void) Line 1853  static char *debugger_readline(void)
1853          cursor_pos = 0;          cursor_pos = 0;
1854    
1855          while (ch != '\n') {          while (ch != '\n') {
1856                  /*                  ch = debugger_readchar();
                  *  TODO: This uses up 100% CPU, maybe that isn't too good.  
                  *  The usleep() call might make it a tiny bit nicer on other  
                  *  running processes, but it is still very ugly.  
                  */  
                 while ((ch = console_readchar(MAIN_CONSOLE)) < 0) {  
                         x11_check_event(debugger_emuls, debugger_n_emuls);  
                         usleep(2);  
                 }  
1857    
1858                  if ((ch == '\b' || ch == 127) && cursor_pos > 0) {                  if ((ch == '\b' || ch == 127) && cursor_pos > 0) {
1859                          /*  Backspace.  */                          /*  Backspace.  */
# Line 1688  static char *debugger_readline(void) Line 1906  static char *debugger_readline(void)
1906                          }                          }
1907                  } else if (ch == 11) {                  } else if (ch == 11) {
1908                          /*  CTRL-K: Kill to end of line.  */                          /*  CTRL-K: Kill to end of line.  */
1909                          for (i=0; i<MAX_CMD_LEN; i++)                          for (i=0; i<MAX_CMD_BUFLEN; i++)
1910                                  console_makeavail(MAIN_CONSOLE, 4); /*  :-)  */                                  console_makeavail(MAIN_CONSOLE, 4); /*  :-)  */
1911                  } else if (ch == 14 || ch == 16) {                  } else if (ch == 14 || ch == 16) {
1912                          /*  CTRL-P: Previous line in the command history,                          /*  CTRL-P: Previous line in the command history,
# Line 1726  static char *debugger_readline(void) Line 1944  static char *debugger_readline(void)
1944                                                  printf(" ");                                                  printf(" ");
1945                                          for (i=cmd_len-1; i>=0; i--)                                          for (i=cmd_len-1; i>=0; i--)
1946                                                  printf("\b \b");                                                  printf("\b \b");
1947                                          strcpy(cmd,                                          strlcpy(cmd,
1948                                              last_cmd[read_from_index]);                                              last_cmd[read_from_index],
1949                                                MAX_CMD_BUFLEN);
1950                                          cmd_len = strlen(cmd);                                          cmd_len = strlen(cmd);
1951                                          printf("%s", cmd);                                          printf("%s", cmd);
1952                                          cursor_pos = cmd_len;                                          cursor_pos = cmd_len;
1953                                  }                                  }
1954                          } while (0);                          } while (0);
1955                  } else if (ch >= ' ' && cmd_len < MAX_CMD_LEN) {                  } else if (ch >= ' ' && cmd_len < MAX_CMD_BUFLEN-1) {
1956                          /*  Visible character:  */                          /*  Visible character:  */
1957                          memmove(cmd + cursor_pos + 1, cmd + cursor_pos,                          memmove(cmd + cursor_pos + 1, cmd + cursor_pos,
1958                              cmd_len - cursor_pos);                              cmd_len - cursor_pos);
# Line 1882  void debugger(void) Line 2101  void debugger(void)
2101          int i, n, i_match, matchlen, cmd_len;          int i, n, i_match, matchlen, cmd_len;
2102          char *cmd;          char *cmd;
2103    
2104          if (n_steps_left_before_interaction > 0) {          if (debugger_n_steps_left_before_interaction > 0) {
2105                  n_steps_left_before_interaction --;                  debugger_n_steps_left_before_interaction --;
2106                  return;                  return;
2107          }          }
2108    
# Line 1904  void debugger(void) Line 2123  void debugger(void)
2123                  if (cmd_len == 0) {                  if (cmd_len == 0) {
2124                          /*  Special case for repeated commands:  */                          /*  Special case for repeated commands:  */
2125                          if (repeat_cmd[0] != '\0')                          if (repeat_cmd[0] != '\0')
2126                                  strcpy(cmd, repeat_cmd);                                  strlcpy(cmd, repeat_cmd, MAX_CMD_BUFLEN);
2127                          else                          else
2128                                  continue;                                  continue;
2129                  } else {                  } else {
# Line 1955  void debugger(void) Line 2174  void debugger(void)
2174                  /*  Check for a command name match:  */                  /*  Check for a command name match:  */
2175                  n = i = i_match = 0;                  n = i = i_match = 0;
2176                  while (cmds[i].name != NULL) {                  while (cmds[i].name != NULL) {
2177                          if (strncasecmp(cmds[i].name, cmd, matchlen) == 0) {                          if (strncasecmp(cmds[i].name, cmd, matchlen) == 0
2178                                && cmds[i].f != NULL) {
2179                                  cmds[i].tmp_flag = 1;                                  cmds[i].tmp_flag = 1;
2180                                  i_match = i;                                  i_match = i;
2181                                  n++;                                  n++;
# Line 2001  void debugger(void) Line 2221  void debugger(void)
2221                          return;                          return;
2222          }          }
2223    
2224            gettimeofday(&debugger_machine->starttime, NULL);
2225            debugger_machine->ncycles_since_gettimeofday = 0;
2226    
2227          single_step = 0;          single_step = 0;
2228          debugger_machine->instruction_trace = old_instruction_trace;          debugger_machine->instruction_trace = old_instruction_trace;
2229          debugger_machine->show_trace_tree = old_show_trace_tree;          debugger_machine->show_trace_tree = old_show_trace_tree;
# Line 2018  void debugger(void) Line 2241  void debugger(void)
2241   */   */
2242  void debugger_reset(void)  void debugger_reset(void)
2243  {  {
2244          n_steps_left_before_interaction = 0;          debugger_n_steps_left_before_interaction = 0;
2245  }  }
2246    
2247    
# Line 2049  void debugger_init(struct emul **emuls, Line 2272  void debugger_init(struct emul **emuls,
2272          debugger_machine = emuls[0]->machines[0];          debugger_machine = emuls[0]->machines[0];
2273    
2274          for (i=0; i<N_PREVIOUS_CMDS; i++) {          for (i=0; i<N_PREVIOUS_CMDS; i++) {
2275                  last_cmd[i] = malloc(MAX_CMD_LEN + 1);                  last_cmd[i] = malloc(MAX_CMD_BUFLEN);
2276                  if (last_cmd[i] == NULL) {                  if (last_cmd[i] == NULL) {
2277                          fprintf(stderr, "debugger_init(): out of memory\n");                          fprintf(stderr, "debugger_init(): out of memory\n");
2278                          exit(1);                          exit(1);

Legend:
Removed from v.2  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26