"I am a person who works hard and plays hard."

Yuan Wei
Second Year Graduate Student Department of Computer Science
University of Virginia Charlottesville, VA 22903
Email: yw3f@cs.virginia.edu


Source Code Analysis

Main Page   Compound List   File List   Compound Members   File Members  

dlite.c

Go to the documentation of this file.
00001 /*
00002  * dlite.c - DLite, the lite debugger, routines
00003  *
00004  * This file is a part of the SimpleScalar tool suite written by
00005  * Todd M. Austin as a part of the Multiscalar Research Project.
00006  *  
00007  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00008  * 
00009  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00010  *
00011  * This source file is distributed "as is" in the hope that it will be
00012  * useful.  The tool set comes with no warranty, and no author or
00013  * distributor accepts any responsibility for the consequences of its
00014  * use. 
00015  * 
00016  * Everyone is granted permission to copy, modify and redistribute
00017  * this tool set under the following conditions:
00018  * 
00019  *    This source code is distributed for non-commercial use only. 
00020  *    Please contact the maintainer for restrictions applying to 
00021  *    commercial use.
00022  *
00023  *    Permission is granted to anyone to make or distribute copies
00024  *    of this source code, either as received or modified, in any
00025  *    medium, provided that all copyright notices, permission and
00026  *    nonwarranty notices are preserved, and that the distributor
00027  *    grants the recipient permission for further redistribution as
00028  *    permitted by this document.
00029  *
00030  *    Permission is granted to distribute this file in compiled
00031  *    or executable form under the same conditions that apply for
00032  *    source code, provided that either:
00033  *
00034  *    A. it is accompanied by the corresponding machine-readable
00035  *       source code,
00036  *    B. it is accompanied by a written offer, with no time limit,
00037  *       to give anyone a machine-readable copy of the corresponding
00038  *       source code in return for reimbursement of the cost of
00039  *       distribution.  This written offer must permit verbatim
00040  *       duplication by anyone, or
00041  *    C. it is distributed by someone who received only the
00042  *       executable form, and is accompanied by a copy of the
00043  *       written offer of source code that they received concurrently.
00044  *
00045  * In other words, you are welcome to use, share and improve this
00046  * source file.  You are forbidden to forbid anyone else to use, share
00047  * and improve what you give them.
00048  *
00049  * INTERNET: dburger@cs.wisc.edu
00050  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00051  *
00052  * $Id: dlite.c,v 1.1.1.1 2000/05/26 15:21:52 taustin Exp $
00053  *
00054  * $Log: dlite.c,v $
00055  * Revision 1.1.1.1  2000/05/26 15:21:52  taustin
00056  * SimpleScalar Tool Set
00057  *
00058  *
00059  * Revision 1.4  1999/12/31 18:31:12  taustin
00060  * cross-endian execution support added
00061  *
00062  * Revision 1.3  1999/12/13 18:42:09  taustin
00063  * cross endian execution support added
00064  *
00065  * Revision 1.2  1998/08/27 08:12:26  taustin
00066  * implemented host interface description in host.h
00067  * added target interface support
00068  * added support for qwordword's
00069  * fixed "help" command for invalid commands
00070  * added control registers display command "cregs"
00071  * added support for register and memory contexts
00072  *
00073  * Revision 1.1  1997/03/11  01:30:41  taustin
00074  * Initial revision
00075  *
00076  *
00077  */
00078 
00079 #include <stdio.h>
00080 #include <stdlib.h>
00081 #include <string.h>
00082 #include <ctype.h>
00083 #if defined(__CYGWIN32__)
00084 #include <errno.h>
00085 #endif
00086 
00087 #include "host.h"
00088 #include "misc.h"
00089 #include "machine.h"
00090 #include "version.h"
00091 #include "eval.h"
00092 #include "regs.h"
00093 #include "memory.h"
00094 #include "sim.h"
00095 #include "symbol.h"
00096 #include "loader.h"
00097 #include "options.h"
00098 #include "stats.h"
00099 #include "range.h"
00100 #include "dlite.h"
00101 
00102 /* architected state accessors, initialized by dlite_init() */
00103 static dlite_reg_obj_t f_dlite_reg_obj = NULL;
00104 static dlite_mem_obj_t f_dlite_mem_obj = NULL;
00105 static dlite_mstate_obj_t f_dlite_mstate_obj = NULL;
00106 
00107 /* set non-zero to enter DLite after next instruction */
00108 int dlite_active = FALSE;
00109 
00110 /* non-zero to force a check for a break */
00111 int dlite_check = FALSE;
00112 
00113 /* set non-zero to exit DLite command loop */
00114 static int dlite_return = FALSE;
00115 
00116 /* size modifier mask bit definitions */
00117 #define MOD_BYTE        0x0001          /* b - print a byte */
00118 #define MOD_HALF        0x0002          /* h - print a half (short) */
00119 #define MOD_WORD        0x0004          /* w - print a word */
00120 #define MOD_QWORD       0x0008          /* q - print a qword */
00121 #define MOD_FLOAT       0x0010          /* F - print a float */
00122 #define MOD_DOUBLE      0x0020          /* f - print a double */
00123 #define MOD_CHAR        0x0040          /* c - print a character */
00124 #define MOD_STRING      0x0080          /* s - print a string */
00125 
00126 #define MOD_SIZES                                                       \
00127   (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_QWORD                                 \
00128    |MOD_FLOAT|MOD_DOUBLE|MOD_CHAR|MOD_STRING)
00129 
00130 /* format modifier mask bit definitions */
00131 #define MOD_DECIMAL     0x0100          /* d - print in decimal format */
00132 #define MOD_UNSIGNED    0x0200          /* u - print in unsigned format */
00133 #define MOD_OCTAL       0x0400          /* o - print in octal format */
00134 #define MOD_HEX         0x0800          /* x - print in hex format */
00135 #define MOD_BINARY      0x1000          /* 1 - print in binary format */
00136 
00137 #define MOD_FORMATS                                                     \
00138   (MOD_DECIMAL|MOD_UNSIGNED|MOD_OCTAL|MOD_HEX|MOD_BINARY)
00139 
00140 
00141 /* DLite modifier parser, transforms /<mods> strings to modifier mask */
00142 static char *                           /* error string, NULL for no err */
00143 modifier_parser(char *p,                /* ptr to /<mods> string */
00144                 char **endp,            /* ptr to first byte not consumed */
00145                 int *pmod)              /* modifier mask written to *PMOD */
00146 {
00147   int modifiers = 0;
00148 
00149   /* default modifiers */
00150   *pmod = 0;
00151 
00152   /* is this a valid modifier? */
00153   if (*p == '/')
00154     {
00155       p++;
00156       /* parse modifiers until end-of-string or whitespace is found */
00157       while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t')
00158         {
00159           switch (*p)
00160             {
00161             case 'b':
00162               modifiers |= MOD_BYTE;
00163               break;
00164             case 'h':
00165               modifiers |= MOD_HALF;
00166               break;
00167             case 'w':
00168               modifiers |= MOD_WORD;
00169               break;
00170             case 'q':
00171               modifiers |= MOD_QWORD;
00172               break;
00173             case 'd':
00174               modifiers |= MOD_DECIMAL;
00175               break;
00176             case 'u':
00177               modifiers |= MOD_UNSIGNED;
00178               break;
00179             case 'o':
00180               modifiers |= MOD_OCTAL;
00181               break;
00182             case 'x':
00183               modifiers |= MOD_HEX;
00184               break;
00185             case '1':
00186               modifiers |= MOD_BINARY;
00187               break;
00188             case 'F':
00189               modifiers |= MOD_FLOAT;
00190               break;
00191             case 'f':
00192               modifiers |= MOD_DOUBLE;
00193               break;
00194             case 'c':
00195               modifiers |= MOD_CHAR;
00196               break;
00197             case 's':
00198               modifiers |= MOD_STRING;
00199               break;
00200             default:
00201               return "bad modifier (use one or more of /bhwqduox1fdcs)";
00202             }
00203           p++;
00204         }
00205     }
00206 
00207   /* no error, return end of string and modifier mask */
00208   *endp = p;
00209   *pmod = modifiers;
00210   return NULL;
00211 }
00212 
00213 /* DLite default expression evaluator */
00214 static struct eval_state_t *dlite_evaluator = NULL;
00215 static struct regs_t *local_regs = NULL;
00216 
00217 /* DLite identifier evaluator, used by the expression evaluator, returns
00218    the value of the ident in ES->TOK_BUF, sets eval_error to value other
00219    than ERR_NOERR if an error is encountered */
00220 static struct eval_value_t                      /* value of identifier */
00221 ident_evaluator(struct eval_state_t *es)        /* expression evaluator */
00222 {
00223   int i;
00224   char *err_str;
00225   struct eval_value_t val;
00226   struct stat_stat_t *stat;
00227   struct sym_sym_t *sym;
00228   static struct eval_value_t err_value = { et_int, { 0 } };
00229 
00230   /* is this a builtin register definition? */
00231   for (i=0; md_reg_names[i].str != NULL; i++)
00232     {
00233       if (!mystricmp(es->tok_buf, md_reg_names[i].str))
00234         {
00235           err_str =
00236             f_dlite_reg_obj(local_regs, /* !is_write */FALSE,
00237                             md_reg_names[i].file, md_reg_names[i].reg, &val);
00238           if (err_str)
00239             {
00240               eval_error = ERR_UNDEFVAR;
00241               val = err_value;
00242             }
00243           return val;
00244         }
00245     }
00246 
00247   /* else, try to locate a program symbol */
00248   sym_loadsyms(ld_prog_fname, /* load locals */TRUE);
00249   sym = sym_bind_name(es->tok_buf, NULL, sdb_any);
00250   if (sym)
00251     {
00252       /* found a symbol with this name, return it's (address) value */
00253       val.type = et_addr;
00254       val.value.as_addr = sym->addr;
00255       return val;
00256     }
00257 
00258   /* else, try to locate a statistical value symbol */
00259   stat = stat_find_stat(sim_sdb, es->tok_buf);
00260   if (stat)
00261     {
00262       /* found it, convert stat value to an eval_value_t value */
00263       switch (stat->sc)
00264         {
00265         case sc_int:
00266           val.type = et_int;
00267           val.value.as_int = *stat->variant.for_int.var;
00268           break;
00269         case sc_uint:
00270           val.type = et_uint;
00271           val.value.as_uint = *stat->variant.for_uint.var;
00272           break;
00273 #ifdef HOST_HAS_QWORD
00274         case sc_qword:
00275           val.type = et_qword;
00276           val.value.as_qword = *stat->variant.for_qword.var;
00277           break;
00278 #endif /* HOST_HAS_QWORD */
00279         case sc_float:
00280           val.type = et_float;
00281           val.value.as_float = *stat->variant.for_float.var;
00282           break;
00283         case sc_double:
00284           val.type = et_double;
00285           val.value.as_double = *stat->variant.for_double.var;
00286           break;
00287         case sc_dist:
00288         case sc_sdist:
00289           eval_error = ERR_BADEXPR;
00290           val = err_value;
00291           break;
00292         case sc_formula:
00293           {
00294             /* instantiate a new evaluator to avoid recursion problems */
00295             struct eval_state_t *es = eval_new(ident_evaluator, sim_sdb);
00296             char *endp;
00297 
00298             val = eval_expr(es, stat->variant.for_formula.formula, &endp);
00299             if (eval_error != ERR_NOERR || *endp != '\0')
00300               {
00301                 /* pass through eval_error */
00302                 val = err_value;
00303               }
00304             /* else, use value returned */
00305             eval_delete(es);
00306           }
00307           break;
00308         default:
00309           panic("bogus stat class");
00310         }
00311       return val;
00312     }
00313   /* else, not found */
00314 
00315   /* else, this is a bogus symbol */
00316   eval_error = ERR_UNDEFVAR;
00317   val = err_value;
00318   return val;
00319 }
00320 
00321 /* maximum number of arguments that can passed to a dlite command handler */
00322 #define MAX_ARGS        4
00323 
00324 /* maximum length of a dlite command string argument */
00325 #define MAX_STR         128
00326 
00327 /* argument array entry, argument arrays are passed to command handlers */
00328 union arg_val_t {
00329   int as_modifier;
00330   struct eval_value_t as_value;
00331   int as_access;
00332   char as_str[MAX_STR];
00333 };
00334 
00335 /* a DLite command handler function pointer */
00336 typedef char *                                  /* err str, NULL for no err */
00337 (*cmd_fn_t)(int nargs,                          /* number of arguments */
00338             union arg_val_t args[],             /* argument vector */
00339             struct regs_t *regs,                /* registers to access */
00340             struct mem_t *mem);                 /* memory to access */
00341 
00342 /* DLite command descriptor, fully describes a command supported by the
00343    DLite debugger command handler */
00344 struct dlite_cmd_t {
00345   char *cmd_str;                /* DLite command string */
00346   char *arg_strs[MAX_ARGS];     /* NULL-terminated cmd args (? - optional):
00347                                      m - size/type modifiers
00348                                      a - address expression
00349                                      c - count expression
00350                                      e - any expression
00351                                      s - any string
00352                                      t - access type {r|w|x}
00353                                      i - breakpoint id */
00354   cmd_fn_t cmd_fn;              /* implementing function */
00355   char *help_str;               /* DLite command help string */
00356 };
00357 
00358 /* forward handler decls */
00359 static char *
00360 dlite_help(int nargs, union arg_val_t args[],
00361            struct regs_t *regs, struct mem_t *mem);
00362 static char *
00363 dlite_version(int nargs, union arg_val_t args[],
00364               struct regs_t *regs, struct mem_t *mem);
00365 static char *
00366 dlite_terminate(int nargs, union arg_val_t args[],
00367                 struct regs_t *regs, struct mem_t *mem);
00368 static char *
00369 dlite_quit(int nargs, union arg_val_t args[],
00370            struct regs_t *regs, struct mem_t *mem);
00371 static char *
00372 dlite_cont(int nargs, union arg_val_t args[],
00373            struct regs_t *regs, struct mem_t *mem);
00374 static char *
00375 dlite_step(int nargs, union arg_val_t args[],
00376            struct regs_t *regs, struct mem_t *mem);
00377 static char *
00378 dlite_print(int nargs, union arg_val_t args[],
00379             struct regs_t *regs, struct mem_t *mem);
00380 static char *
00381 dlite_options(int nargs, union arg_val_t args[],
00382               struct regs_t *regs, struct mem_t *mem);
00383 static char *
00384 dlite_option(int nargs, union arg_val_t args[],
00385              struct regs_t *regs, struct mem_t *mem);
00386 static char *
00387 dlite_stats(int nargs, union arg_val_t args[],
00388             struct regs_t *regs, struct mem_t *mem);
00389 static char *
00390 dlite_stat(int nargs, union arg_val_t args[],
00391            struct regs_t *regs, struct mem_t *mem);
00392 static char *
00393 dlite_whatis(int nargs, union arg_val_t args[],
00394              struct regs_t *regs, struct mem_t *mem);
00395 static char *
00396 dlite_regs(int nargs, union arg_val_t args[],
00397            struct regs_t *regs, struct mem_t *mem);
00398 static char *
00399 dlite_iregs(int nargs, union arg_val_t args[],
00400             struct regs_t *regs, struct mem_t *mem);
00401 static char *
00402 dlite_fpregs(int nargs, union arg_val_t args[],
00403              struct regs_t *regs, struct mem_t *mem);
00404 static char *
00405 dlite_cregs(int nargs, union arg_val_t args[],
00406             struct regs_t *regs, struct mem_t *mem);
00407 static char *
00408 dlite_mstate(int nargs, union arg_val_t args[],
00409              struct regs_t *regs, struct mem_t *mem);
00410 static char *
00411 dlite_display(int nargs, union arg_val_t args[],
00412               struct regs_t *regs, struct mem_t *mem);
00413 static char *
00414 dlite_dump(int nargs, union arg_val_t args[],
00415            struct regs_t *regs, struct mem_t *mem);
00416 static char *
00417 dlite_dis(int nargs, union arg_val_t args[],
00418           struct regs_t *regs, struct mem_t *mem);
00419 static char *
00420 dlite_break(int nargs, union arg_val_t args[],
00421             struct regs_t *regs, struct mem_t *mem);
00422 static char *
00423 dlite_dbreak(int nargs, union arg_val_t args[],
00424              struct regs_t *regs, struct mem_t *mem);
00425 static char *
00426 dlite_rbreak(int nargs, union arg_val_t args[],
00427              struct regs_t *regs, struct mem_t *mem);
00428 static char *
00429 dlite_breaks(int nargs, union arg_val_t args[],
00430              struct regs_t *regs, struct mem_t *mem);
00431 static char *
00432 dlite_delete(int nargs, union arg_val_t args[],
00433              struct regs_t *regs, struct mem_t *mem);
00434 static char *
00435 dlite_clear(int nargs, union arg_val_t args[],
00436             struct regs_t *regs, struct mem_t *mem);
00437 static char *
00438 dlite_symbols(int nargs, union arg_val_t args[],
00439               struct regs_t *regs, struct mem_t *mem);
00440 static char *
00441 dlite_tsymbols(int nargs, union arg_val_t args[],
00442                struct regs_t *regs, struct mem_t *mem);
00443 static char *
00444 dlite_dsymbols(int nargs, union arg_val_t args[],
00445                struct regs_t *regs, struct mem_t *mem);
00446 static char *
00447 dlite_symbol(int nargs, union arg_val_t args[],
00448              struct regs_t *regs, struct mem_t *mem);
00449 
00450 /* DLite debugger command parser command definitions, NOTE: optional
00451    arguments must be trailing arguments, otherwise the command parser will
00452    break (modifiers are an exception to this rule) */
00453 static struct dlite_cmd_t cmd_db[] =
00454 {
00455   { "help", { "s?", NULL }, dlite_help,
00456     "print command reference" },
00457   { "version", { NULL }, dlite_version,
00458     "print DLite version information" },
00459   { "terminate", { NULL }, dlite_terminate,
00460     "terminate the simulation with statistics" },
00461   { "quit", { NULL }, dlite_quit,
00462     "exit the simulator" },
00463   { "cont", { "a?", NULL }, dlite_cont,
00464     "continue program execution (optionally at <addr>)" },
00465   { "step", { NULL }, dlite_step,
00466     "step program one instruction" },
00467 #if 0 /* NYI */
00468   { "next", { NULL }, dlite_next,
00469     "step program one instruction in current procedure" },
00470 #endif
00471   { "print", { "m?", "e", NULL }, dlite_print,
00472     "print the value of <expr> using format <modifiers>" },
00473   { "options", { NULL }, dlite_options,
00474     "print the value of all options" },
00475   { "option", { "s", NULL }, dlite_option,
00476     "print the value of an option" },
00477   { "stats", { NULL }, dlite_stats,
00478     "print the value of all statistical variables" },
00479   { "stat", { "s", NULL }, dlite_stat,
00480     "print the value of a statistical variable" },
00481   { "whatis", { "e", NULL }, dlite_whatis,
00482     "print the type of expression <expr>" },
00483   { "---", { NULL }, NULL, NULL },
00484   { "regs", { NULL }, dlite_regs,
00485     "print all register contents" },
00486   { "iregs", { NULL }, dlite_iregs,
00487     "print integer register contents" },
00488   { "fpregs", { NULL }, dlite_fpregs,
00489     "print floating point register contents" },
00490   { "cregs", { NULL }, dlite_cregs,
00491     "print control register contents" },
00492   { "mstate", { "s?", NULL }, dlite_mstate,
00493     "print machine specific state (simulator dependent)" },
00494   { "display", { "m?", "a", NULL }, dlite_display,
00495     "display the value at memory location <addr> using format <modifiers>" },
00496   { "dump", { "a?", "c?", NULL }, dlite_dump,
00497     "dump memory at <addr> (optionally for <cnt> words)" },
00498   { "dis", { "a?", "c?", NULL }, dlite_dis,
00499     "disassemble instructions at <addr> (for <cnt> insts)" },
00500   { "break", { "a", NULL }, dlite_break,
00501     "set breakpoint at <addr>, returns <id> of breakpoint" },
00502   { "dbreak", { "a", "t?", NULL }, dlite_dbreak,
00503     "set data breakpoint at <addr> (for (r)ead, (w)rite,\n"
00504     "    and/or e(x)ecute, returns <id> of breakpoint" },
00505   { "rbreak", { "s", "t?", NULL }, dlite_rbreak,
00506     "set read/write/exec breakpoint at <range> (for (r)ead, (w)rite,\n"
00507     "    and/or e(x)ecute, returns <id> of breakpoint" },
00508   { "breaks", { NULL }, dlite_breaks,
00509     "list active code and data breakpoints" },
00510   { "delete", { "i", NULL }, dlite_delete,
00511     "delete breakpoint <id>" },
00512   { "clear", { NULL }, dlite_clear,
00513     "clear all breakpoints (code and data)" },
00514   { "---", { NULL }, NULL, NULL },
00515   { "symbols", { NULL }, dlite_symbols,
00516     "print the value of all program symbols" },
00517   { "tsymbols", { NULL }, dlite_tsymbols,
00518     "print the value of all program text symbols" },
00519   { "dsymbols", { NULL }, dlite_dsymbols,
00520     "print the value of all program data symbols" },
00521   { "symbol", { "s", NULL }, dlite_symbol,
00522     "print the value of a symbol" },
00523   { "---", { NULL }, NULL, NULL },
00524   /* list terminator */
00525   { NULL, { NULL }, NULL, NULL }
00526 };
00527 
00528 /* help command trailing text */
00529 static char *dlite_help_tail =
00530   "Arguments <addr>, <cnt>, <expr>, and <id> are any legal expression:\n"
00531   "  <expr>    <-  <factor> +|- <expr>\n"
00532   "  <factor>  <-  <term> *|/ <factor>\n"
00533   "  <term>    <-  ( <expr> )\n"
00534   "                | - <term>\n"
00535   "                | <const>\n"
00536   "                | <symbol>\n"
00537   "                | <file:loc>\n"
00538   "\n"
00539   "Command modifiers <mods> are any of the following:\n"
00540   "\n"
00541   "  b - print a byte\n"
00542   "  h - print a half (short)\n"
00543   "  w - print a word (default)\n"
00544 #ifdef HOST_HAS_QWORD
00545   "  q - print a qword\n"
00546 #endif /* HOST_HAS_QWORD */
00547   "  F - print a float\n"
00548   "  f - print a double\n"
00549   "  c - print a character\n"
00550   "  s - print a string\n"
00551   "  d - print in decimal format (default)\n"
00552   "  u - print in unsigned decimal format\n"
00553   "  o - print in octal format\n"
00554   "  x - print in hex format\n"
00555   "  1 - print in binary format\n";
00556 
00557 
00558 /* execute DLite command string CMD */
00559 static char *                                   /* err str, NULL if no err */
00560 dlite_exec(char *cmd_str,                       /* command string */
00561            struct regs_t *regs,                 /* registers to access */
00562            struct mem_t *mem)                   /* memory to access */
00563 {
00564   int i, arg_cnt;
00565   struct dlite_cmd_t *cmd;
00566   char cmd_buf[512], *p, *q, *endp;
00567   union arg_val_t args[MAX_ARGS];
00568 
00569   p = cmd_str;
00570   q = cmd_buf;
00571 
00572   /* skip any whitespace before argument */
00573   while (*p == ' ' || *p == '\t' || *p == '\n')
00574     p++;
00575 
00576   /* anything left? */
00577   if (*p == '\0')
00578     {
00579       /* NOP, no error */
00580       return NULL;
00581     }
00582 
00583   /* copy out command name string */
00584   while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t' && *p != '/')
00585     *q++ = *p++;
00586   *q = '\0';
00587 
00588   /* find matching command */
00589   for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++)
00590     {
00591       if (!strcmp(cmd->cmd_str, cmd_buf))
00592         break;
00593     }
00594   if (cmd->cmd_str == NULL)
00595     return "unknown command";
00596 
00597   /* match arguments for *CMD */
00598   for (i=0, arg_cnt=0; i<MAX_ARGS && cmd->arg_strs[i] != NULL; i++, arg_cnt++)
00599     {
00600       int optional, access, modifiers;
00601       char *arg, arg_type, *err_str;
00602       struct eval_value_t val;
00603 
00604       /* skip any whitespace before argument */
00605       while (*p == ' ' || *p == '\t' || *p == '\n')
00606         p++;
00607 
00608       arg = cmd->arg_strs[i];
00609       arg_type = arg[0];
00610       optional = (arg[1] == '?');
00611 
00612       if (*p == '\0')
00613         {
00614           if (optional)
00615             {
00616               /* all arguments parsed */
00617               break;
00618             }
00619           else
00620             return "missing an argument";
00621         }
00622 
00623       endp = p;
00624       switch (arg_type)
00625         {
00626         case 'm':
00627           err_str = modifier_parser(p, &endp, &modifiers);
00628           if (err_str)
00629             return err_str;
00630           args[arg_cnt].as_modifier = modifiers;
00631           break;
00632         case 'a':
00633           local_regs = regs;
00634           val = eval_expr(dlite_evaluator, p, &endp);
00635           if (eval_error)
00636             return eval_err_str[eval_error];
00637           args[arg_cnt].as_value = val;
00638           break;
00639         case 'c':
00640           local_regs = regs;
00641           val = eval_expr(dlite_evaluator, p, &endp);
00642           if (eval_error)
00643             return eval_err_str[eval_error];
00644           args[arg_cnt].as_value = val;
00645           break;
00646         case 'e':
00647           local_regs = regs;
00648           val = eval_expr(dlite_evaluator, p, &endp);
00649           if (eval_error)
00650             return eval_err_str[eval_error];
00651           args[arg_cnt].as_value = val;
00652           break;
00653         case 't':
00654           access = 0;
00655           while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t')
00656             {
00657               switch (*p)
00658                 {
00659                 case 'r':
00660                   access |= ACCESS_READ;
00661                   break;
00662                 case 'w':
00663                   access |= ACCESS_WRITE;
00664                   break;
00665                 case 'x':
00666                   access |= ACCESS_EXEC;
00667                   break;
00668                 default:
00669                   return "bad access type specifier (use r|w|x)";
00670                 }
00671               p++;
00672             }
00673           endp = p;
00674           args[arg_cnt].as_access = access;
00675           break;
00676         case 'i':
00677           local_regs = regs;
00678           val = eval_expr(dlite_evaluator, p, &endp);
00679           if (eval_error)
00680             return eval_err_str[eval_error];
00681           args[arg_cnt].as_value = val;
00682           break;
00683         case 's':
00684           q = args[arg_cnt].as_str;
00685           while (*p != ' ' && *p != '\t' && *p != '\0')
00686             *q++ = *p++;
00687           *q = '\0';
00688           endp = p;
00689           break;
00690         default:
00691           panic("bogus argument type: `%c'", arg_type);
00692         }
00693       p = endp;
00694     }
00695 
00696 
00697   /* skip any whitespace before any trailing argument */
00698   while (*p == ' ' || *p == '\t' || *p == '\n')
00699     p++;
00700 
00701   /* check for any orphan arguments */
00702   if (*p != '\0')
00703     return "too many arguments";
00704 
00705   /* if we reach here, all arguments were parsed correctly, call handler */
00706   return cmd->cmd_fn(arg_cnt, args, regs, mem);
00707 }
00708 
00709 /* print expression value VAL using modifiers MODIFIERS */
00710 static char *                                   /* err str, NULL for no err */
00711 print_val(int modifiers,                        /* print modifiers */
00712           struct eval_value_t val)              /* expr value to print */
00713 {
00714   char *format = "", *prefix = "", radix, buf[512];
00715 
00716   /* fill in any default size */
00717   if ((modifiers & MOD_SIZES) == 0)
00718     {
00719       /* compute default size */
00720       switch (val.type)
00721         {
00722         case et_int:    modifiers |= MOD_WORD; break;
00723         case et_uint:   modifiers |= MOD_WORD; break;
00724         case et_addr:
00725 #ifdef HOST_HAS_QWORD
00726           if (sizeof(md_addr_t) > 4)
00727             modifiers |= MOD_QWORD;
00728           else
00729 #endif /* HOST_HAS_QWORD */
00730             modifiers |= MOD_WORD;
00731           break;
00732 #ifdef HOST_HAS_QWORD
00733         case et_qword:  modifiers |= MOD_QWORD; break;
00734         case et_sqword: modifiers |= MOD_QWORD; break;
00735 #endif /* HOST_HAS_QWORD */
00736         case et_float:  modifiers |= MOD_FLOAT; break;
00737         case et_double: modifiers |= MOD_DOUBLE; break;
00738         case et_symbol:
00739         default:        return "bad print value";
00740         }
00741     }
00742   if (((modifiers & MOD_SIZES) & ((modifiers & MOD_SIZES) - 1)) != 0)
00743     return "multiple size specifiers";
00744 
00745   /* fill in any default format */
00746   if ((modifiers & MOD_FORMATS) == 0)
00747     {
00748       /* compute default size */
00749       switch (val.type)
00750         {
00751         case et_int:    modifiers |= MOD_DECIMAL; break;
00752         case et_uint:   modifiers |= MOD_UNSIGNED; break;
00753         case et_addr:   modifiers |= MOD_HEX; break;
00754 #ifdef HOST_HAS_QWORD
00755         case et_qword:  modifiers |= MOD_UNSIGNED; break;
00756         case et_sqword: modifiers |= MOD_DECIMAL; break;
00757 #endif /* HOST_HAS_QWORD */
00758         case et_float:  /* use default format */break;
00759         case et_double: /* use default format */break;
00760         case et_symbol:
00761         default:        return "bad print value";
00762         }
00763     }
00764   if (((modifiers & MOD_FORMATS) & ((modifiers & MOD_FORMATS) - 1)) != 0)
00765     return "multiple format specifiers";
00766 
00767   /* decode modifiers */
00768   if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_QWORD))
00769     {
00770       if (modifiers & MOD_DECIMAL)
00771         radix = 'd';
00772       else if (modifiers & MOD_UNSIGNED)
00773         radix = 'u';
00774       else if (modifiers & MOD_OCTAL)
00775         radix = 'o';
00776       else if (modifiers & MOD_HEX)
00777         radix = 'x';
00778       else if (modifiers & MOD_BINARY)
00779         return "binary format not yet implemented";
00780       else
00781         panic("no default integer format");
00782 
00783       if (modifiers & MOD_BYTE)
00784         {
00785           if (modifiers & MOD_OCTAL)
00786             {
00787               prefix = "0";
00788               format = "03";
00789             }
00790           else if (modifiers & MOD_HEX)
00791             {
00792               prefix = "0x";
00793               format = "02";
00794             }
00795           else
00796             {
00797               prefix = "";
00798               format = "";
00799             }
00800 
00801           sprintf(buf, "%s%%%s%c", prefix, format, radix);
00802           myfprintf(stdout, buf, eval_as_uint(val));
00803         }
00804       else if (modifiers & MOD_HALF)
00805         {
00806           if (modifiers & MOD_OCTAL)
00807             {
00808               prefix = "0";
00809               format = "06";
00810             }
00811           else if (modifiers & MOD_HEX)
00812             {
00813               prefix = "0x";
00814               format = "04";
00815             }
00816           else
00817             {
00818               prefix = "";
00819               format = "";
00820             }
00821 
00822           sprintf(buf, "%s%%%s%c", prefix, format, radix);
00823           myfprintf(stdout, buf, eval_as_uint(val));
00824         }
00825       else if (modifiers & MOD_WORD)
00826         {
00827           if (modifiers & MOD_OCTAL)
00828             {
00829               prefix = "0";
00830               format = "011";
00831             }
00832           else if (modifiers & MOD_HEX)
00833             {
00834               prefix = "0x";
00835               format = "08";
00836             }
00837           else
00838             {
00839               prefix = "";
00840               format = "";
00841             }
00842 
00843           sprintf(buf, "%s%%%s%c", prefix, format, radix);
00844           myfprintf(stdout, buf, eval_as_uint(val));
00845         }
00846 #ifdef HOST_HAS_QWORD
00847       else if (modifiers & MOD_QWORD)
00848         {
00849           if (modifiers & MOD_OCTAL)
00850             {
00851               prefix = "0";
00852               format = "022";
00853             }
00854           else if (modifiers & MOD_HEX)
00855             {
00856               prefix = "0x";
00857               format = "016";
00858             }
00859           else
00860             {
00861               prefix = "";
00862               format = "";
00863             }
00864 
00865           sprintf(buf, "%s%%%sl%c", prefix, format, radix);
00866           myfprintf(stdout, buf, eval_as_qword(val));
00867         }
00868 #endif /* HOST_HAS_QWORD */
00869     }
00870   else if (modifiers & MOD_FLOAT)
00871     fprintf(stdout, "%f", (double)eval_as_float(val));
00872   else if (modifiers & MOD_DOUBLE)
00873     fprintf(stdout, "%f", eval_as_double(val));
00874   else if (modifiers & MOD_CHAR)
00875     fprintf(stdout, "`%c'", eval_as_uint(val));
00876   else if (modifiers & MOD_STRING)
00877     return "string format not yet implemented";
00878   else /* no format specified, default to value type format */
00879     panic("no default format");
00880 
00881   /* no error */
00882   return NULL;
00883 }
00884 
00885 /* default memory state accessor */
00886 char *                                          /* err str, NULL for no err */
00887 dlite_mem_obj(struct mem_t *mem,                /* memory space to access */
00888               int is_write,                     /* access type */
00889               md_addr_t addr,                   /* address to access */
00890               char *p,                          /* input/output buffer */
00891               int nbytes)                       /* size of access */
00892 {
00893   enum mem_cmd cmd;
00894 
00895   if (!is_write)
00896     cmd = Read;
00897   else
00898     cmd = Write;
00899 
00900 #if 0
00901   char *errstr;
00902   errstr = mem_valid(cmd, addr, nbytes, /* !declare */FALSE);
00903   if (errstr)
00904     return errstr;
00905 #endif
00906 
00907   /* else, no error, access memory */
00908   mem_access(mem, cmd, addr, p, nbytes);
00909 
00910   /* no error */
00911   return NULL;
00912 }
00913 
00914 /* default machine state accessor */
00915 char *                                          /* err str, NULL for no err */
00916 dlite_mstate_obj(FILE *stream,                  /* output stream */
00917                  char *cmd,                     /* optional command string */
00918                  struct regs_t *regs,           /* registers to access */
00919                  struct mem_t *mem)             /* memory to access */
00920 {
00921   /* nada */
00922   fprintf(stream, "No machine state.\n");
00923 
00924   /* no error */
00925   return NULL;
00926 }
00927 
00928 /* scroll terminator, wait for user to press return */
00929 static void
00930 dlite_pause(void)
00931 {
00932   char buf[512];
00933   fprintf(stdout, "Press <return> to continue...");
00934   fflush(stdout);
00935   fgets(buf, 512, stdin);
00936 }
00937 
00938 /* print help information for DLite command CMD */
00939 static void
00940 print_help(struct dlite_cmd_t *cmd)             /* command to describe */
00941 {
00942   int i;
00943 
00944   /* print command name */
00945   fprintf(stdout, "  %s ", cmd->cmd_str);
00946 
00947   /* print arguments of command */
00948   for (i=0; i < MAX_ARGS && cmd->arg_strs[i] != NULL; i++)
00949     {
00950       int optional;
00951       char *arg, arg_type;
00952 
00953       arg = cmd->arg_strs[i];
00954       arg_type = arg[0];
00955       optional = (arg[1] == '?');
00956 
00957       if (optional)
00958         fprintf(stdout, "{");
00959       else
00960         fprintf(stdout, "<");
00961 
00962       switch (arg_type)
00963         {
00964         case 'm':
00965           fprintf(stdout, "/modifiers");
00966           break;
00967         case 'a':
00968           fprintf(stdout, "addr");
00969           break;
00970         case 'c':
00971           fprintf(stdout, "count");
00972           break;
00973         case 'e':
00974           fprintf(stdout, "expr");
00975           break;
00976         case 't':
00977           fprintf(stdout, "r|w|x");
00978           break;
00979         case 'i':
00980           fprintf(stdout, "id");
00981           break;
00982         case 's':
00983           fprintf(stdout, "string");
00984           break;
00985         default:
00986           panic("bogus argument type: `%c'", arg_type);
00987         }
00988 
00989       if (optional)
00990         fprintf(stdout, "}");
00991       else
00992         fprintf(stdout, ">");
00993 
00994       fprintf(stdout, " ");
00995     }
00996   fprintf(stdout, "\n");
00997 
00998   /* print command description */
00999   fprintf(stdout, "    %s\n", cmd->help_str);
01000 }
01001 
01002 /* print help messages for all (or single) DLite debugger commands */
01003 static char *                                   /* err str, NULL for no err */
01004 dlite_help(int nargs, union arg_val_t args[],   /* command arguments */
01005            struct regs_t *regs,                 /* registers to access */
01006            struct mem_t *mem)                   /* memory to access */
01007 {
01008   struct dlite_cmd_t *cmd;
01009 
01010   if (nargs != 0 && nargs != 1)
01011     return "too many arguments";
01012 
01013   if (nargs == 1)
01014     {
01015       /* print help for specified commands */
01016       for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++)
01017         {
01018           if (!strcmp(cmd->cmd_str, args[0].as_str))
01019             break;
01020         }
01021       if (!cmd->cmd_str)
01022         return "command unknown";
01023 
01024       print_help(cmd);
01025     }
01026   else
01027     {
01028       /* print help for all commands */
01029       for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++)
01030         {
01031           /* `---' specifies a good point for a scroll pause */
01032           if (!strcmp(cmd->cmd_str, "---"))
01033             dlite_pause();
01034           else
01035             print_help(cmd);
01036         }
01037 
01038       fprintf (stdout, "\n");
01039       if (dlite_help_tail)
01040         fprintf (stdout, "%s\n", dlite_help_tail);
01041     }
01042 
01043   /* no error */
01044   return NULL;
01045 }
01046 
01047 /* print version information for simulator */
01048 static char *                                   /* err str, NULL for no err */
01049 dlite_version(int nargs, union arg_val_t args[],/* command arguments */
01050               struct regs_t *regs,              /* registers to access */
01051               struct mem_t *mem)                /* memory to access */
01052 {
01053   if (nargs != 0)
01054     return "too many arguments";
01055 
01056   /* print simulator version info */
01057   fprintf(stdout, "The SimpleScalar/%s Tool Set, version %d.%d of %s.\n",
01058           VER_TARGET, VER_MAJOR, VER_MINOR, VER_UPDATE);
01059   fprintf(stdout,
01060     "Copyright (c) 1994-1998 by Todd M. Austin.  All Rights Reserved.\n");
01061 
01062   /* no error */
01063   return NULL;
01064 }
01065 
01066 /* terminate simulation with statistics */
01067 static char *                                   /* err str, NULL for no err */
01068 dlite_terminate(int nargs, union arg_val_t args[],/* command arguments */
01069                 struct regs_t *regs,            /* registers to access */
01070                 struct mem_t *mem)              /* memory to access */
01071 {
01072   if (nargs != 0)
01073     return "too many arguments";
01074 
01075   fprintf(stdout, "DLite: terminating simulation...\n");
01076   longjmp(sim_exit_buf, /* exitcode */1);
01077 
01078   /* no error */
01079   return NULL;
01080 }
01081 
01082 /* quit the simulator, omit any stats dump */
01083 static char *                                   /* err str, NULL for no err */
01084 dlite_quit(int nargs, union arg_val_t args[],   /* command arguments */
01085            struct regs_t *regs,                 /* registers to access */
01086            struct mem_t *mem)                   /* memory to access */
01087 {
01088   if (nargs != 0)
01089     return "too many arguments";
01090 
01091   fprintf(stdout, "DLite: exiting simulator...\n");
01092   exit(1);
01093 
01094   /* no error */
01095   return NULL;
01096 }
01097 
01098 /* continue executing program (possibly at specified address) */
01099 static char *                                   /* err str, NULL for no err */
01100 dlite_cont(int nargs, union arg_val_t args[],   /* command arguments */
01101            struct regs_t *regs,                 /* registers to access */
01102            struct mem_t *mem)                   /* memory to access */
01103 {
01104   struct eval_value_t val;
01105 
01106   if (!f_dlite_reg_obj || !f_dlite_mem_obj)
01107     panic("DLite is not configured");
01108 
01109   if (nargs != 0 && nargs != 1)
01110     return "too many arguments";
01111 
01112   if (nargs == 1)
01113     {
01114       /* continue from specified address, check address */
01115       if (!EVAL_INTEGRAL(args[0].as_value.type))
01116         return "address argument must be an integral type";
01117 
01118       /* reset PC */
01119       val.type = et_addr;
01120       val.value.as_addr = eval_as_addr(args[0].as_value);
01121       f_dlite_reg_obj(regs, /* is_write */TRUE, rt_PC, 0, &val);
01122 
01123       myfprintf(stdout, "DLite: continuing execution @ 0x%08p...\n",
01124                 val.value.as_addr);
01125     }
01126 
01127   /* signal end of main debugger loop, and continuation of prog execution */
01128   dlite_active = FALSE;
01129   dlite_return = TRUE;
01130 
01131   /* no error */
01132   return NULL;
01133 }
01134 
01135 /* step program one instruction */
01136 static char *                                   /* err str, NULL for no err */
01137 dlite_step(int nargs, union arg_val_t args[],   /* command arguments */
01138            struct regs_t *regs,                 /* registers to access */
01139            struct mem_t *mem)                   /* memory to access */
01140 {
01141   if (nargs != 0)
01142     return "too many arguments";
01143 
01144   /* signal on instruction step */
01145   dlite_active = TRUE;
01146   dlite_return = TRUE;
01147 
01148   /* no error */
01149   return NULL;
01150 }
01151 
01152 #if 0 /* NYI */
01153 /* step program one instruction in current procedure */
01154 static char *                                   /* err str, NULL for no err */
01155 dlite_next(int nargs, union arg_val_t args[])   /* command arguments */
01156 {
01157   if (nargs != 0)
01158     return "too many arguments";
01159 
01160   /* signal on instruction step */
01161   dlite_step_cnt = 1;
01162   dlite_step_into = FALSE;
01163 
01164   /* no error */
01165   return NULL;
01166 }
01167 #endif
01168 
01169 /* print the value of <expr> using format <modifiers> */
01170 static char *                                   /* err str, NULL for no err */
01171 dlite_print(int nargs, union arg_val_t args[],  /* command arguments */
01172             struct regs_t *regs,                /* registers to access */
01173             struct mem_t *mem)                  /* memory to access */
01174 {
01175   int modifiers = 0;
01176   char *err_str;
01177   struct eval_value_t val;
01178 
01179   if (nargs != 1 && nargs != 2)
01180     return "wrong number of arguments";
01181 
01182   if (nargs == 2)
01183     {
01184       /* arguments include modifiers and expression value */
01185       modifiers = args[0].as_modifier;
01186       val = args[1].as_value;
01187     }
01188   else
01189     {
01190       /* arguments include only expression value */
01191       val = args[0].as_value;
01192     }
01193 
01194   /* print expression value */
01195   err_str = print_val(modifiers, val);
01196   if (err_str)
01197     return err_str;
01198   fprintf(stdout, "\n");
01199 
01200   /* no error */
01201   return NULL;
01202 }
01203 
01204 /* print the value of all command line options */
01205 static char *                                   /* err str, NULL for no err */
01206 dlite_options(int nargs, union arg_val_t args[],/* command arguments */
01207               struct regs_t *regs,              /* registers to access */
01208               struct mem_t *mem)                /* memory to access */
01209 {
01210   if (nargs != 0)
01211     return "wrong number of arguments";
01212 
01213   /* print all options */
01214   opt_print_options(sim_odb, stdout, /* terse */TRUE, /* !notes */FALSE);
01215 
01216   /* no error */
01217   return NULL;
01218 }
01219 
01220 /* print the value of all (or single) command line options */
01221 static char *                                   /* err str, NULL for no err */
01222 dlite_option(int nargs, union arg_val_t args[], /* command arguments */
01223              struct regs_t *regs,               /* registers to access */
01224              struct mem_t *mem)                 /* memory to access */
01225 {
01226   struct opt_opt_t *opt;
01227 
01228   if (nargs != 1)
01229     return "wrong number of arguments";
01230 
01231   /* print a single option, specified by argument */
01232   opt = opt_find_option(sim_odb, args[0].as_str);
01233   if (!opt)
01234     return "option is not defined";
01235 
01236   /* else, print this option's value */
01237   fprintf(stdout, "%-16s  ", opt->name);
01238   opt_print_option(opt, stdout);
01239   if (opt->desc)
01240     fprintf(stdout, " # %s", opt->desc);
01241   fprintf(stdout, "\n");
01242 
01243   /* no error */
01244   return NULL;
01245 }
01246 
01247 /* print the value of all statistical variables */
01248 static char *                                   /* err str, NULL for no err */
01249 dlite_stats(int nargs, union arg_val_t args[],  /* command arguments */
01250             struct regs_t *regs,                /* registers to access */
01251             struct mem_t *mem)                  /* memory to access */
01252 {
01253   if (nargs != 0)
01254     return "wrong number of arguments";
01255 
01256   /* print all options */
01257   stat_print_stats(sim_sdb, stdout);
01258   sim_aux_stats(stdout);
01259 
01260   /* no error */
01261   return NULL;
01262 }
01263 
01264 /* print the value of a statistical variable */
01265 static char *                                   /* err str, NULL for no err */
01266 dlite_stat(int nargs, union arg_val_t args[],   /* command arguments */
01267            struct regs_t *regs,                 /* registers to access */
01268            struct mem_t *mem)                   /* memory to access */
01269 {
01270   struct stat_stat_t *stat;
01271 
01272   if (nargs != 1)
01273     return "wrong number of arguments";
01274 
01275   /* print a single option, specified by argument */
01276   stat = stat_find_stat(sim_sdb, args[0].as_str);
01277   if (!stat)
01278     return "statistical variable is not defined";
01279 
01280   /* else, print this option's value */
01281   stat_print_stat(sim_sdb, stat, stdout);
01282 
01283   /* no error */
01284   return NULL;
01285 }
01286 
01287 /* print the type of expression <expr> */
01288 static char *                                   /* err str, NULL for no err */
01289 dlite_whatis(int nargs, union arg_val_t args[], /* command arguments */
01290              struct regs_t *regs,               /* registers to access */
01291              struct mem_t *mem)                 /* memory to access */
01292 {
01293   if (nargs != 1)
01294     return "wrong number of arguments";
01295 
01296   fprintf(stdout, "type == `%s'\n", eval_type_str[args[0].as_value.type]);
01297 
01298   /* no error */
01299   return NULL;
01300 }
01301 
01302 /* print integer register contents */
01303 static char *                                   /* err str, NULL for no err */
01304 dlite_iregs(int nargs, union arg_val_t args[],  /* command arguments */
01305             struct regs_t *regs,                /* registers to access */
01306             struct mem_t *mem)                  /* memory to access */
01307 {
01308   char *err_str;
01309 
01310   if (nargs != 0)
01311     return "too many arguments";
01312 
01313   /* print integer registers */
01314   myfprintf(stdout, "PC: 0x%08p   NPC: 0x%08p\n",
01315             regs->regs_PC, regs->regs_NPC);
01316   if ((err_str = dlite_cregs(nargs, args, regs, mem)) != NULL)
01317     return err_str;
01318   md_print_iregs(regs->regs_R, stdout);
01319 
01320   /* no error */
01321   return NULL;
01322 }
01323 
01324 /* print floating point register contents */
01325 static char *                                   /* err str, NULL for no err */
01326 dlite_fpregs(int nargs, union arg_val_t args[], /* command arguments */
01327              struct regs_t *regs,               /* registers to access */
01328              struct mem_t *mem)                 /* memory to access */
01329 {
01330   /* print floating point registers */
01331   md_print_fpregs(regs->regs_F, stdout);
01332 
01333   /* no error */
01334   return NULL;
01335 }
01336 
01337 /* print floating point register contents */
01338 static char *                                   /* err str, NULL for no err */
01339 dlite_cregs(int nargs, union arg_val_t args[],  /* command arguments */
01340             struct regs_t *regs,                /* registers to access */
01341             struct mem_t *mem)                  /* memory to access */
01342 {
01343   /* print floating point registers */
01344   md_print_cregs(regs->regs_C, stdout);
01345 
01346   /* no error */
01347   return NULL;
01348 }
01349 
01350 /* print all register contents */
01351 static char *                                   /* err str, NULL for no err */
01352 dlite_regs(int nargs, union arg_val_t args[],   /* command arguments */
01353            struct regs_t *regs,                 /* registers to access */
01354            struct mem_t *mem)                   /* memory to access */
01355 {
01356   char *err_str;
01357 
01358   myfprintf(stdout, "PC: 0x%08p   NPC: 0x%08p\n",
01359             regs->regs_PC, regs->regs_NPC);
01360   if ((err_str = dlite_cregs(nargs, args, regs, mem)) != NULL)
01361     return err_str;
01362   md_print_iregs(regs->regs_R, stdout);
01363   dlite_pause();
01364   if ((err_str = dlite_fpregs(nargs, args, regs, mem)) != NULL)
01365     return err_str;
01366 
01367   /* no error */
01368   return NULL;
01369 }
01370 
01371 /* print machine specific state (simulator dependent) */
01372 static char *                                   /* err str, NULL for no err */
01373 dlite_mstate(int nargs, union arg_val_t args[], /* command arguments */
01374              struct regs_t *regs,               /* registers to access */
01375              struct mem_t *mem)                 /* memory to access */
01376 {
01377   char *errstr;
01378 
01379   if (nargs != 0 && nargs != 1)
01380     return "too many arguments";
01381 
01382   if (f_dlite_mstate_obj)
01383     {
01384       if (nargs == 0)
01385         {
01386           errstr = f_dlite_mstate_obj(stdout, NULL, regs, mem);
01387           if (errstr)
01388             return errstr;
01389         }
01390       else
01391         {
01392           errstr = f_dlite_mstate_obj(stdout, args[0].as_str, regs, mem);
01393           if (errstr)
01394             return errstr;
01395         }
01396     }
01397 
01398   /* no error */
01399   return NULL;
01400 }
01401 
01402 /* display the value at memory location <addr> using format <modifiers> */
01403 static char *                                   /* err str, NULL for no err */
01404 dlite_display(int nargs, union arg_val_t args[],/* command arguments */
01405               struct regs_t *regs,              /* registers to access */
01406               struct mem_t *mem)                /* memory to access */
01407 {
01408   int modifiers, size;
01409   md_addr_t addr;
01410   unsigned char buf[512];
01411   struct eval_value_t val;
01412   char *errstr;
01413 
01414   if (nargs != 1 && nargs != 2)
01415     return "wrong number of arguments";
01416 
01417   if (nargs == 1)
01418     {
01419       /* no modifiers */
01420       modifiers = 0;
01421 
01422       /* check address */
01423       if (!EVAL_INTEGRAL(args[0].as_value.type))
01424         return "address argument must be an integral type";
01425 
01426       /* reset address */
01427       addr = eval_as_addr(args[0].as_value);
01428     }
01429   else if (nargs == 2)
01430     {
01431       modifiers = args[0].as_modifier;
01432 
01433       /* check address */
01434       if (!EVAL_INTEGRAL(args[1].as_value.type))
01435         return "address argument must be an integral type";
01436 
01437       /* reset address */
01438       addr = eval_as_addr(args[1].as_value);
01439     }
01440 
01441   /* determine operand size */
01442   if (modifiers & (MOD_BYTE|MOD_CHAR))
01443     size = 1;
01444   else if (modifiers & MOD_HALF)
01445     size = 2;
01446   else if (modifiers & (MOD_QWORD|MOD_DOUBLE))
01447     size = 8;
01448   else /* no modifiers, or MOD_WORD|MOD_FLOAT */
01449     size = 4;
01450 
01451   /* read memory */
01452   errstr = f_dlite_mem_obj(mem, /* !is_write */FALSE, addr, (char *)buf, size);
01453   if (errstr)
01454     return errstr;
01455 
01456   /* marshall a value */
01457   if (modifiers & (MOD_BYTE|MOD_CHAR))
01458     {
01459       /* size == 1 */
01460       val.type = et_int;
01461       val.value.as_int = (int)*(unsigned char *)buf;
01462     }
01463   else if (modifiers & MOD_HALF)
01464     {
01465       /* size == 2 */
01466       val.type = et_int;
01467       val.value.as_int = (int)*(unsigned short *)buf;
01468     }
01469   else if (modifiers & (MOD_QWORD|MOD_DOUBLE))
01470     {
01471       /* size == 8 */
01472       val.type = et_double;
01473       val.value.as_double = *(double *)buf;
01474     }
01475   else /* no modifiers, or MOD_WORD|MOD_FLOAT */
01476     {
01477       /* size == 4 */
01478       val.type = et_uint;
01479       val.value.as_uint = *(unsigned int *)buf;
01480     }
01481 
01482   /* print the value */
01483   errstr = print_val(modifiers, val);
01484   if (errstr)
01485     return errstr;
01486   fprintf(stdout, "\n");
01487 
01488   /* no error */
01489   return NULL;
01490 }
01491 
01492 /* `dump' command print format */
01493 #define BYTES_PER_LINE                  16 /* must be a power of two */
01494 #define LINES_PER_SCREEN                4
01495 
01496 /* dump the contents of memory to screen */
01497 static char *                                   /* err str, NULL for no err */
01498 dlite_dump(int nargs, union arg_val_t args[],   /* command arguments */
01499            struct regs_t *regs,                 /* registers to access */
01500            struct mem_t *mem)                   /* memory to access */
01501 {
01502   int i, j;
01503   int count = LINES_PER_SCREEN * BYTES_PER_LINE, i_count, fmt_count, fmt_lines;
01504   md_addr_t fmt_addr, i_addr;
01505   static md_addr_t addr = 0;
01506   unsigned char byte;
01507   char buf[512];
01508   char *errstr;
01509 
01510   if (nargs < 0 || nargs > 2)
01511     return "too many arguments";
01512 
01513   if (nargs == 1)
01514     {
01515       /* check address */
01516       if (!EVAL_INTEGRAL(args[0].as_value.type))
01517         return "address argument must be an integral type";
01518 
01519       /* reset PC */
01520       addr = eval_as_addr(args[0].as_value);
01521     }
01522   else if (nargs == 2)
01523     {
01524       /* check address */
01525       if (!EVAL_INTEGRAL(args[0].as_value.type))
01526         return "address argument must be an integral type";
01527 
01528       /* reset addr */
01529       addr = eval_as_addr(args[0].as_value);
01530 
01531       /* check count */
01532       if (!EVAL_INTEGRAL(args[1].as_value.type))
01533         return "count argument must be an integral type";
01534 
01535       if (eval_as_uint(args[1].as_value) > 1024)
01536         return "bad count argument";
01537 
01538       /* reset count */
01539       count = eval_as_uint(args[1].as_value);
01540     }
01541   /* else, nargs == 0, use addr, count */
01542 
01543   /* normalize start address and count */
01544   fmt_addr = addr & ~(BYTES_PER_LINE - 1);
01545   fmt_count = (count + (BYTES_PER_LINE - 1)) & ~(BYTES_PER_LINE - 1);
01546   fmt_lines = fmt_count / BYTES_PER_LINE;
01547 
01548   if (fmt_lines < 1)
01549     panic("no output lines");
01550 
01551   /* print dump */
01552   if (fmt_lines == 1)
01553     {
01554       /* unformatted dump */
01555       i_addr = fmt_addr;
01556       myfprintf(stdout, "0x%08p: ", i_addr);
01557       for (i=0; i < count; i++)
01558         {
01559           errstr =
01560             f_dlite_mem_obj(mem, /* !is_write */FALSE,
01561                             i_addr, (char *)&byte, 1);
01562           if (errstr)
01563             return errstr;
01564           fprintf(stdout, "%02x ", byte);
01565           if (isprint(byte))
01566             buf[i] = byte;
01567           else
01568             buf[i] = '.';
01569           i_addr++;
01570           addr++;
01571         }
01572       buf[i] = '\0';
01573 
01574       /* character view */
01575       fprintf(stdout, "[%s]\n", buf);
01576     }
01577   else /* lines > 1 */
01578     {
01579       i_count = 0;
01580       i_addr = fmt_addr;
01581       for (i=0; i < fmt_lines; i++)
01582         {
01583           myfprintf(stdout, "0x%08p: ", i_addr);
01584 
01585           /* byte view */
01586           for (j=0; j < BYTES_PER_LINE; j++)
01587             {
01588               if (i_addr >= addr && i_count <= count)
01589                 {
01590                   errstr =
01591                     f_dlite_mem_obj(mem, /* !is_write */FALSE,
01592                                     i_addr, (char *)&byte, 1);
01593                   if (errstr)
01594                     return errstr;
01595                   fprintf(stdout, "%02x ", byte);
01596                   if (isprint(byte))
01597                     buf[j] = byte;
01598                   else
01599                     buf[j] = '.';
01600                   i_count++;
01601                   addr++;
01602                 }
01603               else
01604                 {
01605                   fprintf(stdout, "   ");
01606                   buf[j] = ' ';
01607                 }
01608               i_addr++;
01609             }
01610           buf[j] = '\0';
01611 
01612           /* character view */
01613           fprintf(stdout, "[%s]\n", buf);
01614         }
01615     }
01616 
01617   /* no error */
01618   return NULL;
01619 }
01620 
01621 /* disassembler print format */
01622 #define INSTS_PER_SCREEN                16
01623 
01624 /* disassemble instructions at specified address */
01625 static char *                                   /* err str, NULL for no err */
01626 dlite_dis(int nargs, union arg_val_t args[],    /* command arguments */
01627           struct regs_t *regs,                  /* registers to access */
01628           struct mem_t *mem)                    /* memory to access */
01629 {
01630   int i;
01631   int count = INSTS_PER_SCREEN;
01632   static md_addr_t addr = 0;
01633   md_inst_t inst;
01634   char *errstr;
01635 
01636   if (nargs < 0 || nargs > 2)
01637     return "too many arguments";
01638 
01639   if (nargs == 1)
01640     {
01641       /* check address */
01642       if (!EVAL_INTEGRAL(args[0].as_value.type))
01643         return "address argument must be an integral type";
01644 
01645       /* reset PC */
01646       addr = eval_as_addr(args[0].as_value);
01647     }
01648   else if (nargs == 2)
01649     {
01650       /* check address */
01651       if (!EVAL_INTEGRAL(args[0].as_value.type))
01652         return "address argument must be an integral type";
01653 
01654       /* reset addr */
01655       addr = eval_as_addr(args[0].as_value);
01656 
01657       /* check count */
01658       if (!EVAL_INTEGRAL(args[0].as_value.type))
01659         return "count argument must be an integral type";
01660 
01661       /* reset count */
01662       count = eval_as_uint(args[1].as_value);
01663 
01664       if (count < 0 || count > 1024)
01665         return "bad count argument";
01666     }
01667   /* else, nargs == 0, use addr, count */
01668 
01669   if ((addr % sizeof(md_inst_t)) != 0)
01670     return "instruction addresses are a multiple of eight";
01671 
01672   /* disassemble COUNT insts at ADDR */
01673   for (i=0; i<count; i++)
01674     {
01675       /* read and disassemble instruction */
01676       myfprintf(stdout, "    0x%08p:   ", addr);
01677       errstr =
01678         f_dlite_mem_obj(mem, /* !is_write */FALSE,
01679                         addr, (char *)&inst, sizeof(inst));
01680       inst = MD_SWAPI(inst);
01681       if (errstr)
01682         return errstr;
01683       md_print_insn(inst, addr, stdout);
01684       fprintf(stdout, "\n");
01685 
01686       /* go to next instruction */
01687       addr += sizeof(md_inst_t);
01688     }
01689 
01690   /* no error */
01691   return NULL;
01692 }
01693 
01694 /* break instance descriptor, one allocated for each breakpoint set */
01695 struct dlite_break_t {
01696   struct dlite_break_t *next;   /* next active breakpoint */
01697   int id;                       /* break id */
01698   int class;                    /* break class */
01699   struct range_range_t range;   /* break range */
01700 };
01701 
01702 /* all active break points, in a list */
01703 static struct dlite_break_t *dlite_bps = NULL;
01704 
01705 /* unique id of next breakpoint */
01706 static int break_id = 1;
01707 
01708 /* return breakpoint class as a string */
01709 static char *                                   /* breakpoint class string */
01710 bp_class_str(int class)                         /* breakpoint class mask */
01711 {
01712   if (class == (ACCESS_READ|ACCESS_WRITE|ACCESS_EXEC))
01713     return "read|write|exec";
01714   else if (class == (ACCESS_READ|ACCESS_WRITE))
01715     return "read|write";
01716   else if (class == (ACCESS_WRITE|ACCESS_EXEC))
01717     return "write|exec";
01718   else if (class == (ACCESS_READ|ACCESS_EXEC))
01719     return "read|exec";
01720   else if (class == ACCESS_READ)
01721     return "read";
01722   else if (class == ACCESS_WRITE)
01723     return "write";
01724   else if (class == ACCESS_EXEC)
01725     return "exec";
01726   else
01727     panic("bogus access class");
01728 }
01729 
01730 /* set a breakpoint of class CLASS at address ADDR */
01731 static char *                                   /* err str, NULL for no err */
01732 set_break(int class,                            /* break class, use ACCESS_* */
01733           struct range_range_t *range)          /* range breakpoint */
01734 {
01735   struct dlite_break_t *bp;
01736 
01737   /* add breakpoint to break list */
01738   bp = calloc(1, sizeof(struct dlite_break_t));
01739   if (!bp)
01740     fatal("out of virtual memory");
01741 
01742   bp->id = break_id++;
01743   bp->range = *range;
01744   bp->class = class;
01745 
01746   bp->next = dlite_bps;
01747   dlite_bps = bp;
01748 
01749   fprintf(stdout, "breakpoint #%d set @ ", bp->id);
01750   range_print_range(&bp->range, stdout);
01751   fprintf(stdout, ", class: %s\n", bp_class_str(class));
01752 
01753   /* a breakpoint is set now, check for a breakpoint */
01754   dlite_check = TRUE;
01755 
01756   /* no error */
01757   return NULL;
01758 }
01759 
01760 /* delete breakpoint with id ID */
01761 static char *                                   /* err str, NULL for no err */
01762 delete_break(int id)                            /* id of brkpnt to delete */
01763 {
01764   struct dlite_break_t *bp, *prev;
01765 
01766   if (!dlite_bps)
01767     return "no breakpoints set";
01768 
01769   for (bp=dlite_bps,prev=NULL; bp != NULL; prev=bp,bp=bp->next)
01770     {
01771       if (bp->id == id)
01772         break;
01773     }
01774   if (!bp)
01775     return "breakpoint not found";
01776 
01777   if (!prev)
01778     {
01779       /* head of list, unlink */
01780       dlite_bps = bp->next;
01781     }
01782   else
01783     {
01784       /* middle or end of list */
01785       prev->next = bp->next;
01786     }
01787 
01788   fprintf(stdout, "breakpoint #%d deleted @ ",  bp->id);
01789   range_print_range(&bp->range, stdout);
01790   fprintf(stdout, ", class: %s\n", bp_class_str(bp->class));
01791 
01792   bp->next = NULL;
01793   free(bp);
01794 
01795   if (!dlite_bps)
01796     {
01797       /* no breakpoints set, cancel checks */
01798       dlite_check = FALSE;
01799     }
01800   else
01801     {
01802       /* breakpoints are set, do checks */
01803       dlite_check = TRUE;
01804     }
01805 
01806   /* no error */
01807   return NULL;
01808 }
01809 
01810 /* this variable clues dlite_main() into why it was called */
01811 static int break_access = 0;
01812 
01813 /* internal break check interface */
01814 int                                             /* non-zero if brkpt hit */
01815 __check_break(md_addr_t next_PC,                /* address of next inst */
01816               int access,                       /* mem access of last inst */
01817               md_addr_t addr,                   /* mem addr of last inst */
01818               counter_t icount,                 /* instruction count */
01819               counter_t cycle)                  /* cycle count */
01820 {
01821   struct dlite_break_t *bp;
01822 
01823   if (dlite_active)
01824     {
01825       /* single-stepping, break always */
01826       break_access = /* single step */0;
01827       return TRUE;
01828     }
01829   /* else, check for a breakpoint */
01830 
01831   for (bp=dlite_bps; bp != NULL; bp=bp->next)
01832     {
01833       switch (bp->range.start.ptype)
01834         {
01835         case pt_addr:
01836           if ((bp->class & ACCESS_EXEC)
01837               && !range_cmp_range(&bp->range, next_PC))
01838             {
01839               /* hit a code breakpoint */
01840               myfprintf(stdout,
01841                         "Stopping at code breakpoint #%d @ 0x%08p...\n",
01842                         bp->id, next_PC);
01843               break_access = ACCESS_EXEC;
01844               return TRUE;
01845             }
01846           if ((bp->class & ACCESS_READ)
01847               && ((access & ACCESS_READ)
01848                   && !range_cmp_range(&bp->range, addr)))
01849             {
01850               /* hit a read breakpoint */
01851               myfprintf(stdout,
01852                         "Stopping at read breakpoint #%d @ 0x%08p...\n",
01853                         bp->id, addr);
01854               break_access = ACCESS_READ;
01855               return TRUE;
01856             }
01857           if ((bp->class & ACCESS_WRITE)
01858               && ((access & ACCESS_WRITE)
01859                   && !range_cmp_range(&bp->range, addr)))
01860             {
01861               /* hit a write breakpoint */
01862               myfprintf(stdout,
01863                         "Stopping at write breakpoint #%d @ 0x%08p...\n",
01864                         bp->id, addr);
01865               break_access = ACCESS_WRITE;
01866               return TRUE;
01867             }
01868           break;
01869 
01870         case pt_inst:
01871           if (!range_cmp_range(&bp->range, icount))
01872             {
01873               /* hit a code breakpoint */
01874               fprintf(stdout,
01875                       "Stopping at inst count breakpoint #%d @ %.0f...\n",
01876                       bp->id, (double)icount);
01877               break_access = ACCESS_EXEC;
01878               return TRUE;
01879             }
01880           break;
01881 
01882         case pt_cycle:
01883           if (!range_cmp_range(&bp->range, cycle))
01884             {
01885               /* hit a code breakpoint */
01886               fprintf(stdout,
01887                       "Stopping at cycle count breakpoint #%d @ %.0f...\n",
01888                       bp->id, (double)cycle);
01889               break_access = ACCESS_EXEC;
01890               return TRUE;
01891             }
01892           break;
01893 
01894         default:
01895           panic("bogus range type");
01896         }
01897 
01898 
01899     }
01900 
01901   /* no matching breakpoint found */
01902   break_access = /* no break */0;
01903   return FALSE;
01904 }
01905 
01906 /* set a text breakpoint */
01907 static char *                                   /* err str, NULL for no err */
01908 dlite_break(int nargs, union arg_val_t args[],  /* command arguments */
01909             struct regs_t *regs,                /* registers to access */
01910             struct mem_t *mem)                  /* memory to access */
01911 {
01912   md_addr_t addr;
01913   struct range_range_t range;
01914 
01915   if (nargs != 1)
01916     return "wrong number of arguments";
01917 
01918   /* check address */
01919   if (!EVAL_INTEGRAL(args[0].as_value.type))
01920     return "address argument must be an integral type";
01921 
01922   /* reset addr */
01923   addr = eval_as_addr(args[0].as_value);
01924 
01925   /* build the range */
01926   range.start.ptype = pt_addr;
01927   range.start.pos = addr;
01928   range.end.ptype = pt_addr;
01929 #ifdef TARGET_ALPHA
01930   /* need some extra space here, as functional have multiple entry points
01931      depending on if $GP needs to be loaded or not */
01932   range.end.pos = addr + 9;
01933 #else /* !TARGET_ALPHA */
01934   range.end.pos = addr + 1;
01935 #endif /* TARGET_ALPHA */
01936 
01937   /* set a code break point */
01938   return set_break(ACCESS_EXEC, &range);
01939 }
01940 
01941 /* set a data breakpoint at specified address */
01942 static char *                                   /* err str, NULL for no err */
01943 dlite_dbreak(int nargs, union arg_val_t args[], /* command arguments */
01944              struct regs_t *regs,               /* registers to access */
01945              struct mem_t *mem)                 /* memory to access */
01946 {
01947   int access;
01948   md_addr_t addr;
01949   struct range_range_t range;
01950 
01951   if (nargs != 1 && nargs != 2)
01952     return "wrong number of arguments";
01953 
01954   if (nargs == 1)
01955     {
01956       /* check address */
01957       if (!EVAL_INTEGRAL(args[0].as_value.type))
01958         return "address argument must be an integral type";
01959 
01960       /* reset addr */
01961       addr = eval_as_addr(args[0].as_value);
01962 
01963       /* break on read or write */
01964       access = ACCESS_READ|ACCESS_WRITE;
01965     }
01966   else if (nargs == 2)
01967     {
01968       /* check address */
01969       if (!EVAL_INTEGRAL(args[0].as_value.type))
01970         return "address argument must be an integral type";
01971 
01972       /* reset addr */
01973       addr = eval_as_addr(args[0].as_value);
01974 
01975       /* get access */
01976       access = args[1].as_access;
01977     }
01978 
01979   /* build the range */
01980   range.start.ptype = pt_addr;
01981   range.start.pos = addr;
01982   range.end.ptype = pt_addr;
01983   range.end.pos = addr + 1;
01984 
01985   /* set the breakpoint */
01986   return set_break(access, &range);
01987 }
01988 
01989 /* set a breakpoint at specified range */
01990 static char *                                   /* err str, NULL for no err */
01991 dlite_rbreak(int nargs, union arg_val_t args[], /* command arguments */
01992              struct regs_t *regs,               /* registers to access */
01993              struct mem_t *mem)                 /* memory to access */
01994 {
01995   int access;
01996   char *errstr;
01997   struct range_range_t range;
01998 
01999   if (nargs != 1 && nargs != 2)
02000     return "wrong number of arguments";
02001 
02002   if (nargs == 2)
02003     {
02004       /* get access */
02005       access = args[1].as_access;
02006     }
02007   else
02008     {
02009       /* break on read or write or exec */
02010       access = ACCESS_READ|ACCESS_WRITE|ACCESS_EXEC;
02011     }
02012 
02013   /* check range */
02014   errstr = range_parse_range(args[0].as_str, &range);
02015   if (errstr)
02016     return errstr;
02017 
02018   /* sanity checks for ranges */
02019   if (range.start.ptype != range.end.ptype)
02020     return "range endpoints are not of the same type";
02021   else if (range.start.pos > range.end.pos)
02022     return "range start is after range end";
02023 
02024   /* set the breakpoint */
02025   return set_break(access, &range);
02026 }
02027 
02028 /* list all outstanding breakpoints */
02029 static char *                                   /* err str, NULL for no err */
02030 dlite_breaks(int nargs, union arg_val_t args[], /* command arguments */
02031              struct regs_t *regs,               /* registers to access */
02032              struct mem_t *mem)                 /* memory to access */
02033 {
02034   struct dlite_break_t *bp;
02035 
02036   if (!dlite_bps)
02037     {
02038       fprintf(stdout, "No active breakpoints.\n");
02039 
02040       /* no error */
02041       return NULL;
02042     }
02043 
02044   fprintf(stdout, "Active breakpoints:\n");
02045   for (bp=dlite_bps; bp != NULL; bp=bp->next)
02046     {
02047       fprintf(stdout, "  breakpoint #%d @ ",  bp->id);
02048       range_print_range(&bp->range, stdout);
02049       fprintf(stdout, ", class: %s\n", bp_class_str(bp->class));
02050     }
02051 
02052   /* no error */
02053   return NULL;
02054 }
02055 
02056 /* delete specified breakpoint */
02057 static char *                                   /* err str, NULL for no err */
02058 dlite_delete(int nargs, union arg_val_t args[], /* command arguments */
02059              struct regs_t *regs,               /* registers to access */
02060              struct mem_t *mem)                 /* memory to access */
02061 {
02062   int id;
02063 
02064   if (nargs != 1)
02065     return "wrong number of arguments";
02066 
02067   /* check bp id */
02068   if (!EVAL_INTEGRAL(args[0].as_value.type))
02069     return "id must be an integral type";
02070   
02071   id = eval_as_uint(args[0].as_value);
02072   return delete_break(id);
02073 }
02074 
02075 /* clear all breakpoints */
02076 static char *                                   /* err str, NULL for no err */
02077 dlite_clear(int nargs, union arg_val_t args[],  /* command arguments */
02078             struct regs_t *regs,                /* registers to access */
02079             struct mem_t *mem)                  /* memory to access */
02080 {
02081   if (!dlite_bps)
02082     {
02083       fprintf(stdout, "No active breakpoints.\n");
02084 
02085       /* no error */
02086       return NULL;
02087     }
02088 
02089   while (dlite_bps != NULL)
02090     {
02091       /* delete first breakpoint */
02092       delete_break(dlite_bps->id);
02093     }
02094   fprintf(stdout, "All breakpoints cleared.\n");
02095 
02096   /* no error */
02097   return NULL;
02098 }
02099 
02100 /* print the value of all program symbols */
02101 static char *                                   /* err str, NULL for no err */
02102 dlite_symbols(int nargs, union arg_val_t args[],/* command arguments */
02103               struct regs_t *regs,              /* registers to access */
02104               struct mem_t *mem)                /* memory to access */
02105 {
02106   int i;
02107 
02108   if (nargs != 0)
02109     return "wrong number of arguments";
02110 
02111   /* load symbols, if not already loaded */
02112   sym_loadsyms(ld_prog_fname, /* !locals */FALSE);
02113 
02114   /* print all symbol values */
02115   for (i=0; i<sym_nsyms; i++)
02116     sym_dumpsym(sym_syms[i], stdout);
02117 
02118   /* no error */
02119   return NULL;
02120 }
02121 
02122 /* print the value of all text symbols */
02123 static char *                                   /* err str, NULL for no err */
02124 dlite_tsymbols(int nargs, union arg_val_t args[],/* command arguments */
02125                struct regs_t *regs,             /* registers to access */
02126                struct mem_t *mem)               /* memory to access */
02127 {
02128   int i;
02129 
02130   if (nargs != 0)
02131     return "wrong number of arguments";
02132 
02133   /* load symbols, if not already loaded */
02134   sym_loadsyms(ld_prog_fname, /* !locals */FALSE);
02135 
02136   /* print all symbol values */
02137   for (i=0; i<sym_ntextsyms; i++)
02138     sym_dumpsym(sym_textsyms[i], stdout);
02139 
02140   /* no error */
02141   return NULL;
02142 }
02143 
02144 /* print the value of all text symbols */
02145 static char *                                   /* err str, NULL for no err */
02146 dlite_dsymbols(int nargs, union arg_val_t args[],/* command arguments */
02147                struct regs_t *regs,             /* registers to access */
02148                struct mem_t *mem)               /* memory to access */
02149 {
02150   int i;
02151 
02152   if (nargs != 0)
02153     return "wrong number of arguments";
02154 
02155   /* load symbols, if not already loaded */
02156   sym_loadsyms(ld_prog_fname, /* !locals */FALSE);
02157 
02158   /* print all symbol values */
02159   for (i=0; i<sym_ndatasyms; i++)
02160     sym_dumpsym(sym_datasyms[i], stdout);
02161 
02162   /* no error */
02163   return NULL;
02164 }
02165 
02166 /* print the value of all (or single) command line options */
02167 static char *                                   /* err str, NULL for no err */
02168 dlite_symbol(int nargs, union arg_val_t args[], /* command arguments */
02169              struct regs_t *regs,               /* registers to access */
02170              struct mem_t *mem)                 /* memory to access */
02171 {
02172   int index;
02173   struct sym_sym_t *sym;
02174 
02175   if (nargs != 1)
02176     return "wrong number of arguments";
02177 
02178   /* load symbols, if not already loaded */
02179   sym_loadsyms(ld_prog_fname, /* !locals */FALSE);
02180 
02181   /* print a single option, specified by argument */
02182   sym = sym_bind_name(args[0].as_str, &index, sdb_any);
02183   if (!sym)
02184     return "symbol is not defined";
02185 
02186   /* else, print this symbols's value */
02187   sym_dumpsym(sym_syms_by_name[index], stdout);
02188 
02189   /* no error */
02190   return NULL;
02191 }
02192 
02193 /* initialize the DLite debugger */
02194 void
02195 dlite_init(dlite_reg_obj_t reg_obj,             /* register state object */
02196            dlite_mem_obj_t mem_obj,             /* memory state object */
02197            dlite_mstate_obj_t mstate_obj)       /* machine state object */
02198 {
02199   /* architected state accessors */
02200   f_dlite_reg_obj = reg_obj;
02201   f_dlite_mem_obj = mem_obj;
02202   f_dlite_mstate_obj = mstate_obj;
02203 
02204   /* instantiate the expression evaluator */
02205   dlite_evaluator = eval_new(ident_evaluator, NULL);
02206 }
02207 
02208 /* print a mini-state header */
02209 static void
02210 dlite_status(md_addr_t regs_PC,                 /* PC of just completed inst */
02211              md_addr_t next_PC,                 /* PC of next inst to exec */
02212              counter_t cycle,                   /* current cycle */
02213              int dbreak,                        /* last break a data break? */
02214              struct regs_t *regs,               /* registers to access */
02215              struct mem_t *mem)                 /* memory to access */
02216 {
02217   md_inst_t inst;
02218   char *errstr;
02219 
02220   if (dbreak)
02221     {
02222       fprintf(stdout, "\n");
02223       fprintf(stdout, "Instruction (now finished) that caused data break:\n");
02224       myfprintf(stdout, "[%10n] 0x%08p:    ", cycle, regs_PC);
02225       errstr =
02226         f_dlite_mem_obj(mem, /* !is_write */FALSE,
02227                         regs_PC, (char *)&inst, sizeof(inst));
02228       inst = MD_SWAPI(inst);
02229       if (errstr)
02230         fprintf(stdout, "<invalid memory>: %s", errstr);
02231       else
02232         md_print_insn(inst, regs_PC, stdout);
02233       fprintf(stdout, "\n");
02234       fprintf(stdout, "\n");
02235     }
02236 
02237   /* read and disassemble instruction */
02238   myfprintf(stdout, "[%10n] 0x%08p:    ", cycle, next_PC);
02239   errstr =
02240     f_dlite_mem_obj(mem, /* !is_write */FALSE,
02241                     next_PC, (char *)&inst, sizeof(inst));
02242   inst = MD_SWAPI(inst);
02243   if (errstr)
02244     fprintf(stdout, "<invalid memory>: %s", errstr);
02245   else
02246     md_print_insn(inst, next_PC, stdout);
02247   fprintf(stdout, "\n");
02248 }
02249 
02250 /* DLite command line prompt */
02251 #define DLITE_PROMPT            "DLite! > "
02252 
02253 /* DLite debugger main loop */
02254 void
02255 dlite_main(md_addr_t regs_PC,                   /* addr of last inst to exec */
02256            md_addr_t next_PC,                   /* addr of next inst to exec */
02257            counter_t cycle,                     /* current procesor cycle */
02258            struct regs_t *regs,                 /* registers to access */
02259            struct mem_t *mem)                   /* memory to access */
02260 {
02261   char buf[512], *err_str;
02262   int dbreak = (break_access & (ACCESS_READ|ACCESS_WRITE)) != 0;
02263   static char cmd[512] = "";
02264 
02265   dlite_active = TRUE;
02266   dlite_return = FALSE;
02267   dlite_status(regs_PC, next_PC, cycle, dbreak, regs, mem);
02268 
02269   while (dlite_active && !dlite_return)
02270     {
02271       fprintf(stdout, DLITE_PROMPT);
02272       fflush(stdout);
02273       fgets(buf, 512, stdin);
02274 
02275       /* chop */
02276       if (buf[strlen(buf)-1] == '\n')
02277         buf[strlen(buf)-1] = '\0';
02278 
02279       if (buf[0] != '\0')
02280         {
02281           /* use this command */
02282           strcpy(cmd, buf);
02283         }
02284       /* else, use last command */
02285 
02286       err_str = dlite_exec(cmd, regs, mem);
02287       if (err_str)
02288         fprintf(stdout, "Dlite: error: %s\n", err_str);
02289     }
02290 }


UVa CS Department of Computer Science
School of Engineering, University of Virginia
151 Engineer's Way, P.O. Box 400740
Charlottesville, Virginia 22904-4740

(434) 982-2200  Fax: (434) 982-2214