/[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 21 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  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:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $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 $
29   *   *
30   *  Single-step debugger.   *  Single-step debugger.
31   *   *
# Line 36  Line 36 
36   *   *
37   *      Add more functionality that already exists elsewhere in the emulator.   *      Add more functionality that already exists elsewhere in the emulator.
38   *   *
39     *      Call stack display?
40     *
41   *      More generic expression evaluator (for example + - * / between multiple   *      More generic expression evaluator (for example + - * / between multiple
42   *      terms), including _TAB COMPLETION_ of symbols and register names!   *      terms), including _TAB COMPLETION_ of symbols and register names!
43   *   *
# Line 474  static void debugger_cmd_continue(struct Line 476  static void debugger_cmd_continue(struct
476   */   */
477  static void debugger_cmd_device(struct machine *m, char *cmd_line)  static void debugger_cmd_device(struct machine *m, char *cmd_line)
478  {  {
479          int i, j;          int i;
480          struct memory *mem;          struct memory *mem;
481          struct cpu *c;          struct cpu *c;
482    
# Line 507  static void debugger_cmd_device(struct m Line 509  static void debugger_cmd_device(struct m
509                  device_dumplist();                  device_dumplist();
510          } else if (strncmp(cmd_line, "add ", 4) == 0) {          } else if (strncmp(cmd_line, "add ", 4) == 0) {
511                  device_add(m, cmd_line+4);                  device_add(m, cmd_line+4);
512            } else if (strcmp(cmd_line, "consoles") == 0) {
513                    console_debug_dump(m);
514          } else if (strncmp(cmd_line, "remove ", 7) == 0) {          } else if (strncmp(cmd_line, "remove ", 7) == 0) {
515                  i = atoi(cmd_line + 7);                  i = atoi(cmd_line + 7);
516                  if (i==0 && cmd_line[7]!='0') {                  if (i==0 && cmd_line[7]!='0') {
517                          printf("Weird device number. Use 'device list'.\n");                          printf("Weird device number. Use 'device list'.\n");
518                  } else                  } else
519                          memory_device_remove(m->memory, i);                          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");  
                 }  
520          } else if (strcmp(cmd_line, "list") == 0) {          } else if (strcmp(cmd_line, "list") == 0) {
521                  if (mem->n_mmapped_devices == 0)                  if (mem->n_mmapped_devices == 0)
522                          printf("No memory-mapped devices in this machine.\n");                          printf("No memory-mapped devices in this machine.\n");
# Line 575  return_help: Line 547  return_help:
547          printf("  add name_and_params    add a device to the current "          printf("  add name_and_params    add a device to the current "
548              "machine\n");              "machine\n");
549          printf("  all                    list all registered devices\n");          printf("  all                    list all registered devices\n");
550            printf("  consoles               list all slave consoles\n");
551          printf("  list                   list memory-mapped devices in the"          printf("  list                   list memory-mapped devices in the"
552              " current machine\n");              " current machine\n");
553          printf("  remove x               remove device nr x from the "          printf("  remove x               remove device nr x from the "
554              "current machine\n");              "current machine\n");
         printf("  state x                show state of device nr x in"  
             " the current machine\n");  
555  }  }
556    
557    
# Line 715  static void debugger_cmd_dump(struct mac Line 686  static void debugger_cmd_dump(struct mac
686   */   */
687  static void debugger_cmd_emuls(struct machine *m, char *cmd_line)  static void debugger_cmd_emuls(struct machine *m, char *cmd_line)
688  {  {
689          int i, iadd = 4;          int i, iadd = DEBUG_INDENTATION;
690    
691          if (*cmd_line) {          if (*cmd_line) {
692                  printf("syntax: emuls\n");                  printf("syntax: emuls\n");
# Line 874  static void debugger_cmd_lookup(struct m Line 845  static void debugger_cmd_lookup(struct m
845   */   */
846  static void debugger_cmd_machine(struct machine *m, char *cmd_line)  static void debugger_cmd_machine(struct machine *m, char *cmd_line)
847  {  {
848          int iadd = 4;          int iadd = DEBUG_INDENTATION;
849    
850          if (*cmd_line) {          if (*cmd_line) {
851                  printf("syntax: machine\n");                  printf("syntax: machine\n");
# Line 1083  static void debugger_cmd_put(struct mach Line 1054  static void debugger_cmd_put(struct mach
1054          }          }
1055    
1056          /*  here: q is the address, p is the data.  */          /*  here: q is the address, p is the data.  */
   
1057          res = debugger_parse_name(m, q, 0, &addr);          res = debugger_parse_name(m, q, 0, &addr);
1058          switch (res) {          switch (res) {
1059          case NAME_PARSE_NOMATCH:          case NAME_PARSE_NOMATCH:
# Line 1139  static void debugger_cmd_put(struct mach Line 1109  static void debugger_cmd_put(struct mach
1109                  printf("\n");                  printf("\n");
1110                  return;                  return;
1111          case 'h':          case 'h':
1112                  if ((data & 1) != 0)                  if ((addr & 1) != 0)
1113                          printf("WARNING: address isn't aligned\n");                          printf("WARNING: address isn't aligned\n");
1114                  if (m->cpus[0]->is_32bit)                  if (m->cpus[0]->is_32bit)
1115                          printf("0x%08x", (int)addr);                          printf("0x%08x", (int)addr);
# Line 1154  static void debugger_cmd_put(struct mach Line 1124  static void debugger_cmd_put(struct mach
1124                  printf("\n");                  printf("\n");
1125                  return;                  return;
1126          case 'w':          case 'w':
1127                  if ((data & 3) != 0)                  if ((addr & 3) != 0)
1128                          printf("WARNING: address isn't aligned\n");                          printf("WARNING: address isn't aligned\n");
1129                  if (m->cpus[0]->is_32bit)                  if (m->cpus[0]->is_32bit)
1130                          printf("0x%08x", (int)addr);                          printf("0x%08x", (int)addr);
# Line 1170  static void debugger_cmd_put(struct mach Line 1140  static void debugger_cmd_put(struct mach
1140                  printf("\n");                  printf("\n");
1141                  return;                  return;
1142          case 'd':          case 'd':
1143                  if ((data & 7) != 0)                  if ((addr & 7) != 0)
1144                          printf("WARNING: address isn't aligned\n");                          printf("WARNING: address isn't aligned\n");
1145                  if (m->cpus[0]->is_32bit)                  if (m->cpus[0]->is_32bit)
1146                          printf("0x%08x", (int)addr);                          printf("0x%08x", (int)addr);
# Line 1660  static struct cmd cmds[] = { Line 1630  static struct cmd cmds[] = {
1630   */   */
1631  static void debugger_cmd_help(struct machine *m, char *cmd_line)  static void debugger_cmd_help(struct machine *m, char *cmd_line)
1632  {  {
1633          int i, max_name_len = 0, only_one = 0, only_one_match = 0;          int only_one = 0, only_one_match = 0;
1634          char *nlines_env = getenv("LINES");          char *nlines_env = getenv("LINES");
1635          int nlines = atoi(nlines_env != NULL? nlines_env : "999999");          int nlines = atoi(nlines_env != NULL? nlines_env : "999999"), curlines;
1636          int j, curlines;          size_t i, j, max_name_len = 0;
1637    
1638          if (cmd_line[0] != '\0') {          if (cmd_line[0] != '\0') {
1639                  only_one = 1;                  only_one = 1;
# Line 1671  static void debugger_cmd_help(struct mac Line 1641  static void debugger_cmd_help(struct mac
1641    
1642          i = 0;          i = 0;
1643          while (cmds[i].name != NULL) {          while (cmds[i].name != NULL) {
1644                  int a = strlen(cmds[i].name);                  size_t a = strlen(cmds[i].name);
1645                  if (cmds[i].args != NULL)                  if (cmds[i].args != NULL)
1646                          a += 1 + strlen(cmds[i].args);                          a += 1 + strlen(cmds[i].args);
1647                  if (a > max_name_len)                  if (a > max_name_len)
# Line 1829  void debugger_assignment(struct machine Line 1799  void debugger_assignment(struct machine
1799    
1800    
1801  /*  /*
1802     *  debugger_execute_cmd():
1803     */
1804    void debugger_execute_cmd(char *cmd, int cmd_len)
1805    {
1806            int i, n, i_match, matchlen;
1807    
1808            /*
1809             *  Is there a '=' on the command line? Then try to do an
1810             *  assignment.  (Only if there is just one word, followed
1811             *  by the '=' sign. This makes it possible to use commands
1812             *  such as "device add name addr=xyz".)
1813             */
1814            if (strchr(cmd, '=') != NULL) {
1815                    /*  Count the nr of words:  */
1816                    int nw = 0, inword = 0;
1817                    char *p = cmd;
1818                    while (*p) {
1819                            if (*p == '=')
1820                                    break;
1821                            if (*p != ' ') {
1822                                    if (!inword)
1823                                            nw ++;
1824                                    inword = 1;
1825                            } else
1826                                    inword = 0;
1827                            p++;
1828                    }
1829    
1830                    if (nw == 1) {
1831                            debugger_assignment(debugger_machine, cmd);
1832                            return;
1833                    }
1834            }
1835    
1836            i = 0;
1837            while (cmds[i].name != NULL)
1838                    cmds[i++].tmp_flag = 0;
1839    
1840            /*  How many chars in cmd to match against:  */
1841            matchlen = 0;
1842            while (isalpha((int)cmd[matchlen]))
1843                    matchlen ++;
1844    
1845            /*  Check for a command name match:  */
1846            n = i = i_match = 0;
1847            while (cmds[i].name != NULL) {
1848                    if (strncasecmp(cmds[i].name, cmd, matchlen) == 0
1849                        && cmds[i].f != NULL) {
1850                            cmds[i].tmp_flag = 1;
1851                            i_match = i;
1852                            n++;
1853                    }
1854                    i++;
1855            }
1856    
1857            /*  No match?  */
1858            if (n == 0) {
1859                    printf("Unknown command '%s'. Type 'help' for help.\n", cmd);
1860                    return;
1861            }
1862    
1863            /*  More than one match?  */
1864            if (n > 1) {
1865                    printf("Ambiguous command '%s':  ", cmd);
1866                    i = 0;
1867                    while (cmds[i].name != NULL) {
1868                            if (cmds[i].tmp_flag)
1869                                    printf("  %s", cmds[i].name);
1870                            i++;
1871                    }
1872                    printf("\n");
1873                    return;
1874            }
1875    
1876            /*  Exactly one match:  */
1877            if (cmds[i_match].f != NULL) {
1878                    char *p = cmd + matchlen;
1879                    /*  Remove leading whitespace from the args...  */
1880                    while (*p != '\0' && *p == ' ')
1881                            p++;
1882    
1883                    /*  ... and run the command:  */
1884                    cmds[i_match].f(debugger_machine, p);
1885            } else
1886                    printf("FATAL ERROR: internal error in debugger.c:"
1887                        " no handler for this command?\n");
1888    }
1889    
1890    
1891    /*
1892   *  debugger_readline():   *  debugger_readline():
1893   *   *
1894   *  Read a line from the terminal.   *  Read a line from the terminal.
# Line 2003  static char *debugger_readline(void) Line 2063  static char *debugger_readline(void)
2063                                  j = 0;          /*  j = # of cmds printed  */                                  j = 0;          /*  j = # of cmds printed  */
2064                                  while (cmds[i].name != NULL) {                                  while (cmds[i].name != NULL) {
2065                                          if (cmds[i].tmp_flag) {                                          if (cmds[i].tmp_flag) {
2066                                                  int q;                                                  size_t q;
2067                                                  if (j == 0)                                                  if (j == 0)
2068                                                          printf("  ");                                                          printf("  ");
2069                                                  printf("%s",                                                  printf("%s",
# Line 2093  static char *debugger_readline(void) Line 2153  static char *debugger_readline(void)
2153   */   */
2154  void debugger(void)  void debugger(void)
2155  {  {
2156          int i, n, i_match, matchlen, cmd_len;          int i, cmd_len;
2157          char *cmd;          char *cmd;
2158    
2159          if (debugger_n_steps_left_before_interaction > 0) {          if (debugger_n_steps_left_before_interaction > 0) {
# Line 2105  void debugger(void) Line 2165  void debugger(void)
2165           *  Clear all dyntrans translations, because otherwise things would           *  Clear all dyntrans translations, because otherwise things would
2166           *  become to complex to keep in sync.           *  become to complex to keep in sync.
2167           */           */
2168            /*  TODO: In all machines  */
2169          for (i=0; i<debugger_machine->ncpus; i++)          for (i=0; i<debugger_machine->ncpus; i++)
2170                  if (debugger_machine->cpus[i]->translation_cache != NULL)                  if (debugger_machine->cpus[i]->translation_cache != NULL)
2171                          cpu_create_or_reset_tc(debugger_machine->cpus[i]);                          cpu_create_or_reset_tc(debugger_machine->cpus[i]);
# Line 2137  void debugger(void) Line 2198  void debugger(void)
2198                          repeat_cmd[0] = '\0';                          repeat_cmd[0] = '\0';
2199                  }                  }
2200    
2201                  /*                  debugger_execute_cmd(cmd, cmd_len);
                  *  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");  
2202    
2203                  /*  Special hack for the "step" command:  */                  /*  Special hack for the "step" command:  */
2204                  if (exit_debugger == -1)                  if (exit_debugger == -1)

Legend:
Removed from v.21  
changed lines
  Added in v.22

  ViewVC Help
Powered by ViewVC 1.1.26