Fixes issue where the 'next' command in the CLI fails.
PiperOrigin-RevId: 657634577
Change-Id: Id3c42432c4b6c92ff157fabaa7896a74f78514f9
diff --git a/cheriot/cheriot_top.cc b/cheriot/cheriot_top.cc
index 2078de5..c357f0e 100644
--- a/cheriot/cheriot_top.cc
+++ b/cheriot/cheriot_top.cc
@@ -889,7 +889,21 @@
}
absl::StatusOr<Instruction *> CheriotTop::GetInstruction(uint64_t address) {
- auto inst = cheriot_decode_cache_->GetDecodedInstruction(address);
+ // If requesting the instruction at an action point, we need to write the
+ // original instruction back to memory before getting the disassembly.
+ bool inst_swap = rv_ap_manager_->IsActionPointActive(address);
+ if (inst_swap) {
+ (void)rv_ap_manager_->ap_memory_interface()->WriteOriginalInstruction(
+ address);
+ }
+ // Get the decoded instruction.
+ Instruction *inst = cheriot_decode_cache_->GetDecodedInstruction(address);
+ inst->IncRef();
+ // Swap back if required.
+ if (inst_swap) {
+ (void)rv_ap_manager_->ap_memory_interface()->WriteBreakpointInstruction(
+ address);
+ }
return inst;
}
@@ -899,23 +913,11 @@
return absl::FailedPreconditionError("GetDissasembly: Core must be halted");
}
- Instruction *inst = nullptr;
- // If requesting the disassembly for an instruction at an action point, we
- // need to write the original instruction back to memory before getting the
- // disassembly.
- bool inst_swap = rv_ap_manager_->IsActionPointActive(address);
- if (inst_swap) {
- (void)rv_ap_manager_->ap_memory_interface()->WriteOriginalInstruction(
- address);
- }
- // Get the decoded instruction.
- inst = cheriot_decode_cache_->GetDecodedInstruction(address);
+ auto res = GetInstruction(address);
+ if (!res.ok()) return res.status();
+ Instruction *inst = res.value();
auto disasm = inst != nullptr ? inst->AsString() : "Invalid instruction";
- // Swap back if required.
- if (inst_swap) {
- (void)rv_ap_manager_->ap_memory_interface()->WriteBreakpointInstruction(
- address);
- }
+ inst->DecRef();
return disasm;
}
diff --git a/cheriot/cheriot_top.h b/cheriot/cheriot_top.h
index eb7415d..6c0f5dd 100644
--- a/cheriot/cheriot_top.h
+++ b/cheriot/cheriot_top.h
@@ -112,6 +112,10 @@
absl::Status ClearDataWatchpoint(uint64_t address,
AccessType access_type) override;
void SetBreakOnControlFlowChange(bool value) override;
+
+ // If successful, returns a pointer to the instruction at the given address.
+ // The instruction object is IncRef'ed, and the caller must DecRef the object
+ // when it is done with it.
absl::StatusOr<Instruction *> GetInstruction(uint64_t address) override;
absl::StatusOr<std::string> GetDisassembly(uint64_t address) override;
diff --git a/cheriot/debug_command_shell.cc b/cheriot/debug_command_shell.cc
index cbb9ff9..43537b4 100644
--- a/cheriot/debug_command_shell.cc
+++ b/cheriot/debug_command_shell.cc
@@ -1441,12 +1441,14 @@
return absl::UnavailableError(inst_res.status().message());
}
auto *inst = inst_res.value();
+ auto opcode = inst->opcode();
// If it's not a jump-and-link, it's a single step.
- if ((inst->opcode() != *isa32::OpcodeEnum::kCheriotJal) &&
- (inst->opcode() != *isa32::OpcodeEnum::kCheriotJalr) &&
- (inst->opcode() != *isa32::OpcodeEnum::kCheriotJalrCra) &&
- (inst->opcode() != *isa32::OpcodeEnum::kCheriotCjal) &&
- (inst->opcode() != *isa32::OpcodeEnum::kCheriotCjalrCra)) {
+ if ((opcode != *isa32::OpcodeEnum::kCheriotJal) &&
+ (opcode != *isa32::OpcodeEnum::kCheriotJalr) &&
+ (opcode != *isa32::OpcodeEnum::kCheriotJalrCra) &&
+ (opcode != *isa32::OpcodeEnum::kCheriotCjal) &&
+ (opcode != *isa32::OpcodeEnum::kCheriotCjalrCra)) {
+ inst->DecRef();
return core_access_[current_core_].debug_interface->Step(1).status();
}
// If it is a jump-and-link, we have to set a breakpoint on the instruction
@@ -1454,6 +1456,7 @@
// on another breakpoint. Either way, we then remove the breakpoint we
// inserted and return.
uint64_t bp_address = pcc + inst->size();
+ inst->DecRef();
bool bp_set = false;
// See if there is a bp on that address already, if so, don't try to set
// another one.
diff --git a/cheriot/test/librenode_mpact_cheriot_so_test.cc b/cheriot/test/librenode_mpact_cheriot_so_test.cc
index 38a3522..9496c20 100644
--- a/cheriot/test/librenode_mpact_cheriot_so_test.cc
+++ b/cheriot/test/librenode_mpact_cheriot_so_test.cc
@@ -10,7 +10,7 @@
constexpr char kFileName[] = "librenode_mpact_cheriot.so";
-constexpr char kDepotPath[] = "cheriot/";
+constexpr char kDepotPath[] = "third_party/mpact_cheriot/";
class LibRenodeMpactCheriotSoTest : public ::testing::Test {
protected: