dlite.c

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

C
2,262
字号
  /* match arguments for *CMD */  for (i=0, arg_cnt=0; i<MAX_ARGS && cmd->arg_strs[i] != NULL; i++, arg_cnt++)    {      int optional, access, modifiers;      char *arg, arg_type, *err_str;      struct eval_value_t val;      /* skip any whitespace before argument */      while (*p == ' ' || *p == '\t' || *p == '\n')	p++;      arg = cmd->arg_strs[i];      arg_type = arg[0];      optional = (arg[1] == '?');      if (*p == '\0')	{	  if (optional)	    {	      /* all arguments parsed */	      break;	    }	  else	    return "missing an argument";	}      endp = p;      switch (arg_type)	{	case 'm':	  err_str = modifier_parser(p, &endp, &modifiers);	  if (err_str)	    return err_str;	  args[arg_cnt].as_modifier = modifiers;	  break;	case 'a':	  local_regs = regs;	  val = eval_expr(dlite_evaluator, p, &endp);	  if (eval_error)	    return eval_err_str[eval_error];	  args[arg_cnt].as_value = val;	  break;	case 'c':	  local_regs = regs;	  val = eval_expr(dlite_evaluator, p, &endp);	  if (eval_error)	    return eval_err_str[eval_error];	  args[arg_cnt].as_value = val;	  break;	case 'e':	  local_regs = regs;	  val = eval_expr(dlite_evaluator, p, &endp);	  if (eval_error)	    return eval_err_str[eval_error];	  args[arg_cnt].as_value = val;	  break;	case 't':	  access = 0;	  while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t')	    {	      switch (*p)		{		case 'r':		  access |= ACCESS_READ;		  break;		case 'w':		  access |= ACCESS_WRITE;		  break;		case 'x':		  access |= ACCESS_EXEC;		  break;		default:		  return "bad access type specifier (use r|w|x)";		}	      p++;	    }	  endp = p;	  args[arg_cnt].as_access = access;	  break;	case 'i':	  local_regs = regs;	  val = eval_expr(dlite_evaluator, p, &endp);	  if (eval_error)	    return eval_err_str[eval_error];	  args[arg_cnt].as_value = val;	  break;	case 's':	  q = args[arg_cnt].as_str;	  while (*p != ' ' && *p != '\t' && *p != '\0')	    *q++ = *p++;	  *q = '\0';	  endp = p;	  break;	default:	  panic("bogus argument type: `%c'", arg_type);	}      p = endp;    }  /* skip any whitespace before any trailing argument */  while (*p == ' ' || *p == '\t' || *p == '\n')    p++;  /* check for any orphan arguments */  if (*p != '\0')    return "too many arguments";  /* if we reach here, all arguments were parsed correctly, call handler */  return cmd->cmd_fn(arg_cnt, args, regs, mem);}/* print expression value VAL using modifiers MODIFIERS */static char *					/* err str, NULL for no err */print_val(int modifiers,			/* print modifiers */	  struct eval_value_t val)		/* expr value to print */{  char *format = "", *prefix = "", radix, buf[512];  /* fill in any default size */  if ((modifiers & MOD_SIZES) == 0)    {      /* compute default size */      switch (val.type)	{	case et_int:	modifiers |= MOD_WORD; break;	case et_uint:	modifiers |= MOD_WORD; break;	case et_addr:#ifdef HOST_HAS_QWORD	  if (sizeof(md_addr_t) > 4)	    modifiers |= MOD_QWORD;	  else#endif /* HOST_HAS_QWORD */	    modifiers |= MOD_WORD;	  break;#ifdef HOST_HAS_QWORD	case et_qword:	modifiers |= MOD_QWORD; break;	case et_sqword:	modifiers |= MOD_QWORD; break;#endif /* HOST_HAS_QWORD */	case et_float:	modifiers |= MOD_FLOAT; break;	case et_double:	modifiers |= MOD_DOUBLE; break;	case et_symbol:	default:	return "bad print value";	}    }  if (((modifiers & MOD_SIZES) & ((modifiers & MOD_SIZES) - 1)) != 0)    return "multiple size specifiers";  /* fill in any default format */  if ((modifiers & MOD_FORMATS) == 0)    {      /* compute default size */      switch (val.type)	{	case et_int:	modifiers |= MOD_DECIMAL; break;	case et_uint:	modifiers |= MOD_UNSIGNED; break;	case et_addr:	modifiers |= MOD_HEX; break;#ifdef HOST_HAS_QWORD	case et_qword:	modifiers |= MOD_UNSIGNED; break;	case et_sqword:	modifiers |= MOD_DECIMAL; break;#endif /* HOST_HAS_QWORD */	case et_float:	/* use default format */break;	case et_double:	/* use default format */break;	case et_symbol:	default:	return "bad print value";	}    }  if (((modifiers & MOD_FORMATS) & ((modifiers & MOD_FORMATS) - 1)) != 0)    return "multiple format specifiers";  /* decode modifiers */  if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_QWORD))    {      if (modifiers & MOD_DECIMAL)	radix = 'd';      else if (modifiers & MOD_UNSIGNED)	radix = 'u';      else if (modifiers & MOD_OCTAL)	radix = 'o';      else if (modifiers & MOD_HEX)	radix = 'x';      else if (modifiers & MOD_BINARY)	return "binary format not yet implemented";      else	panic("no default integer format");      if (modifiers & MOD_BYTE)	{	  if (modifiers & MOD_OCTAL)	    {	      prefix = "0";	      format = "03";	    }	  else if (modifiers & MOD_HEX)	    {	      prefix = "0x";	      format = "02";	    }	  else	    {	      prefix = "";	      format = "";	    }	  sprintf(buf, "%s%%%s%c", prefix, format, radix);	  myfprintf(stdout, buf, eval_as_uint(val));	}      else if (modifiers & MOD_HALF)	{	  if (modifiers & MOD_OCTAL)	    {	      prefix = "0";	      format = "06";	    }	  else if (modifiers & MOD_HEX)	    {	      prefix = "0x";	      format = "04";	    }	  else	    {	      prefix = "";	      format = "";	    }	  sprintf(buf, "%s%%%s%c", prefix, format, radix);	  myfprintf(stdout, buf, eval_as_uint(val));	}      else if (modifiers & MOD_WORD)	{	  if (modifiers & MOD_OCTAL)	    {	      prefix = "0";	      format = "011";	    }	  else if (modifiers & MOD_HEX)	    {	      prefix = "0x";	      format = "08";	    }	  else	    {	      prefix = "";	      format = "";	    }	  sprintf(buf, "%s%%%s%c", prefix, format, radix);	  myfprintf(stdout, buf, eval_as_uint(val));	}#ifdef HOST_HAS_QWORD      else if (modifiers & MOD_QWORD)	{	  if (modifiers & MOD_OCTAL)	    {	      prefix = "0";	      format = "022";	    }	  else if (modifiers & MOD_HEX)	    {	      prefix = "0x";	      format = "016";	    }	  else	    {	      prefix = "";	      format = "";	    }	  sprintf(buf, "%s%%%sl%c", prefix, format, radix);	  myfprintf(stdout, buf, eval_as_qword(val));	}#endif /* HOST_HAS_QWORD */    }  else if (modifiers & MOD_FLOAT)    fprintf(stdout, "%f", (double)eval_as_float(val));  else if (modifiers & MOD_DOUBLE)    fprintf(stdout, "%f", eval_as_double(val));  else if (modifiers & MOD_CHAR)    fprintf(stdout, "`%c'", eval_as_uint(val));  else if (modifiers & MOD_STRING)    return "string format not yet implemented";  else /* no format specified, default to value type format */    panic("no default format");  /* no error */  return NULL;}/* default memory state accessor */char *						/* err str, NULL for no err */dlite_mem_obj(struct mem_t *mem,		/* memory space to access */	      int is_write,			/* access type */	      md_addr_t addr,			/* address to access */	      char *p,				/* input/output buffer */	      int nbytes)			/* size of access */{  enum mem_cmd cmd;  if (!is_write)    cmd = Read;  else    cmd = Write;#if 0  char *errstr;  errstr = mem_valid(cmd, addr, nbytes, /* !declare */FALSE);  if (errstr)    return errstr;#endif  /* else, no error, access memory */  mem_access(mem, cmd, addr, p, nbytes);  /* no error */  return NULL;}/* default machine state accessor */char *						/* err str, NULL for no err */dlite_mstate_obj(FILE *stream,			/* output stream */		 char *cmd,			/* optional command string */		 struct regs_t *regs,		/* registers to access */		 struct mem_t *mem)		/* memory to access */{  /* nada */  fprintf(stream, "No machine state.\n");  /* no error */  return NULL;}/* scroll terminator, wait for user to press return */static voiddlite_pause(void){  char buf[512];  fprintf(stdout, "Press <return> to continue...");  fflush(stdout);  fgets(buf, 512, stdin);}/* print help information for DLite command CMD */static voidprint_help(struct dlite_cmd_t *cmd)		/* command to describe */{  int i;  /* print command name */  fprintf(stdout, "  %s ", cmd->cmd_str);  /* print arguments of command */  for (i=0; i < MAX_ARGS && cmd->arg_strs[i] != NULL; i++)    {      int optional;      char *arg, arg_type;      arg = cmd->arg_strs[i];      arg_type = arg[0];      optional = (arg[1] == '?');      if (optional)	fprintf(stdout, "{");      else	fprintf(stdout, "<");      switch (arg_type)	{	case 'm':	  fprintf(stdout, "/modifiers");	  break;	case 'a':	  fprintf(stdout, "addr");	  break;	case 'c':	  fprintf(stdout, "count");	  break;	case 'e':	  fprintf(stdout, "expr");	  break;	case 't':	  fprintf(stdout, "r|w|x");	  break;	case 'i':	  fprintf(stdout, "id");	  break;	case 's':	  fprintf(stdout, "string");	  break;	default:	  panic("bogus argument type: `%c'", arg_type);	}      if (optional)	fprintf(stdout, "}");      else	fprintf(stdout, ">");      fprintf(stdout, " ");    }  fprintf(stdout, "\n");  /* print command description */  fprintf(stdout, "    %s\n", cmd->help_str);}/* print help messages for all (or single) DLite debugger commands */static char *					/* err str, NULL for no err */dlite_help(int nargs, union arg_val_t args[],	/* command arguments */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  struct dlite_cmd_t *cmd;  if (nargs != 0 && nargs != 1)    return "too many arguments";  if (nargs == 1)    {      /* print help for specified commands */      for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++)	{	  if (!strcmp(cmd->cmd_str, args[0].as_str))	    break;	}      if (!cmd->cmd_str)	return "command unknown";      print_help(cmd);    }  else    {      /* print help for all commands */      for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++)	{	  /* `---' specifies a good point for a scroll pause */	  if (!strcmp(cmd->cmd_str, "---"))	    dlite_pause();	  else	    print_help(cmd);	}      fprintf (stdout, "\n");      if (dlite_help_tail)	fprintf (stdout, "%s\n", dlite_help_tail);    }  /* no error */  return NULL;}/* print version information for simulator */static char *				 	/* err str, NULL for no err */dlite_version(int nargs, union arg_val_t args[],/* command arguments */	      struct regs_t *regs,		/* registers to access */	      struct mem_t *mem)		/* memory to access */{  if (nargs != 0)    return "too many arguments";  /* print simulator version info */  fprintf(stdout, "The SimpleScalar/%s Tool Set, version %d.%d of %s.\n",	  VER_TARGET, VER_MAJOR, VER_MINOR, VER_UPDATE);  fprintf(stdout,    "Copyright (c) 1994-1998 by Todd M. Austin.  All Rights Reserved.\n");  /* no error */  return NULL;}/* terminate simulation with statistics */static char *					/* err str, NULL for no err */dlite_terminate(int nargs, union arg_val_t args[],/* command arguments */		struct regs_t *regs,		/* registers to access */		struct mem_t *mem)		/* memory to access */{  if (nargs != 0)    return "too many arguments";  fprintf(stdout, "DLite: terminating simulation...\n");  longjmp(sim_exit_buf, /* exitcode */1);  /* no error */  return NULL;}/* quit the simulator, omit any stats dump */static char *					/* err str, NULL for no err */dlite_quit(int nargs, union arg_val_t args[],	/* command arguments */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  if (nargs != 0)    return "too many arguments";  fprintf(stdout, "DLite: exiting simulator...\n");  exit(1);  /* no error */  return NULL;}/* continue executing program (possibly at specified address) */static char *					/* err str, NULL for no err */dlite_cont(int nargs, union arg_val_t args[],	/* command arguments */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  struct eval_value_t val;  if (!f_dlite_reg_obj || !f_dlite_mem_obj)    panic("DLite is not configured");  if (nargs != 0 && nargs != 1)    return "too many arguments";  if (nargs == 1)    {      /* continue from specified address, check address */      if (!EVAL_INTEGRAL(args[0].as_value.type))	return "address argument must be an integral type";      /* reset PC */      val.type = et_addr;      val.value.as_addr = eval_as_addr(args[0].as_value);      f_dlite_reg_obj(regs, /* is_write */TRUE, rt_PC, 0, &val);      myfprintf(stdout, "DLite: continuing execution @ 0x%08p...\n",		val.value.as_addr);    }  /* signal end of main debugger loop, and continuation of prog execution */  dlite_active = FALSE;  dlite_return = TRUE;  /* no error */  return NULL;}/* step program one instruction */static char *					/* err str, NULL for no err */dlite_step(int nargs, union arg_val_t args[],	/* command arguments */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  if (nargs != 0)    return "too many arguments";  /* signal on instruction step */  dlite_active = TRUE;  dlite_return = TRUE;  /* no error */  return NULL;}#if 0 /* NYI *//* step program one instruction in current procedure */static char *					/* err str, NULL for no err */dlite_next(int nargs, union arg_val_t args[])	/* command arguments */{  if (nargs != 0)    return "too many arguments";  /* signal on instruction step */  dlite_step_cnt = 1;

⌨️ 快捷键说明

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