//===-- CommandObjectMemory.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "CommandObjectMemory.h"
#include "CommandObjectMemoryTag.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Section.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandOptionArgumentTable.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupMemoryTag.h"
#include "lldb/Interpreter/OptionGroupOutputFile.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Interpreter/OptionValueLanguage.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/ValueObject/ValueObjectMemory.h"
#include "llvm/Support/MathExtras.h"
#include <cinttypes>
#include <memory>
#include <optional>

using namespace lldb;
using namespace lldb_private;

#define LLDB_OPTIONS_memory_read
#include "CommandOptions.inc"

class OptionGroupReadMemory : public OptionGroup {
public:
  OptionGroupReadMemory()
      : m_num_per_line(1, 1), m_offset(0, 0),
        m_language_for_type(eLanguageTypeUnknown) {}

  ~OptionGroupReadMemory() override = default;

  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
    return llvm::ArrayRef(g_memory_read_options);
  }

  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
                        ExecutionContext *execution_context) override {
    Status error;
    const int short_option = g_memory_read_options[option_idx].short_option;

    switch (short_option) {
    case 'l':
      error = m_num_per_line.SetValueFromString(option_value);
      if (m_num_per_line.GetCurrentValue() == 0)
        error = Status::FromErrorStringWithFormat(
            "invalid value for --num-per-line option '%s'",
            option_value.str().c_str());
      break;

    case 'b':
      m_output_as_binary = true;
      break;

    case 't':
      error = m_view_as_type.SetValueFromString(option_value);
      break;

    case 'r':
      m_force = true;
      break;

    case 'x':
      error = m_language_for_type.SetValueFromString(option_value);
      break;

    case 'E':
      error = m_offset.SetValueFromString(option_value);
      break;

    default:
      llvm_unreachable("Unimplemented option");
    }
    return error;
  }

  void OptionParsingStarting(ExecutionContext *execution_context) override {
    m_num_per_line.Clear();
    m_output_as_binary = false;
    m_view_as_type.Clear();
    m_force = false;
    m_offset.Clear();
    m_language_for_type.Clear();
  }

  Status FinalizeSettings(Target *target, OptionGroupFormat &format_options) {
    Status error;
    OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
    OptionValueUInt64 &count_value = format_options.GetCountValue();
    const bool byte_size_option_set = byte_size_value.OptionWasSet();
    const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
    const bool count_option_set = format_options.GetCountValue().OptionWasSet();

    switch (format_options.GetFormat()) {
    default:
      break;

    case eFormatBoolean:
      if (!byte_size_option_set)
        byte_size_value = 1;
      if (!num_per_line_option_set)
        m_num_per_line = 1;
      if (!count_option_set)
        format_options.GetCountValue() = 8;
      break;

    case eFormatCString:
      break;

    case eFormatInstruction:
      if (count_option_set)
        byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
      m_num_per_line = 1;
      break;

    case eFormatAddressInfo:
      if (!byte_size_option_set)
        byte_size_value = target->GetArchitecture().GetAddressByteSize();
      m_num_per_line = 1;
      if (!count_option_set)
        format_options.GetCountValue() = 8;
      break;

    case eFormatPointer:
      byte_size_value = target->GetArchitecture().GetAddressByteSize();
      if (!num_per_line_option_set)
        m_num_per_line = 4;
      if (!count_option_set)
        format_options.GetCountValue() = 8;
      break;

    case eFormatBinary:
    case eFormatFloat:
    case eFormatFloat128:
    case eFormatOctal:
    case eFormatDecimal:
    case eFormatEnum:
    case eFormatUnicode8:
    case eFormatUnicode16:
    case eFormatUnicode32:
    case eFormatUnsigned:
    case eFormatHexFloat:
      if (!byte_size_option_set)
        byte_size_value = 4;
      if (!num_per_line_option_set)
        m_num_per_line = 1;
      if (!count_option_set)
        format_options.GetCountValue() = 8;
      break;

    case eFormatBytes:
    case eFormatBytesWithASCII:
      if (byte_size_option_set) {
        if (byte_size_value > 1)
          error = Status::FromErrorStringWithFormat(
              "display format (bytes/bytes with ASCII) conflicts with the "
              "specified byte size %" PRIu64 "\n"
              "\tconsider using a different display format or don't specify "
              "the byte size.",
              byte_size_value.GetCurrentValue());
      } else
        byte_size_value = 1;
      if (!num_per_line_option_set)
        m_num_per_line = 16;
      if (!count_option_set)
        format_options.GetCountValue() = 32;
      break;

    case eFormatCharArray:
    case eFormatChar:
    case eFormatCharPrintable:
      if (!byte_size_option_set)
        byte_size_value = 1;
      if (!num_per_line_option_set)
        m_num_per_line = 32;
      if (!count_option_set)
        format_options.GetCountValue() = 64;
      break;

    case eFormatComplex:
      if (!byte_size_option_set)
        byte_size_value = 8;
      if (!num_per_line_option_set)
        m_num_per_line = 1;
      if (!count_option_set)
        format_options.GetCountValue() = 8;
      break;

    case eFormatComplexInteger:
      if (!byte_size_option_set)
        byte_size_value = 8;
      if (!num_per_line_option_set)
        m_num_per_line = 1;
      if (!count_option_set)
        format_options.GetCountValue() = 8;
      break;

    case eFormatHex:
      if (!byte_size_option_set)
        byte_size_value = 4;
      if (!num_per_line_option_set) {
        switch (byte_size_value) {
        case 1:
        case 2:
          m_num_per_line = 8;
          break;
        case 4:
          m_num_per_line = 4;
          break;
        case 8:
          m_num_per_line = 2;
          break;
        default:
          m_num_per_line = 1;
          break;
        }
      }
      if (!count_option_set)
        count_value = 8;
      break;

    case eFormatVectorOfChar:
    case eFormatVectorOfSInt8:
    case eFormatVectorOfUInt8:
    case eFormatVectorOfSInt16:
    case eFormatVectorOfUInt16:
    case eFormatVectorOfSInt32:
    case eFormatVectorOfUInt32:
    case eFormatVectorOfSInt64:
    case eFormatVectorOfUInt64:
    case eFormatVectorOfFloat16:
    case eFormatVectorOfFloat32:
    case eFormatVectorOfFloat64:
    case eFormatVectorOfUInt128:
      if (!byte_size_option_set)
        byte_size_value = 128;
      if (!num_per_line_option_set)
        m_num_per_line = 1;
      if (!count_option_set)
        count_value = 4;
      break;
    }
    return error;
  }

  bool AnyOptionWasSet() const {
    return m_num_per_line.OptionWasSet() || m_output_as_binary ||
           m_view_as_type.OptionWasSet() || m_offset.OptionWasSet() ||
           m_language_for_type.OptionWasSet();
  }

  OptionValueUInt64 m_num_per_line;
  bool m_output_as_binary = false;
  OptionValueString m_view_as_type;
  bool m_force = false;
  OptionValueUInt64 m_offset;
  OptionValueLanguage m_language_for_type;
};

// Read memory from the inferior process
class CommandObjectMemoryRead : public CommandObjectParsed {
public:
  CommandObjectMemoryRead(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "memory read",
            "Read from the memory of the current target process.", nullptr,
            eCommandRequiresTarget | eCommandProcessMustBePaused),
        m_format_options(eFormatBytesWithASCII, 1, 8),
        m_memory_tag_options(/*note_binary=*/true),
        m_prev_format_options(eFormatBytesWithASCII, 1, 8) {
    CommandArgumentEntry arg1;
    CommandArgumentEntry arg2;
    CommandArgumentData start_addr_arg;
    CommandArgumentData end_addr_arg;

    // Define the first (and only) variant of this arg.
    start_addr_arg.arg_type = eArgTypeAddressOrExpression;
    start_addr_arg.arg_repetition = eArgRepeatPlain;

    // There is only one variant this argument could be; put it into the
    // argument entry.
    arg1.push_back(start_addr_arg);

    // Define the first (and only) variant of this arg.
    end_addr_arg.arg_type = eArgTypeAddressOrExpression;
    end_addr_arg.arg_repetition = eArgRepeatOptional;

    // There is only one variant this argument could be; put it into the
    // argument entry.
    arg2.push_back(end_addr_arg);

    // Push the data for the first argument into the m_arguments vector.
    m_arguments.push_back(arg1);
    m_arguments.push_back(arg2);

    // Add the "--format" and "--count" options to group 1 and 3
    m_option_group.Append(&m_format_options,
                          OptionGroupFormat::OPTION_GROUP_FORMAT |
                              OptionGroupFormat::OPTION_GROUP_COUNT,
                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
    m_option_group.Append(&m_format_options,
                          OptionGroupFormat::OPTION_GROUP_GDB_FMT,
                          LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
    // Add the "--size" option to group 1 and 2
    m_option_group.Append(&m_format_options,
                          OptionGroupFormat::OPTION_GROUP_SIZE,
                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
    m_option_group.Append(&m_memory_options);
    m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
    m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
    m_option_group.Append(&m_memory_tag_options, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_ALL);
    m_option_group.Finalize();
  }

  ~CommandObjectMemoryRead() override = default;

  Options *GetOptions() override { return &m_option_group; }

  std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                              uint32_t index) override {
    return m_cmd_name;
  }

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    // No need to check "target" for validity as eCommandRequiresTarget ensures
    // it is valid
    Target *target = m_exe_ctx.GetTargetPtr();

    const size_t argc = command.GetArgumentCount();

    if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2) {
      result.AppendErrorWithFormat("%s takes a start address expression with "
                                   "an optional end address expression",
                                   m_cmd_name.c_str());
      result.AppendWarning("expressions should be quoted if they contain "
                           "spaces or other special characters");
      return;
    }

    ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();

    CompilerType compiler_type;
    Status error;

    const char *view_as_type_cstr =
        m_memory_options.m_view_as_type.GetCurrentValue();
    if (view_as_type_cstr && view_as_type_cstr[0]) {
      // We are viewing memory as a type

      uint32_t reference_count = 0;
      uint32_t pointer_count = 0;
      size_t idx;

#define ALL_KEYWORDS                                                           \
  KEYWORD("const")                                                             \
  KEYWORD("volatile")                                                          \
  KEYWORD("restrict")                                                          \
  KEYWORD("struct")                                                            \
  KEYWORD("class")                                                             \
  KEYWORD("union")

#define KEYWORD(s) s,
      static const char *g_keywords[] = {ALL_KEYWORDS};
#undef KEYWORD

#define KEYWORD(s) (sizeof(s) - 1),
      static const int g_keyword_lengths[] = {ALL_KEYWORDS};
#undef KEYWORD

#undef ALL_KEYWORDS

      static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
      std::string type_str(view_as_type_cstr);

      // Remove all instances of g_keywords that are followed by spaces
      for (size_t i = 0; i < g_num_keywords; ++i) {
        const char *keyword = g_keywords[i];
        int keyword_len = g_keyword_lengths[i];

        idx = 0;
        while ((idx = type_str.find(keyword, idx)) != std::string::npos) {
          if (type_str[idx + keyword_len] == ' ' ||
              type_str[idx + keyword_len] == '\t') {
            type_str.erase(idx, keyword_len + 1);
            idx = 0;
          } else {
            idx += keyword_len;
          }
        }
      }
      bool done = type_str.empty();
      //
      idx = type_str.find_first_not_of(" \t");
      if (idx > 0 && idx != std::string::npos)
        type_str.erase(0, idx);
      while (!done) {
        // Strip trailing spaces
        if (type_str.empty())
          done = true;
        else {
          switch (type_str[type_str.size() - 1]) {
          case '*':
            ++pointer_count;
            [[fallthrough]];
          case ' ':
          case '\t':
            type_str.erase(type_str.size() - 1);
            break;

          case '&':
            if (reference_count == 0) {
              reference_count = 1;
              type_str.erase(type_str.size() - 1);
            } else {
              result.AppendErrorWithFormat("invalid type string: '%s'",
                                           view_as_type_cstr);
              return;
            }
            break;

          default:
            done = true;
            break;
          }
        }
      }

      ConstString lookup_type_name(type_str);
      StackFrame *frame = m_exe_ctx.GetFramePtr();
      ModuleSP search_first;
      if (frame)
        search_first = frame->GetSymbolContext(eSymbolContextModule).module_sp;
      TypeQuery query(lookup_type_name.GetStringRef(),
                      TypeQueryOptions::e_find_one);
      TypeResults results;
      target->GetImages().FindTypes(search_first.get(), query, results);
      TypeSP type_sp = results.GetFirstType();

      if (!type_sp && lookup_type_name.GetCString()) {
        LanguageType language_for_type =
            m_memory_options.m_language_for_type.GetCurrentValue();
        std::set<LanguageType> languages_to_check;
        if (language_for_type != eLanguageTypeUnknown) {
          languages_to_check.insert(language_for_type);
        } else {
          languages_to_check = Language::GetSupportedLanguages();
        }

        std::set<CompilerType> user_defined_types;
        for (auto lang : languages_to_check) {
          if (auto *persistent_vars =
                  target->GetPersistentExpressionStateForLanguage(lang)) {
            if (std::optional<CompilerType> type =
                    persistent_vars->GetCompilerTypeFromPersistentDecl(
                        lookup_type_name)) {
              user_defined_types.emplace(*type);
            }
          }
        }

        if (user_defined_types.size() > 1) {
          result.AppendErrorWithFormat(
              "Mutiple types found matching raw type '%s', please disambiguate "
              "by specifying the language with -x",
              lookup_type_name.GetCString());
          return;
        }

        if (user_defined_types.size() == 1) {
          compiler_type = *user_defined_types.begin();
        }
      }

      if (!compiler_type.IsValid()) {
        if (type_sp) {
          compiler_type = type_sp->GetFullCompilerType();
        } else {
          result.AppendErrorWithFormat("unable to find any types that match "
                                       "the raw type '%s' for full type '%s'",
                                       lookup_type_name.GetCString(),
                                       view_as_type_cstr);
          return;
        }
      }

      while (pointer_count > 0) {
        CompilerType pointer_type = compiler_type.GetPointerType();
        if (pointer_type.IsValid())
          compiler_type = pointer_type;
        else {
          result.AppendError("unable make a pointer type\n");
          return;
        }
        --pointer_count;
      }

      auto size_or_err = compiler_type.GetByteSize(exe_scope);
      if (!size_or_err) {
        result.AppendErrorWithFormat(
            "unable to get the byte size of the type '%s'\n%s",
            view_as_type_cstr, llvm::toString(size_or_err.takeError()).c_str());
        return;
      }
      m_format_options.GetByteSizeValue() = *size_or_err;

      if (!m_format_options.GetCountValue().OptionWasSet())
        m_format_options.GetCountValue() = 1;
    } else {
      error = m_memory_options.FinalizeSettings(target, m_format_options);
    }

    // Look for invalid combinations of settings
    if (error.Fail()) {
      result.AppendError(error.AsCString());
      return;
    }

    lldb::addr_t addr;
    size_t total_byte_size = 0;
    if (argc == 0) {
      // Use the last address and byte size and all options as they were if no
      // options have been set
      addr = m_next_addr;
      total_byte_size = m_prev_byte_size;
      compiler_type = m_prev_compiler_type;
      if (!m_format_options.AnyOptionWasSet() &&
          !m_memory_options.AnyOptionWasSet() &&
          !m_outfile_options.AnyOptionWasSet() &&
          !m_varobj_options.AnyOptionWasSet() &&
          !m_memory_tag_options.AnyOptionWasSet()) {
        m_format_options = m_prev_format_options;
        m_memory_options = m_prev_memory_options;
        m_outfile_options = m_prev_outfile_options;
        m_varobj_options = m_prev_varobj_options;
        m_memory_tag_options = m_prev_memory_tag_options;
      }
    }

    size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
    size_t item_byte_size =
        m_format_options.GetByteSizeValue().GetCurrentValue();
    const size_t num_per_line =
        m_memory_options.m_num_per_line.GetCurrentValue();

    if (total_byte_size == 0) {
      total_byte_size = item_count * item_byte_size;
      if (total_byte_size == 0)
        total_byte_size = 32;
    }

    if (argc > 0)
      addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref(),
                                        LLDB_INVALID_ADDRESS, &error);

    if (addr == LLDB_INVALID_ADDRESS) {
      result.AppendError("invalid start address expression.");
      result.AppendError(error.AsCString());
      return;
    }

    if (argc == 2) {
      lldb::addr_t end_addr = OptionArgParser::ToAddress(
          &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, nullptr);

      if (end_addr == LLDB_INVALID_ADDRESS) {
        result.AppendError("invalid end address expression.");
        result.AppendError(error.AsCString());
        return;
      } else if (end_addr <= addr) {
        result.AppendErrorWithFormat(
            "end address (0x%" PRIx64
            ") must be greater than the start address (0x%" PRIx64 ")",
            end_addr, addr);
        return;
      } else if (m_format_options.GetCountValue().OptionWasSet()) {
        result.AppendErrorWithFormat(
            "specify either the end address (0x%" PRIx64
            ") or the count (--count %" PRIu64 "), not both",
            end_addr, (uint64_t)item_count);
        return;
      }

      total_byte_size = end_addr - addr;
      item_count = total_byte_size / item_byte_size;
    }

    uint32_t max_unforced_size = target->GetMaximumMemReadSize();

    if (total_byte_size > max_unforced_size && !m_memory_options.m_force) {
      result.AppendErrorWithFormat(
          "Normally, \'memory read\' will not read over %" PRIu32
          " bytes of data",
          max_unforced_size);
      result.AppendErrorWithFormat(
          "Please use --force to override this restriction just once");
      result.AppendErrorWithFormat("or set target.max-memory-read-size if you "
                                   "will often need a larger limit");
      return;
    }

    WritableDataBufferSP data_sp;
    size_t bytes_read = 0;
    if (compiler_type.GetOpaqueQualType()) {
      // Make sure we don't display our type as ASCII bytes like the default
      // memory read
      if (!m_format_options.GetFormatValue().OptionWasSet())
        m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);

      auto size_or_err = compiler_type.GetByteSize(exe_scope);
      if (!size_or_err) {
        result.AppendError(llvm::toString(size_or_err.takeError()));
        return;
      }
      auto size = *size_or_err;
      bytes_read = size * m_format_options.GetCountValue().GetCurrentValue();

      if (argc > 0)
        addr = addr + (size * m_memory_options.m_offset.GetCurrentValue());
    } else if (m_format_options.GetFormatValue().GetCurrentValue() !=
               eFormatCString) {
      data_sp = std::make_shared<DataBufferHeap>(total_byte_size, '\0');
      if (data_sp->GetBytes() == nullptr) {
        result.AppendErrorWithFormat(
            "can't allocate 0x%" PRIx32
            " bytes for the memory read buffer, specify a smaller size to read",
            (uint32_t)total_byte_size);
        return;
      }

      Address address(addr);
      bytes_read = target->ReadMemory(address, data_sp->GetBytes(),
                                      data_sp->GetByteSize(), error, true);
      if (bytes_read == 0) {
        const char *error_cstr = error.AsCString();
        if (error_cstr && error_cstr[0]) {
          result.AppendError(error_cstr);
        } else {
          result.AppendErrorWithFormat(
              "failed to read memory from 0x%" PRIx64 ".", addr);
        }
        return;
      }

      if (bytes_read < total_byte_size)
        result.AppendWarningWithFormatv("not all bytes ({0} / {1}) "
                                        "were able to be read from {2:x}",
                                        bytes_read, total_byte_size, addr);
    } else {
      // we treat c-strings as a special case because they do not have a fixed
      // size
      if (m_format_options.GetByteSizeValue().OptionWasSet() &&
          !m_format_options.HasGDBFormat())
        item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
      else
        item_byte_size = target->GetMaximumSizeOfStringSummary();
      if (!m_format_options.GetCountValue().OptionWasSet())
        item_count = 1;
      data_sp = std::make_shared<DataBufferHeap>(
          (item_byte_size + 1) * item_count,
          '\0'); // account for NULLs as necessary
      if (data_sp->GetBytes() == nullptr) {
        result.AppendErrorWithFormat(
            "can't allocate 0x%" PRIx64
            " bytes for the memory read buffer, specify a smaller size to read",
            (uint64_t)((item_byte_size + 1) * item_count));
        return;
      }
      uint8_t *data_ptr = data_sp->GetBytes();
      auto data_addr = addr;
      auto count = item_count;
      item_count = 0;
      bool break_on_no_NULL = false;
      while (item_count < count) {
        std::string buffer;
        buffer.resize(item_byte_size + 1, 0);
        Status error;
        size_t read = target->ReadCStringFromMemory(
            Address(data_addr), &buffer[0], item_byte_size + 1, error);
        if (error.Fail()) {
          result.AppendErrorWithFormat(
              "failed to read memory from 0x%" PRIx64 ".", addr);
          return;
        }

        if (item_byte_size == read) {
          result.AppendWarningWithFormatv(
              "unable to find a NULL terminated string at {0:x}"
              ". Consider increasing the maximum read length",
              data_addr);
          --read;
          break_on_no_NULL = true;
        } else
          ++read; // account for final NULL byte

        memcpy(data_ptr, &buffer[0], read);
        data_ptr += read;
        data_addr += read;
        bytes_read += read;
        item_count++; // if we break early we know we only read item_count
                      // strings

        if (break_on_no_NULL)
          break;
      }
      data_sp =
          std::make_shared<DataBufferHeap>(data_sp->GetBytes(), bytes_read + 1);
    }

    m_next_addr = addr + bytes_read;
    m_prev_byte_size = bytes_read;
    m_prev_format_options = m_format_options;
    m_prev_memory_options = m_memory_options;
    m_prev_outfile_options = m_outfile_options;
    m_prev_varobj_options = m_varobj_options;
    m_prev_memory_tag_options = m_memory_tag_options;
    m_prev_compiler_type = compiler_type;

    std::unique_ptr<Stream> output_stream_storage;
    Stream *output_stream_p = nullptr;
    const FileSpec &outfile_spec =
        m_outfile_options.GetFile().GetCurrentValue();

    std::string path = outfile_spec.GetPath();
    if (outfile_spec) {

      File::OpenOptions open_options =
          File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
      const bool append = m_outfile_options.GetAppend().GetCurrentValue();
      open_options |=
          append ? File::eOpenOptionAppend : File::eOpenOptionTruncate;

      auto outfile = FileSystem::Instance().Open(outfile_spec, open_options);

      if (outfile) {
        auto outfile_stream_up =
            std::make_unique<StreamFile>(std::move(outfile.get()));
        if (m_memory_options.m_output_as_binary) {
          const size_t bytes_written =
              outfile_stream_up->Write(data_sp->GetBytes(), bytes_read);
          if (bytes_written > 0) {
            result.GetOutputStream().Printf(
                "%zi bytes %s to '%s'\n", bytes_written,
                append ? "appended" : "written", path.c_str());
            result.SetStatus(eReturnStatusSuccessFinishResult);
            return;
          } else {
            result.AppendErrorWithFormat("Failed to write %" PRIu64
                                         " bytes to '%s'",
                                         (uint64_t)bytes_read, path.c_str());
            return;
          }
        } else {
          // We are going to write ASCII to the file just point the
          // output_stream to our outfile_stream...
          output_stream_storage = std::move(outfile_stream_up);
          output_stream_p = output_stream_storage.get();
        }
      } else {
        result.AppendErrorWithFormat("Failed to open file '%s' for %s:",
                                     path.c_str(), append ? "append" : "write");

        result.AppendError(llvm::toString(outfile.takeError()));
        return;
      }
    } else {
      output_stream_p = &result.GetOutputStream();
    }

    if (compiler_type.GetOpaqueQualType()) {
      for (uint32_t i = 0; i < item_count; ++i) {
        addr_t item_addr = addr + (i * item_byte_size);
        Address address(item_addr);
        StreamString name_strm;
        name_strm.Printf("0x%" PRIx64, item_addr);
        ValueObjectSP valobj_sp(ValueObjectMemory::Create(
            exe_scope, name_strm.GetString(), address, compiler_type));
        if (valobj_sp) {
          Format format = m_format_options.GetFormat();
          if (format != eFormatDefault)
            valobj_sp->SetFormat(format);

          DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
              eLanguageRuntimeDescriptionDisplayVerbosityFull, format));

          if (llvm::Error error = valobj_sp->Dump(*output_stream_p, options)) {
            result.AppendError(toString(std::move(error)));
            return;
          }
        } else {
          result.AppendErrorWithFormat(
              "failed to create a value object for: (%s) %s", view_as_type_cstr,
              name_strm.GetData());
          return;
        }
      }
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return;
    }

    result.SetStatus(eReturnStatusSuccessFinishResult);
    DataExtractor data(data_sp, target->GetArchitecture().GetByteOrder(),
                       target->GetArchitecture().GetAddressByteSize());

    Format format = m_format_options.GetFormat();
    if (((format == eFormatChar) || (format == eFormatCharPrintable)) &&
        (item_byte_size != 1)) {
      // if a count was not passed, or it is 1
      if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1) {
        // this turns requests such as
        // memory read -fc -s10 -c1 *charPtrPtr
        // which make no sense (what is a char of size 10?) into a request for
        // fetching 10 chars of size 1 from the same memory location
        format = eFormatCharArray;
        item_count = item_byte_size;
        item_byte_size = 1;
      } else {
        // here we passed a count, and it was not 1 so we have a byte_size and
        // a count we could well multiply those, but instead let's just fail
        result.AppendErrorWithFormat(
            "reading memory as characters of size %" PRIu64 " is not supported",
            (uint64_t)item_byte_size);
        return;
      }
    }

    assert(output_stream_p);
    size_t bytes_dumped =
        DumpDataExtractor(data, output_stream_p, 0, format, item_byte_size,
                          item_count, num_per_line, addr, 0, 0, exe_scope,
                          m_memory_tag_options.GetShowTags().GetCurrentValue());
    m_next_addr = addr + bytes_dumped;
    output_stream_p->EOL();
  }

  OptionGroupOptions m_option_group;
  OptionGroupFormat m_format_options;
  OptionGroupReadMemory m_memory_options;
  OptionGroupOutputFile m_outfile_options;
  OptionGroupValueObjectDisplay m_varobj_options;
  OptionGroupMemoryTag m_memory_tag_options;
  lldb::addr_t m_next_addr = LLDB_INVALID_ADDRESS;
  lldb::addr_t m_prev_byte_size = 0;
  OptionGroupFormat m_prev_format_options;
  OptionGroupReadMemory m_prev_memory_options;
  OptionGroupOutputFile m_prev_outfile_options;
  OptionGroupValueObjectDisplay m_prev_varobj_options;
  OptionGroupMemoryTag m_prev_memory_tag_options;
  CompilerType m_prev_compiler_type;
};

#define LLDB_OPTIONS_memory_find
#include "CommandOptions.inc"

static llvm::Error CopyExpressionResult(ValueObject &result,
                                        DataBufferHeap &buffer,
                                        ExecutionContextScope *scope) {
  uint64_t value = result.GetValueAsUnsigned(0);
  auto size_or_err = result.GetCompilerType().GetByteSize(scope);
  if (!size_or_err)
    return size_or_err.takeError();

  switch (*size_or_err) {
  case 1: {
    uint8_t byte = (uint8_t)value;
    buffer.CopyData(&byte, 1);
  } break;
  case 2: {
    uint16_t word = (uint16_t)value;
    buffer.CopyData(&word, 2);
  } break;
  case 4: {
    uint32_t lword = (uint32_t)value;
    buffer.CopyData(&lword, 4);
  } break;
  case 8: {
    buffer.CopyData(&value, 8);
  } break;
  default:
    return llvm::createStringError(
        "Only expressions resulting in 1, 2, 4, or 8-byte-sized values are "
        "supported. For other pattern sizes the --string (-s) option may be "
        "used.");
  }

  return llvm::Error::success();
}

static llvm::Expected<ValueObjectSP>
EvaluateExpression(llvm::StringRef expression, StackFrame &frame,
                   Process &process) {
  ValueObjectSP result_sp;
  auto status =
      process.GetTarget().EvaluateExpression(expression, &frame, result_sp);
  if (!result_sp)
    return llvm::createStringError(
        "No result returned from expression. Exit status: %d", status);

  if (status != eExpressionCompleted)
    return result_sp->GetError().ToError();

  result_sp = result_sp->GetQualifiedRepresentationIfAvailable(
      result_sp->GetDynamicValueType(), /*synthValue=*/true);
  if (!result_sp)
    return llvm::createStringError("failed to get dynamic result type");

  return result_sp;
}

// Find the specified data in memory
class CommandObjectMemoryFind : public CommandObjectParsed {
public:
  class OptionGroupFindMemory : public OptionGroup {
  public:
    OptionGroupFindMemory() : m_count(1), m_offset(0) {}

    ~OptionGroupFindMemory() override = default;

    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
      return llvm::ArrayRef(g_memory_find_options);
    }

    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
                          ExecutionContext *execution_context) override {
      Status error;
      const int short_option = g_memory_find_options[option_idx].short_option;

      switch (short_option) {
      case 'e':
        m_expr.SetValueFromString(option_value);
        break;

      case 's':
        m_string.SetValueFromString(option_value);
        break;

      case 'c':
        if (m_count.SetValueFromString(option_value).Fail())
          error = Status::FromErrorString("unrecognized value for count");
        break;

      case 'o':
        if (m_offset.SetValueFromString(option_value).Fail())
          error = Status::FromErrorString("unrecognized value for dump-offset");
        break;

      default:
        llvm_unreachable("Unimplemented option");
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_expr.Clear();
      m_string.Clear();
      m_count.Clear();
    }

    OptionValueString m_expr;
    OptionValueString m_string;
    OptionValueUInt64 m_count;
    OptionValueUInt64 m_offset;
  };

  CommandObjectMemoryFind(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "memory find",
            "Find a value in the memory of the current target process.",
            nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched) {
    CommandArgumentEntry arg1;
    CommandArgumentEntry arg2;
    CommandArgumentData addr_arg;
    CommandArgumentData value_arg;

    // Define the first (and only) variant of this arg.
    addr_arg.arg_type = eArgTypeAddressOrExpression;
    addr_arg.arg_repetition = eArgRepeatPlain;

    // There is only one variant this argument could be; put it into the
    // argument entry.
    arg1.push_back(addr_arg);

    // Define the first (and only) variant of this arg.
    value_arg.arg_type = eArgTypeAddressOrExpression;
    value_arg.arg_repetition = eArgRepeatPlain;

    // There is only one variant this argument could be; put it into the
    // argument entry.
    arg2.push_back(value_arg);

    // Push the data for the first argument into the m_arguments vector.
    m_arguments.push_back(arg1);
    m_arguments.push_back(arg2);

    m_option_group.Append(&m_memory_options);
    m_option_group.Append(&m_memory_tag_options, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_ALL);
    m_option_group.Finalize();
  }

  ~CommandObjectMemoryFind() override = default;

  Options *GetOptions() override { return &m_option_group; }

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    // No need to check "process" for validity as eCommandRequiresProcess
    // ensures it is valid
    Process *process = m_exe_ctx.GetProcessPtr();

    const size_t argc = command.GetArgumentCount();

    if (argc != 2) {
      result.AppendError("two addresses needed for memory find");
      return;
    }

    Status error;
    lldb::addr_t low_addr = OptionArgParser::ToAddress(
        &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
    if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
      result.AppendError("invalid low address");
      return;
    }
    lldb::addr_t high_addr = OptionArgParser::ToAddress(
        &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, &error);
    if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
      result.AppendError("invalid high address");
      return;
    }

    if (high_addr <= low_addr) {
      result.AppendError(
          "starting address must be smaller than ending address");
      return;
    }

    lldb::addr_t found_location = LLDB_INVALID_ADDRESS;

    DataBufferHeap buffer;

    if (m_memory_options.m_string.OptionWasSet()) {
      llvm::StringRef str =
          m_memory_options.m_string.GetValueAs<llvm::StringRef>().value_or("");
      if (str.empty()) {
        result.AppendError("search string must have non-zero length.");
        return;
      }
      buffer.CopyData(str);
    } else if (m_memory_options.m_expr.OptionWasSet()) {
      auto result_or_err = EvaluateExpression(
          m_memory_options.m_expr.GetValueAs<llvm::StringRef>().value_or(""),
          m_exe_ctx.GetFrameRef(), *process);
      if (!result_or_err) {
        result.AppendError("Expression evaluation failed: ");
        result.AppendError(llvm::toString(result_or_err.takeError()));
        return;
      }

      ValueObjectSP result_sp = *result_or_err;

      if (auto err = CopyExpressionResult(*result_sp, buffer,
                                          m_exe_ctx.GetFramePtr())) {
        result.AppendError(llvm::toString(std::move(err)));
        return;
      }
    } else {
      result.AppendError(
          "please pass either a block of text, or an expression to evaluate.");
      return;
    }

    size_t count = m_memory_options.m_count.GetCurrentValue();
    found_location = low_addr;
    bool ever_found = false;
    while (count) {
      found_location = process->FindInMemory(
          found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize());
      if (found_location == LLDB_INVALID_ADDRESS) {
        if (!ever_found) {
          result.AppendMessage("data not found within the range.\n");
          result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
        } else
          result.AppendMessage("no more matches within the range.\n");
        break;
      }
      result.AppendMessageWithFormatv("data found at location: {0:x}",
                                      found_location);

      DataBufferHeap dumpbuffer(32, 0);
      process->ReadMemory(
          found_location + m_memory_options.m_offset.GetCurrentValue(),
          dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error);
      if (!error.Fail()) {
        DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
                           process->GetByteOrder(),
                           process->GetAddressByteSize());
        DumpDataExtractor(
            data, &result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1,
            dumpbuffer.GetByteSize(), 16,
            found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0,
            m_exe_ctx.GetBestExecutionContextScope(),
            m_memory_tag_options.GetShowTags().GetCurrentValue());
        result.GetOutputStream().EOL();
      }

      --count;
      found_location++;
      ever_found = true;
    }

    result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
  }

  OptionGroupOptions m_option_group;
  OptionGroupFindMemory m_memory_options;
  OptionGroupMemoryTag m_memory_tag_options;
};

#define LLDB_OPTIONS_memory_write
#include "CommandOptions.inc"

// Write memory to the inferior process
class CommandObjectMemoryWrite : public CommandObjectParsed {
public:
  class OptionGroupWriteMemory : public OptionGroup {
  public:
    OptionGroupWriteMemory() = default;

    ~OptionGroupWriteMemory() override = default;

    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
      return llvm::ArrayRef(g_memory_write_options);
    }

    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
                          ExecutionContext *execution_context) override {
      Status error;
      const int short_option = g_memory_write_options[option_idx].short_option;

      switch (short_option) {
      case 'i':
        m_infile.SetFile(option_value, FileSpec::Style::native);
        FileSystem::Instance().Resolve(m_infile);
        if (!FileSystem::Instance().Exists(m_infile)) {
          m_infile.Clear();
          error = Status::FromErrorStringWithFormat(
              "input file does not exist: '%s'", option_value.str().c_str());
        }
        break;

      case 'o': {
        if (option_value.getAsInteger(0, m_infile_offset)) {
          m_infile_offset = 0;
          error = Status::FromErrorStringWithFormat(
              "invalid offset string '%s'", option_value.str().c_str());
        }
      } break;

      default:
        llvm_unreachable("Unimplemented option");
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_infile.Clear();
      m_infile_offset = 0;
    }

    FileSpec m_infile;
    off_t m_infile_offset;
  };

  CommandObjectMemoryWrite(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "memory write",
            "Write to the memory of the current target process.", nullptr,
            eCommandRequiresProcess | eCommandProcessMustBeLaunched),
        m_format_options(
            eFormatBytes, 1, UINT64_MAX,
            {std::make_tuple(
                 eArgTypeFormat,
                 "The format to use for each of the value to be written."),
             std::make_tuple(eArgTypeByteSize,
                             "The size in bytes to write from input file or "
                             "each value.")}) {
    CommandArgumentEntry arg1;
    CommandArgumentEntry arg2;
    CommandArgumentData addr_arg;
    CommandArgumentData value_arg;

    // Define the first (and only) variant of this arg.
    addr_arg.arg_type = eArgTypeAddress;
    addr_arg.arg_repetition = eArgRepeatPlain;

    // There is only one variant this argument could be; put it into the
    // argument entry.
    arg1.push_back(addr_arg);

    // Define the first (and only) variant of this arg.
    value_arg.arg_type = eArgTypeValue;
    value_arg.arg_repetition = eArgRepeatPlus;
    value_arg.arg_opt_set_association = LLDB_OPT_SET_1;

    // There is only one variant this argument could be; put it into the
    // argument entry.
    arg2.push_back(value_arg);

    // Push the data for the first argument into the m_arguments vector.
    m_arguments.push_back(arg1);
    m_arguments.push_back(arg2);

    m_option_group.Append(&m_format_options,
                          OptionGroupFormat::OPTION_GROUP_FORMAT,
                          LLDB_OPT_SET_1);
    m_option_group.Append(&m_format_options,
                          OptionGroupFormat::OPTION_GROUP_SIZE,
                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
    m_option_group.Append(&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
    m_option_group.Finalize();
  }

  ~CommandObjectMemoryWrite() override = default;

  Options *GetOptions() override { return &m_option_group; }

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    // No need to check "process" for validity as eCommandRequiresProcess
    // ensures it is valid
    Process *process = m_exe_ctx.GetProcessPtr();

    const size_t argc = command.GetArgumentCount();

    if (m_memory_options.m_infile) {
      if (argc < 1) {
        result.AppendErrorWithFormat(
            "%s takes a destination address when writing file contents",
            m_cmd_name.c_str());
        return;
      }
      if (argc > 1) {
        result.AppendErrorWithFormat(
            "%s takes only a destination address when writing file contents",
            m_cmd_name.c_str());
        return;
      }
    } else if (argc < 2) {
      result.AppendErrorWithFormat(
          "%s takes a destination address and at least one value",
          m_cmd_name.c_str());
      return;
    }

    StreamString buffer(Stream::eBinary, process->GetByteOrder());

    OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
    size_t item_byte_size = byte_size_value.GetCurrentValue();

    Status error;
    lldb::addr_t addr = OptionArgParser::ToAddress(
        &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);

    if (addr == LLDB_INVALID_ADDRESS) {
      result.AppendError("invalid address expression\n");
      result.AppendError(error.AsCString());
      return;
    }

    if (m_memory_options.m_infile) {
      size_t length = SIZE_MAX;
      if (item_byte_size > 1)
        length = item_byte_size;
      auto data_sp = FileSystem::Instance().CreateDataBuffer(
          m_memory_options.m_infile.GetPath(), length,
          m_memory_options.m_infile_offset);
      if (data_sp) {
        length = data_sp->GetByteSize();
        if (length > 0) {
          Status error;
          size_t bytes_written =
              process->WriteMemory(addr, data_sp->GetBytes(), length, error);

          if (bytes_written == length) {
            // All bytes written
            result.GetOutputStream().Printf(
                "%" PRIu64 " bytes were written to 0x%" PRIx64 "\n",
                (uint64_t)bytes_written, addr);
            result.SetStatus(eReturnStatusSuccessFinishResult);
          } else if (bytes_written > 0) {
            // Some byte written
            result.GetOutputStream().Printf(
                "%" PRIu64 " bytes of %" PRIu64
                " requested were written to 0x%" PRIx64 "\n",
                (uint64_t)bytes_written, (uint64_t)length, addr);
            result.SetStatus(eReturnStatusSuccessFinishResult);
          } else {
            result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
                                         " failed: %s",
                                         addr, error.AsCString());
          }
        }
      } else {
        result.AppendErrorWithFormat("Unable to read contents of file");
      }
      return;
    } else if (item_byte_size == 0) {
      if (m_format_options.GetFormat() == eFormatPointer)
        item_byte_size = process->GetAddressByteSize();
      else
        item_byte_size = 1;
    }

    command.Shift(); // shift off the address argument
    uint64_t uval64;
    int64_t sval64;
    bool success = false;
    for (auto &entry : command) {
      switch (m_format_options.GetFormat()) {
      case kNumFormats:
      case eFormatFloat: // TODO: add support for floats soon
      case eFormatFloat128:
      case eFormatCharPrintable:
      case eFormatBytesWithASCII:
      case eFormatComplex:
      case eFormatEnum:
      case eFormatUnicode8:
      case eFormatUnicode16:
      case eFormatUnicode32:
      case eFormatVectorOfChar:
      case eFormatVectorOfSInt8:
      case eFormatVectorOfUInt8:
      case eFormatVectorOfSInt16:
      case eFormatVectorOfUInt16:
      case eFormatVectorOfSInt32:
      case eFormatVectorOfUInt32:
      case eFormatVectorOfSInt64:
      case eFormatVectorOfUInt64:
      case eFormatVectorOfFloat16:
      case eFormatVectorOfFloat32:
      case eFormatVectorOfFloat64:
      case eFormatVectorOfUInt128:
      case eFormatOSType:
      case eFormatComplexInteger:
      case eFormatAddressInfo:
      case eFormatHexFloat:
      case eFormatInstruction:
      case eFormatVoid:
        result.AppendError("unsupported format for writing memory");
        return;

      case eFormatDefault:
      case eFormatBytes:
      case eFormatHex:
      case eFormatHexUppercase:
      case eFormatPointer: {
        // Decode hex bytes
        // Be careful, getAsInteger with a radix of 16 rejects "0xab" so we
        // have to special case that:
        bool success = false;
        if (entry.ref().starts_with("0x"))
          success = !entry.ref().getAsInteger(0, uval64);
        if (!success)
          success = !entry.ref().getAsInteger(16, uval64);
        if (!success) {
          result.AppendErrorWithFormat("'%s' is not a valid hex string value",
                                       entry.c_str());
          return;
        } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
          result.AppendErrorWithFormat("Value 0x%" PRIx64
                                       " is too large to fit in a %" PRIu64
                                       " byte unsigned integer value",
                                       uval64, (uint64_t)item_byte_size);
          return;
        }
        buffer.PutMaxHex64(uval64, item_byte_size);
        break;
      }
      case eFormatBoolean:
        uval64 = OptionArgParser::ToBoolean(entry.ref(), false, &success);
        if (!success) {
          result.AppendErrorWithFormat(
              "'%s' is not a valid boolean string value", entry.c_str());
          return;
        }
        buffer.PutMaxHex64(uval64, item_byte_size);
        break;

      case eFormatBinary:
        if (entry.ref().getAsInteger(2, uval64)) {
          result.AppendErrorWithFormat(
              "'%s' is not a valid binary string value", entry.c_str());
          return;
        } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
          result.AppendErrorWithFormat("Value 0x%" PRIx64
                                       " is too large to fit in a %" PRIu64
                                       " byte unsigned integer value",
                                       uval64, (uint64_t)item_byte_size);
          return;
        }
        buffer.PutMaxHex64(uval64, item_byte_size);
        break;

      case eFormatCharArray:
      case eFormatChar:
      case eFormatCString: {
        if (entry.ref().empty())
          break;

        size_t len = entry.ref().size();
        // Include the NULL for C strings...
        if (m_format_options.GetFormat() == eFormatCString)
          ++len;
        Status error;
        if (process->WriteMemory(addr, entry.c_str(), len, error) == len) {
          addr += len;
        } else {
          result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
                                       " failed: %s",
                                       addr, error.AsCString());
          return;
        }
        break;
      }
      case eFormatDecimal:
        if (entry.ref().getAsInteger(0, sval64)) {
          result.AppendErrorWithFormat(
              "'%s' is not a valid signed decimal value", entry.c_str());
          return;
        } else if (!llvm::isIntN(item_byte_size * 8, sval64)) {
          result.AppendErrorWithFormat(
              "Value %" PRIi64 " is too large or small to fit in a %" PRIu64
              " byte signed integer value",
              sval64, (uint64_t)item_byte_size);
          return;
        }
        buffer.PutMaxHex64(sval64, item_byte_size);
        break;

      case eFormatUnsigned:

        if (entry.ref().getAsInteger(0, uval64)) {
          result.AppendErrorWithFormat(
              "'%s' is not a valid unsigned decimal string value",
              entry.c_str());
          return;
        } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
          result.AppendErrorWithFormat("Value %" PRIu64
                                       " is too large to fit in a %" PRIu64
                                       " byte unsigned integer value",
                                       uval64, (uint64_t)item_byte_size);
          return;
        }
        buffer.PutMaxHex64(uval64, item_byte_size);
        break;

      case eFormatOctal:
        if (entry.ref().getAsInteger(8, uval64)) {
          result.AppendErrorWithFormat("'%s' is not a valid octal string value",
                                       entry.c_str());
          return;
        } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
          result.AppendErrorWithFormat("Value %" PRIo64
                                       " is too large to fit in a %" PRIu64
                                       " byte unsigned integer value",
                                       uval64, (uint64_t)item_byte_size);
          return;
        }
        buffer.PutMaxHex64(uval64, item_byte_size);
        break;
      }
    }

    if (!buffer.GetString().empty()) {
      Status error;
      const char *buffer_data = buffer.GetString().data();
      const size_t buffer_size = buffer.GetString().size();
      const size_t write_size =
          process->WriteMemory(addr, buffer_data, buffer_size, error);

      if (write_size != buffer_size) {
        result.AppendErrorWithFormat("Memory write to 0x%" PRIx64 " failed: %s",
                                     addr, error.AsCString());
        return;
      }
    }
    result.SetStatus(eReturnStatusSuccessFinishNoResult);
  }

  OptionGroupOptions m_option_group;
  OptionGroupFormat m_format_options;
  OptionGroupWriteMemory m_memory_options;
};

// Get malloc/free history of a memory address.
class CommandObjectMemoryHistory : public CommandObjectParsed {
public:
  CommandObjectMemoryHistory(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "memory history",
                            "Print recorded stack traces for "
                            "allocation/deallocation events "
                            "associated with an address.",
                            nullptr,
                            eCommandRequiresTarget | eCommandRequiresProcess |
                                eCommandProcessMustBePaused |
                                eCommandProcessMustBeLaunched) {
    CommandArgumentEntry arg1;
    CommandArgumentData addr_arg;

    // Define the first (and only) variant of this arg.
    addr_arg.arg_type = eArgTypeAddress;
    addr_arg.arg_repetition = eArgRepeatPlain;

    // There is only one variant this argument could be; put it into the
    // argument entry.
    arg1.push_back(addr_arg);

    // Push the data for the first argument into the m_arguments vector.
    m_arguments.push_back(arg1);
  }

  ~CommandObjectMemoryHistory() override = default;

  std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                              uint32_t index) override {
    return m_cmd_name;
  }

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    const size_t argc = command.GetArgumentCount();

    if (argc == 0 || argc > 1) {
      result.AppendErrorWithFormat("%s takes an address expression",
                                   m_cmd_name.c_str());
      return;
    }

    Status error;
    lldb::addr_t addr = OptionArgParser::ToRawAddress(
        &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);

    if (addr == LLDB_INVALID_ADDRESS) {
      result.AppendError("invalid address expression");
      result.AppendError(error.AsCString());
      return;
    }

    Stream *output_stream = &result.GetOutputStream();

    const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
    const MemoryHistorySP &memory_history =
        MemoryHistory::FindPlugin(process_sp);

    if (!memory_history) {
      result.AppendError("no available memory history provider");
      return;
    }

    HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);

    const bool stop_format = false;
    for (auto thread : thread_list) {
      thread->GetStatus(*output_stream, 0, UINT32_MAX, 0, stop_format,
                        /*should_filter*/ false);
    }

    result.SetStatus(eReturnStatusSuccessFinishResult);
  }
};

// CommandObjectMemoryRegion
#pragma mark CommandObjectMemoryRegion

#define LLDB_OPTIONS_memory_region
#include "CommandOptions.inc"

class CommandObjectMemoryRegion : public CommandObjectParsed {
public:
  class OptionGroupMemoryRegion : public OptionGroup {
  public:
    OptionGroupMemoryRegion() : m_all(false, false) {}

    ~OptionGroupMemoryRegion() override = default;

    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
      return llvm::ArrayRef(g_memory_region_options);
    }

    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
                          ExecutionContext *execution_context) override {
      Status status;
      const int short_option = g_memory_region_options[option_idx].short_option;

      switch (short_option) {
      case 'a':
        m_all.SetCurrentValue(true);
        m_all.SetOptionWasSet();
        break;
      default:
        llvm_unreachable("Unimplemented option");
      }

      return status;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_all.Clear();
    }

    OptionValueBoolean m_all;
  };

  CommandObjectMemoryRegion(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "memory region",
            "Get information on the memory region containing "
            "an address in the current target process.\n"
            "If this command is given an <address-expression> once "
            "and then repeated without options, it will try to print "
            "the memory region that follows the previously printed "
            "region. The command can be repeated until the end of "
            "the address range is reached.",
            "memory region <address-expression> (or --all)",
            eCommandRequiresProcess | eCommandTryTargetAPILock |
                eCommandProcessMustBeLaunched) {
    // Address in option set 1.
    m_arguments.push_back(CommandArgumentEntry{CommandArgumentData(
        eArgTypeAddressOrExpression, eArgRepeatPlain, LLDB_OPT_SET_1)});
    // "--all" will go in option set 2.
    m_option_group.Append(&m_memory_region_options);
    m_option_group.Finalize();
  }

  ~CommandObjectMemoryRegion() override = default;

  Options *GetOptions() override { return &m_option_group; }

protected:
  void DumpRegion(CommandReturnObject &result, Target &target,
                  const MemoryRegionInfo &range_info, lldb::addr_t load_addr) {
    lldb_private::Address addr;
    llvm::StringRef section_name;
    if (target.ResolveLoadAddress(load_addr, addr)) {
      SectionSP section_sp(addr.GetSection());
      if (section_sp) {
        // Got the top most section, not the deepest section
        while (section_sp->GetParent())
          section_sp = section_sp->GetParent();
        section_name = section_sp->GetName();
      }
    }

    ConstString name = range_info.GetName();
    result.AppendMessageWithFormatv(
        "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}",
        range_info.GetRange().GetRangeBase(),
        range_info.GetRange().GetRangeEnd(), range_info.GetReadable(),
        range_info.GetWritable(), range_info.GetExecutable(), name ? " " : "",
        name, !section_name.empty() ? " " : "", section_name);
    LazyBool memory_tagged = range_info.GetMemoryTagged();
    if (memory_tagged == eLazyBoolYes)
      result.AppendMessage("memory tagging: enabled");
    LazyBool is_shadow_stack = range_info.IsShadowStack();
    if (is_shadow_stack == eLazyBoolYes)
      result.AppendMessage("shadow stack: yes");
    if (std::optional<unsigned> protection_key =
            range_info.GetProtectionKey()) {
      Stream &strm = result.GetOutputStream();
      strm << llvm::formatv("protection key: {0}", *protection_key);

      if (const lldb::ABISP &abi = target.GetProcessSP()->GetABI()) {
        if (auto permissions = abi->GetMemoryPermissions(
                *m_exe_ctx.GetRegisterContext(), *protection_key,
                range_info.GetLLDBPermissions())) {
          strm << llvm::formatv(
              " ({0}{1}{2}, effective: {3}{4}{5})",
              permissions->overlay & lldb::ePermissionsReadable ? 'r' : '-',
              permissions->overlay & lldb::ePermissionsWritable ? 'w' : '-',
              permissions->overlay & lldb::ePermissionsExecutable ? 'x' : '-',
              permissions->effective & lldb::ePermissionsReadable ? 'r' : '-',
              permissions->effective & lldb::ePermissionsWritable ? 'w' : '-',
              permissions->effective & lldb::ePermissionsExecutable ? 'x'
                                                                    : '-');
        }
      }
      strm.PutChar('\n');
    }

    const std::optional<std::vector<addr_t>> &dirty_page_list =
        range_info.GetDirtyPageList();
    if (dirty_page_list) {
      const size_t page_count = dirty_page_list->size();
      result.AppendMessageWithFormatv(
          "Modified memory (dirty) page list provided, {0} entries.",
          page_count);
      if (page_count > 0) {
        bool print_comma = false;
        Stream &strm = result.GetOutputStream();
        strm << "Dirty pages: ";
        for (size_t i = 0; i < page_count; i++) {
          if (print_comma)
            strm << ", ";
          else
            print_comma = true;
          strm << llvm::formatv("{0:x}", (*dirty_page_list)[i]);
        }
        strm << ".\n";
      }
    }
  }

  void DoExecute(Args &command, CommandReturnObject &result) override {
    ProcessSP process_sp = m_exe_ctx.GetProcessSP();
    if (!process_sp) {
      m_prev_end_addr = LLDB_INVALID_ADDRESS;
      result.AppendError("invalid process");
      return;
    }

    Status error;
    lldb::addr_t load_addr = m_prev_end_addr;
    m_prev_end_addr = LLDB_INVALID_ADDRESS;

    const size_t argc = command.GetArgumentCount();
    const lldb::ABISP &abi = process_sp->GetABI();

    if (argc == 0) {
      if (!m_memory_region_options.m_all) {
        if ( // When we're repeating the command, the previous end
             // address is used for load_addr. If that was 0xF...F then
             // we must have reached the end of memory.
            (load_addr == LLDB_INVALID_ADDRESS) ||
            // If the target has non-address bits (tags, limited virtual
            // address size, etc.), the end of mappable memory will be
            // lower than that. So if we find any non-address bit set,
            // we must be at the end of the mappable range.
            (abi && (abi->FixAnyAddress(load_addr) != load_addr))) {
          result.AppendErrorWithFormat(
              "No next region address set: one address expression argument or "
              "\"--all\" option required:\nUsage: %s",
              m_cmd_syntax.c_str());
          return;
        }
      }
    } else if (argc == 1) {
      if (m_memory_region_options.m_all) {
        result.AppendError(
            "The \"--all\" option cannot be used when an address "
            "argument is given");
        return;
      }

      auto load_addr_str = command[0].ref();
      load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
                                             LLDB_INVALID_ADDRESS, &error);
      if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
        result.AppendErrorWithFormat("invalid address argument \"%s\": %s",
                                     command[0].c_str(), error.AsCString());
        return;
      }
    } else {
      // argc > 1
      result.AppendErrorWithFormat(
          "'%s' takes one argument or \"--all\" option:\nUsage: %s",
          m_cmd_name.c_str(), m_cmd_syntax.c_str());
      return;
    }

    // It is important that we track the address used to request the region as
    // this will give the correct section name in the case that regions overlap.
    // On Windows we get multiple regions that start at the same place but are
    // different sizes and refer to different sections.
    std::vector<std::pair<lldb_private::MemoryRegionInfo, lldb::addr_t>>
        region_list;
    if (m_memory_region_options.m_all) {
      // We don't use GetMemoryRegions here because it doesn't include unmapped
      // areas like repeating the command would. So instead, emulate doing that.
      lldb::addr_t addr = 0;
      while (error.Success() && addr != LLDB_INVALID_ADDRESS &&
             // When there are non-address bits the last range will not extend
             // to LLDB_INVALID_ADDRESS but to the max virtual address.
             // This prevents us looping forever if that is the case.
             (!abi || (abi->FixAnyAddress(addr) == addr))) {
        lldb_private::MemoryRegionInfo region_info;
        error = process_sp->GetMemoryRegionInfo(addr, region_info);

        if (error.Success()) {
          region_list.push_back({region_info, addr});
          addr = region_info.GetRange().GetRangeEnd();
        }
      }
    } else {
      lldb_private::MemoryRegionInfo region_info;
      error = process_sp->GetMemoryRegionInfo(load_addr, region_info);
      if (error.Success())
        region_list.push_back({region_info, load_addr});
    }

    if (error.Success()) {
      for (std::pair<MemoryRegionInfo, addr_t> &range : region_list) {
        DumpRegion(result, process_sp->GetTarget(), range.first, range.second);
        m_prev_end_addr = range.first.GetRange().GetRangeEnd();
      }

      result.SetStatus(eReturnStatusSuccessFinishResult);
      return;
    }

    result.AppendErrorWithFormat("%s", error.AsCString());
  }

  std::optional<std::string> GetRepeatCommand(Args &current_command_args,
                                              uint32_t index) override {
    // If we repeat this command, repeat it without any arguments so we can
    // show the next memory range
    return m_cmd_name;
  }

  lldb::addr_t m_prev_end_addr = LLDB_INVALID_ADDRESS;

  OptionGroupOptions m_option_group;
  OptionGroupMemoryRegion m_memory_region_options;
};

// CommandObjectMemory

CommandObjectMemory::CommandObjectMemory(CommandInterpreter &interpreter)
    : CommandObjectMultiword(
          interpreter, "memory",
          "Commands for operating on memory in the current target process.",
          "memory <subcommand> [<subcommand-options>]") {
  LoadSubCommand("find",
                 CommandObjectSP(new CommandObjectMemoryFind(interpreter)));
  LoadSubCommand("read",
                 CommandObjectSP(new CommandObjectMemoryRead(interpreter)));
  LoadSubCommand("write",
                 CommandObjectSP(new CommandObjectMemoryWrite(interpreter)));
  LoadSubCommand("history",
                 CommandObjectSP(new CommandObjectMemoryHistory(interpreter)));
  LoadSubCommand("region",
                 CommandObjectSP(new CommandObjectMemoryRegion(interpreter)));
  LoadSubCommand("tag",
                 CommandObjectSP(new CommandObjectMemoryTag(interpreter)));
}

CommandObjectMemory::~CommandObjectMemory() = default;
