diff options
author | Tim Newsome <tim@sifive.com> | 2020-12-14 12:39:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-14 12:39:00 -0800 |
commit | f72e5bb0d82e5feb05efbcbb07c326f28d3e3cdf (patch) | |
tree | 82558a4b609b22e50adbcb978725b59e4df101a2 /src/target | |
parent | 5d0543cc1c7749a9bf3538328397a5e817275fb9 (diff) | |
download | riscv-openocd-f72e5bb0d82e5feb05efbcbb07c326f28d3e3cdf.zip riscv-openocd-f72e5bb0d82e5feb05efbcbb07c326f28d3e3cdf.tar.gz riscv-openocd-f72e5bb0d82e5feb05efbcbb07c326f28d3e3cdf.tar.bz2 |
Fix error handling in read_memory_progbuf_one(). (#560)
* Fix error handling in read_memory_progbuf_one().
Be sure to restore mstatus/s0 even if there is a failure during the
operation.
Fixes #559.
Change-Id: Ib86ca2c7455bad4a668f34703566060a782116db
Signed-off-by: Tim Newsome <tim@sifive.com>
* Style fix suggested in review.
Change-Id: I444112a9dffea483b7d0e5f96ef7bbdaf58d249f
Signed-off-by: Tim Newsome <tim@sifive.com>
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/riscv/riscv-013.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index e458602..c727101 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -3339,9 +3339,10 @@ static int read_memory_progbuf_one(struct target *target, target_addr_t address, return ERROR_FAIL; uint64_t s0; + int result = ERROR_FAIL; if (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK) - return ERROR_FAIL; + goto restore_mstatus; /* Write the program (load, increment) */ struct riscv_program program; @@ -3363,40 +3364,42 @@ static int read_memory_progbuf_one(struct target *target, target_addr_t address, break; default: LOG_ERROR("Unsupported size: %d", size); - return ERROR_FAIL; + goto restore_mstatus; } if (riscv_enable_virtual && has_sufficient_progbuf(target, 5) && get_field(mstatus, MSTATUS_MPRV)) riscv_program_csrrci(&program, GDB_REGNO_ZERO, CSR_DCSR_MPRVEN, GDB_REGNO_DCSR); if (riscv_program_ebreak(&program) != ERROR_OK) - return ERROR_FAIL; + goto restore_mstatus; if (riscv_program_write(&program) != ERROR_OK) - return ERROR_FAIL; + goto restore_mstatus; /* Write address to S0, and execute buffer. */ if (write_abstract_arg(target, 0, address, riscv_xlen(target)) != ERROR_OK) - return ERROR_FAIL; + goto restore_mstatus; uint32_t command = access_register_command(target, GDB_REGNO_S0, riscv_xlen(target), AC_ACCESS_REGISTER_WRITE | AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC); if (execute_abstract_command(target, command) != ERROR_OK) - return ERROR_FAIL; + goto restore_s0; uint64_t value; if (register_read(target, &value, GDB_REGNO_S0) != ERROR_OK) - return ERROR_FAIL; + goto restore_s0; buf_set_u64(buffer, 0, 8 * size, value); log_memory_access(address, value, size, true); + result = ERROR_OK; +restore_s0: if (riscv_set_register(target, GDB_REGNO_S0, s0) != ERROR_OK) - return ERROR_FAIL; + result = ERROR_FAIL; - /* Restore MSTATUS */ +restore_mstatus: if (mstatus != mstatus_old) if (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old)) - return ERROR_FAIL; + result = ERROR_FAIL; - return ERROR_OK; + return result; } /** |