This is an automated email from Gerrit.

"Matt Waltz <[email protected]>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9802

-- gerrit

commit 96102658c3289e170d2807e3e9cc5449098f2375
Author: Matthew Waltz <[email protected]>
Date:   Sat Jul 25 09:21:13 2026 -0600

    target/riscv: fix usage of triggers
    
    This fixes a bug where if the device reports more than 16 hardware 
breakpoints, OpenOCD uses what the device reports when accessing arrays such as 
trigger_unique_id.
    This can lead to out of bounds access and crash OpenOCD.
    
    Instead, we make sure that the max breakpoints supported is constrained by 
the size of the array, and then OpenOCD only uses the maximum it supports.
    Changed the maximum number of hardware breakpoints to 32 to support new 
RISC-V hardware.
    
    Change-Id: Icbcd6cec0e1e9a8a44420f87288e52fd0f3542c3
    Signed-off-by: Matthew Waltz <[email protected]>

diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 30094b34b5..96f45eb4b6 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -6313,8 +6313,10 @@ int riscv_enumerate_triggers(struct target *target)
                LOG_TARGET_DEBUG(target, "Trigger tinfo.version is unknown.");
        }
 
+       const unsigned int max_enumerated_triggers =
+               MIN(ARRAY_SIZE(r->trigger_tinfo), 
ARRAY_SIZE(r->trigger_unique_id));
        unsigned int t = 0;
-       for (; t < ARRAY_SIZE(r->trigger_tinfo); ++t) {
+       for (; t < max_enumerated_triggers; ++t) {
                result = check_if_trigger_exists(target, t);
                if (result == ERROR_FAIL)
                        return ERROR_FAIL;
@@ -6338,12 +6340,29 @@ int riscv_enumerate_triggers(struct target *target)
                        return ERROR_FAIL;
        }
 
+       unsigned int reported_trigger_count = t;
+       if (reported_trigger_count == max_enumerated_triggers) {
+               for (;;) {
+                       result = check_if_trigger_exists(target, 
reported_trigger_count);
+                       if (result == ERROR_FAIL)
+                               return ERROR_FAIL;
+                       if (result == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+                               break;
+                       ++reported_trigger_count;
+               }
+
+               if (reported_trigger_count > max_enumerated_triggers)
+                       LOG_TARGET_WARNING(target, "Target reports %u hardware 
breakpoint "
+                                       "triggers; OpenOCD supports only %u. 
Ignoring remaining triggers.",
+                                       reported_trigger_count, 
max_enumerated_triggers);
+       }
+
        if (riscv_reg_set(target, GDB_REGNO_TSELECT, orig_tselect) != ERROR_OK)
                return ERROR_FAIL;
 
        r->triggers_enumerated = true;
        r->trigger_count = t;
-       LOG_TARGET_INFO(target, "Found %d triggers", r->trigger_count);
+       LOG_TARGET_INFO(target, "Found %d usable triggers", r->trigger_count);
        free(r->reserved_triggers);
        r->reserved_triggers = calloc(t, sizeof(*r->reserved_triggers));
        create_wp_trigger_cache(target);
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 2a0a9b95f0..c482ba3295 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -19,7 +19,7 @@ struct riscv_program;
 
 #define RISCV_MAX_HARTS  ((int)BIT(20))
 #define RISCV_MAX_TRIGGERS 32
-#define RISCV_MAX_HWBPS 16
+#define RISCV_MAX_HWBPS 32
 #define RISCV_MAX_DMS 100
 
 #define DEFAULT_COMMAND_TIMEOUT_SEC 5

-- 

Reply via email to