This is an automated email from Gerrit. "Antonio Borneo <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9560
-- gerrit commit 979cf67d1ecf74651ae4e1dcba77cbf9202f5c86 Author: Antonio Borneo <[email protected]> Date: Fri Apr 3 10:51:57 2026 +0200 watchpoint: consolidate search for hit watchpoint Move the code of watchpoint_hit() inside target_hit_watchpoint() to make the latter more generic and reusable beyond the needs of the gdb server. Add a new watchpoint_read() to extract from the watchpoint the specific data needed by the gdb server. Change-Id: Iad71417ef648120bdfcf5e4790e6bc9132700eb2 Signed-off-by: Antonio Borneo <[email protected]> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index f59eb5029e..f04ebfb0f7 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -831,11 +831,13 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio stop_reason[0] = '\0'; if (ct->debug_reason == DBG_REASON_WATCHPOINT) { + struct watchpoint *wp; enum watchpoint_rw hit_wp_type; target_addr_t hit_wp_address; - if (watchpoint_hit(ct, &hit_wp_type, &hit_wp_address) == ERROR_OK) { - + int retval = target_hit_watchpoint(ct, &wp); + if (retval == ERROR_OK) { + watchpoint_read(wp, &hit_wp_type, &hit_wp_address); switch (hit_wp_type) { case WPT_WRITE: snprintf(stop_reason, sizeof(stop_reason), diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index d260009f5a..54af681df0 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -624,36 +624,10 @@ int watchpoint_remove(struct target *target, target_addr_t address) return retval; } -int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, - target_addr_t *address) +/* report type and address of the watchpoint */ +void watchpoint_read(const struct watchpoint *watchpoint, + enum watchpoint_rw *rw, target_addr_t *address) { - int retval; - struct watchpoint *hit_watchpoint; - - retval = target_hit_watchpoint(target, &hit_watchpoint); - if (retval == ERROR_NOT_IMPLEMENTED - && target->debug_reason == DBG_REASON_WATCHPOINT) { - // Handle the trivial case: only one watchpoint is set - unsigned int cnt = 0; - struct watchpoint *wp = target->watchpoints; - while (wp) { - cnt++; - wp = wp->next; - } - if (cnt == 1) { - retval = ERROR_OK; - hit_watchpoint = target->watchpoints; - } - } - if (retval != ERROR_OK) - return ERROR_FAIL; - - *rw = hit_watchpoint->rw; - *address = hit_watchpoint->address; - - LOG_TARGET_DEBUG(target, "Found hit watchpoint at " TARGET_ADDR_FMT " (WPID: %d)", - hit_watchpoint->address, - hit_watchpoint->unique_id); - - return ERROR_OK; + *rw = watchpoint->rw; + *address = watchpoint->address; } diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h index d547a687fd..f1924a8ab0 100644 --- a/src/target/breakpoints.h +++ b/src/target/breakpoints.h @@ -74,9 +74,9 @@ int watchpoint_add(struct target *target, int watchpoint_remove(struct target *target, target_addr_t address); int watchpoint_remove_all(struct target *target); -/* report type and address of just hit watchpoint */ -int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, - target_addr_t *address); +/* report type and address of the watchpoint */ +void watchpoint_read(const struct watchpoint *watchpoint, + enum watchpoint_rw *rw, target_addr_t *address); static inline void watchpoint_set(struct watchpoint *watchpoint, unsigned int number) { diff --git a/src/target/target.c b/src/target/target.c index f766d1da43..3abeaf43a2 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1358,22 +1358,38 @@ int target_remove_watchpoint(struct target *target, { return target->type->remove_watchpoint(target, watchpoint); } + int target_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint) { + struct watchpoint *wp; + if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "not halted (hit watchpoint)"); return ERROR_TARGET_NOT_HALTED; } - if (!target->type->hit_watchpoint) { - /* For backward compatible, if hit_watchpoint is not implemented, - * return error such that gdb_server will not take the nonsense - * information. */ - return ERROR_NOT_IMPLEMENTED; + if (target->type->hit_watchpoint) { + int retval = target->type->hit_watchpoint(target, &wp); + if (retval == ERROR_OK) + goto out_ok; + + if (retval != ERROR_NOT_IMPLEMENTED) + return retval; } - return target->type->hit_watchpoint(target, hit_watchpoint); + // Handle the trivial case: only one watchpoint is set + wp = target->watchpoints; + if (!wp || wp->next) + return ERROR_FAIL; + +out_ok: + LOG_TARGET_DEBUG(target, + "Found hit watchpoint at " TARGET_ADDR_FMT " (WPID: %d)", + wp->address, wp->unique_id); + + *hit_watchpoint = wp; + return ERROR_OK; } const char *target_get_gdb_arch(const struct target *target) diff --git a/src/target/target.h b/src/target/target.h index 2b66dd741c..d6b710db37 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -487,8 +487,12 @@ int target_remove_watchpoint(struct target *target, /** * Find out the just hit @a watchpoint for @a target. + * @param target The target to query + * @param watchpoint The hit watchpoint + * @return ERROR_OK if the hit watchpoint is detected, otherwise error * - * This routine is a wrapper for target->type->hit_watchpoint. + * This is a wrapper for @a target->type->hit_watchpoint + * and handles the trivial case of a single watchpoint set. */ int target_hit_watchpoint(struct target *target, struct watchpoint **watchpoint); --
