dlite.c

来自「一个很有名的硬件模拟器。可以模拟CPU」· C语言 代码 · 共 2,262 行 · 第 1/4 页

C
2,262
字号
/* dlite.c - DLite, the lite debugger, routines *//* SimpleScalar(TM) Tool Suite * Copyright (C) 1994-2003 by Todd M. Austin, Ph.D. and SimpleScalar, LLC. * All Rights Reserved.  *  * THIS IS A LEGAL DOCUMENT, BY USING SIMPLESCALAR, * YOU ARE AGREEING TO THESE TERMS AND CONDITIONS. *  * No portion of this work may be used by any commercial entity, or for any * commercial purpose, without the prior, written permission of SimpleScalar, * LLC (info@simplescalar.com). Nonprofit and noncommercial use is permitted * as described below. *  * 1. SimpleScalar is provided AS IS, with no warranty of any kind, express * or implied. The user of the program accepts full responsibility for the * application of the program and the use of any results. *  * 2. Nonprofit and noncommercial use is encouraged. SimpleScalar may be * downloaded, compiled, executed, copied, and modified solely for nonprofit, * educational, noncommercial research, and noncommercial scholarship * purposes provided that this notice in its entirety accompanies all copies. * Copies of the modified software can be delivered to persons who use it * solely for nonprofit, educational, noncommercial research, and * noncommercial scholarship purposes provided that this notice in its * entirety accompanies all copies. *  * 3. ALL COMMERCIAL USE, AND ALL USE BY FOR PROFIT ENTITIES, IS EXPRESSLY * PROHIBITED WITHOUT A LICENSE FROM SIMPLESCALAR, LLC (info@simplescalar.com). *  * 4. No nonprofit user may place any restrictions on the use of this software, * including as modified by the user, by any other authorized user. *  * 5. Noncommercial and nonprofit users may distribute copies of SimpleScalar * in compiled or executable form as set forth in Section 2, provided that * either: (A) it is accompanied by the corresponding machine-readable source * code, or (B) it is accompanied by a written offer, with no time limit, to * give anyone a machine-readable copy of the corresponding source code in * return for reimbursement of the cost of distribution. This written offer * must permit verbatim duplication by anyone, or (C) it is distributed by * someone who received only the executable form, and is accompanied by a * copy of the written offer of source code. *  * 6. SimpleScalar was developed by Todd M. Austin, Ph.D. The tool suite is * currently maintained by SimpleScalar LLC (info@simplescalar.com). US Mail: * 2395 Timbercrest Court, Ann Arbor, MI 48105. *  * Copyright (C) 1994-2003 by Todd M. Austin, Ph.D. and SimpleScalar, LLC. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include "host.h"#include "misc.h"#include "machine.h"#include "version.h"#include "eval.h"#include "regs.h"#include "memory.h"#include "sim.h"#include "symbol.h"#include "loader.h"#include "options.h"#include "stats.h"#include "range.h"#include "dlite.h"/* architected state accessors, initialized by dlite_init() */static dlite_reg_obj_t f_dlite_reg_obj = NULL;static dlite_mem_obj_t f_dlite_mem_obj = NULL;static dlite_mstate_obj_t f_dlite_mstate_obj = NULL;/* set non-zero to enter DLite after next instruction */int dlite_active = FALSE;/* non-zero to force a check for a break */int dlite_check = FALSE;/* set non-zero to exit DLite command loop */static int dlite_return = FALSE;/* size modifier mask bit definitions */#define MOD_BYTE	0x0001		/* b - print a byte */#define MOD_HALF	0x0002		/* h - print a half (short) */#define MOD_WORD	0x0004		/* w - print a word */#define MOD_QWORD	0x0008		/* q - print a qword */#define MOD_FLOAT	0x0010		/* F - print a float */#define MOD_DOUBLE	0x0020		/* f - print a double */#define MOD_CHAR	0x0040		/* c - print a character */#define MOD_STRING	0x0080		/* s - print a string */#define MOD_SIZES							\  (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_QWORD					\   |MOD_FLOAT|MOD_DOUBLE|MOD_CHAR|MOD_STRING)/* format modifier mask bit definitions */#define MOD_DECIMAL	0x0100		/* d - print in decimal format */#define MOD_UNSIGNED	0x0200		/* u - print in unsigned format */#define MOD_OCTAL	0x0400		/* o - print in octal format */#define MOD_HEX		0x0800		/* x - print in hex format */#define MOD_BINARY	0x1000		/* 1 - print in binary format */#define MOD_FORMATS							\  (MOD_DECIMAL|MOD_UNSIGNED|MOD_OCTAL|MOD_HEX|MOD_BINARY)/* DLite modifier parser, transforms /<mods> strings to modifier mask */static char *				/* error string, NULL for no err */modifier_parser(char *p,		/* ptr to /<mods> string */		char **endp,		/* ptr to first byte not consumed */		int *pmod)		/* modifier mask written to *PMOD */{  int modifiers = 0;  /* default modifiers */  *pmod = 0;  /* is this a valid modifier? */  if (*p == '/')    {      p++;      /* parse modifiers until end-of-string or whitespace is found */      while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t')	{	  switch (*p)	    {	    case 'b':	      modifiers |= MOD_BYTE;	      break;	    case 'h':	      modifiers |= MOD_HALF;	      break;	    case 'w':	      modifiers |= MOD_WORD;	      break;	    case 'q':	      modifiers |= MOD_QWORD;	      break;	    case 'd':	      modifiers |= MOD_DECIMAL;	      break;	    case 'u':	      modifiers |= MOD_UNSIGNED;	      break;	    case 'o':	      modifiers |= MOD_OCTAL;	      break;	    case 'x':	      modifiers |= MOD_HEX;	      break;	    case '1':	      modifiers |= MOD_BINARY;	      break;	    case 'F':	      modifiers |= MOD_FLOAT;	      break;	    case 'f':	      modifiers |= MOD_DOUBLE;	      break;	    case 'c':	      modifiers |= MOD_CHAR;	      break;	    case 's':	      modifiers |= MOD_STRING;	      break;	    default:	      return "bad modifier (use one or more of /bhwqduox1fdcs)";	    }	  p++;	}    }  /* no error, return end of string and modifier mask */  *endp = p;  *pmod = modifiers;  return NULL;}/* DLite default expression evaluator */static struct eval_state_t *dlite_evaluator = NULL;static struct regs_t *local_regs = NULL;/* DLite identifier evaluator, used by the expression evaluator, returns   the value of the ident in ES->TOK_BUF, sets eval_error to value other   than ERR_NOERR if an error is encountered */static struct eval_value_t			/* value of identifier */ident_evaluator(struct eval_state_t *es)	/* expression evaluator */{  int i;  char *err_str;  struct eval_value_t val;  struct stat_stat_t *stat;  struct sym_sym_t *sym;  static struct eval_value_t err_value = { et_int, { 0 } };  /* is this a builtin register definition? */  for (i=0; md_reg_names[i].str != NULL; i++)    {      if (!mystricmp(es->tok_buf, md_reg_names[i].str))	{	  err_str =	    f_dlite_reg_obj(local_regs, /* !is_write */FALSE,			    md_reg_names[i].file, md_reg_names[i].reg, &val);	  if (err_str)	    {	      eval_error = ERR_UNDEFVAR;	      val = err_value;	    }	  return val;	}    }  /* else, try to locate a program symbol */  sym_loadsyms(ld_prog_fname, /* load locals */TRUE);  sym = sym_bind_name(es->tok_buf, NULL, sdb_any);  if (sym)    {      /* found a symbol with this name, return it's (address) value */      val.type = et_addr;      val.value.as_addr = sym->addr;      return val;    }  /* else, try to locate a statistical value symbol */  stat = stat_find_stat(sim_sdb, es->tok_buf);  if (stat)    {      /* found it, convert stat value to an eval_value_t value */      switch (stat->sc)	{	case sc_int:	  val.type = et_int;	  val.value.as_int = *stat->variant.for_int.var;	  break;	case sc_uint:	  val.type = et_uint;	  val.value.as_uint = *stat->variant.for_uint.var;	  break;#ifdef HOST_HAS_QWORD	case sc_qword:	  val.type = et_qword;	  val.value.as_qword = *stat->variant.for_qword.var;	  break;#endif /* HOST_HAS_QWORD */	case sc_float:	  val.type = et_float;	  val.value.as_float = *stat->variant.for_float.var;	  break;	case sc_double:	  val.type = et_double;	  val.value.as_double = *stat->variant.for_double.var;	  break;	case sc_dist:	case sc_sdist:	  eval_error = ERR_BADEXPR;	  val = err_value;	  break;	case sc_formula:	  {	    /* instantiate a new evaluator to avoid recursion problems */	    struct eval_state_t *es = eval_new(ident_evaluator, sim_sdb);	    char *endp;	    val = eval_expr(es, stat->variant.for_formula.formula, &endp);	    if (eval_error != ERR_NOERR || *endp != '\0')	      {		/* pass through eval_error */		val = err_value;	      }	    /* else, use value returned */	    eval_delete(es);	  }	  break;	default:	  panic("bogus stat class");	}      return val;    }  /* else, not found */  /* else, this is a bogus symbol */  eval_error = ERR_UNDEFVAR;  val = err_value;  return val;}/* maximum number of arguments that can passed to a dlite command handler */#define MAX_ARGS	4/* maximum length of a dlite command string argument */#define MAX_STR		128/* argument array entry, argument arrays are passed to command handlers */union arg_val_t {  int as_modifier;  struct eval_value_t as_value;  int as_access;  char as_str[MAX_STR];};/* a DLite command handler function pointer */typedef char *					/* err str, NULL for no err */(*cmd_fn_t)(int nargs,				/* number of arguments */	    union arg_val_t args[],		/* argument vector */	    struct regs_t *regs,		/* registers to access */	    struct mem_t *mem);			/* memory to access *//* DLite command descriptor, fully describes a command supported by the   DLite debugger command handler */struct dlite_cmd_t {  char *cmd_str;		/* DLite command string */  char *arg_strs[MAX_ARGS];	/* NULL-terminated cmd args (? - optional):				     m - size/type modifiers				     a - address expression				     c - count expression				     e - any expression				     s - any string				     t - access type {r|w|x}				     i - breakpoint id */  cmd_fn_t cmd_fn;		/* implementing function */  char *help_str;		/* DLite command help string */};/* forward handler decls */static char *dlite_help(int nargs, union arg_val_t args[],	   struct regs_t *regs, struct mem_t *mem);static char *dlite_version(int nargs, union arg_val_t args[],	      struct regs_t *regs, struct mem_t *mem);static char *dlite_terminate(int nargs, union arg_val_t args[],		struct regs_t *regs, struct mem_t *mem);static char *dlite_quit(int nargs, union arg_val_t args[],	   struct regs_t *regs, struct mem_t *mem);static char *dlite_cont(int nargs, union arg_val_t args[],	   struct regs_t *regs, struct mem_t *mem);static char *dlite_step(int nargs, union arg_val_t args[],	   struct regs_t *regs, struct mem_t *mem);static char *dlite_print(int nargs, union arg_val_t args[],	    struct regs_t *regs, struct mem_t *mem);static char *dlite_options(int nargs, union arg_val_t args[],	      struct regs_t *regs, struct mem_t *mem);static char *dlite_option(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_stats(int nargs, union arg_val_t args[],	    struct regs_t *regs, struct mem_t *mem);static char *dlite_stat(int nargs, union arg_val_t args[],	   struct regs_t *regs, struct mem_t *mem);static char *dlite_whatis(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_regs(int nargs, union arg_val_t args[],	   struct regs_t *regs, struct mem_t *mem);static char *dlite_iregs(int nargs, union arg_val_t args[],	    struct regs_t *regs, struct mem_t *mem);static char *dlite_fpregs(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_cregs(int nargs, union arg_val_t args[],	    struct regs_t *regs, struct mem_t *mem);static char *dlite_mstate(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_display(int nargs, union arg_val_t args[],	      struct regs_t *regs, struct mem_t *mem);static char *dlite_dump(int nargs, union arg_val_t args[],	   struct regs_t *regs, struct mem_t *mem);static char *dlite_dis(int nargs, union arg_val_t args[],	  struct regs_t *regs, struct mem_t *mem);static char *dlite_break(int nargs, union arg_val_t args[],	    struct regs_t *regs, struct mem_t *mem);static char *dlite_dbreak(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_rbreak(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_breaks(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_delete(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);static char *dlite_clear(int nargs, union arg_val_t args[],	    struct regs_t *regs, struct mem_t *mem);static char *dlite_symbols(int nargs, union arg_val_t args[],	      struct regs_t *regs, struct mem_t *mem);static char *dlite_tsymbols(int nargs, union arg_val_t args[],	       struct regs_t *regs, struct mem_t *mem);static char *dlite_dsymbols(int nargs, union arg_val_t args[],	       struct regs_t *regs, struct mem_t *mem);static char *dlite_symbol(int nargs, union arg_val_t args[],	     struct regs_t *regs, struct mem_t *mem);/* DLite debugger command parser command definitions, NOTE: optional   arguments must be trailing arguments, otherwise the command parser will   break (modifiers are an exception to this rule) */static struct dlite_cmd_t cmd_db[] ={  { "help", { "s?", NULL }, dlite_help,    "print command reference" },  { "version", { NULL }, dlite_version,    "print DLite version information" },  { "terminate", { NULL }, dlite_terminate,    "terminate the simulation with statistics" },  { "quit", { NULL }, dlite_quit,    "exit the simulator" },  { "cont", { "a?", NULL }, dlite_cont,    "continue program execution (optionally at <addr>)" },  { "step", { NULL }, dlite_step,    "step program one instruction" },#if 0 /* NYI */  { "next", { NULL }, dlite_next,    "step program one instruction in current procedure" },#endif  { "print", { "m?", "e", NULL }, dlite_print,    "print the value of <expr> using format <modifiers>" },  { "options", { NULL }, dlite_options,    "print the value of all options" },  { "option", { "s", NULL }, dlite_option,    "print the value of an option" },  { "stats", { NULL }, dlite_stats,    "print the value of all statistical variables" },  { "stat", { "s", NULL }, dlite_stat,    "print the value of a statistical variable" },  { "whatis", { "e", NULL }, dlite_whatis,    "print the type of expression <expr>" },  { "---", { NULL }, NULL, NULL },  { "regs", { NULL }, dlite_regs,    "print all register contents" },  { "iregs", { NULL }, dlite_iregs,    "print integer register contents" },  { "fpregs", { NULL }, dlite_fpregs,    "print floating point register contents" },  { "cregs", { NULL }, dlite_cregs,    "print control register contents" },  { "mstate", { "s?", NULL }, dlite_mstate,    "print machine specific state (simulator dependent)" },  { "display", { "m?", "a", NULL }, dlite_display,    "display the value at memory location <addr> using format <modifiers>" },  { "dump", { "a?", "c?", NULL }, dlite_dump,    "dump memory at <addr> (optionally for <cnt> words)" },  { "dis", { "a?", "c?", NULL }, dlite_dis,    "disassemble instructions at <addr> (for <cnt> insts)" },  { "break", { "a", NULL }, dlite_break,    "set breakpoint at <addr>, returns <id> of breakpoint" },  { "dbreak", { "a", "t?", NULL }, dlite_dbreak,    "set data breakpoint at <addr> (for (r)ead, (w)rite,\n"    "    and/or e(x)ecute, returns <id> of breakpoint" },  { "rbreak", { "s", "t?", NULL }, dlite_rbreak,    "set read/write/exec breakpoint at <range> (for (r)ead, (w)rite,\n"    "    and/or e(x)ecute, returns <id> of breakpoint" },  { "breaks", { NULL }, dlite_breaks,    "list active code and data breakpoints" },  { "delete", { "i", NULL }, dlite_delete,    "delete breakpoint <id>" },  { "clear", { NULL }, dlite_clear,    "clear all breakpoints (code and data)" },  { "---", { NULL }, NULL, NULL },  { "symbols", { NULL }, dlite_symbols,    "print the value of all program symbols" },  { "tsymbols", { NULL }, dlite_tsymbols,    "print the value of all program text symbols" },  { "dsymbols", { NULL }, dlite_dsymbols,    "print the value of all program data symbols" },  { "symbol", { "s", NULL }, dlite_symbol,    "print the value of a symbol" },  { "---", { NULL }, NULL, NULL },  /* list terminator */  { NULL, { NULL }, NULL, NULL }};/* help command trailing text */static char *dlite_help_tail =  "Arguments <addr>, <cnt>, <expr>, and <id> are any legal expression:\n"  "  <expr>    <-  <factor> +|- <expr>\n"  "  <factor>  <-  <term> *|/ <factor>\n"  "  <term>    <-  ( <expr> )\n"  "                | - <term>\n"  "                | <const>\n"  "                | <symbol>\n"  "                | <file:loc>\n"  "\n"  "Command modifiers <mods> are any of the following:\n"  "\n"  "  b - print a byte\n"  "  h - print a half (short)\n"  "  w - print a word (default)\n"#ifdef HOST_HAS_QWORD  "  q - print a qword\n"#endif /* HOST_HAS_QWORD */  "  F - print a float\n"  "  f - print a double\n"  "  c - print a character\n"  "  s - print a string\n"  "  d - print in decimal format (default)\n"  "  u - print in unsigned decimal format\n"  "  o - print in octal format\n"  "  x - print in hex format\n"  "  1 - print in binary format\n";/* execute DLite command string CMD */static char *					/* err str, NULL if no err */dlite_exec(char *cmd_str,			/* command string */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  int i, arg_cnt;  struct dlite_cmd_t *cmd;  char cmd_buf[512], *p, *q, *endp;  union arg_val_t args[MAX_ARGS];  p = cmd_str;  q = cmd_buf;  /* skip any whitespace before argument */  while (*p == ' ' || *p == '\t' || *p == '\n')    p++;  /* anything left? */  if (*p == '\0')    {      /* NOP, no error */      return NULL;    }  /* copy out command name string */  while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t' && *p != '/')    *q++ = *p++;  *q = '\0';  /* find matching command */  for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++)    {      if (!strcmp(cmd->cmd_str, cmd_buf))	break;    }  if (cmd->cmd_str == NULL)    return "unknown command";

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?