//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "CommandObjectTarget.h"

// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupArchitecture.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFile.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionGroupUUID.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Interpreter/OptionGroupVariable.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
#include "lldb/Utility/Timer.h"

#include "llvm/Support/FileSystem.h"

// C Includes
// C++ Includes
#include <cerrno>

using namespace lldb;
using namespace lldb_private;

static void DumpTargetInfo(uint32_t target_idx, Target *target,
                           const char *prefix_cstr,
                           bool show_stopped_process_status, Stream &strm) {
  const ArchSpec &target_arch = target->GetArchitecture();

  Module *exe_module = target->GetExecutableModulePointer();
  char exe_path[PATH_MAX];
  bool exe_valid = false;
  if (exe_module)
    exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));

  if (!exe_valid)
    ::strcpy(exe_path, "<none>");

  strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
              exe_path);

  uint32_t properties = 0;
  if (target_arch.IsValid()) {
    strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
    target_arch.DumpTriple(strm);
    properties++;
  }
  PlatformSP platform_sp(target->GetPlatform());
  if (platform_sp)
    strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
                platform_sp->GetName().GetCString());

  ProcessSP process_sp(target->GetProcessSP());
  bool show_process_status = false;
  if (process_sp) {
    lldb::pid_t pid = process_sp->GetID();
    StateType state = process_sp->GetState();
    if (show_stopped_process_status)
      show_process_status = StateIsStoppedState(state, true);
    const char *state_cstr = StateAsCString(state);
    if (pid != LLDB_INVALID_PROCESS_ID)
      strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
    strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
  }
  if (properties > 0)
    strm.PutCString(" )\n");
  else
    strm.EOL();
  if (show_process_status) {
    const bool only_threads_with_stop_reason = true;
    const uint32_t start_frame = 0;
    const uint32_t num_frames = 1;
    const uint32_t num_frames_with_source = 1;
    const bool     stop_format = false;
    process_sp->GetStatus(strm);
    process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
                                start_frame, num_frames,
                                num_frames_with_source, stop_format);
  }
}

static uint32_t DumpTargetList(TargetList &target_list,
                               bool show_stopped_process_status, Stream &strm) {
  const uint32_t num_targets = target_list.GetNumTargets();
  if (num_targets) {
    TargetSP selected_target_sp(target_list.GetSelectedTarget());
    strm.PutCString("Current targets:\n");
    for (uint32_t i = 0; i < num_targets; ++i) {
      TargetSP target_sp(target_list.GetTargetAtIndex(i));
      if (target_sp) {
        bool is_selected = target_sp.get() == selected_target_sp.get();
        DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : "  ",
                       show_stopped_process_status, strm);
      }
    }
  }
  return num_targets;
}

// TODO: Remove this once llvm can pretty-print time points
static void DumpTimePoint(llvm::sys::TimePoint<> tp, Stream &s, uint32_t width) {
#ifndef LLDB_DISABLE_POSIX
  char time_buf[32];
  time_t time = llvm::sys::toTimeT(tp);
  char *time_cstr = ::ctime_r(&time, time_buf);
  if (time_cstr) {
    char *newline = ::strpbrk(time_cstr, "\n\r");
    if (newline)
      *newline = '\0';
    if (width > 0)
      s.Printf("%-*s", width, time_cstr);
    else
      s.PutCString(time_cstr);
  } else if (width > 0)
    s.Printf("%-*s", width, "");
#endif
}

#pragma mark CommandObjectTargetCreate

//-------------------------------------------------------------------------
// "target create"
//-------------------------------------------------------------------------

class CommandObjectTargetCreate : public CommandObjectParsed {
public:
  CommandObjectTargetCreate(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "target create",
            "Create a target using the argument as the main executable.",
            nullptr),
        m_option_group(), m_arch_option(),
        m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
                    "Fullpath to a core file to use for this target."),
        m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
                        eArgTypePath,
                        "Path to the remote file to use for this target."),
        m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
                      eArgTypeFilename, "Fullpath to a stand alone debug "
                                        "symbols file for when debug symbols "
                                        "are not in the executable."),
        m_remote_file(
            LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
            "Fullpath to the file on the remote host if debugging remotely."),
        m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
                         "Don't load dependent files when creating the target, "
                         "just add the specified executable.",
                         true, true) {
    CommandArgumentEntry arg;
    CommandArgumentData file_arg;

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

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

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

    m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Finalize();
  }

  ~CommandObjectTargetCreate() override = default;

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

  int HandleArgumentCompletion(Args &input, int &cursor_index,
                               int &cursor_char_position,
                               OptionElementVector &opt_element_vector,
                               int match_start_point, int max_return_elements,
                               bool &word_complete,
                               StringList &matches) override {
    std::string completion_str(input.GetArgumentAtIndex(cursor_index));
    completion_str.erase(cursor_char_position);

    CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
        completion_str.c_str(), match_start_point, max_return_elements, nullptr,
        word_complete, matches);
    return matches.GetSize();
  }

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    const size_t argc = command.GetArgumentCount();
    FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
    FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());

    if (core_file) {
      if (!core_file.Exists()) {
        result.AppendErrorWithFormat("core file '%s' doesn't exist",
                                     core_file.GetPath().c_str());
        result.SetStatus(eReturnStatusFailed);
        return false;
      }
      if (!core_file.Readable()) {
        result.AppendErrorWithFormat("core file '%s' is not readable",
                                     core_file.GetPath().c_str());
        result.SetStatus(eReturnStatusFailed);
        return false;
      }
    }

    if (argc == 1 || core_file || remote_file) {
      FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
      if (symfile) {
        if (symfile.Exists()) {
          if (!symfile.Readable()) {
            result.AppendErrorWithFormat("symbol file '%s' is not readable",
                                         symfile.GetPath().c_str());
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
        } else {
          char symfile_path[PATH_MAX];
          symfile.GetPath(symfile_path, sizeof(symfile_path));
          result.AppendErrorWithFormat("invalid symbol file path '%s'",
                                       symfile_path);
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
      }

      const char *file_path = command.GetArgumentAtIndex(0);
      static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
      Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
      FileSpec file_spec;

      if (file_path)
        file_spec.SetFile(file_path, true);

      bool must_set_platform_path = false;

      Debugger &debugger = m_interpreter.GetDebugger();

      TargetSP target_sp;
      llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
      const bool get_dependent_files =
          m_add_dependents.GetOptionValue().GetCurrentValue();
      Status error(debugger.GetTargetList().CreateTarget(
          debugger, file_path, arch_cstr, get_dependent_files, nullptr,
          target_sp));

      if (target_sp) {
        // Only get the platform after we create the target because we might
        // have
        // switched platforms depending on what the arguments were to
        // CreateTarget()
        // we can't rely on the selected platform.

        PlatformSP platform_sp = target_sp->GetPlatform();

        if (remote_file) {
          if (platform_sp) {
            // I have a remote file.. two possible cases
            if (file_spec && file_spec.Exists()) {
              // if the remote file does not exist, push it there
              if (!platform_sp->GetFileExists(remote_file)) {
                Status err = platform_sp->PutFile(file_spec, remote_file);
                if (err.Fail()) {
                  result.AppendError(err.AsCString());
                  result.SetStatus(eReturnStatusFailed);
                  return false;
                }
              }
            } else {
              // there is no local file and we need one
              // in order to make the remote ---> local transfer we need a
              // platform
              // TODO: if the user has passed in a --platform argument, use it
              // to fetch the right platform
              if (!platform_sp) {
                result.AppendError(
                    "unable to perform remote debugging without a platform");
                result.SetStatus(eReturnStatusFailed);
                return false;
              }
              if (file_path) {
                // copy the remote file to the local file
                Status err = platform_sp->GetFile(remote_file, file_spec);
                if (err.Fail()) {
                  result.AppendError(err.AsCString());
                  result.SetStatus(eReturnStatusFailed);
                  return false;
                }
              } else {
                // make up a local file
                result.AppendError("remote --> local transfer without local "
                                   "path is not implemented yet");
                result.SetStatus(eReturnStatusFailed);
                return false;
              }
            }
          } else {
            result.AppendError("no platform found for target");
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
        }

        if (symfile || remote_file) {
          ModuleSP module_sp(target_sp->GetExecutableModule());
          if (module_sp) {
            if (symfile)
              module_sp->SetSymbolFileFileSpec(symfile);
            if (remote_file) {
              std::string remote_path = remote_file.GetPath();
              target_sp->SetArg0(remote_path.c_str());
              module_sp->SetPlatformFileSpec(remote_file);
            }
          }
        }

        debugger.GetTargetList().SetSelectedTarget(target_sp.get());
        if (must_set_platform_path) {
          ModuleSpec main_module_spec(file_spec);
          ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
          if (module_sp)
            module_sp->SetPlatformFileSpec(remote_file);
        }
        if (core_file) {
          char core_path[PATH_MAX];
          core_file.GetPath(core_path, sizeof(core_path));
          if (core_file.Exists()) {
            if (!core_file.Readable()) {
              result.AppendMessageWithFormat(
                  "Core file '%s' is not readable.\n", core_path);
              result.SetStatus(eReturnStatusFailed);
              return false;
            }
            FileSpec core_file_dir;
            core_file_dir.GetDirectory() = core_file.GetDirectory();
            target_sp->GetExecutableSearchPaths().Append(core_file_dir);

            ProcessSP process_sp(target_sp->CreateProcess(
                m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
                &core_file));

            if (process_sp) {
              // Seems weird that we Launch a core file, but that is
              // what we do!
              error = process_sp->LoadCore();

              if (error.Fail()) {
                result.AppendError(
                    error.AsCString("can't find plug-in for core file"));
                result.SetStatus(eReturnStatusFailed);
                return false;
              } else {
                result.AppendMessageWithFormat(
                    "Core file '%s' (%s) was loaded.\n", core_path,
                    target_sp->GetArchitecture().GetArchitectureName());
                result.SetStatus(eReturnStatusSuccessFinishNoResult);
              }
            } else {
              result.AppendErrorWithFormat(
                  "Unable to find process plug-in for core file '%s'\n",
                  core_path);
              result.SetStatus(eReturnStatusFailed);
            }
          } else {
            result.AppendErrorWithFormat("Core file '%s' does not exist\n",
                                         core_path);
            result.SetStatus(eReturnStatusFailed);
          }
        } else {
          result.AppendMessageWithFormat(
              "Current executable set to '%s' (%s).\n", file_path,
              target_sp->GetArchitecture().GetArchitectureName());
          result.SetStatus(eReturnStatusSuccessFinishNoResult);
        }
      } else {
        result.AppendError(error.AsCString());
        result.SetStatus(eReturnStatusFailed);
      }
    } else {
      result.AppendErrorWithFormat("'%s' takes exactly one executable path "
                                   "argument, or use the --core option.\n",
                                   m_cmd_name.c_str());
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }

private:
  OptionGroupOptions m_option_group;
  OptionGroupArchitecture m_arch_option;
  OptionGroupFile m_core_file;
  OptionGroupFile m_platform_path;
  OptionGroupFile m_symbol_file;
  OptionGroupFile m_remote_file;
  OptionGroupBoolean m_add_dependents;
};

#pragma mark CommandObjectTargetList

//----------------------------------------------------------------------
// "target list"
//----------------------------------------------------------------------

class CommandObjectTargetList : public CommandObjectParsed {
public:
  CommandObjectTargetList(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "target list",
            "List all current targets in the current debug session.", nullptr) {
  }

  ~CommandObjectTargetList() override = default;

protected:
  bool DoExecute(Args &args, CommandReturnObject &result) override {
    if (args.GetArgumentCount() == 0) {
      Stream &strm = result.GetOutputStream();

      bool show_stopped_process_status = false;
      if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
                         show_stopped_process_status, strm) == 0) {
        strm.PutCString("No targets.\n");
      }
      result.SetStatus(eReturnStatusSuccessFinishResult);
    } else {
      result.AppendError("the 'target list' command takes no arguments\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetSelect

//----------------------------------------------------------------------
// "target select"
//----------------------------------------------------------------------

class CommandObjectTargetSelect : public CommandObjectParsed {
public:
  CommandObjectTargetSelect(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "target select",
            "Select a target as the current target by target index.", nullptr) {
  }

  ~CommandObjectTargetSelect() override = default;

protected:
  bool DoExecute(Args &args, CommandReturnObject &result) override {
    if (args.GetArgumentCount() == 1) {
      bool success = false;
      const char *target_idx_arg = args.GetArgumentAtIndex(0);
      uint32_t target_idx =
          StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
      if (success) {
        TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
        const uint32_t num_targets = target_list.GetNumTargets();
        if (target_idx < num_targets) {
          TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
          if (target_sp) {
            Stream &strm = result.GetOutputStream();
            target_list.SetSelectedTarget(target_sp.get());
            bool show_stopped_process_status = false;
            DumpTargetList(target_list, show_stopped_process_status, strm);
            result.SetStatus(eReturnStatusSuccessFinishResult);
          } else {
            result.AppendErrorWithFormat("target #%u is NULL in target list\n",
                                         target_idx);
            result.SetStatus(eReturnStatusFailed);
          }
        } else {
          if (num_targets > 0) {
            result.AppendErrorWithFormat(
                "index %u is out of range, valid target indexes are 0 - %u\n",
                target_idx, num_targets - 1);
          } else {
            result.AppendErrorWithFormat(
                "index %u is out of range since there are no active targets\n",
                target_idx);
          }
          result.SetStatus(eReturnStatusFailed);
        }
      } else {
        result.AppendErrorWithFormat("invalid index string value '%s'\n",
                                     target_idx_arg);
        result.SetStatus(eReturnStatusFailed);
      }
    } else {
      result.AppendError(
          "'target select' takes a single argument: a target index\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetSelect

//----------------------------------------------------------------------
// "target delete"
//----------------------------------------------------------------------

class CommandObjectTargetDelete : public CommandObjectParsed {
public:
  CommandObjectTargetDelete(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target delete",
                            "Delete one or more targets by target index.",
                            nullptr),
        m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
                                       "Delete all targets.", false, true),
        m_cleanup_option(
            LLDB_OPT_SET_1, false, "clean", 'c',
            "Perform extra cleanup to minimize memory consumption after "
            "deleting the target.  "
            "By default, LLDB will keep in memory any modules previously "
            "loaded by the target as well "
            "as all of its debug info.  Specifying --clean will unload all of "
            "these shared modules and "
            "cause them to be reparsed again the next time the target is run",
            false, true) {
    m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Finalize();
  }

  ~CommandObjectTargetDelete() override = default;

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

protected:
  bool DoExecute(Args &args, CommandReturnObject &result) override {
    const size_t argc = args.GetArgumentCount();
    std::vector<TargetSP> delete_target_list;
    TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
    TargetSP target_sp;

    if (m_all_option.GetOptionValue()) {
      for (int i = 0; i < target_list.GetNumTargets(); ++i)
        delete_target_list.push_back(target_list.GetTargetAtIndex(i));
    } else if (argc > 0) {
      const uint32_t num_targets = target_list.GetNumTargets();
      // Bail out if don't have any targets.
      if (num_targets == 0) {
        result.AppendError("no targets to delete");
        result.SetStatus(eReturnStatusFailed);
        return false;
      }

      for (auto &entry : args.entries()) {
        uint32_t target_idx;
        if (entry.ref.getAsInteger(0, target_idx)) {
          result.AppendErrorWithFormat("invalid target index '%s'\n",
                                       entry.c_str());
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
        if (target_idx < num_targets) {
          target_sp = target_list.GetTargetAtIndex(target_idx);
          if (target_sp) {
            delete_target_list.push_back(target_sp);
            continue;
          }
        }
        if (num_targets > 1)
          result.AppendErrorWithFormat("target index %u is out of range, valid "
                                       "target indexes are 0 - %u\n",
                                       target_idx, num_targets - 1);
        else
          result.AppendErrorWithFormat(
              "target index %u is out of range, the only valid index is 0\n",
              target_idx);

        result.SetStatus(eReturnStatusFailed);
        return false;
      }
    } else {
      target_sp = target_list.GetSelectedTarget();
      if (!target_sp) {
        result.AppendErrorWithFormat("no target is currently selected\n");
        result.SetStatus(eReturnStatusFailed);
        return false;
      }
      delete_target_list.push_back(target_sp);
    }

    const size_t num_targets_to_delete = delete_target_list.size();
    for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
      target_sp = delete_target_list[idx];
      target_list.DeleteTarget(target_sp);
      target_sp->Destroy();
    }
    // If "--clean" was specified, prune any orphaned shared modules from
    // the global shared module list
    if (m_cleanup_option.GetOptionValue()) {
      const bool mandatory = true;
      ModuleList::RemoveOrphanSharedModules(mandatory);
    }
    result.GetOutputStream().Printf("%u targets deleted.\n",
                                    (uint32_t)num_targets_to_delete);
    result.SetStatus(eReturnStatusSuccessFinishResult);

    return true;
  }

  OptionGroupOptions m_option_group;
  OptionGroupBoolean m_all_option;
  OptionGroupBoolean m_cleanup_option;
};

#pragma mark CommandObjectTargetVariable

//----------------------------------------------------------------------
// "target variable"
//----------------------------------------------------------------------

class CommandObjectTargetVariable : public CommandObjectParsed {
  static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
  static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'

public:
  CommandObjectTargetVariable(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target variable",
                            "Read global variables for the current target, "
                            "before or while running a process.",
                            nullptr, eCommandRequiresTarget),
        m_option_group(),
        m_option_variable(false), // Don't include frame options
        m_option_format(eFormatDefault),
        m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
                               0, eArgTypeFilename,
                               "A basename or fullpath to a file that contains "
                               "global variables. This option can be "
                               "specified multiple times."),
        m_option_shared_libraries(
            LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
            eArgTypeFilename,
            "A basename or fullpath to a shared library to use in the search "
            "for global "
            "variables. This option can be specified multiple times."),
        m_varobj_options() {
    CommandArgumentEntry arg;
    CommandArgumentData var_name_arg;

    // Define the first (and only) variant of this arg.
    var_name_arg.arg_type = eArgTypeVarName;
    var_name_arg.arg_repetition = eArgRepeatPlus;

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

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

    m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_option_format,
                          OptionGroupFormat::OPTION_GROUP_FORMAT |
                              OptionGroupFormat::OPTION_GROUP_GDB_FMT,
                          LLDB_OPT_SET_1);
    m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_1);
    m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_1);
    m_option_group.Finalize();
  }

  ~CommandObjectTargetVariable() override = default;

  void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
                       const char *root_name) {
    DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());

    if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
        valobj_sp->IsRuntimeSupportValue())
      return;

    switch (var_sp->GetScope()) {
    case eValueTypeVariableGlobal:
      if (m_option_variable.show_scope)
        s.PutCString("GLOBAL: ");
      break;

    case eValueTypeVariableStatic:
      if (m_option_variable.show_scope)
        s.PutCString("STATIC: ");
      break;

    case eValueTypeVariableArgument:
      if (m_option_variable.show_scope)
        s.PutCString("   ARG: ");
      break;

    case eValueTypeVariableLocal:
      if (m_option_variable.show_scope)
        s.PutCString(" LOCAL: ");
      break;

    case eValueTypeVariableThreadLocal:
      if (m_option_variable.show_scope)
        s.PutCString("THREAD: ");
      break;

    default:
      break;
    }

    if (m_option_variable.show_decl) {
      bool show_fullpaths = false;
      bool show_module = true;
      if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
        s.PutCString(": ");
    }

    const Format format = m_option_format.GetFormat();
    if (format != eFormatDefault)
      options.SetFormat(format);

    options.SetRootValueObjectName(root_name);

    valobj_sp->Dump(s, options);
  }

  static size_t GetVariableCallback(void *baton, const char *name,
                                    VariableList &variable_list) {
    Target *target = static_cast<Target *>(baton);
    if (target) {
      return target->GetImages().FindGlobalVariables(ConstString(name), true,
                                                     UINT32_MAX, variable_list);
    }
    return 0;
  }

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

protected:
  void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
                              const SymbolContext &sc,
                              const VariableList &variable_list, Stream &s) {
    size_t count = variable_list.GetSize();
    if (count > 0) {
      if (sc.module_sp) {
        if (sc.comp_unit) {
          s.Printf("Global variables for %s in %s:\n",
                   sc.comp_unit->GetPath().c_str(),
                   sc.module_sp->GetFileSpec().GetPath().c_str());
        } else {
          s.Printf("Global variables for %s\n",
                   sc.module_sp->GetFileSpec().GetPath().c_str());
        }
      } else if (sc.comp_unit) {
        s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
      }

      for (uint32_t i = 0; i < count; ++i) {
        VariableSP var_sp(variable_list.GetVariableAtIndex(i));
        if (var_sp) {
          ValueObjectSP valobj_sp(ValueObjectVariable::Create(
              exe_ctx.GetBestExecutionContextScope(), var_sp));

          if (valobj_sp)
            DumpValueObject(s, var_sp, valobj_sp,
                            var_sp->GetName().GetCString());
        }
      }
    }
  }

  bool DoExecute(Args &args, CommandReturnObject &result) override {
    Target *target = m_exe_ctx.GetTargetPtr();
    const size_t argc = args.GetArgumentCount();
    Stream &s = result.GetOutputStream();

    if (argc > 0) {

      // TODO: Convert to entry-based iteration.  Requires converting
      // DumpValueObject.
      for (size_t idx = 0; idx < argc; ++idx) {
        VariableList variable_list;
        ValueObjectList valobj_list;

        const char *arg = args.GetArgumentAtIndex(idx);
        size_t matches = 0;
        bool use_var_name = false;
        if (m_option_variable.use_regex) {
          RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
          if (!regex.IsValid()) {
            result.GetErrorStream().Printf(
                "error: invalid regular expression: '%s'\n", arg);
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
          use_var_name = true;
          matches = target->GetImages().FindGlobalVariables(
              regex, true, UINT32_MAX, variable_list);
        } else {
          Status error(Variable::GetValuesForVariableExpressionPath(
              arg, m_exe_ctx.GetBestExecutionContextScope(),
              GetVariableCallback, target, variable_list, valobj_list));
          matches = variable_list.GetSize();
        }

        if (matches == 0) {
          result.GetErrorStream().Printf(
              "error: can't find global variable '%s'\n", arg);
          result.SetStatus(eReturnStatusFailed);
          return false;
        } else {
          for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
            VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
            if (var_sp) {
              ValueObjectSP valobj_sp(
                  valobj_list.GetValueObjectAtIndex(global_idx));
              if (!valobj_sp)
                valobj_sp = ValueObjectVariable::Create(
                    m_exe_ctx.GetBestExecutionContextScope(), var_sp);

              if (valobj_sp)
                DumpValueObject(s, var_sp, valobj_sp,
                                use_var_name ? var_sp->GetName().GetCString()
                                             : arg);
            }
          }
        }
      }
    } else {
      const FileSpecList &compile_units =
          m_option_compile_units.GetOptionValue().GetCurrentValue();
      const FileSpecList &shlibs =
          m_option_shared_libraries.GetOptionValue().GetCurrentValue();
      SymbolContextList sc_list;
      const size_t num_compile_units = compile_units.GetSize();
      const size_t num_shlibs = shlibs.GetSize();
      if (num_compile_units == 0 && num_shlibs == 0) {
        bool success = false;
        StackFrame *frame = m_exe_ctx.GetFramePtr();
        CompileUnit *comp_unit = nullptr;
        if (frame) {
          SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
          if (sc.comp_unit) {
            const bool can_create = true;
            VariableListSP comp_unit_varlist_sp(
                sc.comp_unit->GetVariableList(can_create));
            if (comp_unit_varlist_sp) {
              size_t count = comp_unit_varlist_sp->GetSize();
              if (count > 0) {
                DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
                success = true;
              }
            }
          }
        }
        if (!success) {
          if (frame) {
            if (comp_unit)
              result.AppendErrorWithFormat(
                  "no global variables in current compile unit: %s\n",
                  comp_unit->GetPath().c_str());
            else
              result.AppendErrorWithFormat(
                  "no debug information for frame %u\n",
                  frame->GetFrameIndex());
          } else
            result.AppendError("'target variable' takes one or more global "
                               "variable names as arguments\n");
          result.SetStatus(eReturnStatusFailed);
        }
      } else {
        SymbolContextList sc_list;
        const bool append = true;
        // We have one or more compile unit or shlib
        if (num_shlibs > 0) {
          for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
            const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
            ModuleSpec module_spec(module_file);

            ModuleSP module_sp(
                target->GetImages().FindFirstModule(module_spec));
            if (module_sp) {
              if (num_compile_units > 0) {
                for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
                  module_sp->FindCompileUnits(
                      compile_units.GetFileSpecAtIndex(cu_idx), append,
                      sc_list);
              } else {
                SymbolContext sc;
                sc.module_sp = module_sp;
                sc_list.Append(sc);
              }
            } else {
              // Didn't find matching shlib/module in target...
              result.AppendErrorWithFormat(
                  "target doesn't contain the specified shared library: %s\n",
                  module_file.GetPath().c_str());
            }
          }
        } else {
          // No shared libraries, we just want to find globals for the compile
          // units files that were specified
          for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
            target->GetImages().FindCompileUnits(
                compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
        }

        const uint32_t num_scs = sc_list.GetSize();
        if (num_scs > 0) {
          SymbolContext sc;
          for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
            if (sc_list.GetContextAtIndex(sc_idx, sc)) {
              if (sc.comp_unit) {
                const bool can_create = true;
                VariableListSP comp_unit_varlist_sp(
                    sc.comp_unit->GetVariableList(can_create));
                if (comp_unit_varlist_sp)
                  DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
                                         s);
              } else if (sc.module_sp) {
                // Get all global variables for this module
                lldb_private::RegularExpression all_globals_regex(
                    llvm::StringRef(
                        ".")); // Any global with at least one character
                VariableList variable_list;
                sc.module_sp->FindGlobalVariables(all_globals_regex, append,
                                                  UINT32_MAX, variable_list);
                DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
              }
            }
          }
        }
      }
    }

    if (m_interpreter.TruncationWarningNecessary()) {
      result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
                                      m_cmd_name.c_str());
      m_interpreter.TruncationWarningGiven();
    }

    return result.Succeeded();
  }

  OptionGroupOptions m_option_group;
  OptionGroupVariable m_option_variable;
  OptionGroupFormat m_option_format;
  OptionGroupFileList m_option_compile_units;
  OptionGroupFileList m_option_shared_libraries;
  OptionGroupValueObjectDisplay m_varobj_options;
};

#pragma mark CommandObjectTargetModulesSearchPathsAdd

class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
public:
  CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target modules search-paths add",
                            "Add new image search paths substitution pairs to "
                            "the current target.",
                            nullptr) {
    CommandArgumentEntry arg;
    CommandArgumentData old_prefix_arg;
    CommandArgumentData new_prefix_arg;

    // Define the first variant of this arg pair.
    old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
    old_prefix_arg.arg_repetition = eArgRepeatPairPlus;

    // Define the first variant of this arg pair.
    new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
    new_prefix_arg.arg_repetition = eArgRepeatPairPlus;

    // There are two required arguments that must always occur together, i.e. an
    // argument "pair".  Because they
    // must always occur together, they are treated as two variants of one
    // argument rather than two independent
    // arguments.  Push them both into the first argument position for
    // m_arguments...

    arg.push_back(old_prefix_arg);
    arg.push_back(new_prefix_arg);

    m_arguments.push_back(arg);
  }

  ~CommandObjectTargetModulesSearchPathsAdd() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target) {
      const size_t argc = command.GetArgumentCount();
      if (argc & 1) {
        result.AppendError("add requires an even number of arguments\n");
        result.SetStatus(eReturnStatusFailed);
      } else {
        for (size_t i = 0; i < argc; i += 2) {
          const char *from = command.GetArgumentAtIndex(i);
          const char *to = command.GetArgumentAtIndex(i + 1);

          if (from[0] && to[0]) {
            Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
            if (log) {
              log->Printf("target modules search path adding ImageSearchPath "
                          "pair: '%s' -> '%s'",
                          from, to);
            }
            bool last_pair = ((argc - i) == 2);
            target->GetImageSearchPathList().Append(
                ConstString(from), ConstString(to),
                last_pair); // Notify if this is the last pair
            result.SetStatus(eReturnStatusSuccessFinishNoResult);
          } else {
            if (from[0])
              result.AppendError("<path-prefix> can't be empty\n");
            else
              result.AppendError("<new-path-prefix> can't be empty\n");
            result.SetStatus(eReturnStatusFailed);
          }
        }
      }
    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesSearchPathsClear

class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
public:
  CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target modules search-paths clear",
                            "Clear all current image search path substitution "
                            "pairs from the current target.",
                            "target modules search-paths clear") {}

  ~CommandObjectTargetModulesSearchPathsClear() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target) {
      bool notify = true;
      target->GetImageSearchPathList().Clear(notify);
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesSearchPathsInsert

class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
public:
  CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target modules search-paths insert",
                            "Insert a new image search path substitution pair "
                            "into the current target at the specified index.",
                            nullptr) {
    CommandArgumentEntry arg1;
    CommandArgumentEntry arg2;
    CommandArgumentData index_arg;
    CommandArgumentData old_prefix_arg;
    CommandArgumentData new_prefix_arg;

    // Define the first and only variant of this arg.
    index_arg.arg_type = eArgTypeIndex;
    index_arg.arg_repetition = eArgRepeatPlain;

    // Put the one and only variant into the first arg for m_arguments:
    arg1.push_back(index_arg);

    // Define the first variant of this arg pair.
    old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
    old_prefix_arg.arg_repetition = eArgRepeatPairPlus;

    // Define the first variant of this arg pair.
    new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
    new_prefix_arg.arg_repetition = eArgRepeatPairPlus;

    // There are two required arguments that must always occur together, i.e. an
    // argument "pair".  Because they
    // must always occur together, they are treated as two variants of one
    // argument rather than two independent
    // arguments.  Push them both into the same argument position for
    // m_arguments...

    arg2.push_back(old_prefix_arg);
    arg2.push_back(new_prefix_arg);

    // Add arguments to m_arguments.
    m_arguments.push_back(arg1);
    m_arguments.push_back(arg2);
  }

  ~CommandObjectTargetModulesSearchPathsInsert() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target) {
      size_t argc = command.GetArgumentCount();
      // check for at least 3 arguments and an odd number of parameters
      if (argc >= 3 && argc & 1) {
        bool success = false;

        uint32_t insert_idx = StringConvert::ToUInt32(
            command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);

        if (!success) {
          result.AppendErrorWithFormat(
              "<index> parameter is not an integer: '%s'.\n",
              command.GetArgumentAtIndex(0));
          result.SetStatus(eReturnStatusFailed);
          return result.Succeeded();
        }

        // shift off the index
        command.Shift();
        argc = command.GetArgumentCount();

        for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
          const char *from = command.GetArgumentAtIndex(i);
          const char *to = command.GetArgumentAtIndex(i + 1);

          if (from[0] && to[0]) {
            bool last_pair = ((argc - i) == 2);
            target->GetImageSearchPathList().Insert(
                ConstString(from), ConstString(to), insert_idx, last_pair);
            result.SetStatus(eReturnStatusSuccessFinishNoResult);
          } else {
            if (from[0])
              result.AppendError("<path-prefix> can't be empty\n");
            else
              result.AppendError("<new-path-prefix> can't be empty\n");
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
        }
      } else {
        result.AppendError("insert requires at least three arguments\n");
        result.SetStatus(eReturnStatusFailed);
        return result.Succeeded();
      }

    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesSearchPathsList

class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
public:
  CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target modules search-paths list",
                            "List all current image search path substitution "
                            "pairs in the current target.",
                            "target modules search-paths list") {}

  ~CommandObjectTargetModulesSearchPathsList() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target) {
      if (command.GetArgumentCount() != 0) {
        result.AppendError("list takes no arguments\n");
        result.SetStatus(eReturnStatusFailed);
        return result.Succeeded();
      }

      target->GetImageSearchPathList().Dump(&result.GetOutputStream());
      result.SetStatus(eReturnStatusSuccessFinishResult);
    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesSearchPathsQuery

class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
public:
  CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "target modules search-paths query",
            "Transform a path using the first applicable image search path.",
            nullptr) {
    CommandArgumentEntry arg;
    CommandArgumentData path_arg;

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

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

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

  ~CommandObjectTargetModulesSearchPathsQuery() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target) {
      if (command.GetArgumentCount() != 1) {
        result.AppendError("query requires one argument\n");
        result.SetStatus(eReturnStatusFailed);
        return result.Succeeded();
      }

      ConstString orig(command.GetArgumentAtIndex(0));
      ConstString transformed;
      if (target->GetImageSearchPathList().RemapPath(orig, transformed))
        result.GetOutputStream().Printf("%s\n", transformed.GetCString());
      else
        result.GetOutputStream().Printf("%s\n", orig.GetCString());

      result.SetStatus(eReturnStatusSuccessFinishResult);
    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

//----------------------------------------------------------------------
// Static Helper functions
//----------------------------------------------------------------------
static void DumpModuleArchitecture(Stream &strm, Module *module,
                                   bool full_triple, uint32_t width) {
  if (module) {
    StreamString arch_strm;

    if (full_triple)
      module->GetArchitecture().DumpTriple(arch_strm);
    else
      arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
    std::string arch_str = arch_strm.GetString();

    if (width)
      strm.Printf("%-*s", width, arch_str.c_str());
    else
      strm.PutCString(arch_str);
  }
}

static void DumpModuleUUID(Stream &strm, Module *module) {
  if (module && module->GetUUID().IsValid())
    module->GetUUID().Dump(&strm);
  else
    strm.PutCString("                                    ");
}

static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
                                         Stream &strm, Module *module,
                                         const FileSpec &file_spec,
                                         bool load_addresses) {
  uint32_t num_matches = 0;
  if (module) {
    SymbolContextList sc_list;
    num_matches = module->ResolveSymbolContextsForFileSpec(
        file_spec, 0, false, eSymbolContextCompUnit, sc_list);

    for (uint32_t i = 0; i < num_matches; ++i) {
      SymbolContext sc;
      if (sc_list.GetContextAtIndex(i, sc)) {
        if (i > 0)
          strm << "\n\n";

        strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
             << " in `" << module->GetFileSpec().GetFilename() << "\n";
        LineTable *line_table = sc.comp_unit->GetLineTable();
        if (line_table)
          line_table->GetDescription(
              &strm, interpreter.GetExecutionContext().GetTargetPtr(),
              lldb::eDescriptionLevelBrief);
        else
          strm << "No line table";
      }
    }
  }
  return num_matches;
}

static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
                         uint32_t width) {
  if (file_spec_ptr) {
    if (width > 0) {
      std::string fullpath = file_spec_ptr->GetPath();
      strm.Printf("%-*s", width, fullpath.c_str());
      return;
    } else {
      file_spec_ptr->Dump(&strm);
      return;
    }
  }
  // Keep the width spacing correct if things go wrong...
  if (width > 0)
    strm.Printf("%-*s", width, "");
}

static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
                          uint32_t width) {
  if (file_spec_ptr) {
    if (width > 0)
      strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
    else
      file_spec_ptr->GetDirectory().Dump(&strm);
    return;
  }
  // Keep the width spacing correct if things go wrong...
  if (width > 0)
    strm.Printf("%-*s", width, "");
}

static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
                         uint32_t width) {
  if (file_spec_ptr) {
    if (width > 0)
      strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
    else
      file_spec_ptr->GetFilename().Dump(&strm);
    return;
  }
  // Keep the width spacing correct if things go wrong...
  if (width > 0)
    strm.Printf("%-*s", width, "");
}

static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
  size_t num_dumped = 0;
  std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
  const size_t num_modules = module_list.GetSize();
  if (num_modules > 0) {
    strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
                static_cast<uint64_t>(num_modules));
    strm.IndentMore();
    for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
      Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
      if (module) {
        if (num_dumped++ > 0) {
          strm.EOL();
          strm.EOL();
        }
        ObjectFile *objfile = module->GetObjectFile();
        objfile->Dump(&strm);
      }
    }
    strm.IndentLess();
  }
  return num_dumped;
}

static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
                             Module *module, SortOrder sort_order) {
  if (module) {
    SymbolVendor *sym_vendor = module->GetSymbolVendor();
    if (sym_vendor) {
      Symtab *symtab = sym_vendor->GetSymtab();
      if (symtab)
        symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
                     sort_order);
    }
  }
}

static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
                               Module *module) {
  if (module) {
    SectionList *section_list = module->GetSectionList();
    if (section_list) {
      strm.Printf("Sections for '%s' (%s):\n",
                  module->GetSpecificationDescription().c_str(),
                  module->GetArchitecture().GetArchitectureName());
      strm.IndentMore();
      section_list->Dump(&strm,
                         interpreter.GetExecutionContext().GetTargetPtr(), true,
                         UINT32_MAX);
      strm.IndentLess();
    }
  }
}

static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
  if (module) {
    SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
    if (symbol_vendor) {
      symbol_vendor->Dump(&strm);
      return true;
    }
  }
  return false;
}

static void DumpAddress(ExecutionContextScope *exe_scope,
                        const Address &so_addr, bool verbose, Stream &strm) {
  strm.IndentMore();
  strm.Indent("    Address: ");
  so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
  strm.PutCString(" (");
  so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
  strm.PutCString(")\n");
  strm.Indent("    Summary: ");
  const uint32_t save_indent = strm.GetIndentLevel();
  strm.SetIndentLevel(save_indent + 13);
  so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
  strm.SetIndentLevel(save_indent);
  // Print out detailed address information when verbose is enabled
  if (verbose) {
    strm.EOL();
    so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
  }
  strm.IndentLess();
}

static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
                                  Module *module, uint32_t resolve_mask,
                                  lldb::addr_t raw_addr, lldb::addr_t offset,
                                  bool verbose) {
  if (module) {
    lldb::addr_t addr = raw_addr - offset;
    Address so_addr;
    SymbolContext sc;
    Target *target = interpreter.GetExecutionContext().GetTargetPtr();
    if (target && !target->GetSectionLoadList().IsEmpty()) {
      if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
        return false;
      else if (so_addr.GetModule().get() != module)
        return false;
    } else {
      if (!module->ResolveFileAddress(addr, so_addr))
        return false;
    }

    ExecutionContextScope *exe_scope =
        interpreter.GetExecutionContext().GetBestExecutionContextScope();
    DumpAddress(exe_scope, so_addr, verbose, strm);
    //        strm.IndentMore();
    //        strm.Indent ("    Address: ");
    //        so_addr.Dump (&strm, exe_scope,
    //        Address::DumpStyleModuleWithFileAddress);
    //        strm.PutCString (" (");
    //        so_addr.Dump (&strm, exe_scope,
    //        Address::DumpStyleSectionNameOffset);
    //        strm.PutCString (")\n");
    //        strm.Indent ("    Summary: ");
    //        const uint32_t save_indent = strm.GetIndentLevel ();
    //        strm.SetIndentLevel (save_indent + 13);
    //        so_addr.Dump (&strm, exe_scope,
    //        Address::DumpStyleResolvedDescription);
    //        strm.SetIndentLevel (save_indent);
    //        // Print out detailed address information when verbose is enabled
    //        if (verbose)
    //        {
    //            strm.EOL();
    //            so_addr.Dump (&strm, exe_scope,
    //            Address::DumpStyleDetailedSymbolContext);
    //        }
    //        strm.IndentLess();
    return true;
  }

  return false;
}

static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
                                     Stream &strm, Module *module,
                                     const char *name, bool name_is_regex,
                                     bool verbose) {
  if (module) {
    SymbolContext sc;

    SymbolVendor *sym_vendor = module->GetSymbolVendor();
    if (sym_vendor) {
      Symtab *symtab = sym_vendor->GetSymtab();
      if (symtab) {
        std::vector<uint32_t> match_indexes;
        ConstString symbol_name(name);
        uint32_t num_matches = 0;
        if (name_is_regex) {
          RegularExpression name_regexp(symbol_name.GetStringRef());
          num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
              name_regexp, eSymbolTypeAny, match_indexes);
        } else {
          num_matches =
              symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
        }

        if (num_matches > 0) {
          strm.Indent();
          strm.Printf("%u symbols match %s'%s' in ", num_matches,
                      name_is_regex ? "the regular expression " : "", name);
          DumpFullpath(strm, &module->GetFileSpec(), 0);
          strm.PutCString(":\n");
          strm.IndentMore();
          for (uint32_t i = 0; i < num_matches; ++i) {
            Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
            if (symbol && symbol->ValueIsAddress()) {
              DumpAddress(interpreter.GetExecutionContext()
                              .GetBestExecutionContextScope(),
                          symbol->GetAddressRef(), verbose, strm);
            }
          }
          strm.IndentLess();
          return num_matches;
        }
      }
    }
  }
  return 0;
}

static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
                                  Stream &strm, SymbolContextList &sc_list,
                                  bool verbose) {
  strm.IndentMore();

  const uint32_t num_matches = sc_list.GetSize();

  for (uint32_t i = 0; i < num_matches; ++i) {
    SymbolContext sc;
    if (sc_list.GetContextAtIndex(i, sc)) {
      AddressRange range;

      sc.GetAddressRange(eSymbolContextEverything, 0, true, range);

      DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
    }
  }
  strm.IndentLess();
}

static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
                                     Stream &strm, Module *module,
                                     const char *name, bool name_is_regex,
                                     bool include_inlines, bool include_symbols,
                                     bool verbose) {
  if (module && name && name[0]) {
    SymbolContextList sc_list;
    const bool append = true;
    size_t num_matches = 0;
    if (name_is_regex) {
      RegularExpression function_name_regex((llvm::StringRef(name)));
      num_matches = module->FindFunctions(function_name_regex, include_symbols,
                                          include_inlines, append, sc_list);
    } else {
      ConstString function_name(name);
      num_matches = module->FindFunctions(
          function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
          include_inlines, append, sc_list);
    }

    if (num_matches) {
      strm.Indent();
      strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
                  num_matches > 1 ? "es" : "");
      DumpFullpath(strm, &module->GetFileSpec(), 0);
      strm.PutCString(":\n");
      DumpSymbolContextList(
          interpreter.GetExecutionContext().GetBestExecutionContextScope(),
          strm, sc_list, verbose);
    }
    return num_matches;
  }
  return 0;
}

static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
                                 Module *module, const char *name_cstr,
                                 bool name_is_regex) {
  if (module && name_cstr && name_cstr[0]) {
    TypeList type_list;
    const uint32_t max_num_matches = UINT32_MAX;
    size_t num_matches = 0;
    bool name_is_fully_qualified = false;
    SymbolContext sc;

    ConstString name(name_cstr);
    llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
    num_matches =
        module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
                          searched_symbol_files, type_list);

    if (num_matches) {
      strm.Indent();
      strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
                  num_matches > 1 ? "es" : "");
      DumpFullpath(strm, &module->GetFileSpec(), 0);
      strm.PutCString(":\n");
      for (TypeSP type_sp : type_list.Types()) {
        if (type_sp) {
          // Resolve the clang type so that any forward references
          // to types that haven't yet been parsed will get parsed.
          type_sp->GetFullCompilerType();
          type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
          // Print all typedef chains
          TypeSP typedef_type_sp(type_sp);
          TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
          while (typedefed_type_sp) {
            strm.EOL();
            strm.Printf("     typedef '%s': ",
                        typedef_type_sp->GetName().GetCString());
            typedefed_type_sp->GetFullCompilerType();
            typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
                                              true);
            typedef_type_sp = typedefed_type_sp;
            typedefed_type_sp = typedef_type_sp->GetTypedefType();
          }
        }
        strm.EOL();
      }
    }
    return num_matches;
  }
  return 0;
}

static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
                             const SymbolContext &sym_ctx,
                             const char *name_cstr, bool name_is_regex) {
  if (!sym_ctx.module_sp)
    return 0;

  TypeList type_list;
  const uint32_t max_num_matches = UINT32_MAX;
  size_t num_matches = 1;
  bool name_is_fully_qualified = false;

  ConstString name(name_cstr);
  llvm::DenseSet<SymbolFile *> searched_symbol_files;
  num_matches = sym_ctx.module_sp->FindTypes(
      sym_ctx, name, name_is_fully_qualified, max_num_matches,
      searched_symbol_files, type_list);

  if (num_matches) {
    strm.Indent();
    strm.PutCString("Best match found in ");
    DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
    strm.PutCString(":\n");

    TypeSP type_sp(type_list.GetTypeAtIndex(0));
    if (type_sp) {
      // Resolve the clang type so that any forward references
      // to types that haven't yet been parsed will get parsed.
      type_sp->GetFullCompilerType();
      type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
      // Print all typedef chains
      TypeSP typedef_type_sp(type_sp);
      TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
      while (typedefed_type_sp) {
        strm.EOL();
        strm.Printf("     typedef '%s': ",
                    typedef_type_sp->GetName().GetCString());
        typedefed_type_sp->GetFullCompilerType();
        typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
        typedef_type_sp = typedefed_type_sp;
        typedefed_type_sp = typedef_type_sp->GetTypedefType();
      }
    }
    strm.EOL();
  }
  return num_matches;
}

static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
                                          Stream &strm, Module *module,
                                          const FileSpec &file_spec,
                                          uint32_t line, bool check_inlines,
                                          bool verbose) {
  if (module && file_spec) {
    SymbolContextList sc_list;
    const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
        file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
    if (num_matches > 0) {
      strm.Indent();
      strm.Printf("%u match%s found in ", num_matches,
                  num_matches > 1 ? "es" : "");
      strm << file_spec;
      if (line > 0)
        strm.Printf(":%u", line);
      strm << " in ";
      DumpFullpath(strm, &module->GetFileSpec(), 0);
      strm.PutCString(":\n");
      DumpSymbolContextList(
          interpreter.GetExecutionContext().GetBestExecutionContextScope(),
          strm, sc_list, verbose);
      return num_matches;
    }
  }
  return 0;
}

static size_t FindModulesByName(Target *target, const char *module_name,
                                ModuleList &module_list,
                                bool check_global_list) {
  FileSpec module_file_spec(module_name, false);
  ModuleSpec module_spec(module_file_spec);

  const size_t initial_size = module_list.GetSize();

  if (check_global_list) {
    // Check the global list
    std::lock_guard<std::recursive_mutex> guard(
        Module::GetAllocationModuleCollectionMutex());
    const size_t num_modules = Module::GetNumberAllocatedModules();
    ModuleSP module_sp;
    for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
      Module *module = Module::GetAllocatedModuleAtIndex(image_idx);

      if (module) {
        if (module->MatchesModuleSpec(module_spec)) {
          module_sp = module->shared_from_this();
          module_list.AppendIfNeeded(module_sp);
        }
      }
    }
  } else {
    if (target) {
      const size_t num_matches =
          target->GetImages().FindModules(module_spec, module_list);

      // Not found in our module list for our target, check the main
      // shared module list in case it is a extra file used somewhere
      // else
      if (num_matches == 0) {
        module_spec.GetArchitecture() = target->GetArchitecture();
        ModuleList::FindSharedModules(module_spec, module_list);
      }
    } else {
      ModuleList::FindSharedModules(module_spec, module_list);
    }
  }

  return module_list.GetSize() - initial_size;
}

#pragma mark CommandObjectTargetModulesModuleAutoComplete

//----------------------------------------------------------------------
// A base command object class that can auto complete with module file
// paths
//----------------------------------------------------------------------

class CommandObjectTargetModulesModuleAutoComplete
    : public CommandObjectParsed {
public:
  CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
                                               const char *name,
                                               const char *help,
                                               const char *syntax)
      : CommandObjectParsed(interpreter, name, help, syntax) {
    CommandArgumentEntry arg;
    CommandArgumentData file_arg;

    // Define the first (and only) variant of this arg.
    file_arg.arg_type = eArgTypeFilename;
    file_arg.arg_repetition = eArgRepeatStar;

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

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

  ~CommandObjectTargetModulesModuleAutoComplete() override = default;

  int HandleArgumentCompletion(Args &input, int &cursor_index,
                               int &cursor_char_position,
                               OptionElementVector &opt_element_vector,
                               int match_start_point, int max_return_elements,
                               bool &word_complete,
                               StringList &matches) override {
    // Arguments are the standard module completer.
    std::string completion_str(input.GetArgumentAtIndex(cursor_index));
    completion_str.erase(cursor_char_position);

    CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
        completion_str.c_str(), match_start_point, max_return_elements, nullptr,
        word_complete, matches);
    return matches.GetSize();
  }
};

#pragma mark CommandObjectTargetModulesSourceFileAutoComplete

//----------------------------------------------------------------------
// A base command object class that can auto complete with module source
// file paths
//----------------------------------------------------------------------

class CommandObjectTargetModulesSourceFileAutoComplete
    : public CommandObjectParsed {
public:
  CommandObjectTargetModulesSourceFileAutoComplete(
      CommandInterpreter &interpreter, const char *name, const char *help,
      const char *syntax, uint32_t flags)
      : CommandObjectParsed(interpreter, name, help, syntax, flags) {
    CommandArgumentEntry arg;
    CommandArgumentData source_file_arg;

    // Define the first (and only) variant of this arg.
    source_file_arg.arg_type = eArgTypeSourceFile;
    source_file_arg.arg_repetition = eArgRepeatPlus;

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

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

  ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;

  int HandleArgumentCompletion(Args &input, int &cursor_index,
                               int &cursor_char_position,
                               OptionElementVector &opt_element_vector,
                               int match_start_point, int max_return_elements,
                               bool &word_complete,
                               StringList &matches) override {
    // Arguments are the standard source file completer.
    std::string completion_str(input.GetArgumentAtIndex(cursor_index));
    completion_str.erase(cursor_char_position);

    CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
        completion_str.c_str(), match_start_point, max_return_elements, nullptr,
        word_complete, matches);
    return matches.GetSize();
  }
};

#pragma mark CommandObjectTargetModulesDumpObjfile

class CommandObjectTargetModulesDumpObjfile
    : public CommandObjectTargetModulesModuleAutoComplete {
public:
  CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
      : CommandObjectTargetModulesModuleAutoComplete(
            interpreter, "target modules dump objfile",
            "Dump the object file headers from one or more target modules.",
            nullptr) {}

  ~CommandObjectTargetModulesDumpObjfile() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == nullptr) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    }

    uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
    result.GetOutputStream().SetAddressByteSize(addr_byte_size);
    result.GetErrorStream().SetAddressByteSize(addr_byte_size);

    size_t num_dumped = 0;
    if (command.GetArgumentCount() == 0) {
      // Dump all headers for all modules images
      num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
                                            target->GetImages());
      if (num_dumped == 0) {
        result.AppendError("the target has no associated executable images");
        result.SetStatus(eReturnStatusFailed);
      }
    } else {
      // Find the modules that match the basename or full path.
      ModuleList module_list;
      const char *arg_cstr;
      for (int arg_idx = 0;
           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
           ++arg_idx) {
        size_t num_matched =
            FindModulesByName(target, arg_cstr, module_list, true);
        if (num_matched == 0) {
          result.AppendWarningWithFormat(
              "Unable to find an image that matches '%s'.\n", arg_cstr);
        }
      }
      // Dump all the modules we found.
      num_dumped =
          DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
    }

    if (num_dumped > 0) {
      result.SetStatus(eReturnStatusSuccessFinishResult);
    } else {
      result.AppendError("no matching executable images found");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesDumpSymtab

static OptionEnumValueElement g_sort_option_enumeration[4] = {
    {eSortOrderNone, "none",
     "No sorting, use the original symbol table order."},
    {eSortOrderByAddress, "address", "Sort output by symbol address."},
    {eSortOrderByName, "name", "Sort output by symbol name."},
    {0, nullptr, nullptr}};

static OptionDefinition g_target_modules_dump_symtab_options[] = {
    // clang-format off
  { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." }
    // clang-format on
};

class CommandObjectTargetModulesDumpSymtab
    : public CommandObjectTargetModulesModuleAutoComplete {
public:
  CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
      : CommandObjectTargetModulesModuleAutoComplete(
            interpreter, "target modules dump symtab",
            "Dump the symbol table from one or more target modules.", nullptr),
        m_options() {}

  ~CommandObjectTargetModulesDumpSymtab() override = default;

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

  class CommandOptions : public Options {
  public:
    CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}

    ~CommandOptions() override = default;

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

      switch (short_option) {
      case 's':
        m_sort_order = (SortOrder)Args::StringToOptionEnum(
            option_arg, GetDefinitions()[option_idx].enum_values,
            eSortOrderNone, error);
        break;

      default:
        error.SetErrorStringWithFormat("invalid short option character '%c'",
                                       short_option);
        break;
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_sort_order = eSortOrderNone;
    }

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

    SortOrder m_sort_order;
  };

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == nullptr) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    } else {
      uint32_t num_dumped = 0;

      uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
      result.GetOutputStream().SetAddressByteSize(addr_byte_size);
      result.GetErrorStream().SetAddressByteSize(addr_byte_size);

      if (command.GetArgumentCount() == 0) {
        // Dump all sections for all modules images
        std::lock_guard<std::recursive_mutex> guard(
            target->GetImages().GetMutex());
        const size_t num_modules = target->GetImages().GetSize();
        if (num_modules > 0) {
          result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
                                          " modules.\n",
                                          (uint64_t)num_modules);
          for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
            if (num_dumped > 0) {
              result.GetOutputStream().EOL();
              result.GetOutputStream().EOL();
            }
            num_dumped++;
            DumpModuleSymtab(
                m_interpreter, result.GetOutputStream(),
                target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
                m_options.m_sort_order);
          }
        } else {
          result.AppendError("the target has no associated executable images");
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
      } else {
        // Dump specified images (by basename or fullpath)
        const char *arg_cstr;
        for (int arg_idx = 0;
             (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
             ++arg_idx) {
          ModuleList module_list;
          const size_t num_matches =
              FindModulesByName(target, arg_cstr, module_list, true);
          if (num_matches > 0) {
            for (size_t i = 0; i < num_matches; ++i) {
              Module *module = module_list.GetModulePointerAtIndex(i);
              if (module) {
                if (num_dumped > 0) {
                  result.GetOutputStream().EOL();
                  result.GetOutputStream().EOL();
                }
                num_dumped++;
                DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
                                 module, m_options.m_sort_order);
              }
            }
          } else
            result.AppendWarningWithFormat(
                "Unable to find an image that matches '%s'.\n", arg_cstr);
        }
      }

      if (num_dumped > 0)
        result.SetStatus(eReturnStatusSuccessFinishResult);
      else {
        result.AppendError("no matching executable images found");
        result.SetStatus(eReturnStatusFailed);
      }
    }
    return result.Succeeded();
  }

  CommandOptions m_options;
};

#pragma mark CommandObjectTargetModulesDumpSections

//----------------------------------------------------------------------
// Image section dumping command
//----------------------------------------------------------------------

class CommandObjectTargetModulesDumpSections
    : public CommandObjectTargetModulesModuleAutoComplete {
public:
  CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
      : CommandObjectTargetModulesModuleAutoComplete(
            interpreter, "target modules dump sections",
            "Dump the sections from one or more target modules.",
            //"target modules dump sections [<file1> ...]")
            nullptr) {}

  ~CommandObjectTargetModulesDumpSections() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == nullptr) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    } else {
      uint32_t num_dumped = 0;

      uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
      result.GetOutputStream().SetAddressByteSize(addr_byte_size);
      result.GetErrorStream().SetAddressByteSize(addr_byte_size);

      if (command.GetArgumentCount() == 0) {
        // Dump all sections for all modules images
        const size_t num_modules = target->GetImages().GetSize();
        if (num_modules > 0) {
          result.GetOutputStream().Printf("Dumping sections for %" PRIu64
                                          " modules.\n",
                                          (uint64_t)num_modules);
          for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
            num_dumped++;
            DumpModuleSections(
                m_interpreter, result.GetOutputStream(),
                target->GetImages().GetModulePointerAtIndex(image_idx));
          }
        } else {
          result.AppendError("the target has no associated executable images");
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
      } else {
        // Dump specified images (by basename or fullpath)
        const char *arg_cstr;
        for (int arg_idx = 0;
             (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
             ++arg_idx) {
          ModuleList module_list;
          const size_t num_matches =
              FindModulesByName(target, arg_cstr, module_list, true);
          if (num_matches > 0) {
            for (size_t i = 0; i < num_matches; ++i) {
              Module *module = module_list.GetModulePointerAtIndex(i);
              if (module) {
                num_dumped++;
                DumpModuleSections(m_interpreter, result.GetOutputStream(),
                                   module);
              }
            }
          } else {
            // Check the global list
            std::lock_guard<std::recursive_mutex> guard(
                Module::GetAllocationModuleCollectionMutex());

            result.AppendWarningWithFormat(
                "Unable to find an image that matches '%s'.\n", arg_cstr);
          }
        }
      }

      if (num_dumped > 0)
        result.SetStatus(eReturnStatusSuccessFinishResult);
      else {
        result.AppendError("no matching executable images found");
        result.SetStatus(eReturnStatusFailed);
      }
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesDumpSymfile

//----------------------------------------------------------------------
// Image debug symbol dumping command
//----------------------------------------------------------------------

class CommandObjectTargetModulesDumpSymfile
    : public CommandObjectTargetModulesModuleAutoComplete {
public:
  CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
      : CommandObjectTargetModulesModuleAutoComplete(
            interpreter, "target modules dump symfile",
            "Dump the debug symbol file for one or more target modules.",
            //"target modules dump symfile [<file1> ...]")
            nullptr) {}

  ~CommandObjectTargetModulesDumpSymfile() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == nullptr) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    } else {
      uint32_t num_dumped = 0;

      uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
      result.GetOutputStream().SetAddressByteSize(addr_byte_size);
      result.GetErrorStream().SetAddressByteSize(addr_byte_size);

      if (command.GetArgumentCount() == 0) {
        // Dump all sections for all modules images
        const ModuleList &target_modules = target->GetImages();
        std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
        const size_t num_modules = target_modules.GetSize();
        if (num_modules > 0) {
          result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
                                          " modules.\n",
                                          (uint64_t)num_modules);
          for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
            if (DumpModuleSymbolVendor(
                    result.GetOutputStream(),
                    target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
              num_dumped++;
          }
        } else {
          result.AppendError("the target has no associated executable images");
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
      } else {
        // Dump specified images (by basename or fullpath)
        const char *arg_cstr;
        for (int arg_idx = 0;
             (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
             ++arg_idx) {
          ModuleList module_list;
          const size_t num_matches =
              FindModulesByName(target, arg_cstr, module_list, true);
          if (num_matches > 0) {
            for (size_t i = 0; i < num_matches; ++i) {
              Module *module = module_list.GetModulePointerAtIndex(i);
              if (module) {
                if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
                  num_dumped++;
              }
            }
          } else
            result.AppendWarningWithFormat(
                "Unable to find an image that matches '%s'.\n", arg_cstr);
        }
      }

      if (num_dumped > 0)
        result.SetStatus(eReturnStatusSuccessFinishResult);
      else {
        result.AppendError("no matching executable images found");
        result.SetStatus(eReturnStatusFailed);
      }
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesDumpLineTable

//----------------------------------------------------------------------
// Image debug line table dumping command
//----------------------------------------------------------------------

class CommandObjectTargetModulesDumpLineTable
    : public CommandObjectTargetModulesSourceFileAutoComplete {
public:
  CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
      : CommandObjectTargetModulesSourceFileAutoComplete(
            interpreter, "target modules dump line-table",
            "Dump the line table for one or more compilation units.", nullptr,
            eCommandRequiresTarget) {}

  ~CommandObjectTargetModulesDumpLineTable() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_exe_ctx.GetTargetPtr();
    uint32_t total_num_dumped = 0;

    uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
    result.GetOutputStream().SetAddressByteSize(addr_byte_size);
    result.GetErrorStream().SetAddressByteSize(addr_byte_size);

    if (command.GetArgumentCount() == 0) {
      result.AppendError("file option must be specified.");
      result.SetStatus(eReturnStatusFailed);
      return result.Succeeded();
    } else {
      // Dump specified images (by basename or fullpath)
      const char *arg_cstr;
      for (int arg_idx = 0;
           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
           ++arg_idx) {
        FileSpec file_spec(arg_cstr, false);

        const ModuleList &target_modules = target->GetImages();
        std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
        const size_t num_modules = target_modules.GetSize();
        if (num_modules > 0) {
          uint32_t num_dumped = 0;
          for (uint32_t i = 0; i < num_modules; ++i) {
            if (DumpCompileUnitLineTable(
                    m_interpreter, result.GetOutputStream(),
                    target_modules.GetModulePointerAtIndexUnlocked(i),
                    file_spec, m_exe_ctx.GetProcessPtr() &&
                                   m_exe_ctx.GetProcessRef().IsAlive()))
              num_dumped++;
          }
          if (num_dumped == 0)
            result.AppendWarningWithFormat(
                "No source filenames matched '%s'.\n", arg_cstr);
          else
            total_num_dumped += num_dumped;
        }
      }
    }

    if (total_num_dumped > 0)
      result.SetStatus(eReturnStatusSuccessFinishResult);
    else {
      result.AppendError("no source filenames matched any command arguments");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetModulesDump

//----------------------------------------------------------------------
// Dump multi-word command for target modules
//----------------------------------------------------------------------

class CommandObjectTargetModulesDump : public CommandObjectMultiword {
public:
  //------------------------------------------------------------------
  // Constructors and Destructors
  //------------------------------------------------------------------
  CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
      : CommandObjectMultiword(interpreter, "target modules dump",
                               "Commands for dumping information about one or "
                               "more target modules.",
                               "target modules dump "
                               "[headers|symtab|sections|symfile|line-table] "
                               "[<file1> <file2> ...]") {
    LoadSubCommand("objfile",
                   CommandObjectSP(
                       new CommandObjectTargetModulesDumpObjfile(interpreter)));
    LoadSubCommand(
        "symtab",
        CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
    LoadSubCommand("sections",
                   CommandObjectSP(new CommandObjectTargetModulesDumpSections(
                       interpreter)));
    LoadSubCommand("symfile",
                   CommandObjectSP(
                       new CommandObjectTargetModulesDumpSymfile(interpreter)));
    LoadSubCommand("line-table",
                   CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
                       interpreter)));
  }

  ~CommandObjectTargetModulesDump() override = default;
};

class CommandObjectTargetModulesAdd : public CommandObjectParsed {
public:
  CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target modules add",
                            "Add a new module to the current target's modules.",
                            "target modules add [<module>]"),
        m_option_group(),
        m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
                      eArgTypeFilename, "Fullpath to a stand alone debug "
                                        "symbols file for when debug symbols "
                                        "are not in the executable.") {
    m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_1);
    m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Finalize();
  }

  ~CommandObjectTargetModulesAdd() override = default;

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

  int HandleArgumentCompletion(Args &input, int &cursor_index,
                               int &cursor_char_position,
                               OptionElementVector &opt_element_vector,
                               int match_start_point, int max_return_elements,
                               bool &word_complete,
                               StringList &matches) override {
    std::string completion_str(input.GetArgumentAtIndex(cursor_index));
    completion_str.erase(cursor_char_position);

    CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
        completion_str.c_str(), match_start_point, max_return_elements, nullptr,
        word_complete, matches);
    return matches.GetSize();
  }

protected:
  OptionGroupOptions m_option_group;
  OptionGroupUUID m_uuid_option_group;
  OptionGroupFile m_symbol_file;

  bool DoExecute(Args &args, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == nullptr) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    } else {
      bool flush = false;

      const size_t argc = args.GetArgumentCount();
      if (argc == 0) {
        if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
          // We are given a UUID only, go locate the file
          ModuleSpec module_spec;
          module_spec.GetUUID() =
              m_uuid_option_group.GetOptionValue().GetCurrentValue();
          if (m_symbol_file.GetOptionValue().OptionWasSet())
            module_spec.GetSymbolFileSpec() =
                m_symbol_file.GetOptionValue().GetCurrentValue();
          if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
            ModuleSP module_sp(target->GetSharedModule(module_spec));
            if (module_sp) {
              result.SetStatus(eReturnStatusSuccessFinishResult);
              return true;
            } else {
              StreamString strm;
              module_spec.GetUUID().Dump(&strm);
              if (module_spec.GetFileSpec()) {
                if (module_spec.GetSymbolFileSpec()) {
                  result.AppendErrorWithFormat(
                      "Unable to create the executable or symbol file with "
                      "UUID %s with path %s and symbol file %s",
                      strm.GetData(),
                      module_spec.GetFileSpec().GetPath().c_str(),
                      module_spec.GetSymbolFileSpec().GetPath().c_str());
                } else {
                  result.AppendErrorWithFormat(
                      "Unable to create the executable or symbol file with "
                      "UUID %s with path %s",
                      strm.GetData(),
                      module_spec.GetFileSpec().GetPath().c_str());
                }
              } else {
                result.AppendErrorWithFormat("Unable to create the executable "
                                             "or symbol file with UUID %s",
                                             strm.GetData());
              }
              result.SetStatus(eReturnStatusFailed);
              return false;
            }
          } else {
            StreamString strm;
            module_spec.GetUUID().Dump(&strm);
            result.AppendErrorWithFormat(
                "Unable to locate the executable or symbol file with UUID %s",
                strm.GetData());
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
        } else {
          result.AppendError(
              "one or more executable image paths must be specified");
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
      } else {
        for (auto &entry : args.entries()) {
          if (entry.ref.empty())
            continue;

          FileSpec file_spec(entry.ref, true);
          if (file_spec.Exists()) {
            ModuleSpec module_spec(file_spec);
            if (m_uuid_option_group.GetOptionValue().OptionWasSet())
              module_spec.GetUUID() =
                  m_uuid_option_group.GetOptionValue().GetCurrentValue();
            if (m_symbol_file.GetOptionValue().OptionWasSet())
              module_spec.GetSymbolFileSpec() =
                  m_symbol_file.GetOptionValue().GetCurrentValue();
            if (!module_spec.GetArchitecture().IsValid())
              module_spec.GetArchitecture() = target->GetArchitecture();
            Status error;
            ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
            if (!module_sp) {
              const char *error_cstr = error.AsCString();
              if (error_cstr)
                result.AppendError(error_cstr);
              else
                result.AppendErrorWithFormat("unsupported module: %s",
                                             entry.c_str());
              result.SetStatus(eReturnStatusFailed);
              return false;
            } else {
              flush = true;
            }
            result.SetStatus(eReturnStatusSuccessFinishResult);
          } else {
            std::string resolved_path = file_spec.GetPath();
            result.SetStatus(eReturnStatusFailed);
            if (resolved_path != entry.ref) {
              result.AppendErrorWithFormat(
                  "invalid module path '%s' with resolved path '%s'\n",
                  entry.ref.str().c_str(), resolved_path.c_str());
              break;
            }
            result.AppendErrorWithFormat("invalid module path '%s'\n",
                                         entry.c_str());
            break;
          }
        }
      }

      if (flush) {
        ProcessSP process = target->GetProcessSP();
        if (process)
          process->Flush();
      }
    }

    return result.Succeeded();
  }
};

class CommandObjectTargetModulesLoad
    : public CommandObjectTargetModulesModuleAutoComplete {
public:
  CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
      : CommandObjectTargetModulesModuleAutoComplete(
            interpreter, "target modules load", "Set the load addresses for "
                                                "one or more sections in a "
                                                "target module.",
            "target modules load [--file <module> --uuid <uuid>] <sect-name> "
            "<address> [<sect-name> <address> ....]"),
        m_option_group(),
        m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
                      "Fullpath or basename for module to load.", ""),
        m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
                      "Write file contents to the memory.", false, true),
        m_pc_option(LLDB_OPT_SET_1, false, "--set-pc-to-entry", 'p',
                    "Set PC to the entry point."
                    " Only applicable with '--load' option.",
                    false, true),
        m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
                       "Set the load address for all sections to be the "
                       "virtual address in the file plus the offset.",
                       0) {
    m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_1);
    m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Finalize();
  }

  ~CommandObjectTargetModulesLoad() override = default;

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

protected:
  bool DoExecute(Args &args, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    const bool load = m_load_option.GetOptionValue().GetCurrentValue();
    const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
    if (target == nullptr) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    } else {
      const size_t argc = args.GetArgumentCount();
      ModuleSpec module_spec;
      bool search_using_module_spec = false;

      // Allow "load" option to work without --file or --uuid
      // option.
      if (load) {
        if (!m_file_option.GetOptionValue().OptionWasSet() &&
            !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
          ModuleList &module_list = target->GetImages();
          if (module_list.GetSize() == 1) {
            search_using_module_spec = true;
            module_spec.GetFileSpec() =
                module_list.GetModuleAtIndex(0)->GetFileSpec();
          }
        }
      }

      if (m_file_option.GetOptionValue().OptionWasSet()) {
        search_using_module_spec = true;
        const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
        const bool use_global_module_list = true;
        ModuleList module_list;
        const size_t num_matches = FindModulesByName(
            target, arg_cstr, module_list, use_global_module_list);
        if (num_matches == 1) {
          module_spec.GetFileSpec() =
              module_list.GetModuleAtIndex(0)->GetFileSpec();
        } else if (num_matches > 1) {
          search_using_module_spec = false;
          result.AppendErrorWithFormat(
              "more than 1 module matched by name '%s'\n", arg_cstr);
          result.SetStatus(eReturnStatusFailed);
        } else {
          search_using_module_spec = false;
          result.AppendErrorWithFormat("no object file for module '%s'\n",
                                       arg_cstr);
          result.SetStatus(eReturnStatusFailed);
        }
      }

      if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
        search_using_module_spec = true;
        module_spec.GetUUID() =
            m_uuid_option_group.GetOptionValue().GetCurrentValue();
      }

      if (search_using_module_spec) {
        ModuleList matching_modules;
        const size_t num_matches =
            target->GetImages().FindModules(module_spec, matching_modules);

        char path[PATH_MAX];
        if (num_matches == 1) {
          Module *module = matching_modules.GetModulePointerAtIndex(0);
          if (module) {
            ObjectFile *objfile = module->GetObjectFile();
            if (objfile) {
              SectionList *section_list = module->GetSectionList();
              if (section_list) {
                bool changed = false;
                if (argc == 0) {
                  if (m_slide_option.GetOptionValue().OptionWasSet()) {
                    const addr_t slide =
                        m_slide_option.GetOptionValue().GetCurrentValue();
                    const bool slide_is_offset = true;
                    module->SetLoadAddress(*target, slide, slide_is_offset,
                                           changed);
                  } else {
                    result.AppendError("one or more section name + load "
                                       "address pair must be specified");
                    result.SetStatus(eReturnStatusFailed);
                    return false;
                  }
                } else {
                  if (m_slide_option.GetOptionValue().OptionWasSet()) {
                    result.AppendError("The \"--slide <offset>\" option can't "
                                       "be used in conjunction with setting "
                                       "section load addresses.\n");
                    result.SetStatus(eReturnStatusFailed);
                    return false;
                  }

                  for (size_t i = 0; i < argc; i += 2) {
                    const char *sect_name = args.GetArgumentAtIndex(i);
                    const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
                    if (sect_name && load_addr_cstr) {
                      ConstString const_sect_name(sect_name);
                      bool success = false;
                      addr_t load_addr = StringConvert::ToUInt64(
                          load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
                      if (success) {
                        SectionSP section_sp(
                            section_list->FindSectionByName(const_sect_name));
                        if (section_sp) {
                          if (section_sp->IsThreadSpecific()) {
                            result.AppendErrorWithFormat(
                                "thread specific sections are not yet "
                                "supported (section '%s')\n",
                                sect_name);
                            result.SetStatus(eReturnStatusFailed);
                            break;
                          } else {
                            if (target->GetSectionLoadList()
                                    .SetSectionLoadAddress(section_sp,
                                                           load_addr))
                              changed = true;
                            result.AppendMessageWithFormat(
                                "section '%s' loaded at 0x%" PRIx64 "\n",
                                sect_name, load_addr);
                          }
                        } else {
                          result.AppendErrorWithFormat("no section found that "
                                                       "matches the section "
                                                       "name '%s'\n",
                                                       sect_name);
                          result.SetStatus(eReturnStatusFailed);
                          break;
                        }
                      } else {
                        result.AppendErrorWithFormat(
                            "invalid load address string '%s'\n",
                            load_addr_cstr);
                        result.SetStatus(eReturnStatusFailed);
                        break;
                      }
                    } else {
                      if (sect_name)
                        result.AppendError("section names must be followed by "
                                           "a load address.\n");
                      else
                        result.AppendError("one or more section name + load "
                                           "address pair must be specified.\n");
                      result.SetStatus(eReturnStatusFailed);
                      break;
                    }
                  }
                }

                if (changed) {
                  target->ModulesDidLoad(matching_modules);
                  Process *process = m_exe_ctx.GetProcessPtr();
                  if (process)
                    process->Flush();
                }
                if (load) {
                  Status error = module->LoadInMemory(*target, set_pc);
                  if (error.Fail()) {
                    result.AppendError(error.AsCString());
                    return false;
                  }
                }
              } else {
                module->GetFileSpec().GetPath(path, sizeof(path));
                result.AppendErrorWithFormat(
                    "no sections in object file '%s'\n", path);
                result.SetStatus(eReturnStatusFailed);
              }
            } else {
              module->GetFileSpec().GetPath(path, sizeof(path));
              result.AppendErrorWithFormat("no object file for module '%s'\n",
                                           path);
              result.SetStatus(eReturnStatusFailed);
            }
          } else {
            FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
            if (module_spec_file) {
              module_spec_file->GetPath(path, sizeof(path));
              result.AppendErrorWithFormat("invalid module '%s'.\n", path);
            } else
              result.AppendError("no module spec");
            result.SetStatus(eReturnStatusFailed);
          }
        } else {
          std::string uuid_str;

          if (module_spec.GetFileSpec())
            module_spec.GetFileSpec().GetPath(path, sizeof(path));
          else
            path[0] = '\0';

          if (module_spec.GetUUIDPtr())
            uuid_str = module_spec.GetUUID().GetAsString();
          if (num_matches > 1) {
            result.AppendErrorWithFormat(
                "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
                path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
            for (size_t i = 0; i < num_matches; ++i) {
              if (matching_modules.GetModulePointerAtIndex(i)
                      ->GetFileSpec()
                      .GetPath(path, sizeof(path)))
                result.AppendMessageWithFormat("%s\n", path);
            }
          } else {
            result.AppendErrorWithFormat(
                "no modules were found  that match%s%s%s%s.\n",
                path[0] ? " file=" : "", path,
                !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
          }
          result.SetStatus(eReturnStatusFailed);
        }
      } else {
        result.AppendError("either the \"--file <module>\" or the \"--uuid "
                           "<uuid>\" option must be specified.\n");
        result.SetStatus(eReturnStatusFailed);
        return false;
      }
    }
    return result.Succeeded();
  }

  OptionGroupOptions m_option_group;
  OptionGroupUUID m_uuid_option_group;
  OptionGroupString m_file_option;
  OptionGroupBoolean m_load_option;
  OptionGroupBoolean m_pc_option;
  OptionGroupUInt64 m_slide_option;
};

//----------------------------------------------------------------------
// List images with associated information
//----------------------------------------------------------------------

static OptionDefinition g_target_modules_list_options[] = {
    // clang-format off
  { LLDB_OPT_SET_1, false, "address",        'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
  { LLDB_OPT_SET_1, false, "arch",           'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the architecture when listing images." },
  { LLDB_OPT_SET_1, false, "triple",         't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the triple when listing images." },
  { LLDB_OPT_SET_1, false, "header",         'h', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "Display the image header address as a load address if debugging, a file address otherwise." },
  { LLDB_OPT_SET_1, false, "offset",         'o', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "Display the image header address offset from the header file address (the slide amount)." },
  { LLDB_OPT_SET_1, false, "uuid",           'u', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "Display the UUID when listing images." },
  { LLDB_OPT_SET_1, false, "fullpath",       'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the fullpath to the image object file." },
  { LLDB_OPT_SET_1, false, "directory",      'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the directory with optional width for the image object file." },
  { LLDB_OPT_SET_1, false, "basename",       'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the basename with optional width for the image object file." },
  { LLDB_OPT_SET_1, false, "symfile",        's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the fullpath to the image symbol file with optional width." },
  { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the symbol file with optional width only if it is different from the executable object file." },
  { LLDB_OPT_SET_1, false, "mod-time",       'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the modification time with optional width of the module." },
  { LLDB_OPT_SET_1, false, "ref-count",      'r', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,               "Display the reference count if the module is still in the shared module cache." },
  { LLDB_OPT_SET_1, false, "pointer",        'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone,                "Display the module pointer." },
  { LLDB_OPT_SET_1, false, "global",         'g', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "Display the modules from the global module list, not just the current target." }
    // clang-format on
};

class CommandObjectTargetModulesList : public CommandObjectParsed {
public:
  class CommandOptions : public Options {
  public:
    CommandOptions()
        : Options(), m_format_array(), m_use_global_module_list(false),
          m_module_addr(LLDB_INVALID_ADDRESS) {}

    ~CommandOptions() override = default;

    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                          ExecutionContext *execution_context) override {
      Status error;

      const int short_option = m_getopt_table[option_idx].val;
      if (short_option == 'g') {
        m_use_global_module_list = true;
      } else if (short_option == 'a') {
        m_module_addr = Args::StringToAddress(execution_context, option_arg,
                                              LLDB_INVALID_ADDRESS, &error);
      } else {
        unsigned long width = 0;
        option_arg.getAsInteger(0, width);
        m_format_array.push_back(std::make_pair(short_option, width));
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_format_array.clear();
      m_use_global_module_list = false;
      m_module_addr = LLDB_INVALID_ADDRESS;
    }

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

    // Instance variables to hold the values for command options.
    typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
    FormatWidthCollection m_format_array;
    bool m_use_global_module_list;
    lldb::addr_t m_module_addr;
  };

  CommandObjectTargetModulesList(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "target modules list",
            "List current executable and dependent shared library images.",
            "target modules list [<cmd-options>]"),
        m_options() {}

  ~CommandObjectTargetModulesList() override = default;

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

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    const bool use_global_module_list = m_options.m_use_global_module_list;
    // Define a local module list here to ensure it lives longer than any
    // "locker"
    // object which might lock its contents below (through the "module_list_ptr"
    // variable).
    ModuleList module_list;
    if (target == nullptr && !use_global_module_list) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    } else {
      if (target) {
        uint32_t addr_byte_size =
            target->GetArchitecture().GetAddressByteSize();
        result.GetOutputStream().SetAddressByteSize(addr_byte_size);
        result.GetErrorStream().SetAddressByteSize(addr_byte_size);
      }
      // Dump all sections for all modules images
      Stream &strm = result.GetOutputStream();

      if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
        if (target) {
          Address module_address;
          if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
            ModuleSP module_sp(module_address.GetModule());
            if (module_sp) {
              PrintModule(target, module_sp.get(), 0, strm);
              result.SetStatus(eReturnStatusSuccessFinishResult);
            } else {
              result.AppendErrorWithFormat(
                  "Couldn't find module matching address: 0x%" PRIx64 ".",
                  m_options.m_module_addr);
              result.SetStatus(eReturnStatusFailed);
            }
          } else {
            result.AppendErrorWithFormat(
                "Couldn't find module containing address: 0x%" PRIx64 ".",
                m_options.m_module_addr);
            result.SetStatus(eReturnStatusFailed);
          }
        } else {
          result.AppendError(
              "Can only look up modules by address with a valid target.");
          result.SetStatus(eReturnStatusFailed);
        }
        return result.Succeeded();
      }

      size_t num_modules = 0;

      // This locker will be locked on the mutex in module_list_ptr if it is
      // non-nullptr.
      // Otherwise it will lock the AllocationModuleCollectionMutex when
      // accessing
      // the global module list directly.
      std::unique_lock<std::recursive_mutex> guard(
          Module::GetAllocationModuleCollectionMutex(), std::defer_lock);

      const ModuleList *module_list_ptr = nullptr;
      const size_t argc = command.GetArgumentCount();
      if (argc == 0) {
        if (use_global_module_list) {
          guard.lock();
          num_modules = Module::GetNumberAllocatedModules();
        } else {
          module_list_ptr = &target->GetImages();
        }
      } else {
        // TODO: Convert to entry based iteration.  Requires converting
        // FindModulesByName.
        for (size_t i = 0; i < argc; ++i) {
          // Dump specified images (by basename or fullpath)
          const char *arg_cstr = command.GetArgumentAtIndex(i);
          const size_t num_matches = FindModulesByName(
              target, arg_cstr, module_list, use_global_module_list);
          if (num_matches == 0) {
            if (argc == 1) {
              result.AppendErrorWithFormat("no modules found that match '%s'",
                                           arg_cstr);
              result.SetStatus(eReturnStatusFailed);
              return false;
            }
          }
        }

        module_list_ptr = &module_list;
      }

      std::unique_lock<std::recursive_mutex> lock;
      if (module_list_ptr != nullptr) {
        lock =
            std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());

        num_modules = module_list_ptr->GetSize();
      }

      if (num_modules > 0) {
        for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
          ModuleSP module_sp;
          Module *module;
          if (module_list_ptr) {
            module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
            module = module_sp.get();
          } else {
            module = Module::GetAllocatedModuleAtIndex(image_idx);
            module_sp = module->shared_from_this();
          }

          const size_t indent = strm.Printf("[%3u] ", image_idx);
          PrintModule(target, module, indent, strm);
        }
        result.SetStatus(eReturnStatusSuccessFinishResult);
      } else {
        if (argc) {
          if (use_global_module_list)
            result.AppendError(
                "the global module list has no matching modules");
          else
            result.AppendError("the target has no matching modules");
        } else {
          if (use_global_module_list)
            result.AppendError("the global module list is empty");
          else
            result.AppendError(
                "the target has no associated executable images");
        }
        result.SetStatus(eReturnStatusFailed);
        return false;
      }
    }
    return result.Succeeded();
  }

  void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
    if (module == nullptr) {
      strm.PutCString("Null module");
      return;
    }

    bool dump_object_name = false;
    if (m_options.m_format_array.empty()) {
      m_options.m_format_array.push_back(std::make_pair('u', 0));
      m_options.m_format_array.push_back(std::make_pair('h', 0));
      m_options.m_format_array.push_back(std::make_pair('f', 0));
      m_options.m_format_array.push_back(std::make_pair('S', 0));
    }
    const size_t num_entries = m_options.m_format_array.size();
    bool print_space = false;
    for (size_t i = 0; i < num_entries; ++i) {
      if (print_space)
        strm.PutChar(' ');
      print_space = true;
      const char format_char = m_options.m_format_array[i].first;
      uint32_t width = m_options.m_format_array[i].second;
      switch (format_char) {
      case 'A':
        DumpModuleArchitecture(strm, module, false, width);
        break;

      case 't':
        DumpModuleArchitecture(strm, module, true, width);
        break;

      case 'f':
        DumpFullpath(strm, &module->GetFileSpec(), width);
        dump_object_name = true;
        break;

      case 'd':
        DumpDirectory(strm, &module->GetFileSpec(), width);
        break;

      case 'b':
        DumpBasename(strm, &module->GetFileSpec(), width);
        dump_object_name = true;
        break;

      case 'h':
      case 'o':
        // Image header address
        {
          uint32_t addr_nibble_width =
              target ? (target->GetArchitecture().GetAddressByteSize() * 2)
                     : 16;

          ObjectFile *objfile = module->GetObjectFile();
          if (objfile) {
            Address header_addr(objfile->GetHeaderAddress());
            if (header_addr.IsValid()) {
              if (target && !target->GetSectionLoadList().IsEmpty()) {
                lldb::addr_t header_load_addr =
                    header_addr.GetLoadAddress(target);
                if (header_load_addr == LLDB_INVALID_ADDRESS) {
                  header_addr.Dump(&strm, target,
                                   Address::DumpStyleModuleWithFileAddress,
                                   Address::DumpStyleFileAddress);
                } else {
                  if (format_char == 'o') {
                    // Show the offset of slide for the image
                    strm.Printf(
                        "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
                        header_load_addr - header_addr.GetFileAddress());
                  } else {
                    // Show the load address of the image
                    strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
                                addr_nibble_width, header_load_addr);
                  }
                }
                break;
              }
              // The address was valid, but the image isn't loaded, output the
              // address in an appropriate format
              header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
              break;
            }
          }
          strm.Printf("%*s", addr_nibble_width + 2, "");
        }
        break;

      case 'r': {
        size_t ref_count = 0;
        ModuleSP module_sp(module->shared_from_this());
        if (module_sp) {
          // Take one away to make sure we don't count our local "module_sp"
          ref_count = module_sp.use_count() - 1;
        }
        if (width)
          strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
        else
          strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
      } break;

      case 's':
      case 'S': {
        const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
        if (symbol_vendor) {
          const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
          if (format_char == 'S') {
            // Dump symbol file only if different from module file
            if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
              print_space = false;
              break;
            }
            // Add a newline and indent past the index
            strm.Printf("\n%*s", indent, "");
          }
          DumpFullpath(strm, &symfile_spec, width);
          dump_object_name = true;
          break;
        }
        strm.Printf("%.*s", width, "<NONE>");
      } break;

      case 'm':
        DumpTimePoint(module->GetModificationTime(), strm, width);
        break;

      case 'p':
        strm.Printf("%p", static_cast<void *>(module));
        break;

      case 'u':
        DumpModuleUUID(strm, module);
        break;

      default:
        break;
      }
    }
    if (dump_object_name) {
      const char *object_name = module->GetObjectName().GetCString();
      if (object_name)
        strm.Printf("(%s)", object_name);
    }
    strm.EOL();
  }

  CommandOptions m_options;
};

#pragma mark CommandObjectTargetModulesShowUnwind

//----------------------------------------------------------------------
// Lookup unwind information in images
//----------------------------------------------------------------------

static OptionDefinition g_target_modules_show_unwind_options[] = {
    // clang-format off
  { LLDB_OPT_SET_1, false, "name",    'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName,        "Show unwind instructions for a function or symbol name." },
  { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
    // clang-format on
};

class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
public:
  enum {
    eLookupTypeInvalid = -1,
    eLookupTypeAddress = 0,
    eLookupTypeSymbol,
    eLookupTypeFunction,
    eLookupTypeFunctionOrSymbol,
    kNumLookupTypes
  };

  class CommandOptions : public Options {
  public:
    CommandOptions()
        : Options(), m_type(eLookupTypeInvalid), m_str(),
          m_addr(LLDB_INVALID_ADDRESS) {}

    ~CommandOptions() override = default;

    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                          ExecutionContext *execution_context) override {
      Status error;

      const int short_option = m_getopt_table[option_idx].val;

      switch (short_option) {
      case 'a': {
        m_str = option_arg;
        m_type = eLookupTypeAddress;
        m_addr = Args::StringToAddress(execution_context, option_arg,
                                       LLDB_INVALID_ADDRESS, &error);
        if (m_addr == LLDB_INVALID_ADDRESS)
          error.SetErrorStringWithFormat("invalid address string '%s'",
                                         option_arg.str().c_str());
        break;
      }

      case 'n':
        m_str = option_arg;
        m_type = eLookupTypeFunctionOrSymbol;
        break;

      default:
        error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
        break;
      }

      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_type = eLookupTypeInvalid;
      m_str.clear();
      m_addr = LLDB_INVALID_ADDRESS;
    }

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

    // Instance variables to hold the values for command options.

    int m_type;        // Should be a eLookupTypeXXX enum after parsing options
    std::string m_str; // Holds name lookup
    lldb::addr_t m_addr; // Holds the address to lookup
  };

  CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "target modules show-unwind",
            "Show synthesized unwind instructions for a function.", nullptr,
            eCommandRequiresTarget | eCommandRequiresProcess |
                eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
        m_options() {}

  ~CommandObjectTargetModulesShowUnwind() override = default;

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

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_exe_ctx.GetTargetPtr();
    Process *process = m_exe_ctx.GetProcessPtr();
    ABI *abi = nullptr;
    if (process)
      abi = process->GetABI().get();

    if (process == nullptr) {
      result.AppendError(
          "You must have a process running to use this command.");
      result.SetStatus(eReturnStatusFailed);
      return false;
    }

    ThreadList threads(process->GetThreadList());
    if (threads.GetSize() == 0) {
      result.AppendError("The process must be paused to use this command.");
      result.SetStatus(eReturnStatusFailed);
      return false;
    }

    ThreadSP thread(threads.GetThreadAtIndex(0));
    if (!thread) {
      result.AppendError("The process must be paused to use this command.");
      result.SetStatus(eReturnStatusFailed);
      return false;
    }

    SymbolContextList sc_list;

    if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
      ConstString function_name(m_options.m_str.c_str());
      target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
                                        true, false, true, sc_list);
    } else if (m_options.m_type == eLookupTypeAddress && target) {
      Address addr;
      if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
                                                          addr)) {
        SymbolContext sc;
        ModuleSP module_sp(addr.GetModule());
        module_sp->ResolveSymbolContextForAddress(addr,
                                                  eSymbolContextEverything, sc);
        if (sc.function || sc.symbol) {
          sc_list.Append(sc);
        }
      }
    } else {
      result.AppendError(
          "address-expression or function name option must be specified.");
      result.SetStatus(eReturnStatusFailed);
      return false;
    }

    size_t num_matches = sc_list.GetSize();
    if (num_matches == 0) {
      result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
                                   m_options.m_str.c_str());
      result.SetStatus(eReturnStatusFailed);
      return false;
    }

    for (uint32_t idx = 0; idx < num_matches; idx++) {
      SymbolContext sc;
      sc_list.GetContextAtIndex(idx, sc);
      if (sc.symbol == nullptr && sc.function == nullptr)
        continue;
      if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
        continue;
      AddressRange range;
      if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
                              false, range))
        continue;
      if (!range.GetBaseAddress().IsValid())
        continue;
      ConstString funcname(sc.GetFunctionName());
      if (funcname.IsEmpty())
        continue;
      addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
      if (abi)
        start_addr = abi->FixCodeAddress(start_addr);

      FuncUnwindersSP func_unwinders_sp(
          sc.module_sp->GetObjectFile()
              ->GetUnwindTable()
              .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
      if (!func_unwinders_sp)
        continue;

      result.GetOutputStream().Printf(
          "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
          sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
          funcname.AsCString(), start_addr);

      UnwindPlanSP non_callsite_unwind_plan =
          func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
      if (non_callsite_unwind_plan) {
        result.GetOutputStream().Printf(
            "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
            non_callsite_unwind_plan->GetSourceName().AsCString());
      }
      UnwindPlanSP callsite_unwind_plan =
          func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
      if (callsite_unwind_plan) {
        result.GetOutputStream().Printf(
            "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
            callsite_unwind_plan->GetSourceName().AsCString());
      }
      UnwindPlanSP fast_unwind_plan =
          func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
      if (fast_unwind_plan) {
        result.GetOutputStream().Printf(
            "Fast UnwindPlan is '%s'\n",
            fast_unwind_plan->GetSourceName().AsCString());
      }

      result.GetOutputStream().Printf("\n");

      UnwindPlanSP assembly_sp =
          func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
      if (assembly_sp) {
        result.GetOutputStream().Printf(
            "Assembly language inspection UnwindPlan:\n");
        assembly_sp->Dump(result.GetOutputStream(), thread.get(),
                          LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      UnwindPlanSP ehframe_sp =
          func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
      if (ehframe_sp) {
        result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
        ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
                         LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      UnwindPlanSP ehframe_augmented_sp =
          func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
      if (ehframe_augmented_sp) {
        result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
        ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
                                   LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      if (UnwindPlanSP plan_sp =
              func_unwinders_sp->GetDebugFrameUnwindPlan(*target, 0)) {
        result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
        plan_sp->Dump(result.GetOutputStream(), thread.get(),
                      LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      if (UnwindPlanSP plan_sp =
              func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
                                                                  *thread, 0)) {
        result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
        plan_sp->Dump(result.GetOutputStream(), thread.get(),
                      LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      UnwindPlanSP arm_unwind_sp =
          func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
      if (arm_unwind_sp) {
        result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
        arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
                            LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      UnwindPlanSP compact_unwind_sp =
          func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
      if (compact_unwind_sp) {
        result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
        compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
                                LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      if (fast_unwind_plan) {
        result.GetOutputStream().Printf("Fast UnwindPlan:\n");
        fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
                               LLDB_INVALID_ADDRESS);
        result.GetOutputStream().Printf("\n");
      }

      ABISP abi_sp = process->GetABI();
      if (abi_sp) {
        UnwindPlan arch_default(lldb::eRegisterKindGeneric);
        if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
          result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
          arch_default.Dump(result.GetOutputStream(), thread.get(),
                            LLDB_INVALID_ADDRESS);
          result.GetOutputStream().Printf("\n");
        }

        UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
        if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
          result.GetOutputStream().Printf(
              "Arch default at entry point UnwindPlan:\n");
          arch_entry.Dump(result.GetOutputStream(), thread.get(),
                          LLDB_INVALID_ADDRESS);
          result.GetOutputStream().Printf("\n");
        }
      }

      result.GetOutputStream().Printf("\n");
    }
    return result.Succeeded();
  }

  CommandOptions m_options;
};

//----------------------------------------------------------------------
// Lookup information in images
//----------------------------------------------------------------------

static OptionDefinition g_target_modules_lookup_options[] = {
    // clang-format off
  { LLDB_OPT_SET_1,                                  true,  "address",    'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
  { LLDB_OPT_SET_1,                                  false, "offset",     'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset,              "When looking up an address subtract <offset> from any addresses before doing the lookup." },
  /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
  { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex",      'r', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "The <name> argument for name lookups are regular expressions." },
  { LLDB_OPT_SET_2,                                  true,  "symbol",     's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSymbol,              "Lookup a symbol by name in the symbol tables in one or more target modules." },
  { LLDB_OPT_SET_3,                                  true,  "file",       'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename,            "Lookup a file by fullpath or basename in one or more target modules." },
  { LLDB_OPT_SET_3,                                  false, "line",       'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,             "Lookup a line number in a file (must be used in conjunction with --file)." },
  { LLDB_OPT_SET_FROM_TO(3,5),                       false, "no-inlines", 'i', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "Ignore inline entries (must be used in conjunction with --file or --function)." },
  { LLDB_OPT_SET_4,                                  true,  "function",   'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName,        "Lookup a function by name in the debug symbols in one or more target modules." },
  { LLDB_OPT_SET_5,                                  true,  "name",       'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionOrSymbol,    "Lookup a function or symbol by name in one or more target modules." },
  { LLDB_OPT_SET_6,                                  true,  "type",       't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName,                "Lookup a type by name in the debug symbols in one or more target modules." },
  { LLDB_OPT_SET_ALL,                                false, "verbose",    'v', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "Enable verbose lookup information." },
  { LLDB_OPT_SET_ALL,                                false, "all",        'A', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,                "Print all matches, not just the best match, if a best match is available." },
    // clang-format on
};

class CommandObjectTargetModulesLookup : public CommandObjectParsed {
public:
  enum {
    eLookupTypeInvalid = -1,
    eLookupTypeAddress = 0,
    eLookupTypeSymbol,
    eLookupTypeFileLine, // Line is optional
    eLookupTypeFunction,
    eLookupTypeFunctionOrSymbol,
    eLookupTypeType,
    kNumLookupTypes
  };

  class CommandOptions : public Options {
  public:
    CommandOptions() : Options() { OptionParsingStarting(nullptr); }

    ~CommandOptions() override = default;

    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                          ExecutionContext *execution_context) override {
      Status error;

      const int short_option = m_getopt_table[option_idx].val;

      switch (short_option) {
      case 'a': {
        m_type = eLookupTypeAddress;
        m_addr = Args::StringToAddress(execution_context, option_arg,
                                       LLDB_INVALID_ADDRESS, &error);
      } break;

      case 'o':
        if (option_arg.getAsInteger(0, m_offset))
          error.SetErrorStringWithFormat("invalid offset string '%s'",
                                         option_arg.str().c_str());
        break;

      case 's':
        m_str = option_arg;
        m_type = eLookupTypeSymbol;
        break;

      case 'f':
        m_file.SetFile(option_arg, false);
        m_type = eLookupTypeFileLine;
        break;

      case 'i':
        m_include_inlines = false;
        break;

      case 'l':
        if (option_arg.getAsInteger(0, m_line_number))
          error.SetErrorStringWithFormat("invalid line number string '%s'",
                                         option_arg.str().c_str());
        else if (m_line_number == 0)
          error.SetErrorString("zero is an invalid line number");
        m_type = eLookupTypeFileLine;
        break;

      case 'F':
        m_str = option_arg;
        m_type = eLookupTypeFunction;
        break;

      case 'n':
        m_str = option_arg;
        m_type = eLookupTypeFunctionOrSymbol;
        break;

      case 't':
        m_str = option_arg;
        m_type = eLookupTypeType;
        break;

      case 'v':
        m_verbose = 1;
        break;

      case 'A':
        m_print_all = true;
        break;

      case 'r':
        m_use_regex = true;
        break;
      }

      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_type = eLookupTypeInvalid;
      m_str.clear();
      m_file.Clear();
      m_addr = LLDB_INVALID_ADDRESS;
      m_offset = 0;
      m_line_number = 0;
      m_use_regex = false;
      m_include_inlines = true;
      m_verbose = false;
      m_print_all = false;
    }

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

    int m_type;        // Should be a eLookupTypeXXX enum after parsing options
    std::string m_str; // Holds name lookup
    FileSpec m_file;   // Files for file lookups
    lldb::addr_t m_addr; // Holds the address to lookup
    lldb::addr_t
        m_offset; // Subtract this offset from m_addr before doing lookups.
    uint32_t m_line_number; // Line number for file+line lookups
    bool m_use_regex;       // Name lookups in m_str are regular expressions.
    bool m_include_inlines; // Check for inline entries when looking up by
                            // file/line.
    bool m_verbose;         // Enable verbose lookup info
    bool m_print_all; // Print all matches, even in cases where there's a best
                      // match.
  };

  CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target modules lookup",
                            "Look up information within executable and "
                            "dependent shared library images.",
                            nullptr, eCommandRequiresTarget),
        m_options() {
    CommandArgumentEntry arg;
    CommandArgumentData file_arg;

    // Define the first (and only) variant of this arg.
    file_arg.arg_type = eArgTypeFilename;
    file_arg.arg_repetition = eArgRepeatStar;

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

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

  ~CommandObjectTargetModulesLookup() override = default;

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

  bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
                  bool &syntax_error) {
    switch (m_options.m_type) {
    case eLookupTypeAddress:
    case eLookupTypeFileLine:
    case eLookupTypeFunction:
    case eLookupTypeFunctionOrSymbol:
    case eLookupTypeSymbol:
    default:
      return false;
    case eLookupTypeType:
      break;
    }

    StackFrameSP frame = m_exe_ctx.GetFrameSP();

    if (!frame)
      return false;

    const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));

    if (!sym_ctx.module_sp)
      return false;

    switch (m_options.m_type) {
    default:
      return false;
    case eLookupTypeType:
      if (!m_options.m_str.empty()) {
        if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
                           m_options.m_str.c_str(), m_options.m_use_regex)) {
          result.SetStatus(eReturnStatusSuccessFinishResult);
          return true;
        }
      }
      break;
    }

    return true;
  }

  bool LookupInModule(CommandInterpreter &interpreter, Module *module,
                      CommandReturnObject &result, bool &syntax_error) {
    switch (m_options.m_type) {
    case eLookupTypeAddress:
      if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
        if (LookupAddressInModule(
                m_interpreter, result.GetOutputStream(), module,
                eSymbolContextEverything |
                    (m_options.m_verbose
                         ? static_cast<int>(eSymbolContextVariable)
                         : 0),
                m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
          result.SetStatus(eReturnStatusSuccessFinishResult);
          return true;
        }
      }
      break;

    case eLookupTypeSymbol:
      if (!m_options.m_str.empty()) {
        if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
                                 module, m_options.m_str.c_str(),
                                 m_options.m_use_regex, m_options.m_verbose)) {
          result.SetStatus(eReturnStatusSuccessFinishResult);
          return true;
        }
      }
      break;

    case eLookupTypeFileLine:
      if (m_options.m_file) {
        if (LookupFileAndLineInModule(
                m_interpreter, result.GetOutputStream(), module,
                m_options.m_file, m_options.m_line_number,
                m_options.m_include_inlines, m_options.m_verbose)) {
          result.SetStatus(eReturnStatusSuccessFinishResult);
          return true;
        }
      }
      break;

    case eLookupTypeFunctionOrSymbol:
    case eLookupTypeFunction:
      if (!m_options.m_str.empty()) {
        if (LookupFunctionInModule(
                m_interpreter, result.GetOutputStream(), module,
                m_options.m_str.c_str(), m_options.m_use_regex,
                m_options.m_include_inlines,
                m_options.m_type ==
                    eLookupTypeFunctionOrSymbol, // include symbols
                m_options.m_verbose)) {
          result.SetStatus(eReturnStatusSuccessFinishResult);
          return true;
        }
      }
      break;

    case eLookupTypeType:
      if (!m_options.m_str.empty()) {
        if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
                               m_options.m_str.c_str(),
                               m_options.m_use_regex)) {
          result.SetStatus(eReturnStatusSuccessFinishResult);
          return true;
        }
      }
      break;

    default:
      m_options.GenerateOptionUsage(
          result.GetErrorStream(), this,
          GetCommandInterpreter().GetDebugger().GetTerminalWidth());
      syntax_error = true;
      break;
    }

    result.SetStatus(eReturnStatusFailed);
    return false;
  }

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == nullptr) {
      result.AppendError("invalid target, create a debug target using the "
                         "'target create' command");
      result.SetStatus(eReturnStatusFailed);
      return false;
    } else {
      bool syntax_error = false;
      uint32_t i;
      uint32_t num_successful_lookups = 0;
      uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
      result.GetOutputStream().SetAddressByteSize(addr_byte_size);
      result.GetErrorStream().SetAddressByteSize(addr_byte_size);
      // Dump all sections for all modules images

      if (command.GetArgumentCount() == 0) {
        ModuleSP current_module;

        // Where it is possible to look in the current symbol context
        // first, try that.  If this search was successful and --all
        // was not passed, don't print anything else.
        if (LookupHere(m_interpreter, result, syntax_error)) {
          result.GetOutputStream().EOL();
          num_successful_lookups++;
          if (!m_options.m_print_all) {
            result.SetStatus(eReturnStatusSuccessFinishResult);
            return result.Succeeded();
          }
        }

        // Dump all sections for all other modules

        const ModuleList &target_modules = target->GetImages();
        std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
        const size_t num_modules = target_modules.GetSize();
        if (num_modules > 0) {
          for (i = 0; i < num_modules && !syntax_error; ++i) {
            Module *module_pointer =
                target_modules.GetModulePointerAtIndexUnlocked(i);

            if (module_pointer != current_module.get() &&
                LookupInModule(
                    m_interpreter,
                    target_modules.GetModulePointerAtIndexUnlocked(i), result,
                    syntax_error)) {
              result.GetOutputStream().EOL();
              num_successful_lookups++;
            }
          }
        } else {
          result.AppendError("the target has no associated executable images");
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
      } else {
        // Dump specified images (by basename or fullpath)
        const char *arg_cstr;
        for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
                    !syntax_error;
             ++i) {
          ModuleList module_list;
          const size_t num_matches =
              FindModulesByName(target, arg_cstr, module_list, false);
          if (num_matches > 0) {
            for (size_t j = 0; j < num_matches; ++j) {
              Module *module = module_list.GetModulePointerAtIndex(j);
              if (module) {
                if (LookupInModule(m_interpreter, module, result,
                                   syntax_error)) {
                  result.GetOutputStream().EOL();
                  num_successful_lookups++;
                }
              }
            }
          } else
            result.AppendWarningWithFormat(
                "Unable to find an image that matches '%s'.\n", arg_cstr);
        }
      }

      if (num_successful_lookups > 0)
        result.SetStatus(eReturnStatusSuccessFinishResult);
      else
        result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }

  CommandOptions m_options;
};

#pragma mark CommandObjectMultiwordImageSearchPaths

//-------------------------------------------------------------------------
// CommandObjectMultiwordImageSearchPaths
//-------------------------------------------------------------------------

class CommandObjectTargetModulesImageSearchPaths
    : public CommandObjectMultiword {
public:
  CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
      : CommandObjectMultiword(
            interpreter, "target modules search-paths",
            "Commands for managing module search paths for a target.",
            "target modules search-paths <subcommand> [<subcommand-options>]") {
    LoadSubCommand(
        "add", CommandObjectSP(
                   new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
    LoadSubCommand(
        "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
                     interpreter)));
    LoadSubCommand(
        "insert",
        CommandObjectSP(
            new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
    LoadSubCommand(
        "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
                    interpreter)));
    LoadSubCommand(
        "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
                     interpreter)));
  }

  ~CommandObjectTargetModulesImageSearchPaths() override = default;
};

#pragma mark CommandObjectTargetModules

//-------------------------------------------------------------------------
// CommandObjectTargetModules
//-------------------------------------------------------------------------

class CommandObjectTargetModules : public CommandObjectMultiword {
public:
  //------------------------------------------------------------------
  // Constructors and Destructors
  //------------------------------------------------------------------
  CommandObjectTargetModules(CommandInterpreter &interpreter)
      : CommandObjectMultiword(interpreter, "target modules",
                               "Commands for accessing information for one or "
                               "more target modules.",
                               "target modules <sub-command> ...") {
    LoadSubCommand(
        "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
    LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
                               interpreter)));
    LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
                               interpreter)));
    LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
                               interpreter)));
    LoadSubCommand(
        "lookup",
        CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
    LoadSubCommand(
        "search-paths",
        CommandObjectSP(
            new CommandObjectTargetModulesImageSearchPaths(interpreter)));
    LoadSubCommand(
        "show-unwind",
        CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
  }

  ~CommandObjectTargetModules() override = default;

private:
  //------------------------------------------------------------------
  // For CommandObjectTargetModules only
  //------------------------------------------------------------------
  DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
};

class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
public:
  CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "target symbols add",
            "Add a debug symbol file to one of the target's current modules by "
            "specifying a path to a debug symbols file, or using the options "
            "to specify a module to download symbols for.",
            "target symbols add [<symfile>]", eCommandRequiresTarget),
        m_option_group(),
        m_file_option(
            LLDB_OPT_SET_1, false, "shlib", 's',
            CommandCompletions::eModuleCompletion, eArgTypeShlibName,
            "Fullpath or basename for module to find debug symbols for."),
        m_current_frame_option(
            LLDB_OPT_SET_2, false, "frame", 'F',
            "Locate the debug symbols the currently selected frame.", false,
            true)

  {
    m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_1);
    m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
    m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
                          LLDB_OPT_SET_2);
    m_option_group.Finalize();
  }

  ~CommandObjectTargetSymbolsAdd() override = default;

  int HandleArgumentCompletion(Args &input, int &cursor_index,
                               int &cursor_char_position,
                               OptionElementVector &opt_element_vector,
                               int match_start_point, int max_return_elements,
                               bool &word_complete,
                               StringList &matches) override {
    std::string completion_str(input.GetArgumentAtIndex(cursor_index));
    completion_str.erase(cursor_char_position);

    CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
        completion_str.c_str(), match_start_point, max_return_elements, nullptr,
        word_complete, matches);
    return matches.GetSize();
  }

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

protected:
  bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
                        CommandReturnObject &result) {
    const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
    if (symbol_fspec) {
      char symfile_path[PATH_MAX];
      symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));

      if (!module_spec.GetUUID().IsValid()) {
        if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
          module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
      }
      // We now have a module that represents a symbol file
      // that can be used for a module that might exist in the
      // current target, so we need to find that module in the
      // target
      ModuleList matching_module_list;

      size_t num_matches = 0;
      // First extract all module specs from the symbol file
      lldb_private::ModuleSpecList symfile_module_specs;
      if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
                                              0, 0, symfile_module_specs)) {
        // Now extract the module spec that matches the target architecture
        ModuleSpec target_arch_module_spec;
        ModuleSpec symfile_module_spec;
        target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
        if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
                                                        symfile_module_spec)) {
          // See if it has a UUID?
          if (symfile_module_spec.GetUUID().IsValid()) {
            // It has a UUID, look for this UUID in the target modules
            ModuleSpec symfile_uuid_module_spec;
            symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
            num_matches = target->GetImages().FindModules(
                symfile_uuid_module_spec, matching_module_list);
          }
        }

        if (num_matches == 0) {
          // No matches yet, iterate through the module specs to find a UUID
          // value that
          // we can match up to an image in our target
          const size_t num_symfile_module_specs =
              symfile_module_specs.GetSize();
          for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
               ++i) {
            if (symfile_module_specs.GetModuleSpecAtIndex(
                    i, symfile_module_spec)) {
              if (symfile_module_spec.GetUUID().IsValid()) {
                // It has a UUID, look for this UUID in the target modules
                ModuleSpec symfile_uuid_module_spec;
                symfile_uuid_module_spec.GetUUID() =
                    symfile_module_spec.GetUUID();
                num_matches = target->GetImages().FindModules(
                    symfile_uuid_module_spec, matching_module_list);
              }
            }
          }
        }
      }

      // Just try to match up the file by basename if we have no matches at this
      // point
      if (num_matches == 0)
        num_matches =
            target->GetImages().FindModules(module_spec, matching_module_list);

      while (num_matches == 0) {
        ConstString filename_no_extension(
            module_spec.GetFileSpec().GetFileNameStrippingExtension());
        // Empty string returned, lets bail
        if (!filename_no_extension)
          break;

        // Check if there was no extension to strip and the basename is the same
        if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
          break;

        // Replace basename with one less extension
        module_spec.GetFileSpec().GetFilename() = filename_no_extension;

        num_matches =
            target->GetImages().FindModules(module_spec, matching_module_list);
      }

      if (num_matches > 1) {
        result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
                                     "use the --uuid option to resolve the "
                                     "ambiguity.\n",
                                     symfile_path);
      } else if (num_matches == 1) {
        ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));

        // The module has not yet created its symbol vendor, we can just
        // give the existing target module the symfile path to use for
        // when it decides to create it!
        module_sp->SetSymbolFileFileSpec(symbol_fspec);

        SymbolVendor *symbol_vendor =
            module_sp->GetSymbolVendor(true, &result.GetErrorStream());
        if (symbol_vendor) {
          SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();

          if (symbol_file) {
            ObjectFile *object_file = symbol_file->GetObjectFile();

            if (object_file && object_file->GetFileSpec() == symbol_fspec) {
              // Provide feedback that the symfile has been successfully added.
              const FileSpec &module_fs = module_sp->GetFileSpec();
              result.AppendMessageWithFormat(
                  "symbol file '%s' has been added to '%s'\n", symfile_path,
                  module_fs.GetPath().c_str());

              // Let clients know something changed in the module
              // if it is currently loaded
              ModuleList module_list;
              module_list.Append(module_sp);
              target->SymbolsDidLoad(module_list);

              // Make sure we load any scripting resources that may be embedded
              // in the debug info files in case the platform supports that.
              Status error;
              StreamString feedback_stream;
              module_sp->LoadScriptingResourceInTarget(target, error,
                                                       &feedback_stream);
              if (error.Fail() && error.AsCString())
                result.AppendWarningWithFormat(
                    "unable to load scripting data for module %s - error "
                    "reported was %s",
                    module_sp->GetFileSpec()
                        .GetFileNameStrippingExtension()
                        .GetCString(),
                    error.AsCString());
              else if (feedback_stream.GetSize())
                result.AppendWarningWithFormat("%s", feedback_stream.GetData());

              flush = true;
              result.SetStatus(eReturnStatusSuccessFinishResult);
              return true;
            }
          }
        }
        // Clear the symbol file spec if anything went wrong
        module_sp->SetSymbolFileFileSpec(FileSpec());
      }

      namespace fs = llvm::sys::fs;
      if (module_spec.GetUUID().IsValid()) {
        StreamString ss_symfile_uuid;
        module_spec.GetUUID().Dump(&ss_symfile_uuid);
        result.AppendErrorWithFormat(
            "symbol file '%s' (%s) does not match any existing module%s\n",
            symfile_path, ss_symfile_uuid.GetData(),
            !fs::is_regular_file(symbol_fspec.GetPath())
                ? "\n       please specify the full path to the symbol file"
                : "");
      } else {
        result.AppendErrorWithFormat(
            "symbol file '%s' does not match any existing module%s\n",
            symfile_path,
            !fs::is_regular_file(symbol_fspec.GetPath())
                ? "\n       please specify the full path to the symbol file"
                : "");
      }
    } else {
      result.AppendError(
          "one or more executable image paths must be specified");
    }
    result.SetStatus(eReturnStatusFailed);
    return false;
  }

  bool DoExecute(Args &args, CommandReturnObject &result) override {
    Target *target = m_exe_ctx.GetTargetPtr();
    result.SetStatus(eReturnStatusFailed);
    bool flush = false;
    ModuleSpec module_spec;
    const bool uuid_option_set =
        m_uuid_option_group.GetOptionValue().OptionWasSet();
    const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
    const bool frame_option_set =
        m_current_frame_option.GetOptionValue().OptionWasSet();
    const size_t argc = args.GetArgumentCount();

    if (argc == 0) {
      if (uuid_option_set || file_option_set || frame_option_set) {
        bool success = false;
        bool error_set = false;
        if (frame_option_set) {
          Process *process = m_exe_ctx.GetProcessPtr();
          if (process) {
            const StateType process_state = process->GetState();
            if (StateIsStoppedState(process_state, true)) {
              StackFrame *frame = m_exe_ctx.GetFramePtr();
              if (frame) {
                ModuleSP frame_module_sp(
                    frame->GetSymbolContext(eSymbolContextModule).module_sp);
                if (frame_module_sp) {
                  if (frame_module_sp->GetPlatformFileSpec().Exists()) {
                    module_spec.GetArchitecture() =
                        frame_module_sp->GetArchitecture();
                    module_spec.GetFileSpec() =
                        frame_module_sp->GetPlatformFileSpec();
                  }
                  module_spec.GetUUID() = frame_module_sp->GetUUID();
                  success = module_spec.GetUUID().IsValid() ||
                            module_spec.GetFileSpec();
                } else {
                  result.AppendError("frame has no module");
                  error_set = true;
                }
              } else {
                result.AppendError("invalid current frame");
                error_set = true;
              }
            } else {
              result.AppendErrorWithFormat("process is not stopped: %s",
                                           StateAsCString(process_state));
              error_set = true;
            }
          } else {
            result.AppendError(
                "a process must exist in order to use the --frame option");
            error_set = true;
          }
        } else {
          if (uuid_option_set) {
            module_spec.GetUUID() =
                m_uuid_option_group.GetOptionValue().GetCurrentValue();
            success |= module_spec.GetUUID().IsValid();
          } else if (file_option_set) {
            module_spec.GetFileSpec() =
                m_file_option.GetOptionValue().GetCurrentValue();
            ModuleSP module_sp(
                target->GetImages().FindFirstModule(module_spec));
            if (module_sp) {
              module_spec.GetFileSpec() = module_sp->GetFileSpec();
              module_spec.GetPlatformFileSpec() =
                  module_sp->GetPlatformFileSpec();
              module_spec.GetUUID() = module_sp->GetUUID();
              module_spec.GetArchitecture() = module_sp->GetArchitecture();
            } else {
              module_spec.GetArchitecture() = target->GetArchitecture();
            }
            success |= module_spec.GetUUID().IsValid() ||
                       module_spec.GetFileSpec().Exists();
          }
        }

        if (success) {
          if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
            if (module_spec.GetSymbolFileSpec())
              success = AddModuleSymbols(target, module_spec, flush, result);
          }
        }

        if (!success && !error_set) {
          StreamString error_strm;
          if (uuid_option_set) {
            error_strm.PutCString("unable to find debug symbols for UUID ");
            module_spec.GetUUID().Dump(&error_strm);
          } else if (file_option_set) {
            error_strm.PutCString(
                "unable to find debug symbols for the executable file ");
            error_strm << module_spec.GetFileSpec();
          } else if (frame_option_set) {
            error_strm.PutCString(
                "unable to find debug symbols for the current frame");
          }
          result.AppendError(error_strm.GetString());
        }
      } else {
        result.AppendError("one or more symbol file paths must be specified, "
                           "or options must be specified");
      }
    } else {
      if (uuid_option_set) {
        result.AppendError("specify either one or more paths to symbol files "
                           "or use the --uuid option without arguments");
      } else if (file_option_set) {
        result.AppendError("specify either one or more paths to symbol files "
                           "or use the --file option without arguments");
      } else if (frame_option_set) {
        result.AppendError("specify either one or more paths to symbol files "
                           "or use the --frame option without arguments");
      } else {
        PlatformSP platform_sp(target->GetPlatform());

        for (auto &entry : args.entries()) {
          if (!entry.ref.empty()) {
            module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
            if (platform_sp) {
              FileSpec symfile_spec;
              if (platform_sp
                      ->ResolveSymbolFile(*target, module_spec, symfile_spec)
                      .Success())
                module_spec.GetSymbolFileSpec() = symfile_spec;
            }

            ArchSpec arch;
            bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();

            if (symfile_exists) {
              if (!AddModuleSymbols(target, module_spec, flush, result))
                break;
            } else {
              std::string resolved_symfile_path =
                  module_spec.GetSymbolFileSpec().GetPath();
              if (resolved_symfile_path != entry.ref) {
                result.AppendErrorWithFormat(
                    "invalid module path '%s' with resolved path '%s'\n",
                    entry.c_str(), resolved_symfile_path.c_str());
                break;
              }
              result.AppendErrorWithFormat("invalid module path '%s'\n",
                                           entry.c_str());
              break;
            }
          }
        }
      }
    }

    if (flush) {
      Process *process = m_exe_ctx.GetProcessPtr();
      if (process)
        process->Flush();
    }
    return result.Succeeded();
  }

  OptionGroupOptions m_option_group;
  OptionGroupUUID m_uuid_option_group;
  OptionGroupFile m_file_option;
  OptionGroupBoolean m_current_frame_option;
};

#pragma mark CommandObjectTargetSymbols

//-------------------------------------------------------------------------
// CommandObjectTargetSymbols
//-------------------------------------------------------------------------

class CommandObjectTargetSymbols : public CommandObjectMultiword {
public:
  //------------------------------------------------------------------
  // Constructors and Destructors
  //------------------------------------------------------------------
  CommandObjectTargetSymbols(CommandInterpreter &interpreter)
      : CommandObjectMultiword(
            interpreter, "target symbols",
            "Commands for adding and managing debug symbol files.",
            "target symbols <sub-command> ...") {
    LoadSubCommand(
        "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
  }

  ~CommandObjectTargetSymbols() override = default;

private:
  //------------------------------------------------------------------
  // For CommandObjectTargetModules only
  //------------------------------------------------------------------
  DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
};

#pragma mark CommandObjectTargetStopHookAdd

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookAdd
//-------------------------------------------------------------------------

static OptionDefinition g_target_stop_hook_add_options[] = {
    // clang-format off
  { LLDB_OPT_SET_ALL, false, "one-liner",    'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,                                         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
  { LLDB_OPT_SET_ALL, false, "shlib",        's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,    "Set the module within which the stop-hook is to be run." },
  { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,                                      "The stop hook is run only for the thread whose index matches this argument." },
  { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,                                         "The stop hook is run only for the thread whose TID matches this argument." },
  { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,                                       "The stop hook is run only for the thread whose thread name matches this argument." },
  { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,                                        "The stop hook is run only for threads in the queue whose name is given by this argument." },
  { LLDB_OPT_SET_1,   false, "file",         'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
  { LLDB_OPT_SET_1,   false, "start-line",   'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,                                          "Set the start of the line range for which the stop-hook is to be run." },
  { LLDB_OPT_SET_1,   false, "end-line",     'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,                                          "Set the end of the line range for which the stop-hook is to be run." },
  { LLDB_OPT_SET_2,   false, "classname",    'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName,                                        "Specify the class within which the stop-hook is to be run." },
  { LLDB_OPT_SET_3,   false, "name",         'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
    // clang-format on
};

class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
                                       public IOHandlerDelegateMultiline {
public:
  class CommandOptions : public Options {
  public:
    CommandOptions()
        : Options(), m_line_start(0), m_line_end(UINT_MAX),
          m_func_name_type_mask(eFunctionNameTypeAuto),
          m_sym_ctx_specified(false), m_thread_specified(false),
          m_use_one_liner(false), m_one_liner() {}

    ~CommandOptions() override = default;

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

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

      switch (short_option) {
      case 'c':
        m_class_name = option_arg;
        m_sym_ctx_specified = true;
        break;

      case 'e':
        if (option_arg.getAsInteger(0, m_line_end)) {
          error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
                                         option_arg.str().c_str());
          break;
        }
        m_sym_ctx_specified = true;
        break;

      case 'l':
        if (option_arg.getAsInteger(0, m_line_start)) {
          error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
                                         option_arg.str().c_str());
          break;
        }
        m_sym_ctx_specified = true;
        break;

      case 'i':
        m_no_inlines = true;
        break;

      case 'n':
        m_function_name = option_arg;
        m_func_name_type_mask |= eFunctionNameTypeAuto;
        m_sym_ctx_specified = true;
        break;

      case 'f':
        m_file_name = option_arg;
        m_sym_ctx_specified = true;
        break;

      case 's':
        m_module_name = option_arg;
        m_sym_ctx_specified = true;
        break;

      case 't':
        if (option_arg.getAsInteger(0, m_thread_id))
          error.SetErrorStringWithFormat("invalid thread id string '%s'",
                                         option_arg.str().c_str());
        m_thread_specified = true;
        break;

      case 'T':
        m_thread_name = option_arg;
        m_thread_specified = true;
        break;

      case 'q':
        m_queue_name = option_arg;
        m_thread_specified = true;
        break;

      case 'x':
        if (option_arg.getAsInteger(0, m_thread_index))
          error.SetErrorStringWithFormat("invalid thread index string '%s'",
                                         option_arg.str().c_str());
        m_thread_specified = true;
        break;

      case 'o':
        m_use_one_liner = true;
        m_one_liner = option_arg;
        break;

      default:
        error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
        break;
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_class_name.clear();
      m_function_name.clear();
      m_line_start = 0;
      m_line_end = UINT_MAX;
      m_file_name.clear();
      m_module_name.clear();
      m_func_name_type_mask = eFunctionNameTypeAuto;
      m_thread_id = LLDB_INVALID_THREAD_ID;
      m_thread_index = UINT32_MAX;
      m_thread_name.clear();
      m_queue_name.clear();

      m_no_inlines = false;
      m_sym_ctx_specified = false;
      m_thread_specified = false;

      m_use_one_liner = false;
      m_one_liner.clear();
    }

    std::string m_class_name;
    std::string m_function_name;
    uint32_t m_line_start;
    uint32_t m_line_end;
    std::string m_file_name;
    std::string m_module_name;
    uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
    lldb::tid_t m_thread_id;
    uint32_t m_thread_index;
    std::string m_thread_name;
    std::string m_queue_name;
    bool m_sym_ctx_specified;
    bool m_no_inlines;
    bool m_thread_specified;
    // Instance variables to hold the values for one_liner options.
    bool m_use_one_liner;
    std::string m_one_liner;
  };

  CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target stop-hook add",
                            "Add a hook to be executed when the target stops.",
                            "target stop-hook add"),
        IOHandlerDelegateMultiline("DONE",
                                   IOHandlerDelegate::Completion::LLDBCommand),
        m_options() {}

  ~CommandObjectTargetStopHookAdd() override = default;

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

protected:
  void IOHandlerActivated(IOHandler &io_handler) override {
    StreamFileSP output_sp(io_handler.GetOutputStreamFile());
    if (output_sp) {
      output_sp->PutCString(
          "Enter your stop hook command(s).  Type 'DONE' to end.\n");
      output_sp->Flush();
    }
  }

  void IOHandlerInputComplete(IOHandler &io_handler,
                              std::string &line) override {
    if (m_stop_hook_sp) {
      if (line.empty()) {
        StreamFileSP error_sp(io_handler.GetErrorStreamFile());
        if (error_sp) {
          error_sp->Printf("error: stop hook #%" PRIu64
                           " aborted, no commands.\n",
                           m_stop_hook_sp->GetID());
          error_sp->Flush();
        }
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target)
          target->RemoveStopHookByID(m_stop_hook_sp->GetID());
      } else {
        m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
        if (output_sp) {
          output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
                            m_stop_hook_sp->GetID());
          output_sp->Flush();
        }
      }
      m_stop_hook_sp.reset();
    }
    io_handler.SetIsDone(true);
  }

  bool DoExecute(Args &command, CommandReturnObject &result) override {
    m_stop_hook_sp.reset();

    Target *target = GetSelectedOrDummyTarget();
    if (target) {
      Target::StopHookSP new_hook_sp = target->CreateStopHook();

      //  First step, make the specifier.
      std::unique_ptr<SymbolContextSpecifier> specifier_ap;
      if (m_options.m_sym_ctx_specified) {
        specifier_ap.reset(new SymbolContextSpecifier(
            m_interpreter.GetDebugger().GetSelectedTarget()));

        if (!m_options.m_module_name.empty()) {
          specifier_ap->AddSpecification(
              m_options.m_module_name.c_str(),
              SymbolContextSpecifier::eModuleSpecified);
        }

        if (!m_options.m_class_name.empty()) {
          specifier_ap->AddSpecification(
              m_options.m_class_name.c_str(),
              SymbolContextSpecifier::eClassOrNamespaceSpecified);
        }

        if (!m_options.m_file_name.empty()) {
          specifier_ap->AddSpecification(
              m_options.m_file_name.c_str(),
              SymbolContextSpecifier::eFileSpecified);
        }

        if (m_options.m_line_start != 0) {
          specifier_ap->AddLineSpecification(
              m_options.m_line_start,
              SymbolContextSpecifier::eLineStartSpecified);
        }

        if (m_options.m_line_end != UINT_MAX) {
          specifier_ap->AddLineSpecification(
              m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
        }

        if (!m_options.m_function_name.empty()) {
          specifier_ap->AddSpecification(
              m_options.m_function_name.c_str(),
              SymbolContextSpecifier::eFunctionSpecified);
        }
      }

      if (specifier_ap)
        new_hook_sp->SetSpecifier(specifier_ap.release());

      // Next see if any of the thread options have been entered:

      if (m_options.m_thread_specified) {
        ThreadSpec *thread_spec = new ThreadSpec();

        if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
          thread_spec->SetTID(m_options.m_thread_id);
        }

        if (m_options.m_thread_index != UINT32_MAX)
          thread_spec->SetIndex(m_options.m_thread_index);

        if (!m_options.m_thread_name.empty())
          thread_spec->SetName(m_options.m_thread_name.c_str());

        if (!m_options.m_queue_name.empty())
          thread_spec->SetQueueName(m_options.m_queue_name.c_str());

        new_hook_sp->SetThreadSpecifier(thread_spec);
      }
      if (m_options.m_use_one_liner) {
        // Use one-liner.
        new_hook_sp->GetCommandPointer()->AppendString(
            m_options.m_one_liner.c_str());
        result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
                                       new_hook_sp->GetID());
      } else {
        m_stop_hook_sp = new_hook_sp;
        m_interpreter.GetLLDBCommandsFromIOHandler(
            "> ",     // Prompt
            *this,    // IOHandlerDelegate
            true,     // Run IOHandler in async mode
            nullptr); // Baton for the "io_handler" that will be passed back
                      // into our IOHandlerDelegate functions
      }
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }

    return result.Succeeded();
  }

private:
  CommandOptions m_options;
  Target::StopHookSP m_stop_hook_sp;
};

#pragma mark CommandObjectTargetStopHookDelete

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookDelete
//-------------------------------------------------------------------------

class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
public:
  CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target stop-hook delete",
                            "Delete a stop-hook.",
                            "target stop-hook delete [<idx>]") {}

  ~CommandObjectTargetStopHookDelete() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = GetSelectedOrDummyTarget();
    if (target) {
      // FIXME: see if we can use the breakpoint id style parser?
      size_t num_args = command.GetArgumentCount();
      if (num_args == 0) {
        if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
          result.SetStatus(eReturnStatusFailed);
          return false;
        } else {
          target->RemoveAllStopHooks();
        }
      } else {
        bool success;
        for (size_t i = 0; i < num_args; i++) {
          lldb::user_id_t user_id = StringConvert::ToUInt32(
              command.GetArgumentAtIndex(i), 0, 0, &success);
          if (!success) {
            result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
                                         command.GetArgumentAtIndex(i));
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
          success = target->RemoveStopHookByID(user_id);
          if (!success) {
            result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
                                         command.GetArgumentAtIndex(i));
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
        }
      }
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }

    return result.Succeeded();
  }
};

#pragma mark CommandObjectTargetStopHookEnableDisable

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookEnableDisable
//-------------------------------------------------------------------------

class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
public:
  CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
                                           bool enable, const char *name,
                                           const char *help, const char *syntax)
      : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
  }

  ~CommandObjectTargetStopHookEnableDisable() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = GetSelectedOrDummyTarget();
    if (target) {
      // FIXME: see if we can use the breakpoint id style parser?
      size_t num_args = command.GetArgumentCount();
      bool success;

      if (num_args == 0) {
        target->SetAllStopHooksActiveState(m_enable);
      } else {
        for (size_t i = 0; i < num_args; i++) {
          lldb::user_id_t user_id = StringConvert::ToUInt32(
              command.GetArgumentAtIndex(i), 0, 0, &success);
          if (!success) {
            result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
                                         command.GetArgumentAtIndex(i));
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
          success = target->SetStopHookActiveStateByID(user_id, m_enable);
          if (!success) {
            result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
                                         command.GetArgumentAtIndex(i));
            result.SetStatus(eReturnStatusFailed);
            return false;
          }
        }
      }
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
    } else {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
    }
    return result.Succeeded();
  }

private:
  bool m_enable;
};

#pragma mark CommandObjectTargetStopHookList

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookList
//-------------------------------------------------------------------------

class CommandObjectTargetStopHookList : public CommandObjectParsed {
public:
  CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "target stop-hook list",
                            "List all stop-hooks.",
                            "target stop-hook list [<type>]") {}

  ~CommandObjectTargetStopHookList() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = GetSelectedOrDummyTarget();
    if (!target) {
      result.AppendError("invalid target\n");
      result.SetStatus(eReturnStatusFailed);
      return result.Succeeded();
    }

    size_t num_hooks = target->GetNumStopHooks();
    if (num_hooks == 0) {
      result.GetOutputStream().PutCString("No stop hooks.\n");
    } else {
      for (size_t i = 0; i < num_hooks; i++) {
        Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
        if (i > 0)
          result.GetOutputStream().PutCString("\n");
        this_hook->GetDescription(&(result.GetOutputStream()),
                                  eDescriptionLevelFull);
      }
    }
    result.SetStatus(eReturnStatusSuccessFinishResult);
    return result.Succeeded();
  }
};

#pragma mark CommandObjectMultiwordTargetStopHooks

//-------------------------------------------------------------------------
// CommandObjectMultiwordTargetStopHooks
//-------------------------------------------------------------------------

class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
public:
  CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
      : CommandObjectMultiword(
            interpreter, "target stop-hook",
            "Commands for operating on debugger target stop-hooks.",
            "target stop-hook <subcommand> [<subcommand-options>]") {
    LoadSubCommand("add", CommandObjectSP(
                              new CommandObjectTargetStopHookAdd(interpreter)));
    LoadSubCommand(
        "delete",
        CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
    LoadSubCommand("disable",
                   CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
                       interpreter, false, "target stop-hook disable [<id>]",
                       "Disable a stop-hook.", "target stop-hook disable")));
    LoadSubCommand("enable",
                   CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
                       interpreter, true, "target stop-hook enable [<id>]",
                       "Enable a stop-hook.", "target stop-hook enable")));
    LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
                               interpreter)));
  }

  ~CommandObjectMultiwordTargetStopHooks() override = default;
};

#pragma mark CommandObjectMultiwordTarget

//-------------------------------------------------------------------------
// CommandObjectMultiwordTarget
//-------------------------------------------------------------------------

CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
    CommandInterpreter &interpreter)
    : CommandObjectMultiword(interpreter, "target",
                             "Commands for operating on debugger targets.",
                             "target <subcommand> [<subcommand-options>]") {
  LoadSubCommand("create",
                 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
  LoadSubCommand("delete",
                 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
  LoadSubCommand("list",
                 CommandObjectSP(new CommandObjectTargetList(interpreter)));
  LoadSubCommand("select",
                 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
  LoadSubCommand(
      "stop-hook",
      CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
  LoadSubCommand("modules",
                 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
  LoadSubCommand("symbols",
                 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
  LoadSubCommand("variable",
                 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
}

CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
