From 515e7be314069d05e855f8abddebe584accaf78b Mon Sep 17 00:00:00 2001 From: tracer-ysyx Date: Thu, 8 Feb 2024 18:43:12 +0800 Subject: [PATCH] =?UTF-8?q?>=20compile=20NEMU=20ysyx=5F22040000=20?= =?UTF-8?q?=E6=9D=8E=E5=BF=83=E6=9D=A8=20Linux=20calcite=206.1.75=20#1-Nix?= =?UTF-8?q?OS=20SMP=20PREEMPT=5FDYNAMIC=20Thu=20Jan=2025=2023:27:52=20UTC?= =?UTF-8?q?=202024=20x86=5F64=20GNU/Linux=20=2018:43:12=20=20up=201=20day?= =?UTF-8?q?=20=204:19,=20=202=20users,=20=20load=20average:=201.84,=201.38?= =?UTF-8?q?,=200.75?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nemu/src/monitor/sdb/sdb.c | 14 ++++ nemu/src/monitor/sdb/sdb.h | 2 + nemu/src/monitor/sdb/watchpoint.c | 104 +++++++++++++++--------------- 3 files changed, 68 insertions(+), 52 deletions(-) diff --git a/nemu/src/monitor/sdb/sdb.c b/nemu/src/monitor/sdb/sdb.c index 8d4df29..aa646dd 100644 --- a/nemu/src/monitor/sdb/sdb.c +++ b/nemu/src/monitor/sdb/sdb.c @@ -32,6 +32,7 @@ static int is_batch_mode = false; static int cmd_help(char *args); static int cmd_c(char *args); static int cmd_q(char *args); +static int cmd_w(char *args); static int cmd_x(char *args); static int cmd_si(char *args); static int cmd_info(char *args); @@ -55,6 +56,7 @@ static struct CommandTable { {"c", "Continue the execution of the program", cmd_c, NULL, 0}, {"q", "Exit NEMU", cmd_q, NULL, 0}, {"x", "Examine content of physical memory address", cmd_x, NULL, 0}, + {"w", "Break when expression is changed", cmd_w, NULL, 0}, {"si", "Execute next [n] program line", cmd_si, NULL, 0}, {"info", "Print information of registers or watchpoints", cmd_info, cmd_info_table, ARRLEN(cmd_info_table)}, @@ -181,6 +183,18 @@ static int cmd_info_w(char *args) { return 0; } +static int cmd_w(char *args) { + char *expr = strtok(NULL, " "); + bool success = false; + parse_expr(expr, &success); + if (!success) { + Error("Failed to parse given expression %s", expr); + return 0; + } + wp_add(expr); + return 0; +} + static int cmd_x(char *args) { char *arg = strtok(NULL, " "); bool res = false; diff --git a/nemu/src/monitor/sdb/sdb.h b/nemu/src/monitor/sdb/sdb.h index d83d2c6..883f1b6 100644 --- a/nemu/src/monitor/sdb/sdb.h +++ b/nemu/src/monitor/sdb/sdb.h @@ -19,5 +19,7 @@ #include word_t parse_expr(const char *arg, bool *success); +int wp_add(char * expr); +int wp_remove_by_number(int number); #endif diff --git a/nemu/src/monitor/sdb/watchpoint.c b/nemu/src/monitor/sdb/watchpoint.c index cbe1b74..bd03030 100644 --- a/nemu/src/monitor/sdb/watchpoint.c +++ b/nemu/src/monitor/sdb/watchpoint.c @@ -27,8 +27,8 @@ typedef struct watchpoint { } WP; static WP wp_pool[NR_WP] = {}; -static WP *head = NULL, *free_ = NULL; -// static int wp_count = 0; +static WP *head = NULL, *tail = NULL, *free_ = NULL; +static int wp_count = 0; void init_wp_pool() { int i; @@ -41,62 +41,62 @@ void init_wp_pool() { free_ = wp_pool; } -// static 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; -// } + ret->NO = 0; + ret->next = NULL; + return ret; +} -// static void wp_delete(WP *wp) { -// assert(wp); -// wp->next = free_; -// free_ = wp; -// } +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; -// } +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; -// } + 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; -// } +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;