rtos: server: target: ask the RTOS which target to set swbp on.
This is the result of squashing two commits from RISC-V OpenOCD:
- [1] ("Ask the RTOS which target to set swbp on. (#673)")
- [2] ("Fix breackpoint_add for rtos swbp (#734)")
The resulting change lets the RTOS pick the "current" target for setting
the software breakpoint on, which matters if address translation differs
between threads.
Link: https://github.com/riscv-collab/riscv-openocd/commit/52ca5d198e3b [1]
Link: https://github.com/riscv-collab/riscv-openocd/commit/8ae41e86e15d [2]
Change-Id: I67ce24d6aa0ca9225436b380065d1e265424e70f
Signed-off-by: Tim Newsome <tim@sifive.com>
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/9176
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
@@ -29,6 +29,8 @@ static int hwthread_read_buffer(struct rtos *rtos, target_addr_t address,
|
||||
static int hwthread_write_buffer(struct rtos *rtos, target_addr_t address,
|
||||
uint32_t size, const uint8_t *buffer);
|
||||
static bool hwthread_needs_fake_step(struct target *target, int64_t thread_id);
|
||||
struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address,
|
||||
uint32_t length, enum breakpoint_type type);
|
||||
|
||||
#define HW_THREAD_NAME_STR_SIZE (32)
|
||||
|
||||
@@ -60,7 +62,8 @@ const struct rtos_type hwthread_rtos = {
|
||||
.set_reg = hwthread_set_reg,
|
||||
.read_buffer = hwthread_read_buffer,
|
||||
.write_buffer = hwthread_write_buffer,
|
||||
.needs_fake_step = hwthread_needs_fake_step
|
||||
.needs_fake_step = hwthread_needs_fake_step,
|
||||
.swbp_target = hwthread_swbp_target,
|
||||
};
|
||||
|
||||
struct hwthread_params {
|
||||
@@ -456,3 +459,9 @@ bool hwthread_needs_fake_step(struct target *target, int64_t thread_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address,
|
||||
uint32_t length, enum breakpoint_type type)
|
||||
{
|
||||
return hwthread_find_thread(rtos->target, rtos->current_thread);
|
||||
}
|
||||
|
||||
@@ -762,3 +762,11 @@ bool rtos_needs_fake_step(struct target *target, int64_t thread_id)
|
||||
return target->rtos->type->needs_fake_step(target, thread_id);
|
||||
return target->rtos->current_thread != thread_id;
|
||||
}
|
||||
|
||||
struct target *rtos_swbp_target(struct target *target, target_addr_t address,
|
||||
uint32_t length, enum breakpoint_type type)
|
||||
{
|
||||
if (target->rtos->type->swbp_target)
|
||||
return target->rtos->type->swbp_target(target->rtos, address, length, type);
|
||||
return target;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define OPENOCD_RTOS_RTOS_H
|
||||
|
||||
#include "server/server.h"
|
||||
#include "target/breakpoints.h"
|
||||
#include "target/target.h"
|
||||
|
||||
typedef int64_t threadid_t;
|
||||
@@ -86,6 +87,12 @@ struct rtos_type {
|
||||
* target running a multi-threading OS. If an RTOS can do this, override
|
||||
* needs_fake_step(). */
|
||||
bool (*needs_fake_step)(struct target *target, int64_t thread_id);
|
||||
/* When a software breakpoint is set, it is set on only one target,
|
||||
* because we assume memory is shared across them. By default this is the
|
||||
* first target in the SMP group. Override this function to have
|
||||
* breakpoint_add() use a different target. */
|
||||
struct target * (*swbp_target)(struct rtos *rtos, target_addr_t address,
|
||||
uint32_t length, enum breakpoint_type type);
|
||||
};
|
||||
|
||||
struct stack_register_offset {
|
||||
@@ -145,6 +152,8 @@ int rtos_read_buffer(struct target *target, target_addr_t address,
|
||||
int rtos_write_buffer(struct target *target, target_addr_t address,
|
||||
uint32_t size, const uint8_t *buffer);
|
||||
bool rtos_needs_fake_step(struct target *target, int64_t thread_id);
|
||||
struct target *rtos_swbp_target(struct target *target, target_addr_t address,
|
||||
uint32_t length, enum breakpoint_type type);
|
||||
|
||||
// Keep in alphabetic order this list of rtos
|
||||
extern const struct rtos_type chibios_rtos;
|
||||
|
||||
@@ -1814,7 +1814,15 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
|
||||
case 0:
|
||||
case 1:
|
||||
if (packet[0] == 'Z') {
|
||||
retval = breakpoint_add(target, address, size, bp_type);
|
||||
struct target *bp_target = target;
|
||||
if (target->rtos && bp_type == BKPT_SOFT) {
|
||||
bp_target = rtos_swbp_target(target, address, size, bp_type);
|
||||
if (!bp_target) {
|
||||
retval = ERROR_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
retval = breakpoint_add(bp_target, address, size, bp_type);
|
||||
} else {
|
||||
assert(packet[0] == 'z');
|
||||
retval = breakpoint_remove(target, address);
|
||||
|
||||
@@ -210,16 +210,10 @@ int breakpoint_add(struct target *target,
|
||||
unsigned int length,
|
||||
enum breakpoint_type type)
|
||||
{
|
||||
if (target->smp) {
|
||||
struct target_list *head;
|
||||
|
||||
if (type == BKPT_SOFT) {
|
||||
head = list_first_entry(target->smp_targets, struct target_list, lh);
|
||||
return breakpoint_add_internal(head->target, address, length, type);
|
||||
}
|
||||
|
||||
foreach_smp_target(head, target->smp_targets) {
|
||||
struct target *curr = head->target;
|
||||
if (target->smp && type == BKPT_HARD) {
|
||||
struct target_list *list_node;
|
||||
foreach_smp_target(list_node, target->smp_targets) {
|
||||
struct target *curr = list_node->target;
|
||||
int retval = breakpoint_add_internal(curr, address, length, type);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
Reference in New Issue
Block a user