watchpoint_add() cleanup
Fail watchpoint_add() if it's the same address but the parameters are different ... don't just assume having the same address means the same watchpoint! (Note that overlapping watchpoints aren't detected...) Handle unrecognized return codes more sanely; don't exit()! And describe command params right. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
This commit is contained in:
parent
16b4b8cf54
commit
98788d7a75
|
@ -178,54 +178,61 @@ breakpoint_t* breakpoint_find(target_t *target, uint32_t address)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int watchpoint_add(target_t *target, uint32_t address, uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask)
|
int watchpoint_add(target_t *target, uint32_t address, uint32_t length,
|
||||||
|
enum watchpoint_rw rw, uint32_t value, uint32_t mask)
|
||||||
{
|
{
|
||||||
watchpoint_t *watchpoint = target->watchpoints;
|
watchpoint_t *watchpoint = target->watchpoints;
|
||||||
watchpoint_t **watchpoint_p = &target->watchpoints;
|
watchpoint_t **watchpoint_p = &target->watchpoints;
|
||||||
int retval;
|
int retval;
|
||||||
|
char *reason;
|
||||||
|
|
||||||
while (watchpoint)
|
while (watchpoint)
|
||||||
{
|
{
|
||||||
if (watchpoint->address == address)
|
if (watchpoint->address == address) {
|
||||||
|
if (watchpoint->length != length
|
||||||
|
|| watchpoint->value != value
|
||||||
|
|| watchpoint->mask != mask
|
||||||
|
|| watchpoint->rw != rw) {
|
||||||
|
LOG_ERROR("address 0x%8.8" PRIx32
|
||||||
|
"already has watchpoint %d",
|
||||||
|
address, watchpoint->unique_id);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore duplicate watchpoint */
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
}
|
||||||
watchpoint_p = &watchpoint->next;
|
watchpoint_p = &watchpoint->next;
|
||||||
watchpoint = watchpoint->next;
|
watchpoint = watchpoint->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*watchpoint_p) = malloc(sizeof(watchpoint_t));
|
(*watchpoint_p) = calloc(1, sizeof(watchpoint_t));
|
||||||
(*watchpoint_p)->address = address;
|
(*watchpoint_p)->address = address;
|
||||||
(*watchpoint_p)->length = length;
|
(*watchpoint_p)->length = length;
|
||||||
(*watchpoint_p)->value = value;
|
(*watchpoint_p)->value = value;
|
||||||
(*watchpoint_p)->mask = mask;
|
(*watchpoint_p)->mask = mask;
|
||||||
(*watchpoint_p)->rw = rw;
|
(*watchpoint_p)->rw = rw;
|
||||||
(*watchpoint_p)->set = 0;
|
|
||||||
(*watchpoint_p)->next = NULL;
|
|
||||||
(*watchpoint_p)->unique_id = bpwp_unique_id++;
|
(*watchpoint_p)->unique_id = bpwp_unique_id++;
|
||||||
|
|
||||||
if ((retval = target_add_watchpoint(target, *watchpoint_p)) != ERROR_OK)
|
retval = target_add_watchpoint(target, *watchpoint_p);
|
||||||
{
|
switch (retval) {
|
||||||
switch (retval)
|
case ERROR_OK:
|
||||||
{
|
break;
|
||||||
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
|
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
|
||||||
LOG_INFO("can't add %s watchpoint, resource not available (WPID: %d)",
|
reason = "resource not available";
|
||||||
watchpoint_rw_strings[(*watchpoint_p)->rw],
|
goto bye;
|
||||||
(*watchpoint_p)->unique_id );
|
case ERROR_TARGET_NOT_HALTED:
|
||||||
free (*watchpoint_p);
|
reason = "target running";
|
||||||
*watchpoint_p = NULL;
|
goto bye;
|
||||||
return retval;
|
default:
|
||||||
break;
|
reason = "unrecognized error";
|
||||||
case ERROR_TARGET_NOT_HALTED:
|
bye:
|
||||||
LOG_INFO("can't add watchpoint while target is running (WPID: %d)",
|
LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32 ", %s",
|
||||||
(*watchpoint_p)->unique_id );
|
watchpoint_rw_strings[(*watchpoint_p)->rw],
|
||||||
free (*watchpoint_p);
|
address, reason);
|
||||||
*watchpoint_p = NULL;
|
free (*watchpoint_p);
|
||||||
return retval;
|
*watchpoint_p = NULL;
|
||||||
break;
|
return retval;
|
||||||
default:
|
|
||||||
LOG_ERROR("unknown error");
|
|
||||||
exit(-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32 " of length 0x%8.8x (WPID: %d)",
|
LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32 " of length 0x%8.8x (WPID: %d)",
|
||||||
|
|
|
@ -49,7 +49,7 @@ typedef struct breakpoint_s
|
||||||
typedef struct watchpoint_s
|
typedef struct watchpoint_s
|
||||||
{
|
{
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
int length;
|
uint32_t length;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
enum watchpoint_rw rw;
|
enum watchpoint_rw rw;
|
||||||
|
|
|
@ -1199,7 +1199,7 @@ cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
|
|
||||||
for (mask = 0; mask < 16; mask++) {
|
for (mask = 0; mask < 16; mask++) {
|
||||||
if ((1 << mask) == watchpoint->length)
|
if ((1u << mask) == watchpoint->length)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mask == 16) {
|
if (mask == 16) {
|
||||||
|
|
|
@ -2988,7 +2988,8 @@ static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
|
command_print(cmd_ctx, "usage: wp [address length "
|
||||||
|
"[(r|w|a) [value [mask]]]]");
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue