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);

-- 

Reply via email to