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: