Skip to content

Commit

Permalink
breakpoints: add rwp all command
Browse files Browse the repository at this point in the history
This patch adds the "all" option to the rwp command.
It removes all watchpoints, much like rbp all removes
all breakpoints.

Change-Id: Id58dd103085e558f17afa4a287888cf085566ca9
Signed-off-by: Marek Vrbka <[email protected]>
Reviewed-on: https://review.openocd.org/c/openocd/+/7907
Tested-by: jenkins
Reviewed-by: Antonio Borneo <[email protected]>
  • Loading branch information
MarekVCodasip authored and borneoa committed Oct 14, 2023
1 parent 2c8c2cb commit eba5d21
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 41 deletions.
4 changes: 2 additions & 2 deletions doc/openocd.texi
Original file line number Diff line number Diff line change
Expand Up @@ -9358,8 +9358,8 @@ for similar mechanisms that do not consume hardware breakpoints.)
Remove the breakpoint at @var{address} or all breakpoints.
@end deffn

@deffn {Command} {rwp} address
Remove data watchpoint on @var{address}
@deffn {Command} {rwp} @option{all} | address
Remove data watchpoint on @var{address} or all watchpoints.
@end deffn

@deffn {Command} {wp} [address len [(@option{r}|@option{w}|@option{a}) [value [mask]]]]
Expand Down
104 changes: 72 additions & 32 deletions src/target/breakpoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
#include "breakpoints.h"
#include "smp.h"

enum breakpoint_watchpoint {
BREAKPOINT,
WATCHPOINT,
};

static const char * const breakpoint_type_strings[] = {
"hardware",
"software"
Expand Down Expand Up @@ -375,26 +380,90 @@ int breakpoint_remove(struct target *target, target_addr_t address)
return retval;
}

int breakpoint_remove_all(struct target *target)
static int watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
{
struct watchpoint *watchpoint = target->watchpoints;
struct watchpoint **watchpoint_p = &target->watchpoints;
int retval;

while (watchpoint) {
if (watchpoint == watchpoint_to_remove)
break;
watchpoint_p = &watchpoint->next;
watchpoint = watchpoint->next;
}

if (!watchpoint)
return ERROR_OK;
retval = target_remove_watchpoint(target, watchpoint);
if (retval != ERROR_OK) {
LOG_TARGET_ERROR(target, "could not remove watchpoint #%d on this target",
watchpoint->number);
return retval;
}

LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
(*watchpoint_p) = watchpoint->next;
free(watchpoint);

return ERROR_OK;
}

static int watchpoint_remove_all_internal(struct target *target)
{
struct watchpoint *watchpoint = target->watchpoints;
int retval = ERROR_OK;

while (watchpoint) {
struct watchpoint *tmp = watchpoint;
watchpoint = watchpoint->next;
int status = watchpoint_free(target, tmp);
if (status != ERROR_OK)
retval = status;
}

return retval;
}

int breakpoint_watchpoint_remove_all(struct target *target, enum breakpoint_watchpoint bp_wp)
{
assert(bp_wp == BREAKPOINT || bp_wp == WATCHPOINT);
int retval = ERROR_OK;
if (target->smp) {
struct target_list *head;

foreach_smp_target(head, target->smp_targets) {
struct target *curr = head->target;
int status = breakpoint_remove_all_internal(curr);

int status = ERROR_OK;
if (bp_wp == BREAKPOINT)
status = breakpoint_remove_all_internal(curr);
else
status = watchpoint_remove_all_internal(curr);

if (status != ERROR_OK)
retval = status;
}
} else {
retval = breakpoint_remove_all_internal(target);
if (bp_wp == BREAKPOINT)
retval = breakpoint_remove_all_internal(target);
else
retval = watchpoint_remove_all_internal(target);
}

return retval;
}

int breakpoint_remove_all(struct target *target)
{
return breakpoint_watchpoint_remove_all(target, BREAKPOINT);
}

int watchpoint_remove_all(struct target *target)
{
return breakpoint_watchpoint_remove_all(target, WATCHPOINT);
}

static int breakpoint_clear_target_internal(struct target *target)
{
LOG_DEBUG("Delete all breakpoints for target: %s",
Expand Down Expand Up @@ -532,35 +601,6 @@ int watchpoint_add(struct target *target, target_addr_t address,
}
}

static int watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
{
struct watchpoint *watchpoint = target->watchpoints;
struct watchpoint **watchpoint_p = &target->watchpoints;
int retval;

while (watchpoint) {
if (watchpoint == watchpoint_to_remove)
break;
watchpoint_p = &watchpoint->next;
watchpoint = watchpoint->next;
}

if (!watchpoint)
return ERROR_OK;
retval = target_remove_watchpoint(target, watchpoint);
if (retval != ERROR_OK) {
LOG_TARGET_ERROR(target, "could not remove watchpoint #%d on this target",
watchpoint->number);
return retval;
}

LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
(*watchpoint_p) = watchpoint->next;
free(watchpoint);

return ERROR_OK;
}

static int watchpoint_remove_internal(struct target *target, target_addr_t address)
{
struct watchpoint *watchpoint = target->watchpoints;
Expand Down
1 change: 1 addition & 0 deletions src/target/breakpoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ int watchpoint_add(struct target *target,
target_addr_t address, uint32_t length,
enum watchpoint_rw rw, uint64_t value, uint64_t mask);
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,
Expand Down
25 changes: 18 additions & 7 deletions src/target/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -4136,17 +4136,28 @@ COMMAND_HANDLER(handle_wp_command)

COMMAND_HANDLER(handle_rwp_command)
{
int retval;

if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;

target_addr_t addr;
COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);

struct target *target = get_current_target(CMD_CTX);
int retval = watchpoint_remove(target, addr);
if (!strcmp(CMD_ARGV[0], "all")) {
retval = watchpoint_remove_all(target);

if (retval != ERROR_OK)
command_print(CMD, "Error during removal of watchpoint at address " TARGET_ADDR_FMT, addr);
if (retval != ERROR_OK) {
command_print(CMD, "Error encountered during removal of all watchpoints.");
command_print(CMD, "Some watchpoints may have remained set.");
}
} else {
target_addr_t addr;
COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);

retval = watchpoint_remove(target, addr);

if (retval != ERROR_OK)
command_print(CMD, "Error during removal of watchpoint at address " TARGET_ADDR_FMT, addr);
}

return retval;
}
Expand Down Expand Up @@ -7065,7 +7076,7 @@ static const struct command_registration target_exec_command_handlers[] = {
.handler = handle_rwp_command,
.mode = COMMAND_EXEC,
.help = "remove watchpoint",
.usage = "address",
.usage = "'all' | address",
},
{
.name = "load_image",
Expand Down

0 comments on commit eba5d21

Please sign in to comment.