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 + -
显示快捷键?