diff --git a/src/helper/util.c b/src/helper/util.c index 2e9f6155e..1ced8bd5f 100644 --- a/src/helper/util.c +++ b/src/helper/util.c @@ -40,3 +40,26 @@ int util_init(struct command_context *cmd_ctx) { return register_commands(cmd_ctx, NULL, util_command_handlers); } + +bool is_memory_regions_overlap(target_addr_t start1, + unsigned int size1, + target_addr_t start2, + unsigned int size2) +{ + /* Two memory regions: [S1,E1] and [S2,E2] where: + * E1 = S1 + size1 - 1, E2 = S2 + size2 - 1 + * + * After normalization: + * Region 1: [0, size1 - 1] + * Region 2: [start2 - start1, (start2 - start1) + size2 - 1] + * + * Intersection cases: + * 1. Normalized region 2 wraps around 0 (unsigned overflow) + * 2. Start of normalized region 2 is within region 1 + */ + start2 -= start1; + target_addr_t end1 = size1 - 1; + target_addr_t end2 = start2 + size2 - 1; + + return start2 > end2 || start2 <= end1; +} diff --git a/src/helper/util.h b/src/helper/util.h index 3ccdc4fdf..c10135678 100644 --- a/src/helper/util.h +++ b/src/helper/util.h @@ -10,5 +10,7 @@ struct command_context; int util_init(struct command_context *cmd_ctx); +bool is_memory_regions_overlap(target_addr_t start1, unsigned int size1, + target_addr_t start2, unsigned int size2); #endif /* OPENOCD_HELPER_UTIL_H */ diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index 753c343c5..d260009f5 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -16,6 +16,7 @@ #include #include "breakpoints.h" #include "smp.h" +#include "helper/util.h" enum breakpoint_watchpoint { BREAKPOINT, @@ -56,6 +57,13 @@ static int breakpoint_add_internal(struct target *target, address, breakpoint->unique_id); return ERROR_TARGET_DUPLICATE_BREAKPOINT; } + if (type == BKPT_SOFT && + is_memory_regions_overlap(address, length, breakpoint->address, breakpoint->length)) { + LOG_TARGET_ERROR(target, "Breakpoint intersects with another one at " TARGET_ADDR_FMT + " of length %u (BP %" PRIu32 ")", breakpoint->address, + breakpoint->length, breakpoint->unique_id); + return ERROR_TARGET_INTERSECT_BREAKPOINT; + } breakpoint_p = &breakpoint->next; breakpoint = breakpoint->next; } diff --git a/src/target/target.h b/src/target/target.h index 94e6aa335..3e202ffa6 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -796,6 +796,7 @@ int target_profiling_default(struct target *target, uint32_t *samples, uint32_t #define ERROR_TARGET_SIZE_NOT_SUPPORTED (-314) #define ERROR_TARGET_PACKING_NOT_SUPPORTED (-315) #define ERROR_TARGET_HALTED_DO_RESUME (-316) /* used to workaround incorrect debug halt */ +#define ERROR_TARGET_INTERSECT_BREAKPOINT (-317) extern bool get_target_reset_nag(void);