diff --git a/nemu/include/debug.h b/nemu/include/debug.h index f60e6f9..835f8dc 100644 --- a/nemu/include/debug.h +++ b/nemu/include/debug.h @@ -48,4 +48,6 @@ #define TODO() panic("please implement me") + + #endif diff --git a/nemu/src/cpu/cpu-exec.c b/nemu/src/cpu/cpu-exec.c index 0c244ea..e91b4c8 100644 --- a/nemu/src/cpu/cpu-exec.c +++ b/nemu/src/cpu/cpu-exec.c @@ -31,6 +31,7 @@ static uint64_t g_timer = 0; // unit: us static bool g_print_step = false; void device_update(); +void wp_eval_all(); static void trace_and_difftest(Decode *_this, vaddr_t dnpc) { #ifdef CONFIG_ITRACE_COND @@ -113,6 +114,8 @@ void cpu_exec(uint64_t n) { uint64_t timer_end = get_time(); g_timer += timer_end - timer_start; + wp_eval_all(); + switch (nemu_state.state) { case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break; diff --git a/nemu/src/monitor/sdb/watchpoint.c b/nemu/src/monitor/sdb/watchpoint.c index f84bed8..cbe1b74 100644 --- a/nemu/src/monitor/sdb/watchpoint.c +++ b/nemu/src/monitor/sdb/watchpoint.c @@ -13,8 +13,8 @@ * See the Mulan PSL v2 for more details. ***************************************************************************************/ -#include "common.h" #include "sdb.h" +#include #include #define NR_WP 32 @@ -27,8 +27,8 @@ typedef struct watchpoint { } WP; static WP wp_pool[NR_WP] = {}; -static WP *head = NULL, *tail = NULL, *free_ = NULL; -static int wp_count = 0; +static WP *head = NULL, *free_ = NULL; +// static int wp_count = 0; void init_wp_pool() { int i; @@ -41,77 +41,87 @@ void init_wp_pool() { free_ = wp_pool; } -WP *wp_new() { - if (free_ == NULL) { - Error("wp_pool: Watchpoint pool not initialized or is full."); - return NULL; - } +// static WP *wp_new() { +// if (free_ == NULL) { +// Error("wp_pool: Watchpoint pool not initialized or is full."); +// return NULL; +// } - WP *ret = free_; - free_ = free_->next; +// WP *ret = free_; +// free_ = free_->next; - ret->NO = 0; - ret->next = NULL; - return ret; -} - -void wp_delete(WP *wp) { - assert(wp); - wp->next = free_; - free_ = wp; -} - -int wp_add(char * expr) { - WP *wp = wp_new(); - if (wp == NULL) { - Error("watchpoint: Failed to add watchpoint, pool is full."); - return 1; - } - - wp->NO = wp_count++; - if (tail == NULL) { - head = wp; - tail = wp; - } else { - tail->next = wp; - tail = wp; - } - return 0; -} - -int wp_remove_by_number(int number) { - WP *target_prev; - // Find previous node of target number - for (target_prev = head; target_prev != NULL && target_prev->next->NO != number; target_prev = target_prev->next) ; - if (target_prev == NULL) { - Error("Watchpoint not found, you can check current watchpoints with `info w`"); - return 1; - } - WP *target = target_prev->next; - target_prev->next = target->next; - if (target == head) { - head = target->next; - } else if (target == tail) { - tail = target_prev; - } - wp_delete(target); - return 0; -} - -// int wp_eval(WP* wp) { -// bool success = false; -// word_t result; - -// result = parse_expr(wp->expr, &success); -// if (!success) { - -// } +// ret->NO = 0; +// ret->next = NULL; +// return ret; // } +// static void wp_delete(WP *wp) { +// assert(wp); +// wp->next = free_; +// free_ = wp; +// } + +// static int wp_add(char * expr) { +// WP *wp = wp_new(); +// if (wp == NULL) { +// Error("watchpoint: Failed to add watchpoint, pool is full."); +// return 1; +// } + +// wp->NO = wp_count++; +// if (tail == NULL) { +// head = wp; +// tail = wp; +// } else { +// tail->next = wp; +// tail = wp; +// } +// return 0; +// } + +// static int wp_remove_by_number(int number) { +// WP *target_prev; +// // Find previous node of target number +// for (target_prev = head; target_prev != NULL && target_prev->next->NO != number; target_prev = target_prev->next) ; +// if (target_prev == NULL) { +// Error("Watchpoint not found, you can check current watchpoints with `info w`"); +// return 1; +// } +// WP *target = target_prev->next; +// target_prev->next = target->next; +// if (target == head) { +// head = target->next; +// } else if (target == tail) { +// tail = target_prev; +// } +// wp_delete(target); +// return 0; +// } + +static bool wp_check_change(WP* wp) { + bool success = false; + word_t result; + + result = parse_expr(wp->expr, &success); + if (!success) { + panic("Failed to evaluate %s", wp->expr); + } + if (result != wp->val) { + wp->val = result; + return true; + } + return false; +} + /* Check if watchpoint value changed after execution */ -// int wp_eval_all() { -// } - -/* TODO: Implement the functionality of watchpoint */ +void wp_eval_all() { + WP *wp; + for (wp = head; wp != NULL; wp = wp->next) { + int prev_val = wp->val; + if (wp_check_change(wp)) { + printf("Watchpoint %d: %s\n %u -> %u\n", wp->NO, wp->expr, prev_val, wp->val); + } + } +}