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