Skip to content

Commit 60368dd

Browse files
aka-spstimsifive
authored andcommitted
FIX(src/target/riscv/riscv.c): riscv_add_breakpoint: RVC: invalid 32bit transactions size for 16bit aligned instruction (#322)
1 parent 936c514 commit 60368dd

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/target/riscv/riscv.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -512,19 +512,30 @@ static int add_trigger(struct target *target, struct trigger *trigger)
512512

513513
int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
514514
{
515+
assert(breakpoint);
515516
if (breakpoint->type == BKPT_SOFT) {
516-
if (target_read_memory(target, breakpoint->address, breakpoint->length, 1,
517+
/// @todo check RVC for size/alignment
518+
if (!(breakpoint->length == 4 || breakpoint->length == 2)) {
519+
LOG_ERROR("Invalid breakpoint length %d", breakpoint->length);
520+
return ERROR_FAIL;
521+
}
522+
523+
if (0 != (breakpoint->address % 2)) {
524+
LOG_ERROR("Invalid breakpoint alignment for address 0x%" TARGET_PRIxADDR, breakpoint->address);
525+
return ERROR_FAIL;
526+
}
527+
528+
if (target_read_memory(target, breakpoint->address, 2, breakpoint->length / 2,
517529
breakpoint->orig_instr) != ERROR_OK) {
518530
LOG_ERROR("Failed to read original instruction at 0x%" TARGET_PRIxADDR,
519531
breakpoint->address);
520532
return ERROR_FAIL;
521533
}
522534

523-
int retval;
524-
if (breakpoint->length == 4)
525-
retval = target_write_u32(target, breakpoint->address, ebreak());
526-
else
527-
retval = target_write_u16(target, breakpoint->address, ebreak_c());
535+
uint8_t buff[4];
536+
buf_set_u32(buff, 0, breakpoint->length * CHAR_BIT, breakpoint->length == 4 ? ebreak() : ebreak_c());
537+
int const retval = target_write_memory(target, breakpoint->address, 2, breakpoint->length / 2, buff);
538+
528539
if (retval != ERROR_OK) {
529540
LOG_ERROR("Failed to write %d-byte breakpoint instruction at 0x%"
530541
TARGET_PRIxADDR, breakpoint->length, breakpoint->address);
@@ -534,17 +545,15 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
534545
} else if (breakpoint->type == BKPT_HARD) {
535546
struct trigger trigger;
536547
trigger_from_breakpoint(&trigger, breakpoint);
537-
int result = add_trigger(target, &trigger);
548+
int const result = add_trigger(target, &trigger);
538549
if (result != ERROR_OK)
539550
return result;
540-
541551
} else {
542552
LOG_INFO("OpenOCD only supports hardware and software breakpoints.");
543553
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
544554
}
545555

546556
breakpoint->set = true;
547-
548557
return ERROR_OK;
549558
}
550559

@@ -597,7 +606,7 @@ int riscv_remove_breakpoint(struct target *target,
597606
struct breakpoint *breakpoint)
598607
{
599608
if (breakpoint->type == BKPT_SOFT) {
600-
if (target_write_memory(target, breakpoint->address, breakpoint->length, 1,
609+
if (target_write_memory(target, breakpoint->address, 2, breakpoint->length / 2,
601610
breakpoint->orig_instr) != ERROR_OK) {
602611
LOG_ERROR("Failed to restore instruction for %d-byte breakpoint at "
603612
"0x%" TARGET_PRIxADDR, breakpoint->length, breakpoint->address);

0 commit comments

Comments
 (0)