Skip to content

Commit 9b6f4e8

Browse files
[backport] target: support auto-selection of software breakpoint size
Add default breakpoint length specifier. When passed, derivation of breakpoint length is delegated to target-type-specific method. Link: https://review.openocd.org/c/openocd/+/9116 Change-Id: Ie3473514beace15b76714aa6d5441122cd3262aa Signed-off-by: Kulyatskaya Alexandra <[email protected]>
1 parent c0a2b6b commit 9b6f4e8

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

doc/openocd.texi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9640,10 +9640,11 @@ hardware support for a handful of code breakpoints and data
96409640
watchpoints.
96419641
In addition, CPUs almost always support software breakpoints.
96429642

9643-
@deffn {Command} {bp} [address len [@option{hw}]]
9643+
@deffn {Command} {bp} [address (len|@option{default}) [@option{hw}]]
96449644
With no parameters, lists all active breakpoints.
96459645
Else sets a breakpoint on code execution starting
9646-
at @var{address} for @var{length} bytes.
9646+
at @var{address} for @var{length} bytes. When @option{default} is passed
9647+
the length is derived automatically.
96479648
This is a software breakpoint, unless @option{hw} is specified
96489649
in which case it will be a hardware breakpoint.
96499650

src/target/target.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,14 @@ int target_add_breakpoint(struct target *target,
13101310
return target->type->add_breakpoint(target, breakpoint);
13111311
}
13121312

1313+
static int target_get_default_breakpoint_size(struct target *target, target_addr_t addr,
1314+
uint32_t asid, int hw, unsigned int *length)
1315+
{
1316+
if (!target->type->get_default_breakpoint_length)
1317+
return ERROR_NOT_IMPLEMENTED;
1318+
return target->type->get_default_breakpoint_length(target, addr, asid, hw, length);
1319+
}
1320+
13131321
int target_add_context_breakpoint(struct target *target,
13141322
struct breakpoint *breakpoint)
13151323
{
@@ -3981,6 +3989,24 @@ static int handle_bp_command_set(struct command_invocation *cmd,
39813989
return retval;
39823990
}
39833991

3992+
static COMMAND_HELPER(parse_bp_length, uint32_t asid, target_addr_t addr,
3993+
int hw, unsigned int *length)
3994+
{
3995+
if (strcmp(CMD_ARGV[1], "default") == 0) {
3996+
struct target *target = get_current_target(CMD_CTX);
3997+
int ret_errno = target_get_default_breakpoint_size(target, addr, asid, hw, length);
3998+
if (ret_errno == ERROR_NOT_IMPLEMENTED) {
3999+
command_print(CMD, "Default breakpoint size derivation is "
4000+
"not implemented on target %s", target_name(target));
4001+
} else if (ret_errno != ERROR_OK) {
4002+
command_print(CMD, "Unknown error when deriving default breakpoint size");
4003+
}
4004+
return ret_errno;
4005+
}
4006+
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], *length);
4007+
return ERROR_OK;
4008+
}
4009+
39844010
COMMAND_HANDLER(handle_bp_command)
39854011
{
39864012
target_addr_t addr;
@@ -3995,29 +4021,29 @@ COMMAND_HANDLER(handle_bp_command)
39954021
case 2:
39964022
asid = 0;
39974023
COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
3998-
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
4024+
CALL_COMMAND_HANDLER(parse_bp_length, asid, addr, hw, &length);
39994025
return handle_bp_command_set(CMD, addr, asid, length, hw);
40004026

40014027
case 3:
40024028
if (strcmp(CMD_ARGV[2], "hw") == 0) {
40034029
hw = BKPT_HARD;
40044030
COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
4005-
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
40064031
asid = 0;
4032+
CALL_COMMAND_HANDLER(parse_bp_length, asid, addr, hw, &length);
40074033
return handle_bp_command_set(CMD, addr, asid, length, hw);
40084034
} else if (strcmp(CMD_ARGV[2], "hw_ctx") == 0) {
40094035
hw = BKPT_HARD;
40104036
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], asid);
4011-
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
40124037
addr = 0;
4038+
CALL_COMMAND_HANDLER(parse_bp_length, asid, addr, hw, &length);
40134039
return handle_bp_command_set(CMD, addr, asid, length, hw);
40144040
}
40154041
/* fallthrough */
40164042
case 4:
40174043
hw = BKPT_HARD;
40184044
COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
40194045
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], asid);
4020-
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], length);
4046+
CALL_COMMAND_HANDLER(parse_bp_length, asid, addr, hw, &length);
40214047
return handle_bp_command_set(CMD, addr, asid, length, hw);
40224048

40234049
default:
@@ -6662,7 +6688,7 @@ static const struct command_registration target_exec_command_handlers[] = {
66626688
.handler = handle_bp_command,
66636689
.mode = COMMAND_EXEC,
66646690
.help = "list or set hardware or software breakpoint",
6665-
.usage = "[<address> [<asid>] <length> ['hw'|'hw_ctx']]",
6691+
.usage = "[<address> [<asid>] (<length>|'default') ['hw'|'hw_ctx']]",
66666692
},
66676693
{
66686694
.name = "rbp",

src/target/target_type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ struct target_type {
309309
* will typically be 32 for 32-bit targets, and 64 for 64-bit targets. If
310310
* not implemented, it's assumed to be 32. */
311311
unsigned int (*data_bits)(struct target *target);
312+
313+
int (*get_default_breakpoint_length)(struct target *target, target_addr_t addr,
314+
uint32_t asid, int hw, unsigned int *length);
312315
};
313316

314317
extern struct target_type aarch64_target;

0 commit comments

Comments
 (0)