// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cheriot/debug_command_shell.h"

#include <cstdint>
#include <cstring>
#include <fstream>
#include <functional>
#include <istream>
#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/functional/bind_front.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "cheriot/cheriot_debug_interface.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/cheriot_state.h"
#include "cheriot/cheriot_top.h"
#include "cheriot/riscv_cheriot_enums.h"
#include "cheriot/riscv_cheriot_register_aliases.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/type_helpers.h"
#include "re2/re2.h"
#include "riscv//stoull_wrapper.h"

namespace mpact {
namespace sim {
namespace cheriot {

using PB = ::mpact::sim::cheriot::CheriotRegister::PermissionBits;

using HaltReason = ::mpact::sim::generic::CoreDebugInterface::HaltReason;
using ::mpact::sim::generic::operator*;  // NOLINT: used below (clang error).

DebugCommandShell::InterruptListener::InterruptListener(CoreAccess *core_access)
    : core_access_(core_access),
      state_(static_cast<CheriotState *>(core_access_->state)),
      dbg_if_(static_cast<CheriotTop *>(core_access->debug_interface)),
      taken_listener_(
          absl::bind_front(&InterruptListener::SetTakenValue, this)),
      return_listener_(
          absl::bind_front(&InterruptListener::SetReturnValue, this)) {
  state_->counter_interrupts_taken()->AddListener(&taken_listener_);
  state_->counter_interrupt_returns()->AddListener(&return_listener_);
}

void DebugCommandShell::InterruptListener::SetReturnValue(int64_t value) {
  auto &interrupt_info_list = state_->interrupt_info_list();
  if (interrupt_info_list.empty()) {
    LOG(ERROR) << "Interrupt stack is empty";
    return;
  }
  auto info = interrupt_info_list.back();
  // If breakpoints are enabled, then request a halt of the appropriate type.
  if (info.is_interrupt && interrupts_enabled_)
    (void)dbg_if_->Halt(kInterruptReturn);
  if (!info.is_interrupt && exceptions_enabled_)
    (void)dbg_if_->Halt(kExceptionReturn);
}

void DebugCommandShell::InterruptListener::SetTakenValue(int64_t value) {
  InterruptInfo info = state_->interrupt_info_list().back();
  // If breakpoints are enabled, the request a halt of the appropriate type.
  if (info.is_interrupt && interrupts_enabled_)
    (void)dbg_if_->Halt(kInterruptTaken);
  if (!info.is_interrupt && exceptions_enabled_)
    (void)dbg_if_->Halt(kExceptionTaken);
}

// The constructor initializes all the regular expressions and the help string.
DebugCommandShell::DebugCommandShell()
    : quit_re_{R"(\s*quit\s*)"},
      core_re_{R"(\s*core\s+(\d+)\s*)"},
      run_re_{R"(\s*(?:run|c)\s*)"},
      run_free_re_{R"(\s*run\s+free\s*)"},
      wait_re_{R"(\s*wait\s*)"},
      step_1_re_{R"(\s*step\s*)"},
      step_n_re_{R"(\s*step\s+(\d+)\s*)"},
      halt_re_{R"(\s*halt\s*)"},
      next_re_{R"(\s*next\s*)"},
      read_reg_re_{R"(\s*reg\s+get\s+(\$?(\w|\.)+)(\s+[foduxX]\d+)?\s*)"},
      read_reg2_re_{R"(\s*reg\s+(\$?(\w|\.)+)(\s+[foduxX]\d+)?\s*)"},
      write_reg_re_{R"(\s*reg\s+set\s+(\$?\w+)\s+(\w+)\s*)"},
      rd_vreg_re_{R"(\s*vreg(?:\s+get)?\s+(\$?\w+)(?:(?:\s*\:(\d+))?)"
                  R"((?:\s+(?:([oduxX])(8|16|32|64))?)?)?\s*)"},
      read_mem_re_{R"(\s*mem\s+get\s+(\w+)(?:\s+([foduxX]\d+|i)?)?\s*)"},
      read_mem2_re_{R"(\s*mem\s+(\w+)(?:\s+([foduxX]\d+|i)?)?\s*)"},
      write_mem_re_{R"(\s*mem\s+set\s+(\w+)\s+([oduxX]\d+)?\s+(\w+)\s*)"},
      set_break_re_{R"(\s*break\s+set\s+(\$?\w+)\s*)"},
      set_break2_re_{R"(\s*break\s+(\$?\w+)\s*)"},
      set_break_n_re_{R"(\s*break\s+(set\s+)?\#(\d+)\s*)"},
      list_break_re_{R"(\s*break\s*)"},
      clear_break_n_re_{R"(\s*break\s+clear\s+\#(\d+)\s*)"},
      clear_break_re_{R"(\s*break\s+clear\s+(\$?\w+)\s*)"},
      clear_all_break_re_{R"(\s*break\s+clear-all\s*)"},
      set_watch_re_{R"(\s*watch\s+set\s+(\w+)\s+(\w+)(\s+r|\s+w|\s+rw)?\s*)"},
      set_watch2_re_{R"(\s*watch\s+(\w+)\s+(\w+)(\s+r|\s+w|\s+rw)?\s*)"},
      set_watch_n_re_{R"(\s*watch\s+(set\s+)?\#(\d+)\s*)"},
      list_watch_re_{R"(\s*watch\s*)"},
      clear_watch_re_{R"(\s*watch\s+clear\s+(\w+)(\s+r|\s+w|\s+rw)?\s*)"},
      clear_watch_n_re_{R"(\s*watch\s+clear\s+\#(\d+)\s*)"},
      clear_all_watch_re_{R"(\s*watch\s+clear-all\s*)"},
      list_action_re_{R"(\s*action\s*)"},
      enable_action_n_re_{R"(\s*action\s+enable\s+\*(\d+)\s*)"},
      disable_action_n_re_{R"(\s*action\s+disable\s+\*(\d+)\s*)"},
      clear_action_n_re_{R"(\s*action\s+clear\s+\*(\d+)\s*)"},
      clear_all_action_re_{R"(\s*action\s+clear-all\s*)"},
      branch_trace_re_{R"(\s*branch-trace\s*)"},
      exec_re_{R"(\s*exec\s+(.+)\s*)"},
      empty_re_{R"(\s*(?:\#.*)?)"},
      help_re_{R"(\s*help\s*)"} {
  help_message_ =
      R"raw(  quit                             - exit command shell.
  core [N]                         - direct subsequent commands to core N
                                     (default: 0).
  run                              - run program from current pcc until a
                                     breakpoint or exit. Wait until halted.
  run free                         - run program in background from current pcc
                                     until breakpoint or exit.
  wait                             - wait for any free run to complete.
  step [N]                         - step [N] instructions (default: 1).
  next                             - step 1 instruction (stepping over calls).
  halt                             - halt a running program.
  reg get NAME [FORMAT]            - get the value or register NAME (see below
                                     for special names and display formats).
  reg NAME [FORMAT]                - get the value of register NAME (see below).
  reg set NAME VALUE               - set register NAME to VALUE.
  reg set NAME SYMBOL              - set register NAME to value of SYMBOL.
  mem get VALUE [FORMAT]           - get memory from location VALUE according to
                                     FORMAT (see below for display formats).
                                     Default format is x32.
  mem get SYMBOL [FORMAT]          - get memory from location SYMBOL and format
                                     according to FORMAT (see below).
  mem SYMBOL [FORMAT]              - get memory from location SYMBOL and format
                                     according to FORMAT (see below).
  mem set VALUE [FORMAT] VALUE     - set memory at location VALUE(1) to VALUE(2)
                                     according to FORMAT (see below). Default
                                     format is x32.
  mem set SYMBOL [FORMAT] VALUE    - set memory at location SYMBOL to VALUE
                                     according to FORMAT (see below). Default
                                     format is x32.
  break [set] VALUE                - set breakpoint at address VALUE.
  break [set] SYMBOL               - set breakpoint at value of SYMBOL (see below
                                     for special symbol names).
  break set #<N>                   - reactivate breakpoint index N.
  break #<N>                       - reactivate breakpoint index N.
  break clear VALUE                - clear breakpoint at address VALUE.
  break clear SYMBOL               - clear breakpoint at value of SYMBOL (see
                                     below for pseudo-symbols).
  break clear #<N>                 - clear breakpoint index N.
  break clear-all                  - remove all breakpoints.
  break                            - list breakpoints.
  watch [set] VALUE len [r|w|rw]   - set watchpoint at value (read, write, or
                                     read+write) - default is write.
  watch [set] SYMBOL len [r|w|rw]  - set watchpoint at value (read, write, or
                                     read+write) - default is write.
  watch set #<N>                   - reactivate watchpoint index N.
  watch clear VALUE [r|w|rw]       - clear watchpoint at value (read, write, or
                                     readwrite) - default is write.
  watch clear SYMBOL [r|w|rw]      - clear watchpoint at symbol (read, write or
                                     readwrite) - default is write.
  watch clear #<N>                 - clear watchpoint index N.
  watch clear-all                  - remove all watchpoints.
  watch                            - list watchpoints.
  action enable #<N>               - enable action point with index N.
  action disable #<N>              - disable action point with index N.
  action clear #<N>                - clear action point with index N.
  action clear-all                 - clear all action points.
  action                           - list action points.
  branch-trace                     - list the control flow change (includes
                                     interrupts) w/out repetitions due to loops.
  exec    NAME                     - load commands from file 'NAME' and execute
                                     each line as a command. Lines starting with
                                     a '#' are treated as comments.
  help                             - display this message.

  Special names:
  $all                             - core set of registers (e.g., reg $all).
  $exception                       - pseudo-symbol for exception handler entry/exit
                                     (e.g., break set $exception).
  $interrupt                       - pseudo-symbol for interrupt handler entry/exit
                                     (e.g., break clear $interrupt).

  Display formats:
  o{8|16|32|64}                    - octal (base 8) of bit-width data
  d{8|16|32|64}                    - signed decimal (base 10) of bit-width data
  u{8|16|32|64}                    - unsigned decimal (base 10) of bit-width data
  x{8|16|32|64}                    - lower-case hexdecimal (base 16) of bit-width data
  X{8|16|32|64}                    - upper-case hexdecimal (base 16) of bit-width data
  i                                - decode as instruction (only use with memory get)
)raw";
  // Insert known capability registers
  for (int i = 0; i < 16; i++) {
    reg_vector_.push_back(kCRegisterAliases[i]);
    capability_registers_.insert(absl::StrCat("c", i));
    capability_registers_.insert(kCRegisterAliases[i]);
  }
  capability_registers_.insert("pcc");
  capability_registers_.insert("mtcc");
  capability_registers_.insert("mtdc");
  capability_registers_.insert("mscratchc");
  capability_registers_.insert("mepcc");
  reg_vector_.push_back("pcc");
  reg_vector_.push_back("mepcc");
  reg_vector_.push_back("mtcc");
  reg_vector_.push_back("mtdc");
  reg_vector_.push_back("mscratchc");
}

DebugCommandShell::~DebugCommandShell() {
  for (auto *listener : interrupt_listeners_) {
    delete listener;
  }
}

void DebugCommandShell::AddCore(const CoreAccess &core_access) {
  core_access_.push_back(core_access);
  interrupt_listeners_.push_back(new InterruptListener(&core_access_.back()));
  core_action_point_id_.push_back(0);
  core_action_point_info_.emplace_back();
}

void DebugCommandShell::AddCores(const std::vector<CoreAccess> &core_access) {
  for (const auto &core_access : core_access) {
    AddCore(core_access);
  }
}

// NOLINTBEGIN(readability/fn_size)
void DebugCommandShell::Run(std::istream &is, std::ostream &os) {
  // TODO(torerik): refactor this function.
  // Assumes the max linesize is 512.
  command_streams_.push_back(&is);
  constexpr int kLineSize = 512;
  char line[kLineSize];
  std::string previous_line;
  current_core_ = 0;
  absl::string_view line_view;
  bool halt_reason = false;
  int last_info_list_size = 0;
  while (true) {
    // Prompt and read in the next command.
    auto pcc_result =
        core_access_[current_core_].debug_interface->ReadRegister("pcc");
    std::string prompt;
    if (halt_reason) {
      halt_reason = false;
      auto result =
          core_access_[current_core_].debug_interface->GetLastHaltReason();
      if (result.ok()) {
        switch (result.value()) {
          case *HaltReason::kSoftwareBreakpoint:
            absl::StrAppend(&prompt, "Stopped at software breakpoint\n");
            break;
          case *HaltReason::kUserRequest:
            absl::StrAppend(&prompt, "Stopped at user request\n");
            break;
          case *HaltReason::kDataWatchPoint:
            absl::StrAppend(&prompt, "Stopped at data watchpoint\n");
            break;
          case InterruptListener::kInterruptTaken:
            absl::StrAppend(&prompt, "Stopped at taken interrupt\n");
            break;
          case InterruptListener::kInterruptReturn:
            absl::StrAppend(&prompt,
                            "Stopped at return from interrupt handler\n");
            break;
          case InterruptListener::kExceptionTaken:
            absl::StrAppend(&prompt, "Stopped at exception\n");
            break;
          case InterruptListener::kExceptionReturn:
            absl::StrAppend(&prompt, "Stopped at return exception handler\n");
            break;
          case *HaltReason::kProgramDone:
            absl::StrAppend(&prompt, "Program done\n");
            break;
          default:
            if ((result.value() >= *HaltReason::kUserSpecifiedMin) &&
                (result.value() <= *HaltReason::kUserSpecifiedMax)) {
              absl::StrAppend(&prompt, "Stopped for custom halt reason\n");
            }
            break;
        }
      }
    }
    if (pcc_result.ok()) {
      auto *loader = core_access_[current_core_].loader_getter();
      if (loader != nullptr) {
        auto fcn_result = loader->GetFunctionName(pcc_result.value());
        if (fcn_result.ok()) {
          absl::StrAppend(&prompt, "[", fcn_result.value(), "]:\n");
        }
        auto symbol_result = loader->GetFcnSymbolName(pcc_result.value());
        if (symbol_result.ok()) {
          absl::StrAppend(&prompt, symbol_result.value(), ":\n");
        }
      }
      absl::StrAppend(&prompt,
                      absl::Hex(pcc_result.value(), absl::PadSpec::kZeroPad8));
      auto disasm_result =
          core_access_[current_core_].debug_interface->GetDisassembly(
              pcc_result.value());
      if (disasm_result.ok()) {
        absl::StrAppend(&prompt, "   ", disasm_result.value());
      }
      absl::StrAppend(&prompt, "\n");
    }
    auto cheriot_state =
        static_cast<CheriotState *>(core_access_[current_core_].state);
    auto &info_list = cheriot_state->interrupt_info_list();
    // Check if there is a new interrupt, if so print the info.
    if (info_list.size() > last_info_list_size) {
      auto const &info = *info_list.rbegin();
      absl::StrAppend(&prompt, info.is_interrupt ? "interrupt " : "exception ",
                      info.is_interrupt ? GetInterruptDescription(info)
                                        : GetExceptionDescription(info));
    }
    last_info_list_size = info_list.size();
    absl::StrAppend(&prompt, "[", current_core_, "] > ");
    while (!command_streams_.empty()) {
      auto &current_is = *command_streams_.back();
      // Ignore comments or empty lines.
      bool is_file = command_streams_.size() > 1;
      // Read a command from the input stream. If it's from a file, then ignore
      // empty lines and comments.
      do {
        if (command_streams_.size() == 1) os << prompt;
        current_is.getline(line, kLineSize);
      } while ((is_file && RE2::FullMatch(line, *empty_re_)) &&
               !current_is.bad() && !current_is.eof());

      if (command_streams_.empty()) return;

      // If the current is at eof or gone bad, pop the stream and try the next.
      if (current_is.bad() || current_is.eof()) {
        // If it's not the only stream, delete the stream since it was allocated
        // for an exec command.
        if (is_file) {
          delete command_streams_.back();
        }
        command_streams_.pop_back();
        previous_line = previous_commands_.back();
        previous_commands_.pop_back();
        continue;
      }
      // We have a valid command.
      break;
    }

    if (command_streams_.empty()) {
      os << "Error: input end of file or bad stream state\n" << std::endl;
      os.flush();
      return;
    }

    if (line[0] != '\0') {
      previous_line = line;
    }
    line_view = absl::string_view(previous_line);

    // Start matching commands.

    // First try any added custom commands.
    bool executed = false;
    for (auto &fcn : command_functions_) {
      std::string output;
      executed = fcn(line_view, core_access_[current_core_], output);
      if (executed) {
        os << output << std::endl;
        break;
      }
    }
    if (executed) continue;

    // quit
    if (RE2::FullMatch(line_view, *quit_re_)) return;

    // core N
    if (int new_core;
        RE2::FullMatch(line_view, *core_re_, RE2::CRadix(&new_core))) {
      if (new_core >= core_access_.size()) {
        os << absl::StrCat("Error: core number must be less than ",
                           core_access_.size())
           << std::endl;
        os.flush();
        continue;
      }
      current_core_ = new_core;
      continue;
    }

    // run
    if (RE2::FullMatch(line_view, *run_re_)) {
      auto run_result = core_access_[current_core_].debug_interface->Run();
      if (!run_result.ok()) {
        os << "Error: " << run_result.message() << std::endl;
        os.flush();
      }
      auto wait_result = core_access_[current_core_].debug_interface->Wait();
      if (!wait_result.ok()) {
        os << "Error: " << wait_result.message() << std::endl;
        os.flush();
      }
      halt_reason = true;
      continue;
    }

    // run free
    if (RE2::FullMatch(line_view, *run_free_re_)) {
      auto result = core_access_[current_core_].debug_interface->Run();
      if (!result.ok()) {
        os << "Error: " << result.message() << std::endl;
        os.flush();
      }
      halt_reason = true;
      continue;
    }

    // wait
    if (RE2::FullMatch(line_view, *wait_re_)) {
      auto result = core_access_[current_core_].debug_interface->Wait();
      if (!result.ok()) {
        os << "Error: " << result.message() << std::endl;
        os.flush();
      }
      continue;
    }

    // step
    if (RE2::FullMatch(line_view, *step_1_re_)) {
      auto result = core_access_[current_core_].debug_interface->Step(1);
      if (!result.status().ok()) {
        os << "Error: " << result.status().message() << std::endl;
        os.flush();
        continue;
      }
      if (result.value() != 1) {
        os << result.value() << " instructions executed" << std::endl;
        os.flush();
      }
      continue;
    }

    // step N
    if (int count;
        RE2::FullMatch(line_view, *step_n_re_, RE2::CRadix(&count))) {
      auto result = core_access_[current_core_].debug_interface->Step(count);
      if (!result.status().ok()) {
        os << "Error: " << result.status().message() << std::endl;
        os.flush();
        continue;
      }
      if (result.value() != count) {
        os << result.value() << " instructions executed" << std::endl;
        os.flush();
        halt_reason = true;
      }
      continue;
    }

    // halt
    if (RE2::FullMatch(line_view, *halt_re_)) {
      auto result = core_access_[current_core_].debug_interface->Halt();
      if (!result.ok()) {
        os << "Error: " << result.message() << std::endl;
        os.flush();
      }
      halt_reason = true;
      continue;
    }

    // reg read NAME
    if (std::string name, format;
        RE2::FullMatch(line_view, *read_reg_re_, &name, &format)) {
      // If it is the simulator 'register' $all, print all registers.
      if (name == "$all") {
        os << FormatAllRegisters(current_core_);
        continue;
      }
      os << FormatRegister(current_core_, name) << std::endl;
      os.flush();
      continue;
    }

    // reg write NAME = VALUE
    if (std::string name, value;
        RE2::FullMatch(line_view, *write_reg_re_, &name, &value)) {
      auto result = GetValueFromString(current_core_, value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: '", value, "' ", result.status().message())
           << std::endl;
        os.flush();
        continue;
      }
      auto write_result =
          core_access_[current_core_].debug_interface->WriteRegister(
              name, result.value());
      if (!write_result.ok()) {
        os << "Error: " << write_result.message() << std::endl;
        os.flush();
      }
      continue;
    }

    // mem get VALUE | SYMBOL [FORMAT]

    if (std::string str_value, format;
        RE2::FullMatch(line_view, *read_mem_re_, &str_value, &format)) {
      os << ReadMemory(current_core_, str_value, format) << std::endl;
      continue;
    }

    if (std::string str_value1, format, str_value2; RE2::FullMatch(
            line_view, *write_mem_re_, &str_value1, &format, &str_value2)) {
      os << WriteMemory(current_core_, str_value1, format, str_value2)
         << std::endl;
      continue;
    }

    // break set VALUE | SYMBOL
    if (std::string str_value;
        RE2::FullMatch(line_view, *set_break_re_, &str_value) ||
        RE2::FullMatch(line_view, *set_break2_re_, &str_value)) {
      if (str_value == "$branch") {
        auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
            core_access_[current_core_].debug_interface);
        cheriot_interface->SetBreakOnControlFlowChange(true);
        continue;
      } else if (str_value == "$exception") {
        if (interrupt_listeners_[current_core_]->AreExceptionsEnabled()) {
          os << "Break on exceptions are already enabled\n";
          continue;
        }
        interrupt_listeners_[current_core_]->SetEnableExceptions(true);
        continue;
      } else if (str_value == "$interrupt") {
        if (interrupt_listeners_[current_core_]->AreInterruptsEnabled()) {
          os << "Break on interrupts are already enabled\n";
          continue;
        }
        interrupt_listeners_[current_core_]->SetEnableInterrupts(true);
        continue;
      }
      auto result = GetValueFromString(current_core_, str_value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: ?????? '", str_value, "' ",
                           result.status().message())
           << std::endl;
        os.flush();
        continue;
      }
      auto cmd_result =
          core_access_[current_core_].debug_interface->SetSwBreakpoint(
              result.value());
      if (!cmd_result.ok()) {
        os << "Error:  " << cmd_result.message() << std::endl;
        os.flush();
        continue;
      }
      core_access_[current_core_]
          .breakpoint_map[core_access_[current_core_].breakpoint_index++] =
          result.value();
      os << absl::StrCat("Breakpoint set at 0x",
                         absl::Hex(result.value(), absl::PadSpec::kZeroPad8))
         << std::endl;
      continue;
    }

    // break set #<N>
    if (std::string str_value, num_value;
        RE2::FullMatch(line_view, *set_break_n_re_, &str_value, &num_value)) {
      int index;
      if (!absl::SimpleAtoi(num_value, &index)) {
        os << absl::StrCat("Error: cannot parse '", str_value,
                           "' as a breakpoint index\n");
        continue;
      }
      auto iter = core_access_[current_core_].breakpoint_map.find(index);
      if (iter == core_access_[current_core_].breakpoint_map.end()) {
        os << absl::StrCat("Error: no breakpoint with index ", index, "\n");
        continue;
      }
      uint64_t address = iter->second;
      if (!core_access_[current_core_].debug_interface->HasBreakpoint(
              address)) {
        auto status =
            core_access_[current_core_].debug_interface->SetSwBreakpoint(
                address);
        if (!status.ok()) {
          os << absl::StrCat("Error: ", status.message(), "\n");
        }
      } else {
        os << "Breakpoint already active\n";
      }
      continue;
    }

    // break clear #<N>
    if (std::string str_value;
        RE2::FullMatch(line_view, *clear_break_n_re_, &str_value)) {
      int index;
      if (!absl::SimpleAtoi(str_value, &index)) {
        os << absl::StrCat("Error: cannot parse '", str_value,
                           "' as a breakpoint index\n");
        continue;
      }
      auto iter = core_access_[current_core_].breakpoint_map.find(index);
      if (iter == core_access_[current_core_].breakpoint_map.end()) {
        os << absl::StrCat("Error: no breakpoint with index ", index, "\n");
        continue;
      }
      uint64_t address = iter->second;
      if (core_access_[current_core_].debug_interface->HasBreakpoint(address)) {
        auto status =
            core_access_[current_core_].debug_interface->ClearSwBreakpoint(
                address);
        if (!status.ok()) {
          os << absl::StrCat("Error: ", status.message(), "\n");
        }
      } else {
        os << absl::StrCat("No such active breakpoint: #", index, "\n");
      }
      continue;
    }

    // break clear-all
    if (RE2::FullMatch(line_view, *clear_all_break_re_)) {
      auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
          core_access_[current_core_].debug_interface);
      cheriot_interface->SetBreakOnControlFlowChange(false);
      interrupt_listeners_[current_core_]->SetEnableExceptions(false);
      interrupt_listeners_[current_core_]->SetEnableInterrupts(false);
      auto result =
          core_access_[current_core_].debug_interface->ClearAllSwBreakpoints();
      if (!result.ok()) {
        os << absl::StrCat("Error: ", result.message()) << std::endl;
        os.flush();
        continue;
      }
      os << "All breakpoints removed" << std::endl;
      continue;
    }

    // break clear VALUE | SYMBOL
    if (std::string str_value;
        RE2::FullMatch(line_view, *clear_break_re_, &str_value)) {
      if (str_value == "$branch") {
        auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
            core_access_[current_core_].debug_interface);
        cheriot_interface->SetBreakOnControlFlowChange(false);
        continue;
      } else if (str_value == "$exception") {
        if (!interrupt_listeners_[current_core_]->AreExceptionsEnabled()) {
          os << "Break on exceptions are already disabled\n";
          continue;
        }
        interrupt_listeners_[current_core_]->SetEnableExceptions(false);
        continue;
      } else if (str_value == "$interrupt") {
        if (!interrupt_listeners_[current_core_]->AreInterruptsEnabled()) {
          os << "Break on interrupts are already disabled\n";
          continue;
        }
        interrupt_listeners_[current_core_]->SetEnableInterrupts(false);
        continue;
      }
      auto result = GetValueFromString(current_core_, str_value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: '", str_value, "' ",
                           result.status().message())
           << std::endl;
        os.flush();
        continue;
      }
      auto cmd_result =
          core_access_[current_core_].debug_interface->ClearSwBreakpoint(
              result.value());
      if (!cmd_result.ok()) {
        os << "Error:  " << cmd_result.message() << std::endl;
        os.flush();
        continue;
      }
      os << absl::StrCat("Breakpoint removed from 0x",
                         absl::Hex(result.value(), absl::PadSpec::kZeroPad8))
         << std::endl;
      continue;
    }

    // break list
    if (RE2::FullMatch(line_view, *list_break_re_)) {
      std::string bp_list;
      absl::StrAppend(&bp_list, " index    active      address   symbol\n");
      absl::StrAppend(&bp_list, " -------------------------------------\n");
      for (auto [index, address] : core_access_[current_core_].breakpoint_map) {
        bool active =
            core_access_[current_core_].debug_interface->HasBreakpoint(address);
        std::string symbol;
        auto *loader = core_access_[current_core_].loader_getter();
        if (loader != nullptr) {
          auto res = loader->GetFcnSymbolName(address);
          if (res.ok()) symbol = std::move(res.value());
        }
        absl::StrAppend(&bp_list,
                        absl::StrFormat("  %3d   %8s   0x%08x   %s\n", index,
                                        active ? "active" : "inactive", address,
                                        symbol.empty() ? "-" : symbol));
      }
      auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
          core_access_[current_core_].debug_interface);
      if (cheriot_interface->BreakOnControlFlowChange()) {
        absl::StrAppend(&bp_list,
                        absl::StrFormat("        %8s   0x%08s   %s\n", "active",
                                        "--------", "$branch"));
      }
      if (interrupt_listeners_[current_core_]->AreExceptionsEnabled()) {
        absl::StrAppend(&bp_list,
                        absl::StrFormat("        %8s   0x%08s   %s\n", "active",
                                        "--------", "$exception"));
      }
      if (interrupt_listeners_[current_core_]->AreInterruptsEnabled()) {
        absl::StrAppend(&bp_list,
                        absl::StrFormat("        %8s   0x%08s   %s\n", "active",
                                        "--------", "$interrupt"));
      }
      os << bp_list << std::endl;
      continue;
    }

    // help
    if (RE2::FullMatch(line_view, *help_re_)) {
      for (auto const &usage : command_usage_) {
        os << usage << std::endl;
      }
      os << help_message_;
      os.flush();
      continue;
    }

    // reg NAME
    if (std::string name, format;
        RE2::FullMatch(line_view, *read_reg2_re_, &name, &format)) {
      if (name == "$all") {
        os << FormatAllRegisters(current_core_) << std::endl;
        continue;
      }
      os << FormatRegister(current_core_, name) << std::endl;
      os.flush();
      continue;
    }

    // watch set SYMBOL | VALUE  <length> [r|w|rw]
    if (std::string str_value, length_value, rw_value; RE2::FullMatch(
            line_view, *set_watch_re_, &str_value, &length_value, &rw_value)) {
      auto result = GetValueFromString(current_core_, str_value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: '", str_value, "' ",
                           result.status().message())
           << std::endl;
        os.flush();
        continue;
      }
      if (!rw_value.empty()) {
        rw_value = rw_value.substr(rw_value.find_first_not_of(' '));
      }
      AccessType access_type = AccessType::kStore;
      if (rw_value == "r") {
        access_type = AccessType::kLoad;
      } else if (rw_value == "rw") {
        access_type = AccessType::kStore;
      }

      uint64_t address = result.value();
      result = GetValueFromString(current_core_, length_value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: cannot parse '", length_value,
                           "' as a length\n");
        os.flush();
        continue;
      }
      size_t length = result.value();
      auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
          core_access_[current_core_].debug_interface);
      auto cmd_result =
          cheriot_interface->SetDataWatchpoint(address, length, access_type);
      if (!cmd_result.ok()) {
        os << "Error:  " << cmd_result.message() << std::endl;
        os.flush();
        continue;
      }
      core_access_[current_core_]
          .watchpoint_map[core_access_[current_core_].watchpoint_index++] = {
          address, length, access_type, /*active=*/true};
      os << absl::StrCat("Watchpoint set at 0x",
                         absl::Hex(address, absl::PadSpec::kZeroPad8))
         << std::endl;
      continue;
    }

    // watch set #<N>
    if (std::string str_value, num_value;
        RE2::FullMatch(line_view, *set_watch_n_re_, &str_value, &num_value)) {
      int index;
      if (!absl::SimpleAtoi(num_value, &index)) {
        os << absl::StrCat("Error: cannot parse '", str_value,
                           "' as a watchpoint index\n");
        continue;
      }
      auto iter = core_access_[current_core_].watchpoint_map.find(index);
      if (iter == core_access_[current_core_].watchpoint_map.end()) {
        os << absl::StrCat("Error: no watchpoint with index ", index, "\n");
        continue;
      }
      if (iter->second.active) {
        os << "Watchpoint already active\n";
        continue;
      }
      uint64_t address = iter->second.address;
      size_t length = iter->second.length;
      AccessType access_type = iter->second.access_type;
      auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
          core_access_[current_core_].debug_interface);
      auto status =
          cheriot_interface->SetDataWatchpoint(address, length, access_type);
      if (!status.ok()) {
        os << absl::StrCat("Error: ", status.message(), "\n");
        continue;
      }
      iter->second.active = true;
      continue;
    }

    // watch clear #<N>
    if (std::string str_value;
        RE2::FullMatch(line_view, *clear_watch_n_re_, &str_value)) {
      int index;
      if (!absl::SimpleAtoi(str_value, &index)) {
        os << absl::StrCat("Error: cannot parse '", str_value,
                           "' as a watchpoint index\n");
        continue;
      }
      auto iter = core_access_[current_core_].watchpoint_map.find(index);
      if (iter == core_access_[current_core_].watchpoint_map.end()) {
        os << absl::StrCat("Error: no watchpoint with index ", index, "\n");
        continue;
      }
      if (!iter->second.active) continue;
      uint64_t address = iter->second.address;
      auto access_type = iter->second.access_type;
      auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
          core_access_[current_core_].debug_interface);
      auto status =
          cheriot_interface->ClearDataWatchpoint(address, access_type);
      if (!status.ok()) {
        os << absl::StrCat("Error: ", status.message(), "\n");
        continue;
      }
      iter->second.active = false;
      continue;
    }

    // watch clear-all
    if (RE2::FullMatch(line_view, *clear_all_watch_re_)) {
      for (auto &[index, info] : core_access_[current_core_].watchpoint_map) {
        if (!info.active) continue;

        uint64_t address = info.address;
        auto access_type = info.access_type;
        auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
            core_access_[current_core_].debug_interface);
        auto status =
            cheriot_interface->ClearDataWatchpoint(address, access_type);
        if (!status.ok()) {
          os << absl::StrCat("Error: ", status.message(), "\n");
          continue;
        }
        info.active = false;
      }
      os << "All watchpoints removed" << std::endl;
      continue;
    }

    // watch clear VALUE | SYMBOL [r|w|rw]
    if (std::string str_value, rw_value;
        RE2::FullMatch(line_view, *clear_watch_re_, &str_value, &rw_value)) {
      auto result = GetValueFromString(current_core_, str_value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: '", str_value, "' ",
                           result.status().message())
           << std::endl;
        os.flush();
        continue;
      }
      if (!rw_value.empty()) {
        rw_value = rw_value.substr(rw_value.find_first_not_of(' '));
      }
      auto access_type = AccessType::kStore;
      if (rw_value == "r") {
        access_type = AccessType::kLoad;
      } else if (rw_value == "rw") {
        access_type = AccessType::kLoadStore;
      }
      bool done = false;
      for (auto &[index, info] : core_access_[current_core_].watchpoint_map) {
        if ((info.address == result.value()) &&
            (info.access_type == access_type)) {
          auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
              core_access_[current_core_].debug_interface);
          auto cmd_result = cheriot_interface->ClearDataWatchpoint(
              result.value(), access_type);
          if (!cmd_result.ok()) {
            os << "Error:  " << cmd_result.message() << std::endl;
            os.flush();
            break;
          }
          info.active = false;
          done = true;
          break;
        }
      }
      if (!done) {
        continue;
      }
      os << absl::StrCat("Watchpoint removed from 0x",
                         absl::Hex(result.value(), absl::PadSpec::kZeroPad8))
         << std::endl;
      continue;
    }

    // watch SYMBOL | VALUE [r|w|rw]
    if (std::string str_value, length_value, rw_value; RE2::FullMatch(
            line_view, *set_watch2_re_, &str_value, &length_value, &rw_value)) {
      auto result = GetValueFromString(current_core_, str_value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: '", str_value, "' ",
                           result.status().message())
           << std::endl;
        os.flush();
        continue;
      }
      AccessType access_type = AccessType::kStore;
      if (!rw_value.empty()) {
        rw_value = rw_value.substr(rw_value.find_first_not_of(' '));
      }
      if (rw_value == "r") {
        access_type = AccessType::kLoad;
      } else if (rw_value == "rw") {
        access_type = AccessType::kLoadStore;
      }
      uint64_t address = result.value();
      result = GetValueFromString(current_core_, length_value, /*radix=*/0);
      if (!result.ok()) {
        os << absl::StrCat("Error: cannot parse '", length_value,
                           "' as a length\n");
        os.flush();
        continue;
      }
      size_t length = result.value();
      auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
          core_access_[current_core_].debug_interface);
      auto cmd_result =
          cheriot_interface->SetDataWatchpoint(address, length, access_type);
      if (!cmd_result.ok()) {
        os << "Error:  " << cmd_result.message() << std::endl;
        os.flush();
        continue;
      }
      core_access_[current_core_]
          .watchpoint_map[core_access_[current_core_].watchpoint_index++] = {
          address, length, access_type, /*active=*/true};
      os << absl::StrCat("Watchpoint set at 0x",
                         absl::Hex(address, absl::PadSpec::kZeroPad8))
         << std::endl;
      continue;
    }

    // watch list
    if (RE2::FullMatch(line_view, *list_watch_re_)) {
      std::string bp_list;
      for (auto const &[index, info] :
           core_access_[current_core_].watchpoint_map) {
        std::string symbol;
        auto *loader = core_access_[current_core_].loader_getter();
        if (loader != nullptr) {
          auto res = loader->GetFcnSymbolName(info.address);
          if (res.ok()) symbol = std::move(res.value());
        }
        std::string access_type;
        switch (info.access_type) {
          case AccessType::kStore:
            access_type = "w";
            break;
          case AccessType::kLoad:
            access_type = "r";
            break;
          case AccessType::kLoadStore:
            access_type = "rw";
        }
        absl::StrAppend(
            &bp_list,
            absl::StrFormat("  %3d   %-8s   0x%08x   %3d   %2s   %s\n", index,
                            info.active ? "active" : "inactive", info.address,
                            info.length, access_type,
                            symbol.empty() ? "-" : symbol));
      }
      os << absl::StrCat("Watchpoints:\n", bp_list, "\n");
      continue;
    }

    // mem get VALUE | SYMBOL [FORMAT]
    if (std::string str_value, format;
        RE2::FullMatch(line_view, *read_mem2_re_, &str_value, &format)) {
      os << ReadMemory(current_core_, str_value, format) << std::endl;
      continue;
    }

    // Action points.
    if (RE2::FullMatch(line_view, *list_action_re_)) {
      os << ListActionPoints();
      continue;
    }
    if (std::string str_value;
        RE2::FullMatch(line_view, *enable_action_n_re_, &str_value)) {
      os << EnableActionPointN(str_value);
      continue;
    }
    if (std::string str_value;
        RE2::FullMatch(line_view, *disable_action_n_re_, &str_value)) {
      os << DisableActionPointN(str_value);
      continue;
    }
    if (std::string str_value;
        RE2::FullMatch(line_view, *clear_action_n_re_, &str_value)) {
      os << ClearActionPointN(str_value);
      continue;
    }
    if (RE2::FullMatch(line_view, *clear_all_action_re_)) {
      os << ClearAllActionPoints();
      continue;
    }
    // branch-trace.
    // This prints out a list of the last 16 pairs of <from, to> control flow
    // changes (including interrupts), with no repetitions for loops.
    if (RE2::FullMatch(line_view, *branch_trace_re_)) {
      // Get the index of the head of the queue.
      auto head_result =
          core_access_[current_core_].debug_interface->ReadRegister(
              "$branch_trace_head");
      if (!head_result.ok()) {
        os << "Error: " << head_result.status().message() << "\n";
        continue;
      }
      // Adjust by one, as the head points to the most recent valid entry.
      auto head = head_result.value() + 1;
      // Get the branch trace data buffer.
      auto result =
          core_access_[current_core_].debug_interface->GetRegisterDataBuffer(
              "$branch_trace");
      if (!result.ok()) {
        os << "Error: " << result.status().message() << "\n";
        continue;
      }
      auto *db = result.value();
      // Check for null data buffer.
      if (db == nullptr) {
        os << "Error: register '$branch_trace' has no data buffer\n";
        os.flush();
        continue;
      }
      // Get a span for the branch trace.
      auto trace_span = db->Get<BranchTraceEntry>();
      auto size = trace_span.size();
      os << absl::StrFormat("     %-8s      %-8s     %8s\n", "From", "To",
                            "Count");
      for (int i = 0; i < size; ++i) {
        auto index = (head + i) % size;
        auto [from, to, count] = trace_span[index];
        // Ignore 0 -> 0 entries. Those are the initial values.
        if (count == 0) continue;
        os << absl::StrFormat("   0x%08x -> 0x%08x     %8u\n", from, to, count);
      }
      os.flush();
      continue;
    }

    // Step (over function call).
    if (RE2::FullMatch(line_view, *next_re_)) {
      auto res = StepOverCall(current_core_, os);
      if (!res.ok()) {
        os << "Error: " << res.message() << "\n";
      }
      continue;
    }

    if (std::string file_name;
        RE2::FullMatch(line_view, *exec_re_, &file_name)) {
      auto *ifile = new std::ifstream(file_name);
      if (!ifile->is_open() || !ifile->good()) {
        os << "Error: unable to open '" << file_name << "'\n";
        os.flush();
        continue;
      }
      previous_commands_.push_back(previous_line);
      command_streams_.push_back(ifile);
      continue;
    }

    // At this point a valid command should have been matched, so assume an
    // error.
    os << absl::StrCat("Error: unrecognized command '", line, "'") << std::endl;
    os.flush();
  }
}
// NOLINTEND(readability/fn_size)

void DebugCommandShell::AddCommand(absl::string_view usage,
                                   CommandFunction command_function) {
  command_usage_.emplace_back(usage);
  command_functions_.emplace_back(std::move(command_function));
}

namespace {

constexpr absl::string_view kHexFormatNone = "%x";
constexpr absl::string_view kHexFormatCapNone = "%X";
constexpr absl::string_view kHexFormatUint8 = "%02x";
constexpr absl::string_view kHexFormatCapUint8 = "%02X";
constexpr absl::string_view kHexFormatUint16 = "%04x";
constexpr absl::string_view kHexFormatCapUint16 = "%04X";
constexpr absl::string_view kHexFormatUint32 = "%08x";
constexpr absl::string_view kHexFormatCapUint32 = "%08X";
constexpr absl::string_view kHexFormatUint64 = "%016x";
constexpr absl::string_view kHexFormatCapUint64 = "%016X";

constexpr absl::string_view kHexFormat[] = {
    kHexFormatNone, kHexFormatUint8,  kHexFormatUint16,
    kHexFormatNone, kHexFormatUint32, kHexFormatNone,
    kHexFormatNone, kHexFormatNone,   kHexFormatUint64};

constexpr absl::string_view kHexFormatCap[] = {
    kHexFormatCapNone, kHexFormatCapUint8,  kHexFormatCapUint16,
    kHexFormatCapNone, kHexFormatCapUint32, kHexFormatCapNone,
    kHexFormatCapNone, kHexFormatCapNone,   kHexFormatCapUint64};

// Templated helper function to help format integer values of different widths.
template <typename T>
std::string FormatDbValue(generic::DataBuffer *db, absl::string_view format,
                          int index) {
  std::string output;
  if (index < 0 || index >= db->size<T>()) return "Error: index out of range";
  T value = db->Get<T>(index);
  switch (format[0]) {
    case 'd':
      output += absl::StrFormat("%d", value);
      break;
    case 'o':
      output += absl::StrFormat("%o", value);
      break;
    case 'u':
      output += absl::StrFormat("%u", value);
      break;
    case 'x':
      output += absl::StrFormat(kHexFormat[sizeof(T)], value);
      break;
    case 'X':
      output += absl::StrFormat(kHexFormatCap[sizeof(T)], value);
      break;
    default:
      output = absl::StrCat("Error: invalid '", format, "'");
      break;
  }
  return output;
}

template <typename T>
absl::Status WriteDbValue(absl::string_view str_value, absl::string_view format,
                          int index, generic::DataBuffer *db) {
  if (index < 0 || index >= db->size<T>())
    return absl::OutOfRangeError("Error: index out of range");
  if (format[0] == 'd') {
    int64_t value;
    if (!absl::SimpleAtoi(str_value, &value)) {
      return absl::InvalidArgumentError(
          absl::StrCat("Error: could not convert '", str_value, "' to number"));
    }
    db->Set<T>(index, static_cast<T>(value));
    return absl::OkStatus();
  }
  if (format[0] == 'u') {
    uint64_t value;
    if (!absl::SimpleAtoi(str_value, &value)) {
      return absl::InvalidArgumentError(
          absl::StrCat("Error: could not convert '", str_value, "' to number"));
    }
    db->Set<T>(index, static_cast<T>(value));
    return absl::OkStatus();
  }
  if (format[0] == 'x' || format[0] == 'X') {
    uint64_t value;
    if (!absl::SimpleHexAtoi(str_value, &value)) {
      return absl::InvalidArgumentError(
          absl::StrCat("Error: could not convert '", str_value, "' to number"));
    }
    db->Set<T>(index, static_cast<T>(value));
    return absl::OkStatus();
  }
  return absl::InternalError(absl::StrCat("Unsupported format '", format, "'"));
}

}  // namespace

std::string DebugCommandShell::FormatSingleDbValue(generic::DataBuffer *db,
                                                   const std::string &format,
                                                   int width, int index) const {
  switch (width) {
    case 8:
      return FormatDbValue<uint8_t>(db, format, index);
    case 16:
      return FormatDbValue<uint16_t>(db, format, index);
    case 32:
      return FormatDbValue<uint32_t>(db, format, index);
    case 64:
      return FormatDbValue<uint64_t>(db, format, index);
    default:
      return absl::StrCat("Error: illegal width '", width, "'");
  }
}

std::string DebugCommandShell::FormatAllDbValues(generic::DataBuffer *db,
                                                 const std::string &format,
                                                 int width) const {
  std::string output;
  std::string sep;
  switch (width) {
    case 8:
      for (int i = 0; i < db->size<uint8_t>(); ++i) {
        output += sep + FormatDbValue<uint8_t>(db, format, i);
        sep = ":";
      }
      break;
    case 16:
      for (int i = 0; i < db->size<uint16_t>(); ++i) {
        output += sep + FormatDbValue<uint16_t>(db, format, i);
        sep = ":";
      }
      break;
    case 32:
      for (int i = 0; i < db->size<uint32_t>(); ++i) {
        output += sep + FormatDbValue<uint32_t>(db, format, i);
        sep = ":";
      }
      break;
    case 64:
      for (int i = 0; i < db->size<uint64_t>(); ++i) {
        output += sep + FormatDbValue<uint64_t>(db, format, i);
        sep = ":";
      }
      break;
    default:
      output = absl::StrCat("Error: illegal width '", width, "'");
      break;
  }
  return output;
}

absl::Status DebugCommandShell::WriteSingleValueToDb(
    absl::string_view str_value, generic::DataBuffer *db, std::string format,
    int width, int index) const {
  switch (width) {
    case 8:
      return WriteDbValue<uint8_t>(str_value, format, index, db);
    case 16:
      return WriteDbValue<uint16_t>(str_value, format, index, db);
    case 32:
      return WriteDbValue<uint32_t>(str_value, format, index, db);
    case 64:
      return WriteDbValue<uint64_t>(str_value, format, index, db);
    default:
      return absl::InternalError("Error");
  }
  return absl::OkStatus();
}

std::string DebugCommandShell::ReadMemory(int core,
                                          const std::string &str_value,
                                          absl::string_view format) {
  int size = 0;
  char format_char = 'x';
  int bit_width = 32;

  // Get the bit width, but only if the format is not 'i'.
  if (!format.empty()) {
    if (format[0] == 'i') {
      format_char = 'i';
    } else {
      // Check the format specification.
      auto pos = format.find_first_not_of(' ');
      format_char = format[pos];
      auto status = absl::SimpleAtoi(format.substr(pos + 1), &bit_width);
      if (!status) {
        return absl::StrCat("Error '", format.substr(pos + 1),
                            "': ", "unable to convert to int");
      }
      if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32) &&
          (bit_width != 64)) {
        return absl::StrCat("Illegal bit width specification: ", bit_width);
      }
    }
  }

  // Get the address.
  auto result = GetValueFromString(current_core_, str_value, /*radix=*/0);
  if (!result.ok()) {
    return absl::StrCat("Error: '", str_value, "' ", result.status().message());
  }
  auto address = result.value();

  // If format is 'i', then we are getting a disassembled instruction. Ignore
  // bitwidth.
  if (format_char == 'i') {
    auto disasm_result =
        core_access_[current_core_].debug_interface->GetDisassembly(address);
    if (!disasm_result.ok()) {
      return absl::StrCat("Error: ", disasm_result.status().message());
    }
    return absl::StrCat("    ", disasm_result.value());
  }

  // Perform the memory access.
  size = bit_width / 8;
  if (size > kMemBufferSize) size = kMemBufferSize;
  auto mem_result = core_access_[current_core_].debug_interface->ReadMemory(
      address, mem_buffer_, size);
  if (!mem_result.ok()) {
    return absl::StrCat("Error: ", mem_result.status().message());
  }
  // Perform tag memory access.
  // There is a tag per each 8 bytes of data. So compute the number of tags
  // that need to be loaded, taking into account misalignment.
  auto tag_address = address & ~0x7ULL;
  int tag_size = (address + size - tag_address + 7) / 8;
  auto *cheriot_interface = reinterpret_cast<CheriotDebugInterface *>(
      core_access_[current_core_].debug_interface);
  auto tag_result =
      cheriot_interface->ReadTagMemory(tag_address, tag_buffer_, tag_size);
  if (!tag_result.ok()) {
    return absl::StrCat("Error: ", tag_result.status().message());
  }
  std::string tag_string;
  std::string sep = "[";
  for (int i = 0; i < tag_size; ++i) {
    absl::StrAppend(&tag_string, sep, tag_buffer_[i]);
    sep = ", ";
  }
  absl::StrAppend(&tag_string, "]");
  // Get the result and format it.
  void *void_buffer = mem_buffer_;
  std::string output;
  if ((format_char == 'f') && (bit_width >= 32)) {
    switch (bit_width) {
      case 32:
        output = absl::StrCat(*reinterpret_cast<float *>(void_buffer));
        break;
      case 64:
        output = absl::StrCat(*reinterpret_cast<double *>(void_buffer));
        break;
      default:
        break;
    }
  } else if (format_char == 'd') {
    switch (bit_width) {
      case 8:
        output = absl::StrCat(*static_cast<int8_t *>(void_buffer));
        break;
      case 16:
        output = absl::StrCat(*static_cast<int16_t *>(void_buffer));
        break;
      case 32:
        output = absl::StrCat(*static_cast<int32_t *>(void_buffer));
        break;
      case 64:
        output = absl::StrCat(*static_cast<int64_t *>(void_buffer));
        break;
      default:
        break;
    }
  } else {
    uint64_t val = 0;
    auto pad = absl::PadSpec::kNoPad;
    switch (bit_width) {
      case 8:
        val = *static_cast<uint8_t *>(void_buffer);
        pad = absl::PadSpec::kZeroPad2;
        break;
      case 16:
        val = *static_cast<uint16_t *>(void_buffer);
        pad = absl::PadSpec::kZeroPad4;
        break;
      case 32:
        val = *static_cast<uint32_t *>(void_buffer);
        pad = absl::PadSpec::kZeroPad8;
        break;
      case 64:
        val = *static_cast<uint64_t *>(void_buffer);
        pad = absl::PadSpec::kZeroPad16;
        break;
    }
    std::string format_string;
    if ((format_char == 'x') || (format_char == 'X')) {
      output = absl::StrCat(absl::Hex(val, pad));
    } else if (format_char == 'u') {
      output = absl::StrCat(val);
    } else {
      output = absl::StrFormat("%o", val);
    }
  }
  return absl::StrCat("[", absl::Hex(address, absl::PadSpec::kZeroPad8),
                      "] = ", output, "  ", tag_string);
}

std::string DebugCommandShell::WriteMemory(int core,
                                           const std::string &str_value1,
                                           const std::string &format,
                                           const std::string &str_value2) {
  int size = 0;
  char format_char = '\0';
  int radix = 0;
  int bit_width = 32;
  if (!format.empty()) {
    // Check the format specification.
    auto pos = format.find_first_not_of(' ');
    format_char = format[pos];
    if ((format_char == 'x') || (format_char == 'X')) {
      radix = 16;
    } else if ((format_char == 'd') || (format_char == 'u')) {
      radix = 10;
    } else if (format_char == 'o') {
      radix = 8;
    }
    auto status = riscv::internal::stoull(format.substr(pos + 1));
    bit_width = 0;
    if (!status.ok()) {
      return absl::StrCat("Error '", format.substr(pos + 1),
                          "': ", status.status().message());
    }
    bit_width = status.value();
  }

  // Determine the zero padding for hex number.
  auto pad = absl::kNoPad;
  if (bit_width == 8) {
    pad = absl::kZeroPad2;
  } else if (bit_width == 16) {
    pad = absl::kZeroPad4;
  } else if (bit_width == 32) {
    pad = absl::kZeroPad8;
  } else if (bit_width == 64) {
    pad = absl::kZeroPad16;
  } else {
    return absl::StrCat("Illegal bit width specification: ", bit_width);
  }

  // Get the address.
  auto result = GetValueFromString(current_core_, str_value1, /*radix=*/0);
  if (!result.ok()) {
    return absl::StrCat("Error: '", str_value1, "' ",
                        result.status().message());
  }
  auto address = result.value();

  // Get the value to be stored.
  auto value_result = GetValueFromString(current_core_, str_value2, radix);
  if (!value_result.ok()) {
    return absl::StrCat("Error: '", str_value2, "' ",
                        result.status().message());
  }
  int64_t mem_value = value_result.value();

  // Perform the memory access.
  size = bit_width / 8;
  if (size > kMemBufferSize) size = kMemBufferSize;
  std::memcpy(mem_buffer_, &mem_value, size);
  auto mem_result = core_access_[current_core_].debug_interface->WriteMemory(
      address, mem_buffer_, size);
  if (!mem_result.ok()) {
    return absl::StrCat("Error: ", mem_result.status().message());
  }
  return absl::StrCat("[", absl::Hex(address, absl::kZeroPad8),
                      "] = ", absl::Hex(mem_value, pad));
}

absl::StatusOr<uint64_t> DebugCommandShell::GetValueFromString(
    int core, const std::string &str_value, int radix) {
  size_t index;
  // Attempt to convert to a number.
  auto convert_result = riscv::internal::stoull(str_value, &index, radix);
  // If successful and the entire string was consumed, the number is good.
  if (convert_result.ok() && (index >= str_value.size())) {
    return convert_result.value();
  }
  // If it's out of range, signal an error.
  if (convert_result.status().code() == absl::StatusCode::kOutOfRange) {
    return convert_result.status();
  }
  // If all else fails, let's see if it's a symbol.
  auto *loader = core_access_[core].loader_getter();
  if (loader == nullptr)
    return absl::NotFoundError("No symbol table available");
  auto result = loader->GetSymbol(str_value);
  if (!result.ok()) return result.status();
  return result.value().first;
}

absl::Status DebugCommandShell::StepOverCall(int core, std::ostream &os) {
  auto pcc_result =
      core_access_[current_core_].debug_interface->ReadRegister("pcc");
  if (!pcc_result.ok()) {
    return absl::UnavailableError(pcc_result.status().message());
  }
  auto pcc = pcc_result.value();
  auto inst_res =
      core_access_[current_core_].debug_interface->GetInstruction(pcc);
  if (!inst_res.ok()) {
    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 ((opcode != *isa32::OpcodeEnum::kCheriotJal) &&
      (opcode != *isa32::OpcodeEnum::kCheriotJalCra) &&
      (opcode != *isa32::OpcodeEnum::kCheriotJalr) &&
      (opcode != *isa32::OpcodeEnum::kCheriotJalrCra) &&
      (opcode != *isa32::OpcodeEnum::kCheriotCjal) &&
      (opcode != *isa32::OpcodeEnum::kCheriotCjalCra) &&
      (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
  // following the jump-and-link, then run until it halts, which may even be
  // on another breakpoint. Either way, we then remove the breakpoint we
  // inserted and return.
  uint64_t bp_address = pcc + inst->size();
  inst->DecRef();
  // See if there is a bp on that address already, if so, don't try to set
  // another one.
  if (!core_access_[current_core_].debug_interface->HasBreakpoint(bp_address)) {
    auto bp_set_res =
        core_access_[current_core_].debug_interface->SetSwBreakpoint(
            bp_address);
    if (!bp_set_res.ok()) {
      return bp_set_res;
    }
  }
  auto run_res = core_access_[current_core_].debug_interface->Run();
  if (!run_res.ok()) {
    // First remove the breakpoint, then return error.
    (void)core_access_[current_core_].debug_interface->ClearSwBreakpoint(
        bp_address);
    return run_res;
  }
  (void)core_access_[current_core_].debug_interface->Wait();
  auto bp_clr_res =
      core_access_[current_core_].debug_interface->ClearSwBreakpoint(
          bp_address);
  pcc_result = core_access_[current_core_].debug_interface->ReadRegister("pcc");
  pcc = pcc_result.value();
  if (pcc != bp_address) {
    os << absl::StrCat(
        "Warning: Stopped at instruction other than the expected: [",
        absl::Hex(bp_address, absl::kZeroPad8), "]\n");
  }
  return bp_clr_res;
}

std::string DebugCommandShell::FormatCapabilityRegister(
    int core, const std::string &reg_name) const {
  std::string output;
  std::vector<uint64_t> values;
  auto res =
      core_access_[current_core_].debug_interface->ReadRegister(reg_name);
  if (!res.ok()) {
    return absl::StrCat("Error reading '", reg_name,
                        "': ", res.status().message());
  }
  values.push_back(res.value());
  // Read the capability components.
  for (auto const &suffix :
       {"tag", "base", "top", "length", "object_type", "permissions"}) {
    res = core_access_[current_core_].debug_interface->ReadRegister(
        absl::StrCat(reg_name, ".", suffix));
    if (!res.ok()) {
      return absl::StrCat("Error reading '", reg_name, ".", suffix,
                          "': ", res.status().message());
    }
    values.push_back(res.value());
  }
  // Format the capability register components into a readable format.
  uint64_t obj_type =
      values[5] |
      ((values[5] && !(values[6] & PB::kPermitExecute)) ? 0x8 : 0x0);
  std::string permissions =
      absl::StrCat(values[6] & PB::kPermitGlobal ? "G " : "- ",
                   values[6] & PB::kPermitLoad ? "R" : "-",
                   values[6] & PB::kPermitStore ? "W" : "-",
                   values[6] & PB::kPermitLoadStoreCapability ? "c" : "-",
                   values[6] & PB::kPermitLoadMutable ? "m" : "-",
                   values[6] & PB::kPermitLoadGlobal ? "g" : "-",
                   values[6] & PB::kPermitStoreLocalCapability ? "l " : "- ",
                   values[6] & PB::kPermitExecute ? "X" : "-",
                   values[6] & PB::kPermitAccessSystemRegisters ? "a " : "- ",
                   values[6] & PB::kPermitSeal ? "S" : "-",
                   values[6] & PB::kPermitUnseal ? "U" : "-",
                   values[6] & PB::kUserPerm0 ? "0" : "-");
  absl::StrAppend(
      &output,
      absl::StrFormat(
          "%-5s = 0x%08x (v: %1x 0x%08x-0x%09x l: 0x%09x o: 0x%x p: %s)",
          reg_name, values[0], values[1], values[2], values[3], values[4],
          obj_type, permissions));
  return output;
}

bool DebugCommandShell::IsCapabilityRegister(
    const std::string &reg_name) const {
  return capability_registers_.contains(reg_name);
}

std::string DebugCommandShell::FormatRegister(
    int core, const std::string &reg_name) const {
  if (IsCapabilityRegister(reg_name)) {
    return FormatCapabilityRegister(current_core_, reg_name);
  }
  std::string output;
  auto result =
      core_access_[current_core_].debug_interface->ReadRegister(reg_name);
  if (result.ok()) {
    absl::StrAppend(&output, reg_name, " = ", absl::Hex(result.value()));
  } else {
    absl::StrAppend(&output, "Error reading '", reg_name,
                    "': ", result.status().message());
  }
  return output;
}

std::string DebugCommandShell::FormatAllRegisters(int core) const {
  std::string output;
  // Interrupt stack.
  auto cheriot_state =
      static_cast<CheriotState *>(core_access_[current_core_].state);
  auto &info_list = cheriot_state->interrupt_info_list();
  int count = 0;
  if (!info_list.empty()) {
    absl::StrAppend(&output, "Interrupt stack:\n");
    for (auto iter = info_list.rbegin(); iter != info_list.rend(); ++iter) {
      auto const &info = *iter;
      absl::StrAppend(&output, "[", count++, "] ",
                      info.is_interrupt ? "interrupt" : "exception", " ",
                      info.is_interrupt ? GetInterruptDescription(info)
                                        : GetExceptionDescription(info));
    }
    absl::StrAppend(&output, "\n");
  }
  // Registers.
  for (auto const &reg_name : reg_vector_) {
    absl::StrAppend(&output, FormatRegister(current_core_, reg_name), "\n");
  }
  return output;
}

// Action point methods.
std::string DebugCommandShell::ListActionPoints() {
  std::string output;
  auto &action_map = core_action_point_info_[current_core_];
  for (auto const &[local_id, info] : action_map) {
    absl::StrAppend(
        &output,
        absl::StrFormat("%02d  [0x%08lx] %8s  %s\n", local_id, info.address,
                        info.is_enabled ? "enabled" : "disabled", info.name));
  }
  return output;
}

std::string DebugCommandShell::EnableActionPointN(
    const std::string &index_str) {
  auto res = riscv::internal::stoull(index_str, nullptr, 10);
  if (!res.ok()) {
    return std::string(res.status().message());
  }
  auto &action_map = core_action_point_info_[current_core_];
  int index = res.value();
  auto it = action_map.find(index);
  if (it == action_map.end()) {
    return absl::StrCat("Action point ", index, " not found");
  }
  auto &info = it->second;
  if (info.is_enabled) {
    return absl::StrCat("Action point ", index, " is already enabled");
  }
  info.is_enabled = true;
  auto *dbg_if = core_access_[current_core_].debug_interface;
  auto *cheriot_dbg_if = static_cast<CheriotDebugInterface *>(dbg_if);
  auto status = cheriot_dbg_if->EnableAction(info.address, info.id);
  if (!status.ok()) {
    return absl::StrCat("Error: ", status.message());
  }
  return "";
}

std::string DebugCommandShell::DisableActionPointN(
    const std::string &index_str) {
  auto res = riscv::internal::stoull(index_str, nullptr, 10);
  if (!res.ok()) {
    return std::string(res.status().message());
  }
  auto &action_map = core_action_point_info_[current_core_];
  int index = res.value();
  auto it = action_map.find(index);
  if (it == action_map.end()) {
    return absl::StrCat("Action point ", index, " not found");
  }
  auto &info = it->second;
  if (!info.is_enabled) {
    return absl::StrCat("Action point ", index, " is already disabled");
  }
  info.is_enabled = false;
  auto *dbg_if = core_access_[current_core_].debug_interface;
  auto *cheriot_dbg_if = static_cast<CheriotDebugInterface *>(dbg_if);
  auto status = cheriot_dbg_if->DisableAction(info.address, info.id);
  if (!status.ok()) {
    return absl::StrCat("Error: ", status.message());
  }
  return "";
}

std::string DebugCommandShell::ClearActionPointN(const std::string &index_str) {
  auto res = riscv::internal::stoull(index_str, nullptr, 10);
  if (!res.ok()) {
    return std::string(res.status().message());
  }
  auto &action_map = core_action_point_info_[current_core_];
  int index = res.value();
  auto it = action_map.find(index);
  if (it == action_map.end()) {
    return absl::StrCat("Action point ", index, " not found");
  }
  auto &info = it->second;
  auto *dbg_if = core_access_[current_core_].debug_interface;
  auto *cheriot_dbg_if = static_cast<CheriotDebugInterface *>(dbg_if);
  auto status = cheriot_dbg_if->ClearActionPoint(info.address, info.id);
  if (!status.ok()) {
    return absl::StrCat("Error: ", status.message());
  }
  action_map.erase(it);
  return "";
}

std::string DebugCommandShell::ClearAllActionPoints() {
  std::string output;
  auto *dbg_if = core_access_[current_core_].debug_interface;
  auto *cheriot_dbg_if = static_cast<CheriotDebugInterface *>(dbg_if);
  for (auto &[local_id, info] : core_action_point_info_[current_core_]) {
    auto status = cheriot_dbg_if->ClearActionPoint(info.address, info.id);
    if (!status.ok()) {
      absl::StrAppend(&output, "Error: ", status.message());
    }
  }
  return output;
}

absl::Status DebugCommandShell::SetActionPoint(
    uint64_t address, std::string name,
    absl::AnyInvocable<void(uint64_t, int)> function) {
  auto *dbg_if = core_access_[current_core_].debug_interface;
  auto *cheriot_dbg_if = static_cast<CheriotDebugInterface *>(dbg_if);
  auto result = cheriot_dbg_if->SetActionPoint(address, std::move(function));
  if (!result.ok()) {
    return absl::InternalError(result.status().message());
  }
  int id = result.value();
  int local_id = core_action_point_id_[current_core_]++;
  auto &action_map = core_action_point_info_[current_core_];
  action_map.emplace(local_id, ActionPointInfo{address, id, name, true});
  return absl::OkStatus();
}

std::string DebugCommandShell::GetInterruptDescription(
    const InterruptInfo &info) const {
  std::string output;
  if (!info.is_interrupt) return output;
  switch (info.cause & 0x7fff'ffff) {
    case 0:
      absl::StrAppend(&output, "User software interrupt");
      break;
    case 1:
      absl::StrAppend(&output, "Supervisor software interrupt");
      break;
    case 3:
      absl::StrAppend(&output, "Machine software interrupt");
      break;
    case 4:
      absl::StrAppend(&output, "User timer interrupt");
      break;
    case 5:
      absl::StrAppend(&output, "Supervisor timer interrupt");
      break;
    case 7:
      absl::StrAppend(&output, "Machine timer interrupt");
      break;
    case 8:
      absl::StrAppend(&output, "User external interrupt");
      break;
    case 9:
      absl::StrAppend(&output, "Supervisor external interrupt");
      break;
    case 11:
      absl::StrAppend(&output, "Machine external interrupt");
      break;
    default:
      absl::StrAppend(&output, "Error - Unknown interrupt");
      break;
  }
  absl::StrAppend(&output, "\n");
  return output;
}

std::string DebugCommandShell::GetExceptionDescription(
    const InterruptInfo &info) const {
  std::string output;
  if (info.is_interrupt) return output;
  absl::StrAppend(&output, " Exception taken at ", absl::Hex(info.epc), ": ");
  switch (info.cause) {
    case 0:
      absl::StrAppend(&output, "Instruction address misaligned: ");
      absl::StrAppend(&output, ": ", absl::Hex(info.tval));
      break;
    case 1:
      absl::StrAppend(&output, "Instruction access fault");
      break;
    case 2:
      absl::StrAppend(&output, "Illegal instruction");
      absl::StrAppend(&output, " opcode: ", absl::Hex(info.tval));
      break;
    case 3:
      absl::StrAppend(&output, "Breakpoint instruction");
      break;
    case 4:
      absl::StrAppend(&output, "Load address misaligned");
      absl::StrAppend(&output, ": ", absl::Hex(info.tval));
      break;
    case 5:
      absl::StrAppend(&output, "Load access fault");
      break;
    case 6:
      absl::StrAppend(&output, "Store/AMO address misaligned");
      absl::StrAppend(&output, ": ", absl::Hex(info.tval));
      break;
    case 7:
      absl::StrAppend(&output, "Store/AMO access fault");
      break;
    case 8:
      absl::StrAppend(&output, "Environment call from U-mode");
      break;
    case 9:
      absl::StrAppend(&output, "Environment call from S-mode");
      break;
    case 11:
      absl::StrAppend(&output, "Environment call from M-mode");
      break;
    case 12:
      absl::StrAppend(&output, "Instruction page fault");
      absl::StrAppend(&output, ": ", absl::Hex(info.tval));
      break;
    case 13:
      absl::StrAppend(&output, "Load page fault");
      absl::StrAppend(&output, ": ", absl::Hex(info.tval));
      break;
    case 15:
      absl::StrAppend(&output, "Store/AMO page fault");
      absl::StrAppend(&output, ": ", absl::Hex(info.tval));
      break;
    case 0x1c: {
      absl::StrAppend(&output, "CHERI exception");
      switch (info.tval & 0x1f) {
        case 0:
          absl::StrAppend(&output, ": none??");
          break;
        case 1:
          absl::StrAppend(&output, ": bounds violation");
          break;
        case 2:
          absl::StrAppend(&output, ": tag violation");
          break;
        case 3:
          absl::StrAppend(&output, ": seal violation");
          break;
        case 0x11:
          absl::StrAppend(&output, ": PERMIT_EXECUTION violation");
          break;
        case 0x12:
          absl::StrAppend(&output, ": PERMIT_LOAD violation");
          break;
        case 0x13:
          absl::StrAppend(&output, ": PERMIT_STORE violation");
          break;
        case 0x15:
          absl::StrAppend(&output, ": PERMIT_STORE_CAPABILITY violation");
          break;
        case 0x18:
          absl::StrAppend(&output,
                          ": PERMIT_ACCESS_SYSTEM_REGISTERS violation");
          break;
        default:
          absl::StrAppend(&output, ": unknown cause");
          break;
      }
      int cap_indx = (info.tval >> 5) & 0x1f;
      if (cap_indx < 16)
        absl::StrAppend(&output, " c", cap_indx);
      else if (cap_indx == 28)
        absl::StrAppend(&output, " mtcc");
      else if (cap_indx == 29)
        absl::StrAppend(&output, " mtdc");
      else if (cap_indx == 30)
        absl::StrAppend(&output, " mscratchc");
      else if (cap_indx == 31)
        absl::StrAppend(&output, " mepcc");
      else
        absl::StrAppend(&output, " unknown capability");
      break;
    }
    default:
      absl::StrAppend(&output, "Error - Unknown trap");
      break;
  }
  absl::StrAppend(&output, "\n");
  return output;
}

}  // namespace cheriot
}  // namespace sim
}  // namespace mpact
