// 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::kNone:
            LOG(FATAL) << "Invalid access type - should not happen";
            break;
          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
