> compile NEMU

221220000 张三
Linux zzy 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
 13:13:10 up 1 day, 12:03,  1 user,  load average: 0.41, 0.23, 0.13
This commit is contained in:
tracer-ics2023
2024-09-01 13:13:11 +08:00
committed by zzy
parent 646495f529
commit 1f5fbebd46
5 changed files with 149 additions and 24 deletions

View File

@ -1,5 +1,14 @@
mainmenu "NEMU Configuration Menu"
menu "NEMU Configuration Options"
config CONFIG_WATCHPOINT
bool "Enable Watchpoint"
default n
help
Say Y here if you want to enable watchpoint functionality.
This will add performance overhead but is useful for debugging.
endmenu
choice
prompt "Base ISA"
default ISA_riscv

View File

@ -38,6 +38,15 @@ static void trace_and_difftest(Decode *_this, vaddr_t dnpc) {
#endif
if (g_print_step) { IFDEF(CONFIG_ITRACE, puts(_this->logbuf)); }
IFDEF(CONFIG_DIFFTEST, difftest_step(_this->pc, dnpc));
#ifdef CONFIG_WATCHPOINT
bool wp_check_hit(void);
if (wp_check_hit()) {
printf("watchpoint hit\n");
isa_reg_display();
nemu_state.state = NEMU_STOP;
}
#endif
}
static void exec_once(Decode *s, vaddr_t pc) {

View File

@ -42,21 +42,21 @@ static struct rule {
int token_type;
} rules[] = {
{" +", TK_NOTYPE}, // spaces
{"\\+", '+'}, // plus
{"==", TK_EQ}, // equal
{"\\!=", TK_NEQ}, // not equal
{"\\&\\&", TK_AND}, // and
{" +", TK_NOTYPE}, // spaces
{"\\+", '+'}, // plus
{"==", TK_EQ}, // equal
{"\\!=", TK_NEQ}, // not equal
{"\\&\\&", TK_AND}, // and
{"-", '-'}, // sub
{"\\*", '*'}, // mul
{"/", '/'}, // div
{"\\(", '('}, // (
{"\\)", ')'}, // )
{"-", '-'}, // sub
{"\\*", '*'}, // mul
{"/", '/'}, // div
{"\\(", '('}, // (
{"\\)", ')'}, // )
{"0[xX][0-9a-fA-F]+", TK_HEX}, // hex number
{"[0-9]+", TK_DEC}, // dec number
{"\\$[0-9a-z]+", TK_REG}, // register
{"0[xX][0-9a-fA-F]+", TK_HEX}, // hex number
{"[0-9]+", TK_DEC}, // dec number
{"\\$[0-9a-z]+", TK_REG}, // register
};
#define NR_REGEX ARRLEN(rules)
@ -266,8 +266,8 @@ uint32_t eval(const Token* arr, int p, int q, bool* success) {
case TK_EQ: return val_l == val_r;
case TK_NEQ: return val_l != val_r;
case TK_AND: return val_l && val_r;
case '+': return val_l + val_r;
case '-': return val_l - val_r;
case '+': return (uint32_t)val_l + (uint32_t)val_r;
case '-': return (uint32_t)val_l - (uint32_t)val_r;
case '*': return val_l * val_r;
case '/': return val_l / val_r;
default: *success &= false; return 0;

View File

@ -90,12 +90,14 @@ static int cmd_x(char *args) {
char *arg0 = strtok(NULL, " ");
char *arg1 = strtok(NULL, " ");
if (arg0 == NULL || arg1 == NULL) {
goto END;
goto ERROR;
}
vaddr_t addr = 0;
if (!sscanf(arg1, FMT_PADDR, &addr)) {
goto END;
bool success = true;
expr(arg1, &success);
if (!success) {
goto ERROR;
}
size_t N = atoi(arg0);
@ -106,7 +108,7 @@ static int cmd_x(char *args) {
addr += 4;
}
return 0;
END:
ERROR:
p_help("x");
return 0;
}
@ -119,12 +121,50 @@ static int cmd_p(char *args) {
} else {
printf("Invalid expression\n");
}
return success;
return !success;
}
static int cmd_w(char *args) { return 0; }
static int cmd_d(char *args) { return 0; }
typedef void WP;
WP* new_wp(char* expr, int len);
WP* get_wp(int NO);
void free_wp(WP* wp);
static int cmd_w(char *args) {
char*arg = strtok(NULL, " ");
if (arg == NULL) {
goto ERROR;
}
if (new_wp(arg, strlen(arg)) != NULL) {
printf("Watchpoint Set Failure\n");
goto ERROR;
}
return 0;
ERROR:
p_help("w");
return 1;
}
static int cmd_d(char *args) {
char* arg = strtok(NULL, " ");
if (arg == NULL) {
goto ERROR;
}
int number = atoi(arg);
if (number == 0 && arg[0] != '0') {
printf("Invalid watchpoint number\n");
goto ERROR;
}
WP* wp = get_wp(number);
if (wp == NULL) {
printf("No such watchpoint\n");
goto ERROR;
}
free_wp(wp);
return 0;
ERROR:
p_help("d");
return 1;
}
static struct {
const char *name;

View File

@ -18,11 +18,13 @@
#define NR_WP 32
typedef struct watchpoint {
struct watchpoint *next; // can use WP** to access the next element
int NO;
struct watchpoint *next;
/* TODO: Add more members if necessary */
word_t val;
bool hit;
char expr[65532];
} WP;
static WP wp_pool[NR_WP] = {};
@ -33,6 +35,9 @@ void init_wp_pool() {
for (i = 0; i < NR_WP; i ++) {
wp_pool[i].NO = i;
wp_pool[i].next = (i == NR_WP - 1 ? NULL : &wp_pool[i + 1]);
wp_pool[i].hit = false;
wp_pool[i].expr[0] = '\0';
}
head = NULL;
@ -41,3 +46,65 @@ void init_wp_pool() {
/* TODO: Implement the functionality of watchpoint */
bool wp_check_hit(void) {
bool res = false;
for (WP* tmp = head; tmp != NULL; tmp = tmp->next) {
bool success = true;
word_t val = expr(tmp->expr, &success);
assert(success);
if (val != tmp->val) {
tmp->hit = true;
tmp->val = val;
res = true;
}
}
return res;
}
static WP* del_wp(WP* head, WP* pos) {
for (WP** i = &head; (*i) != NULL && (*i)->next != NULL; i = (WP**)*i) {
if ((**i).NO == pos->NO) {
WP* res = *i;
*i = (**i).next;
return res;
}
}
return NULL;
}
#define MIN(x, y) ((x) < (y) ? (x) : (y))
WP* new_wp(char* _expr, int len) {
bool success = true;
word_t val = expr(_expr, &success);
if (!success) {
return NULL;
}
WP* wp = del_wp(free_, free_);
if (wp == NULL) {
assert(0);
}
wp->next = head;
head = wp;
strncpy(wp->expr, _expr, MIN(sizeof(wp->expr), len));
wp->val = val;
return head;
}
WP* get_wp(int NO) {
for (WP* tmp = head; tmp != NULL; tmp = tmp->next) {
if (tmp->NO == NO) {
return tmp;
}
}
return NULL;
}
void free_wp(WP *_wp) {
WP* wp = del_wp(head, _wp);
wp->next = free_;
free_ = wp;
wp->expr[0] = '\0';
wp->hit = false;
wp->val = 0;
}