dlite.c
来自「一个很有名的硬件模拟器。可以模拟CPU」· C语言 代码 · 共 2,262 行 · 第 1/4 页
C
2,262 行
dlite_step_into = FALSE; /* no error */ return NULL;}#endif/* print the value of <expr> using format <modifiers> */static char * /* err str, NULL for no err */dlite_print(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ int modifiers = 0; char *err_str; struct eval_value_t val; if (nargs != 1 && nargs != 2) return "wrong number of arguments"; if (nargs == 2) { /* arguments include modifiers and expression value */ modifiers = args[0].as_modifier; val = args[1].as_value; } else { /* arguments include only expression value */ val = args[0].as_value; } /* print expression value */ err_str = print_val(modifiers, val); if (err_str) return err_str; fprintf(stdout, "\n"); /* no error */ return NULL;}/* print the value of all command line options */static char * /* err str, NULL for no err */dlite_options(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 "wrong number of arguments"; /* print all options */ opt_print_options(sim_odb, stdout, /* terse */TRUE, /* !notes */FALSE); /* no error */ return NULL;}/* print the value of all (or single) command line options */static char * /* err str, NULL for no err */dlite_option(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ struct opt_opt_t *opt; if (nargs != 1) return "wrong number of arguments"; /* print a single option, specified by argument */ opt = opt_find_option(sim_odb, args[0].as_str); if (!opt) return "option is not defined"; /* else, print this option's value */ fprintf(stdout, "%-16s ", opt->name); opt_print_option(opt, stdout); if (opt->desc) fprintf(stdout, " # %s", opt->desc); fprintf(stdout, "\n"); /* no error */ return NULL;}/* print the value of all statistical variables */static char * /* err str, NULL for no err */dlite_stats(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 "wrong number of arguments"; /* print all options */ stat_print_stats(sim_sdb, stdout); sim_aux_stats(stdout); /* no error */ return NULL;}/* print the value of a statistical variable */static char * /* err str, NULL for no err */dlite_stat(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ struct stat_stat_t *stat; if (nargs != 1) return "wrong number of arguments"; /* print a single option, specified by argument */ stat = stat_find_stat(sim_sdb, args[0].as_str); if (!stat) return "statistical variable is not defined"; /* else, print this option's value */ stat_print_stat(sim_sdb, stat, stdout); /* no error */ return NULL;}/* print the type of expression <expr> */static char * /* err str, NULL for no err */dlite_whatis(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 != 1) return "wrong number of arguments"; fprintf(stdout, "type == `%s'\n", eval_type_str[args[0].as_value.type]); /* no error */ return NULL;}/* print integer register contents */static char * /* err str, NULL for no err */dlite_iregs(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ char *err_str; if (nargs != 0) return "too many arguments"; /* print integer registers */ myfprintf(stdout, "PC: 0x%08p NPC: 0x%08p\n", regs->regs_PC, regs->regs_NPC); if ((err_str = dlite_cregs(nargs, args, regs, mem)) != NULL) return err_str; md_print_iregs(regs->regs_R, stdout); /* no error */ return NULL;}/* print floating point register contents */static char * /* err str, NULL for no err */dlite_fpregs(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ /* print floating point registers */ md_print_fpregs(regs->regs_F, stdout); /* no error */ return NULL;}/* print floating point register contents */static char * /* err str, NULL for no err */dlite_cregs(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ /* print floating point registers */ md_print_cregs(regs->regs_C, stdout); /* no error */ return NULL;}/* print all register contents */static char * /* err str, NULL for no err */dlite_regs(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ char *err_str; myfprintf(stdout, "PC: 0x%08p NPC: 0x%08p\n", regs->regs_PC, regs->regs_NPC); if ((err_str = dlite_cregs(nargs, args, regs, mem)) != NULL) return err_str; md_print_iregs(regs->regs_R, stdout); dlite_pause(); if ((err_str = dlite_fpregs(nargs, args, regs, mem)) != NULL) return err_str; /* no error */ return NULL;}/* print machine specific state (simulator dependent) */static char * /* err str, NULL for no err */dlite_mstate(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ char *errstr; if (nargs != 0 && nargs != 1) return "too many arguments"; if (f_dlite_mstate_obj) { if (nargs == 0) { errstr = f_dlite_mstate_obj(stdout, NULL, regs, mem); if (errstr) return errstr; } else { errstr = f_dlite_mstate_obj(stdout, args[0].as_str, regs, mem); if (errstr) return errstr; } } /* no error */ return NULL;}/* display the value at memory location <addr> using format <modifiers> */static char * /* err str, NULL for no err */dlite_display(int nargs, union arg_val_t args[],/* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ int modifiers, size; md_addr_t addr; unsigned char buf[512]; struct eval_value_t val; char *errstr; if (nargs != 1 && nargs != 2) return "wrong number of arguments"; if (nargs == 1) { /* no modifiers */ modifiers = 0; /* check address */ if (!EVAL_INTEGRAL(args[0].as_value.type)) return "address argument must be an integral type"; /* reset address */ addr = eval_as_addr(args[0].as_value); } else if (nargs == 2) { modifiers = args[0].as_modifier; /* check address */ if (!EVAL_INTEGRAL(args[1].as_value.type)) return "address argument must be an integral type"; /* reset address */ addr = eval_as_addr(args[1].as_value); } /* determine operand size */ if (modifiers & (MOD_BYTE|MOD_CHAR)) size = 1; else if (modifiers & MOD_HALF) size = 2; else if (modifiers & (MOD_QWORD|MOD_DOUBLE)) size = 8; else /* no modifiers, or MOD_WORD|MOD_FLOAT */ size = 4; /* read memory */ errstr = f_dlite_mem_obj(mem, /* !is_write */FALSE, addr, (char *)buf, size); if (errstr) return errstr; /* marshall a value */ if (modifiers & (MOD_BYTE|MOD_CHAR)) { /* size == 1 */ val.type = et_int; val.value.as_int = (int)*(unsigned char *)buf; } else if (modifiers & MOD_HALF) { /* size == 2 */ val.type = et_int; val.value.as_int = (int)*(unsigned short *)buf; } else if (modifiers & (MOD_QWORD|MOD_DOUBLE)) { /* size == 8 */ val.type = et_double; val.value.as_double = *(double *)buf; } else /* no modifiers, or MOD_WORD|MOD_FLOAT */ { /* size == 4 */ val.type = et_uint; val.value.as_uint = *(unsigned int *)buf; } /* print the value */ errstr = print_val(modifiers, val); if (errstr) return errstr; fprintf(stdout, "\n"); /* no error */ return NULL;}/* `dump' command print format */#define BYTES_PER_LINE 16 /* must be a power of two */#define LINES_PER_SCREEN 4/* dump the contents of memory to screen */static char * /* err str, NULL for no err */dlite_dump(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ int i, j; int count = LINES_PER_SCREEN * BYTES_PER_LINE, i_count, fmt_count, fmt_lines; md_addr_t fmt_addr, i_addr; static md_addr_t addr = 0; unsigned char byte; char buf[512]; char *errstr; if (nargs < 0 || nargs > 2) return "too many arguments"; if (nargs == 1) { /* check address */ if (!EVAL_INTEGRAL(args[0].as_value.type)) return "address argument must be an integral type"; /* reset PC */ addr = eval_as_addr(args[0].as_value); } else if (nargs == 2) { /* check address */ if (!EVAL_INTEGRAL(args[0].as_value.type)) return "address argument must be an integral type"; /* reset addr */ addr = eval_as_addr(args[0].as_value); /* check count */ if (!EVAL_INTEGRAL(args[1].as_value.type)) return "count argument must be an integral type"; if (eval_as_uint(args[1].as_value) > 1024) return "bad count argument"; /* reset count */ count = eval_as_uint(args[1].as_value); } /* else, nargs == 0, use addr, count */ /* normalize start address and count */ fmt_addr = addr & ~(BYTES_PER_LINE - 1); fmt_count = (count + (BYTES_PER_LINE - 1)) & ~(BYTES_PER_LINE - 1); fmt_lines = fmt_count / BYTES_PER_LINE; if (fmt_lines < 1) panic("no output lines"); /* print dump */ if (fmt_lines == 1) { /* unformatted dump */ i_addr = fmt_addr; myfprintf(stdout, "0x%08p: ", i_addr); for (i=0; i < count; i++) { errstr = f_dlite_mem_obj(mem, /* !is_write */FALSE, i_addr, (char *)&byte, 1); if (errstr) return errstr; fprintf(stdout, "%02x ", byte); if (isprint(byte)) buf[i] = byte; else buf[i] = '.'; i_addr++; addr++; } buf[i] = '\0'; /* character view */ fprintf(stdout, "[%s]\n", buf); } else /* lines > 1 */ { i_count = 0; i_addr = fmt_addr; for (i=0; i < fmt_lines; i++) { myfprintf(stdout, "0x%08p: ", i_addr); /* byte view */ for (j=0; j < BYTES_PER_LINE; j++) { if (i_addr >= addr && i_count <= count) { errstr = f_dlite_mem_obj(mem, /* !is_write */FALSE, i_addr, (char *)&byte, 1); if (errstr) return errstr; fprintf(stdout, "%02x ", byte); if (isprint(byte)) buf[j] = byte; else buf[j] = '.'; i_count++; addr++; } else { fprintf(stdout, " "); buf[j] = ' '; } i_addr++; } buf[j] = '\0'; /* character view */ fprintf(stdout, "[%s]\n", buf); } } /* no error */ return NULL;}/* disassembler print format */#define INSTS_PER_SCREEN 16/* disassemble instructions at specified address */static char * /* err str, NULL for no err */dlite_dis(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ int i; int count = INSTS_PER_SCREEN; static md_addr_t addr = 0; md_inst_t inst; char *errstr; if (nargs < 0 || nargs > 2) return "too many arguments"; if (nargs == 1) { /* check address */ if (!EVAL_INTEGRAL(args[0].as_value.type)) return "address argument must be an integral type"; /* reset PC */ addr = eval_as_addr(args[0].as_value); } else if (nargs == 2) { /* check address */ if (!EVAL_INTEGRAL(args[0].as_value.type)) return "address argument must be an integral type"; /* reset addr */ addr = eval_as_addr(args[0].as_value); /* check count */ if (!EVAL_INTEGRAL(args[0].as_value.type)) return "count argument must be an integral type"; /* reset count */ count = eval_as_uint(args[1].as_value); if (count < 0 || count > 1024) return "bad count argument"; } /* else, nargs == 0, use addr, count */ if ((addr % sizeof(md_inst_t)) != 0) return "instruction addresses are a multiple of eight"; /* disassemble COUNT insts at ADDR */ for (i=0; i<count; i++) { /* read and disassemble instruction */ myfprintf(stdout, " 0x%08p: ", addr); errstr = f_dlite_mem_obj(mem, /* !is_write */FALSE, addr, (char *)&inst, sizeof(inst)); inst = MD_SWAPI(inst); if (errstr) return errstr; md_print_insn(inst, addr, stdout); fprintf(stdout, "\n"); /* go to next instruction */ addr += sizeof(md_inst_t); } /* 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");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?