⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlite.c

📁 RISC处理器仿真分析程序。可以用于研究通用RISC处理器的指令和架构设计。在linux下编译
💻 C
📖 第 1 页 / 共 4 页
字号:
      ss_print_insn(inst, addr, stdout);      fprintf(stdout, "\n");      /* go to next instruction */      addr += SS_INST_SIZE;    }  /* no error */  return NULL;}/* break instance descriptor, one allocated for each breakpoint set */struct dlite_break_t {  struct dlite_break_t *next;	/* next active breakpoint */  int id;			/* break id */  int class;			/* break class */  struct range_range_t range;	/* break range */};/* all active break points, in a list */static struct dlite_break_t *dlite_bps = NULL;/* unique id of next breakpoint */static int break_id = 1;/* return breakpoint class as a string */static char *					/* breakpoint class string */bp_class_str(int class)				/* breakpoint class mask */{  if (class == (ACCESS_READ|ACCESS_WRITE|ACCESS_EXEC))    return "read|write|exec";  else if (class == (ACCESS_READ|ACCESS_WRITE))    return "read|write";  else if (class == (ACCESS_WRITE|ACCESS_EXEC))    return "write|exec";  else if (class == (ACCESS_READ|ACCESS_EXEC))    return "read|exec";  else if (class == ACCESS_READ)    return "read";  else if (class == ACCESS_WRITE)    return "write";  else if (class == ACCESS_EXEC)    return "exec";  else    panic("bogus access class");}/* set a breakpoint of class CLASS at address ADDR */static char *					/* err str, NULL for no err */set_break(int class,				/* break class, use ACCESS_* */	  struct range_range_t *range)		/* range breakpoint */{  struct dlite_break_t *bp;  /* add breakpoint to break list */  bp = calloc(1, sizeof(struct dlite_break_t));  if (!bp)    fatal("out of virtual memory");  bp->id = break_id++;  bp->range = *range;  bp->class = class;  bp->next = dlite_bps;  dlite_bps = bp;  fprintf(stdout, "breakpoint #%d set @ ", bp->id);  range_print_range(&bp->range, stdout);  fprintf(stdout, ", class: %s\n", bp_class_str(class));  /* a breakpoint is set now, check for a breakpoint */  dlite_check = TRUE;  /* no error */  return NULL;}/* delete breakpoint with id ID */static char *					/* err str, NULL for no err */delete_break(int id)				/* id of brkpnt to delete */{  struct dlite_break_t *bp, *prev;  if (!dlite_bps)    return "no breakpoints set";  for (bp=dlite_bps,prev=NULL; bp != NULL; prev=bp,bp=bp->next)    {      if (bp->id == id)	break;    }  if (!bp)    return "breakpoint not found";  if (!prev)    {      /* head of list, unlink */      dlite_bps = bp->next;    }  else    {      /* middle or end of list */      prev->next = bp->next;    }  fprintf(stdout, "breakpoint #%d deleted @ ",  bp->id);  range_print_range(&bp->range, stdout);  fprintf(stdout, ", class: %s\n", bp_class_str(bp->class));  bp->next = NULL;  free(bp);  if (!dlite_bps)    {      /* no breakpoints set, cancel checks */      dlite_check = FALSE;    }  else    {      /* breakpoints are set, do checks */      dlite_check = TRUE;    }  /* no error */  return NULL;}/* this variable clues dlite_main() into why it was called */static int break_access = 0;/* internal break check interface */int						/* non-zero if brkpt hit */__check_break(SS_ADDR_TYPE next_PC,		/* address of next inst */	      int access,			/* mem access of last inst */	      SS_ADDR_TYPE addr,		/* mem addr of last inst */	      SS_COUNTER_TYPE icount,		/* instruction count */	      SS_COUNTER_TYPE cycle)		/* cycle count */{  struct dlite_break_t *bp;  if (dlite_active)    {      /* single-stepping, break always */      break_access = /* single step */0;      return TRUE;    }  /* else, check for a breakpoint */  for (bp=dlite_bps; bp != NULL; bp=bp->next)    {      switch (bp->range.start.ptype)	{	case pt_addr:	  if ((bp->class & ACCESS_EXEC)	      && !range_cmp_range(&bp->range, next_PC))	    {	      /* hit a code breakpoint */	      fprintf(stdout,		      "Stopping at code breakpoint #%d @ 0x%08x...\n",		      bp->id, next_PC);	      break_access = ACCESS_EXEC;	      return TRUE;	    }	  if ((bp->class & ACCESS_READ)	      && ((access & ACCESS_READ)		  && !range_cmp_range(&bp->range, addr)))	    {	      /* hit a read breakpoint */	      fprintf(stdout,		      "Stopping at read breakpoint #%d @ 0x%08x...\n",		      bp->id, addr);	      break_access = ACCESS_READ;	      return TRUE;	    }	  if ((bp->class & ACCESS_WRITE)	      && ((access & ACCESS_WRITE)		  && !range_cmp_range(&bp->range, addr)))	    {	      /* hit a write breakpoint */	      fprintf(stdout,		      "Stopping at write breakpoint #%d @ 0x%08x...\n",		      bp->id, addr);	      break_access = ACCESS_WRITE;	      return TRUE;	    }	  break;	case pt_inst:	  if (!range_cmp_range(&bp->range, icount))	    {	      /* hit a code breakpoint */	      fprintf(stdout,		      "Stopping at inst count breakpoint #%d @ %.0f...\n",		      bp->id, (double)icount);	      break_access = ACCESS_EXEC;	      return TRUE;	    }	  break;	case pt_cycle:	  if (!range_cmp_range(&bp->range, cycle))	    {	      /* hit a code breakpoint */	      fprintf(stdout,		      "Stopping at cycle count breakpoint #%d @ %.0f...\n",		      bp->id, (double)cycle);	      break_access = ACCESS_EXEC;	      return TRUE;	    }	  break;	default:	  panic("bogus range type");	}    }  /* no matching breakpoint found */  break_access = /* no break */0;  return FALSE;}/* set a text breakpoint */static char *					/* err str, NULL for no err */dlite_break(int nargs, union arg_val_t args[])	/* command arguments */{  SS_ADDR_TYPE addr;  struct range_range_t range;  if (nargs != 1)    return "wrong number of arguments";  /* check address */  if (args[0].as_value.type != et_int && args[0].as_value.type != et_uint)    return "address argument must be an integral type";  /* reset addr */  addr = args[0].as_value.value.as_uint;  /* build the range */  range.start.ptype = pt_addr;  range.start.pos = addr;  range.end.ptype = pt_addr;  range.end.pos = addr + 1;  /* set a code break point */  return set_break(ACCESS_EXEC, &range);}/* set a data breakpoint at specified address */static char *					/* err str, NULL for no err */dlite_dbreak(int nargs, union arg_val_t args[])	/* command arguments */{  int access;  SS_ADDR_TYPE addr;  struct range_range_t range;  if (nargs != 1 && nargs != 2)    return "wrong number of arguments";  if (nargs == 1)    {      /* check address */      if (args[0].as_value.type != et_int && args[0].as_value.type != et_uint)	return "address argument must be an integral type";      /* reset addr */      addr = args[0].as_value.value.as_uint;      /* break on read or write */      access = ACCESS_READ|ACCESS_WRITE;    }  else if (nargs == 2)    {      /* check address */      if (args[0].as_value.type != et_int && args[0].as_value.type != et_uint)	return "address argument must be an integral type";      /* reset addr */      addr = args[0].as_value.value.as_uint;      /* get access */      access = args[1].as_access;    }  /* build the range */  range.start.ptype = pt_addr;  range.start.pos = addr;  range.end.ptype = pt_addr;  range.end.pos = addr + 1;  /* set the breakpoint */  return set_break(access, &range);}/* set a breakpoint at specified range */static char *					/* err str, NULL for no err */dlite_rbreak(int nargs, union arg_val_t args[])	/* command arguments */{  int access;  char *errstr;  struct range_range_t range;  if (nargs != 1 && nargs != 2)    return "wrong number of arguments";  if (nargs == 2)    {      /* get access */      access = args[1].as_access;    }  else    {      /* break on read or write or exec */      access = ACCESS_READ|ACCESS_WRITE|ACCESS_EXEC;    }  /* check range */  errstr = range_parse_range(args[0].as_str, &range);  if (errstr)    return errstr;  /* sanity checks for ranges */  if (range.start.ptype != range.end.ptype)    return "range endpoints are not of the same type";  else if (range.start.pos > range.end.pos)    return "range start is after range end";  /* set the breakpoint */  return set_break(access, &range);}/* list all outstanding breakpoints */static char *					/* err str, NULL for no err */dlite_breaks(int nargs, union arg_val_t args[])	/* command arguments */{  struct dlite_break_t *bp;  if (!dlite_bps)    {      fprintf(stdout, "No active breakpoints.\n");      /* no error */      return NULL;    }  fprintf(stdout, "Active breakpoints:\n");  for (bp=dlite_bps; bp != NULL; bp=bp->next)    {      fprintf(stdout, "  breakpoint #%d @ ",  bp->id);      range_print_range(&bp->range, stdout);      fprintf(stdout, ", class: %s\n", bp_class_str(bp->class));    }  /* no error */  return NULL;}/* delete specified breakpoint */static char *					/* err str, NULL for no err */dlite_delete(int nargs, union arg_val_t args[])	/* command arguments */{  int id;  if (nargs != 1)    return "wrong number of arguments";  /* check bp id */  if (args[0].as_value.type != et_int && args[0].as_value.type != et_uint)    return "id must be an integral type";    id = args[0].as_value.value.as_uint;  return delete_break(id);}/* clear all breakpoints */static char *					/* err str, NULL for no err */dlite_clear(int nargs, union arg_val_t args[])	/* command arguments */{  if (!dlite_bps)    {      fprintf(stdout, "No active breakpoints.\n");      /* no error */      return NULL;    }  while (dlite_bps != NULL)    {      /* delete first breakpoint */      delete_break(dlite_bps->id);    }  fprintf(stdout, "All breakpoints cleared.\n");  /* no error */  return NULL;}/* print the value of all program symbols */static char *					/* err str, NULL for no err */dlite_symbols(int nargs, union arg_val_t args[])/* command arguments */{  int i;  if (nargs != 0)    return "wrong number of arguments";  /* load symbols, if not already loaded */  sym_loadsyms(ld_prog_fname, /* !locals */FALSE);  /* print all symbol values */  for (i=0; i<sym_nsyms; i++)    sym_dumpsym(sym_syms[i], stdout);  /* no error */  return NULL;}/* print the value of all text symbols */static char *					/* err str, NULL for no err */dlite_tsymbols(int nargs, union arg_val_t args[])/* command arguments */{  int i;  if (nargs != 0)    return "wrong number of arguments";  /* load symbols, if not already loaded */  sym_loadsyms(ld_prog_fname, /* !locals */FALSE);  /* print all symbol values */  for (i=0; i<sym_ntextsyms; i++)    sym_dumpsym(sym_textsyms[i], stdout);  /* no error */  return NULL;}/* print the value of all text symbols */static char *					/* err str, NULL for no err */dlite_dsymbols(int nargs, union arg_val_t args[])/* command arguments */{  int i;  if (nargs != 0)    return "wrong number of arguments";  /* load symbols, if not already loaded */  sym_loadsyms(ld_prog_fname, /* !locals */FALSE);  /* print all symbol values */  for (i=0; i<sym_ndatasyms; i++)    sym_dumpsym(sym_datasyms[i], stdout);  /* no error */  return NULL;}/* print the value of all (or single) command line options */static char *					/* err str, NULL for no err */dlite_symbol(int nargs, union arg_val_t args[])	/* command arguments */{  int index;  struct sym_sym_t *sym;  if (nargs != 1)    return "wrong number of arguments";  /* load symbols, if not already loaded */  sym_loadsyms(ld_prog_fname, /* !locals */FALSE);  /* print a single option, specified by argument */  sym = sym_bind_name(args[0].as_str, &index, sdb_any);  if (!sym)    return "symbol is not defined";  /* else, print this symbols's value */  sym_dumpsym(sym_syms_by_name[index], stdout);  /* no error */  return NULL;}/* initialize the DLite debugger */voiddlite_init(dlite_reg_obj_t reg_obj,		/* register state object */	   dlite_mem_obj_t mem_obj,		/* memory state object */	   dlite_mstate_obj_t mstate_obj)	/* machine state object */{  /* architected state accessors */  f_dlite_reg_obj = reg_obj;  f_dlite_mem_obj = mem_obj;  f_dlite_mstate_obj = mstate_obj;  /* instantiate the expression evaluator */  dlite_evaluator = eval_new(ident_evaluator, NULL);}/* print a mini-state header */static voiddlite_status(SS_ADDR_TYPE regs_PC,		/* PC of just completed inst */	     SS_ADDR_TYPE next_PC,		/* PC of next inst to exec */	     SS_COUNTER_TYPE cycle,		/* current cycle */	     int dbreak)			/* last break a data break? */{  SS_INST_TYPE inst;  char *errstr;  if (dbreak)    {      fprintf(stdout, "\n");      fprintf(stdout, "Instruction (now finished) that caused data break:\n");      fprintf(stdout, "[%10.0f] 0x%08x:    ", (double)cycle, regs_PC);      errstr = f_dlite_mem_obj(at_read, regs_PC, (char *)&inst, sizeof(inst));      if (errstr)	fprintf(stdout, "<invalid memory>");      else	ss_print_insn(inst, regs_PC, stdout);      fprintf(stdout, "\n");      fprintf(stdout, "\n");    }  /* read and disassemble instruction */  fprintf(stdout, "[%10.0f] 0x%08x:    ", (double)cycle, next_PC);  errstr = f_dlite_mem_obj(at_read, next_PC, (char *)&inst, sizeof(inst));  if (errstr)    fprintf(stdout, "<invalid memory>");  else    ss_print_insn(inst, next_PC, stdout);  fprintf(stdout, "\n");}/* DLite command line prompt */#define DLITE_PROMPT		"DLite! > "/* DLite debugger main loop */voiddlite_main(SS_ADDR_TYPE regs_PC,		/* addr of last inst to exec */	   SS_ADDR_TYPE next_PC,		/* addr of next inst to exec */	   SS_COUNTER_TYPE cycle)		/* current cycle */{  char buf[512], *err_str;  int dbreak = (break_access & (ACCESS_READ|ACCESS_WRITE)) != 0;  static char cmd[512] = "";  dlite_active = TRUE;  dlite_return = FALSE;  dlite_status(regs_PC, next_PC, cycle, dbreak);  while (dlite_active && !dlite_return)    {      fprintf(stdout, DLITE_PROMPT);      fflush(stdout);      fgets(buf, 512, stdin);      /* chop */      if (buf[strlen(buf)-1] == '\n')	buf[strlen(buf)-1] = '\0';      if (buf[0] != '\0')	{	  /* use this command */	  strcpy(cmd, buf);	}      /* else, use last command */      err_str = dlite_exec(cmd);      if (err_str)	fprintf(stdout, "Dlite: error: %s\n", err_str);    }}

⌨️ 快捷键说明

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