brintos

brintos / llvm-project-archived public Read only

0
0
Text · 197.4 KiB · 7f880d2 Raw
5439 lines · cpp
1//===-- CommandObjectTarget.cpp -------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "CommandObjectTarget.h"10 11#include "lldb/Core/Address.h"12#include "lldb/Core/Debugger.h"13#include "lldb/Core/IOHandler.h"14#include "lldb/Core/Module.h"15#include "lldb/Core/ModuleSpec.h"16#include "lldb/Core/PluginManager.h"17#include "lldb/Core/Section.h"18#include "lldb/DataFormatters/ValueObjectPrinter.h"19#include "lldb/Host/OptionParser.h"20#include "lldb/Interpreter/CommandInterpreter.h"21#include "lldb/Interpreter/CommandOptionArgumentTable.h"22#include "lldb/Interpreter/CommandReturnObject.h"23#include "lldb/Interpreter/OptionArgParser.h"24#include "lldb/Interpreter/OptionGroupArchitecture.h"25#include "lldb/Interpreter/OptionGroupBoolean.h"26#include "lldb/Interpreter/OptionGroupFile.h"27#include "lldb/Interpreter/OptionGroupFormat.h"28#include "lldb/Interpreter/OptionGroupPlatform.h"29#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"30#include "lldb/Interpreter/OptionGroupString.h"31#include "lldb/Interpreter/OptionGroupUInt64.h"32#include "lldb/Interpreter/OptionGroupUUID.h"33#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"34#include "lldb/Interpreter/OptionGroupVariable.h"35#include "lldb/Interpreter/Options.h"36#include "lldb/Symbol/CompileUnit.h"37#include "lldb/Symbol/FuncUnwinders.h"38#include "lldb/Symbol/LineTable.h"39#include "lldb/Symbol/ObjectFile.h"40#include "lldb/Symbol/SymbolFile.h"41#include "lldb/Symbol/UnwindPlan.h"42#include "lldb/Symbol/VariableList.h"43#include "lldb/Target/ABI.h"44#include "lldb/Target/Process.h"45#include "lldb/Target/RegisterContext.h"46#include "lldb/Target/SectionLoadList.h"47#include "lldb/Target/StackFrame.h"48#include "lldb/Target/Thread.h"49#include "lldb/Target/ThreadSpec.h"50#include "lldb/Utility/Args.h"51#include "lldb/Utility/ConstString.h"52#include "lldb/Utility/FileSpec.h"53#include "lldb/Utility/LLDBLog.h"54#include "lldb/Utility/State.h"55#include "lldb/Utility/Stream.h"56#include "lldb/Utility/StructuredData.h"57#include "lldb/Utility/Timer.h"58#include "lldb/ValueObject/ValueObjectVariable.h"59#include "lldb/lldb-enumerations.h"60#include "lldb/lldb-forward.h"61#include "lldb/lldb-private-enumerations.h"62 63#include "clang/Driver/CreateInvocationFromArgs.h"64#include "clang/Frontend/CompilerInstance.h"65#include "clang/Frontend/CompilerInvocation.h"66#include "clang/Frontend/FrontendActions.h"67#include "clang/Serialization/ObjectFilePCHContainerReader.h"68#include "llvm/ADT/ScopeExit.h"69#include "llvm/ADT/StringRef.h"70#include "llvm/Support/FileSystem.h"71#include "llvm/Support/FormatAdapters.h"72 73 74using namespace lldb;75using namespace lldb_private;76 77static void DumpTargetInfo(uint32_t target_idx, Target *target,78                           const char *prefix_cstr,79                           bool show_stopped_process_status, Stream &strm) {80  const ArchSpec &target_arch = target->GetArchitecture();81 82  Module *exe_module = target->GetExecutableModulePointer();83  char exe_path[PATH_MAX];84  bool exe_valid = false;85  if (exe_module)86    exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));87 88  if (!exe_valid)89    ::strcpy(exe_path, "<none>");90 91  std::string formatted_label = "";92  const std::string &label = target->GetLabel();93  if (!label.empty()) {94    formatted_label = " (" + label + ")";95  }96 97  strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,98              formatted_label.data(), exe_path);99 100  uint32_t properties = 0;101  if (target_arch.IsValid()) {102    strm.Printf(" ( arch=");103    target_arch.DumpTriple(strm.AsRawOstream());104    properties++;105  }106  PlatformSP platform_sp(target->GetPlatform());107  if (platform_sp)108    strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",109                platform_sp->GetName());110 111  ProcessSP process_sp(target->GetProcessSP());112  bool show_process_status = false;113  if (process_sp) {114    lldb::pid_t pid = process_sp->GetID();115    StateType state = process_sp->GetState();116    if (show_stopped_process_status)117      show_process_status = StateIsStoppedState(state, true);118    const char *state_cstr = StateAsCString(state);119    if (pid != LLDB_INVALID_PROCESS_ID)120      strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);121    strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);122  }123  if (properties > 0)124    strm.PutCString(" )\n");125  else126    strm.EOL();127  if (show_process_status) {128    const bool only_threads_with_stop_reason = true;129    const uint32_t start_frame = 0;130    const uint32_t num_frames = 1;131    const uint32_t num_frames_with_source = 1;132    const bool stop_format = false;133    process_sp->GetStatus(strm);134    process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,135                                start_frame, num_frames, num_frames_with_source,136                                stop_format);137  }138}139 140static uint32_t DumpTargetList(TargetList &target_list,141                               bool show_stopped_process_status, Stream &strm) {142  const uint32_t num_targets = target_list.GetNumTargets();143  if (num_targets) {144    TargetSP selected_target_sp(target_list.GetSelectedTarget());145    strm.PutCString("Current targets:\n");146    for (uint32_t i = 0; i < num_targets; ++i) {147      TargetSP target_sp(target_list.GetTargetAtIndex(i));148      if (target_sp) {149        bool is_selected = target_sp.get() == selected_target_sp.get();150        DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : "  ",151                       show_stopped_process_status, strm);152      }153    }154  }155  return num_targets;156}157 158#define LLDB_OPTIONS_target_dependents159#include "CommandOptions.inc"160 161class OptionGroupDependents : public OptionGroup {162public:163  OptionGroupDependents() = default;164 165  ~OptionGroupDependents() override = default;166 167  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {168    return llvm::ArrayRef(g_target_dependents_options);169  }170 171  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,172                        ExecutionContext *execution_context) override {173    Status error;174 175    // For compatibility no value means don't load dependents.176    if (option_value.empty()) {177      m_load_dependent_files = eLoadDependentsNo;178      return error;179    }180 181    const char short_option =182        g_target_dependents_options[option_idx].short_option;183    if (short_option == 'd') {184      LoadDependentFiles tmp_load_dependents;185      tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(186          option_value, g_target_dependents_options[option_idx].enum_values, 0,187          error);188      if (error.Success())189        m_load_dependent_files = tmp_load_dependents;190    } else {191      error = Status::FromErrorStringWithFormat(192          "unrecognized short option '%c'", short_option);193    }194 195    return error;196  }197 198  Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;199 200  void OptionParsingStarting(ExecutionContext *execution_context) override {201    m_load_dependent_files = eLoadDependentsDefault;202  }203 204  LoadDependentFiles m_load_dependent_files;205 206private:207  OptionGroupDependents(const OptionGroupDependents &) = delete;208  const OptionGroupDependents &209  operator=(const OptionGroupDependents &) = delete;210};211 212#pragma mark CommandObjectTargetCreate213 214class CommandObjectTargetCreate : public CommandObjectParsed {215public:216  CommandObjectTargetCreate(CommandInterpreter &interpreter)217      : CommandObjectParsed(218            interpreter, "target create",219            "Create a target using the argument as the main executable.",220            nullptr),221        m_platform_options(true), // Include the --platform option.222        m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,223                    "Fullpath to a core file to use for this target."),224        m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,225                "Optional name for this target.", nullptr),226        m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,227                      eArgTypeFilename,228                      "Fullpath to a stand alone debug "229                      "symbols file for when debug symbols "230                      "are not in the executable."),231        m_remote_file(232            LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,233            "Fullpath to the file on the remote host if debugging remotely.") {234 235    AddSimpleArgumentList(eArgTypeFilename);236 237    m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);238    m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);239    m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);240    m_option_group.Append(&m_label, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);241    m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);242    m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);243    m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);244    m_option_group.Finalize();245  }246 247  ~CommandObjectTargetCreate() override = default;248 249  Options *GetOptions() override { return &m_option_group; }250 251protected:252  void DoExecute(Args &command, CommandReturnObject &result) override {253    const size_t argc = command.GetArgumentCount();254    FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());255    FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());256 257    if (core_file) {258      auto file = FileSystem::Instance().Open(259          core_file, lldb_private::File::eOpenOptionReadOnly);260 261      if (!file) {262        result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",263                                      core_file.GetPath(),264                                      llvm::toString(file.takeError()));265        return;266      }267    }268 269    if (argc == 1 || core_file || remote_file) {270      FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());271      if (symfile) {272        auto file = FileSystem::Instance().Open(273            symfile, lldb_private::File::eOpenOptionReadOnly);274 275        if (!file) {276          result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",277                                        symfile.GetPath(),278                                        llvm::toString(file.takeError()));279          return;280        }281      }282 283      const char *file_path = command.GetArgumentAtIndex(0);284      LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);285 286      bool must_set_platform_path = false;287 288      Debugger &debugger = GetDebugger();289 290      TargetSP target_sp;291      llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();292      Status error(debugger.GetTargetList().CreateTarget(293          debugger, file_path, arch_cstr,294          m_add_dependents.m_load_dependent_files, &m_platform_options,295          target_sp));296 297      if (!target_sp) {298        result.AppendError(error.AsCString());299        return;300      }301 302      const llvm::StringRef label =303          m_label.GetOptionValue().GetCurrentValueAsRef();304      if (!label.empty()) {305        if (auto E = target_sp->SetLabel(label))306          result.SetError(std::move(E));307        return;308      }309 310      auto on_error = llvm::make_scope_exit(311          [&target_list = debugger.GetTargetList(), &target_sp]() {312            target_list.DeleteTarget(target_sp);313          });314 315      // Only get the platform after we create the target because we might316      // have switched platforms depending on what the arguments were to317      // CreateTarget() we can't rely on the selected platform.318 319      PlatformSP platform_sp = target_sp->GetPlatform();320 321      FileSpec file_spec;322      if (file_path) {323        file_spec.SetFile(file_path, FileSpec::Style::native);324        FileSystem::Instance().Resolve(file_spec);325 326        // Try to resolve the exe based on PATH and/or platform-specific327        // suffixes, but only if using the host platform.328        if (platform_sp && platform_sp->IsHost() &&329            !FileSystem::Instance().Exists(file_spec))330          FileSystem::Instance().ResolveExecutableLocation(file_spec);331      }332 333      if (remote_file) {334        if (platform_sp) {335          // I have a remote file.. two possible cases336          if (file_spec && FileSystem::Instance().Exists(file_spec)) {337            // if the remote file does not exist, push it there338            if (!platform_sp->GetFileExists(remote_file)) {339              Status err = platform_sp->PutFile(file_spec, remote_file);340              if (err.Fail()) {341                result.AppendError(err.AsCString());342                return;343              }344            }345          } else {346            // there is no local file and we need one347            // in order to make the remote ---> local transfer we need a348            // platform349            // TODO: if the user has passed in a --platform argument, use it350            // to fetch the right platform351            if (file_path) {352              // copy the remote file to the local file353              Status err = platform_sp->GetFile(remote_file, file_spec);354              if (err.Fail()) {355                result.AppendError(err.AsCString());356                return;357              }358            } else {359              // If the remote file exists, we can debug reading that out of360              // memory.  If the platform is already connected to an lldb-server361              // then we can at least check the file exists remotely.  Otherwise362              // we'll just have to trust that it will be there when we do363              // process connect.364              // I don't do this for the host platform because it seems odd to365              // support supplying a remote file but no local file for a local366              // debug session.367              if (platform_sp->IsHost()) {368                result.AppendError("Supply a local file, not a remote file, "369                                   "when debugging on the host.");370                return;371              }372              if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {373                result.AppendError("remote --> local transfer without local "374                                 "path is not implemented yet");375                return;376              }377              // Since there's only a remote file, we need to set the executable378              // file spec to the remote one.379              ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();380              launch_info.SetExecutableFile(FileSpec(remote_file), true);381              target_sp->SetProcessLaunchInfo(launch_info);382            }383          }384        } else {385          result.AppendError("no platform found for target");386          return;387        }388      }389 390      if (symfile || remote_file) {391        ModuleSP module_sp(target_sp->GetExecutableModule());392        if (module_sp) {393          if (symfile)394            module_sp->SetSymbolFileFileSpec(symfile);395          if (remote_file) {396            std::string remote_path = remote_file.GetPath();397            target_sp->SetArg0(remote_path.c_str());398            module_sp->SetPlatformFileSpec(remote_file);399          }400        }401      }402 403      if (must_set_platform_path) {404        ModuleSpec main_module_spec(file_spec);405        ModuleSP module_sp =406            target_sp->GetOrCreateModule(main_module_spec, true /* notify */);407        if (module_sp)408          module_sp->SetPlatformFileSpec(remote_file);409      }410 411      if (core_file) {412        FileSpec core_file_dir;413        core_file_dir.SetDirectory(core_file.GetDirectory());414        target_sp->AppendExecutableSearchPaths(core_file_dir);415 416        ProcessSP process_sp(target_sp->CreateProcess(417            GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));418 419        if (process_sp) {420          // Seems weird that we Launch a core file, but that is what we421          // do!422          {423            ElapsedTime load_core_time(424                target_sp->GetStatistics().GetLoadCoreTime());425            error = process_sp->LoadCore();426          }427 428          if (error.Fail()) {429            result.AppendError(error.AsCString("unknown core file format"));430            return;431          } else {432            result.AppendMessageWithFormatv(433                "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),434                target_sp->GetArchitecture().GetArchitectureName());435            result.SetStatus(eReturnStatusSuccessFinishNoResult);436            on_error.release();437          }438        } else {439          result.AppendErrorWithFormatv("Unknown core file format '{0}'\n",440                                        core_file.GetPath());441        }442      } else {443        result.AppendMessageWithFormat(444            "Current executable set to '%s' (%s).\n",445            file_spec.GetPath().c_str(),446            target_sp->GetArchitecture().GetArchitectureName());447        result.SetStatus(eReturnStatusSuccessFinishNoResult);448        on_error.release();449      }450    } else {451      result.AppendErrorWithFormat("'%s' takes exactly one executable path "452                                   "argument, or use the --core option.\n",453                                   m_cmd_name.c_str());454    }455  }456 457private:458  OptionGroupOptions m_option_group;459  OptionGroupArchitecture m_arch_option;460  OptionGroupPlatform m_platform_options;461  OptionGroupFile m_core_file;462  OptionGroupString m_label;463  OptionGroupFile m_symbol_file;464  OptionGroupFile m_remote_file;465  OptionGroupDependents m_add_dependents;466};467 468#pragma mark CommandObjectTargetList469 470class CommandObjectTargetList : public CommandObjectParsed {471public:472  CommandObjectTargetList(CommandInterpreter &interpreter)473      : CommandObjectParsed(474            interpreter, "target list",475            "List all current targets in the current debug session.", nullptr) {476  }477 478  ~CommandObjectTargetList() override = default;479 480protected:481  void DoExecute(Args &args, CommandReturnObject &result) override {482    Stream &strm = result.GetOutputStream();483 484    bool show_stopped_process_status = false;485    if (DumpTargetList(GetDebugger().GetTargetList(),486                       show_stopped_process_status, strm) == 0) {487      strm.PutCString("No targets.\n");488    }489    result.SetStatus(eReturnStatusSuccessFinishResult);490  }491};492 493#pragma mark CommandObjectTargetSelect494 495class CommandObjectTargetSelect : public CommandObjectParsed {496public:497  CommandObjectTargetSelect(CommandInterpreter &interpreter)498      : CommandObjectParsed(499            interpreter, "target select",500            "Select a target as the current target by target index.", nullptr) {501    AddSimpleArgumentList(eArgTypeTargetID);502  }503 504  ~CommandObjectTargetSelect() override = default;505 506protected:507  void DoExecute(Args &args, CommandReturnObject &result) override {508    if (args.GetArgumentCount() == 1) {509      const char *target_identifier = args.GetArgumentAtIndex(0);510      uint32_t target_idx = LLDB_INVALID_INDEX32;511      TargetList &target_list = GetDebugger().GetTargetList();512      const uint32_t num_targets = target_list.GetNumTargets();513      if (llvm::to_integer(target_identifier, target_idx)) {514        if (target_idx < num_targets) {515          target_list.SetSelectedTarget(target_idx);516          Stream &strm = result.GetOutputStream();517          bool show_stopped_process_status = false;518          DumpTargetList(target_list, show_stopped_process_status, strm);519          result.SetStatus(eReturnStatusSuccessFinishResult);520        } else {521          if (num_targets > 0) {522            result.AppendErrorWithFormat(523                "index %u is out of range, valid target indexes are 0 - %u\n",524                target_idx, num_targets - 1);525          } else {526            result.AppendErrorWithFormat(527                "index %u is out of range since there are no active targets\n",528                target_idx);529          }530        }531      } else {532        for (size_t i = 0; i < num_targets; i++) {533          if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {534            const std::string &label = target_sp->GetLabel();535            if (!label.empty() && label == target_identifier) {536              target_idx = i;537              break;538            }539          }540        }541 542        if (target_idx != LLDB_INVALID_INDEX32) {543          target_list.SetSelectedTarget(target_idx);544          Stream &strm = result.GetOutputStream();545          bool show_stopped_process_status = false;546          DumpTargetList(target_list, show_stopped_process_status, strm);547          result.SetStatus(eReturnStatusSuccessFinishResult);548        } else {549          result.AppendErrorWithFormat("invalid index string value '%s'\n",550                                       target_identifier);551        }552      }553    } else {554      result.AppendError(555          "'target select' takes a single argument: a target index\n");556    }557  }558};559 560#pragma mark CommandObjectTargetDelete561 562class CommandObjectTargetDelete : public CommandObjectParsed {563public:564  CommandObjectTargetDelete(CommandInterpreter &interpreter)565      : CommandObjectParsed(interpreter, "target delete",566                            "Delete one or more targets by target index.",567                            nullptr),568        m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",569                     false, true),570        m_cleanup_option(571            LLDB_OPT_SET_1, false, "clean", 'c',572            "Perform extra cleanup to minimize memory consumption after "573            "deleting the target.  "574            "By default, LLDB will keep in memory any modules previously "575            "loaded by the target as well "576            "as all of its debug info.  Specifying --clean will unload all of "577            "these shared modules and "578            "cause them to be reparsed again the next time the target is run",579            false, true) {580    m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);581    m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);582    m_option_group.Finalize();583    AddSimpleArgumentList(eArgTypeTargetID, eArgRepeatStar);584  }585 586  ~CommandObjectTargetDelete() override = default;587 588  Options *GetOptions() override { return &m_option_group; }589 590protected:591  void DoExecute(Args &args, CommandReturnObject &result) override {592    const size_t argc = args.GetArgumentCount();593    std::vector<TargetSP> delete_target_list;594    TargetList &target_list = GetDebugger().GetTargetList();595    TargetSP target_sp;596 597    if (m_all_option.GetOptionValue()) {598      for (size_t i = 0; i < target_list.GetNumTargets(); ++i)599        delete_target_list.push_back(target_list.GetTargetAtIndex(i));600    } else if (argc > 0) {601      const uint32_t num_targets = target_list.GetNumTargets();602      // Bail out if don't have any targets.603      if (num_targets == 0) {604        result.AppendError("no targets to delete");605        return;606      }607 608      for (auto &entry : args.entries()) {609        uint32_t target_idx;610        if (entry.ref().getAsInteger(0, target_idx)) {611          result.AppendErrorWithFormat("invalid target index '%s'\n",612                                       entry.c_str());613          return;614        }615        if (target_idx < num_targets) {616          target_sp = target_list.GetTargetAtIndex(target_idx);617          if (target_sp) {618            delete_target_list.push_back(target_sp);619            continue;620          }621        }622        if (num_targets > 1)623          result.AppendErrorWithFormat("target index %u is out of range, valid "624                                       "target indexes are 0 - %u\n",625                                       target_idx, num_targets - 1);626        else627          result.AppendErrorWithFormat(628              "target index %u is out of range, the only valid index is 0\n",629              target_idx);630 631        return;632      }633    } else {634      target_sp = target_list.GetSelectedTarget();635      if (!target_sp) {636        result.AppendErrorWithFormat("no target is currently selected\n");637        return;638      }639      delete_target_list.push_back(target_sp);640    }641 642    const size_t num_targets_to_delete = delete_target_list.size();643    for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {644      target_sp = delete_target_list[idx];645      target_list.DeleteTarget(target_sp);646      target_sp->Destroy();647    }648    // If "--clean" was specified, prune any orphaned shared modules from the649    // global shared module list650    if (m_cleanup_option.GetOptionValue()) {651      const bool mandatory = true;652      ModuleList::RemoveOrphanSharedModules(mandatory);653    }654    result.GetOutputStream().Printf("%u targets deleted.\n",655                                    (uint32_t)num_targets_to_delete);656    result.SetStatus(eReturnStatusSuccessFinishResult);657  }658 659  OptionGroupOptions m_option_group;660  OptionGroupBoolean m_all_option;661  OptionGroupBoolean m_cleanup_option;662};663 664class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {665public:666  CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)667      : CommandObjectParsed(668            interpreter, "target show-launch-environment",669            "Shows the environment being passed to the process when launched, "670            "taking info account 3 settings: target.env-vars, "671            "target.inherit-env and target.unset-env-vars.",672            nullptr, eCommandRequiresTarget) {}673 674  ~CommandObjectTargetShowLaunchEnvironment() override = default;675 676protected:677  void DoExecute(Args &args, CommandReturnObject &result) override {678    Target *target = m_exe_ctx.GetTargetPtr();679    Environment env = target->GetEnvironment();680 681    std::vector<Environment::value_type *> env_vector;682    env_vector.reserve(env.size());683    for (auto &KV : env)684      env_vector.push_back(&KV);685    std::sort(env_vector.begin(), env_vector.end(),686              [](Environment::value_type *a, Environment::value_type *b) {687                return a->first() < b->first();688              });689 690    auto &strm = result.GetOutputStream();691    for (auto &KV : env_vector)692      strm.Format("{0}={1}\n", KV->first(), KV->second);693 694    result.SetStatus(eReturnStatusSuccessFinishResult);695  }696};697 698#pragma mark CommandObjectTargetVariable699 700class CommandObjectTargetVariable : public CommandObjectParsed {701  static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'702  static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'703 704public:705  CommandObjectTargetVariable(CommandInterpreter &interpreter)706      : CommandObjectParsed(interpreter, "target variable",707                            "Read global variables for the current target, "708                            "before or while running a process.",709                            nullptr, eCommandRequiresTarget),710        m_option_variable(false), // Don't include frame options711        m_option_format(eFormatDefault),712        m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,713                               0, eArgTypeFilename,714                               "A basename or fullpath to a file that contains "715                               "global variables. This option can be "716                               "specified multiple times."),717        m_option_shared_libraries(718            LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,719            eArgTypeFilename,720            "A basename or fullpath to a shared library to use in the search "721            "for global "722            "variables. This option can be specified multiple times.") {723    AddSimpleArgumentList(eArgTypeVarName, eArgRepeatPlus);724 725    m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);726    m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);727    m_option_group.Append(&m_option_format,728                          OptionGroupFormat::OPTION_GROUP_FORMAT |729                              OptionGroupFormat::OPTION_GROUP_GDB_FMT,730                          LLDB_OPT_SET_1);731    m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,732                          LLDB_OPT_SET_1);733    m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,734                          LLDB_OPT_SET_1);735    m_option_group.Finalize();736  }737 738  ~CommandObjectTargetVariable() override = default;739 740  void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,741                       const char *root_name) {742    DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());743 744    if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&745        valobj_sp->IsRuntimeSupportValue())746      return;747 748    switch (var_sp->GetScope()) {749    case eValueTypeVariableGlobal:750      if (m_option_variable.show_scope)751        s.PutCString("GLOBAL: ");752      break;753 754    case eValueTypeVariableStatic:755      if (m_option_variable.show_scope)756        s.PutCString("STATIC: ");757      break;758 759    case eValueTypeVariableArgument:760      if (m_option_variable.show_scope)761        s.PutCString("   ARG: ");762      break;763 764    case eValueTypeVariableLocal:765      if (m_option_variable.show_scope)766        s.PutCString(" LOCAL: ");767      break;768 769    case eValueTypeVariableThreadLocal:770      if (m_option_variable.show_scope)771        s.PutCString("THREAD: ");772      break;773 774    default:775      break;776    }777 778    if (m_option_variable.show_decl) {779      bool show_fullpaths = false;780      bool show_module = true;781      if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))782        s.PutCString(": ");783    }784 785    const Format format = m_option_format.GetFormat();786    if (format != eFormatDefault)787      options.SetFormat(format);788 789    options.SetRootValueObjectName(root_name);790 791    if (llvm::Error error = valobj_sp->Dump(s, options))792      s << "error: " << toString(std::move(error));793  }794 795  static size_t GetVariableCallback(void *baton, const char *name,796                                    VariableList &variable_list) {797    size_t old_size = variable_list.GetSize();798    Target *target = static_cast<Target *>(baton);799    if (target)800      target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,801                                              variable_list);802    return variable_list.GetSize() - old_size;803  }804 805  Options *GetOptions() override { return &m_option_group; }806 807protected:808  void DumpGlobalVariableList(const ExecutionContext &exe_ctx,809                              const SymbolContext &sc,810                              const VariableList &variable_list,811                              CommandReturnObject &result) {812    Stream &s = result.GetOutputStream();813    if (variable_list.Empty())814      return;815    if (sc.module_sp) {816      if (sc.comp_unit) {817        s.Format("Global variables for {0} in {1}:\n",818                 sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());819      } else {820        s.Printf("Global variables for %s\n",821                 sc.module_sp->GetFileSpec().GetPath().c_str());822      }823    } else if (sc.comp_unit) {824      s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());825    }826 827    for (VariableSP var_sp : variable_list) {828      if (!var_sp)829        continue;830      ValueObjectSP valobj_sp(ValueObjectVariable::Create(831          exe_ctx.GetBestExecutionContextScope(), var_sp));832 833      if (valobj_sp) {834        result.GetValueObjectList().Append(valobj_sp);835        DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());836      }837    }838  }839 840  void DoExecute(Args &args, CommandReturnObject &result) override {841    Target *target = m_exe_ctx.GetTargetPtr();842    const size_t argc = args.GetArgumentCount();843 844    if (argc > 0) {845      for (const Args::ArgEntry &arg : args) {846        VariableList variable_list;847        ValueObjectList valobj_list;848 849        size_t matches = 0;850        bool use_var_name = false;851        if (m_option_variable.use_regex) {852          RegularExpression regex(arg.ref());853          if (!regex.IsValid()) {854            result.GetErrorStream().Printf(855                "error: invalid regular expression: '%s'\n", arg.c_str());856            return;857          }858          use_var_name = true;859          target->GetImages().FindGlobalVariables(regex, UINT32_MAX,860                                                  variable_list);861          matches = variable_list.GetSize();862        } else {863          Status error(Variable::GetValuesForVariableExpressionPath(864              arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),865              GetVariableCallback, target, variable_list, valobj_list));866          matches = variable_list.GetSize();867        }868 869        if (matches == 0) {870          result.AppendErrorWithFormat("can't find global variable '%s'",871                                       arg.c_str());872          return;873        } else {874          for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {875            VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));876            if (var_sp) {877              ValueObjectSP valobj_sp(878                  valobj_list.GetValueObjectAtIndex(global_idx));879              if (!valobj_sp)880                valobj_sp = ValueObjectVariable::Create(881                    m_exe_ctx.GetBestExecutionContextScope(), var_sp);882 883              if (valobj_sp)884                DumpValueObject(result.GetOutputStream(), var_sp, valobj_sp,885                                use_var_name ? var_sp->GetName().GetCString()886                                             : arg.c_str());887            }888          }889        }890      }891    } else {892      const FileSpecList &compile_units =893          m_option_compile_units.GetOptionValue().GetCurrentValue();894      const FileSpecList &shlibs =895          m_option_shared_libraries.GetOptionValue().GetCurrentValue();896      SymbolContextList sc_list;897      const size_t num_compile_units = compile_units.GetSize();898      const size_t num_shlibs = shlibs.GetSize();899      if (num_compile_units == 0 && num_shlibs == 0) {900        bool success = false;901        StackFrame *frame = m_exe_ctx.GetFramePtr();902        CompileUnit *comp_unit = nullptr;903        if (frame) {904          SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);905          comp_unit = sc.comp_unit;906          if (sc.comp_unit) {907            const bool can_create = true;908            VariableListSP comp_unit_varlist_sp(909                sc.comp_unit->GetVariableList(can_create));910            if (comp_unit_varlist_sp) {911              size_t count = comp_unit_varlist_sp->GetSize();912              if (count > 0) {913                DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,914                                       result);915                success = true;916              }917            }918          }919        }920        if (!success) {921          if (frame) {922            if (comp_unit)923              result.AppendErrorWithFormatv(924                  "no global variables in current compile unit: {0}\n",925                  comp_unit->GetPrimaryFile());926            else927              result.AppendErrorWithFormat(928                  "no debug information for frame %u\n",929                  frame->GetFrameIndex());930          } else931            result.AppendError("'target variable' takes one or more global "932                               "variable names as arguments\n");933        }934      } else {935        SymbolContextList sc_list;936        // We have one or more compile unit or shlib937        if (num_shlibs > 0) {938          for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {939            const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));940            ModuleSpec module_spec(module_file);941 942            ModuleSP module_sp(943                target->GetImages().FindFirstModule(module_spec));944            if (module_sp) {945              if (num_compile_units > 0) {946                for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)947                  module_sp->FindCompileUnits(948                      compile_units.GetFileSpecAtIndex(cu_idx), sc_list);949              } else {950                SymbolContext sc;951                sc.module_sp = module_sp;952                sc_list.Append(sc);953              }954            } else {955              // Didn't find matching shlib/module in target...956              result.AppendErrorWithFormat(957                  "target doesn't contain the specified shared library: %s\n",958                  module_file.GetPath().c_str());959            }960          }961        } else {962          // No shared libraries, we just want to find globals for the compile963          // units files that were specified964          for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)965            target->GetImages().FindCompileUnits(966                compile_units.GetFileSpecAtIndex(cu_idx), sc_list);967        }968 969        for (const SymbolContext &sc : sc_list) {970          if (sc.comp_unit) {971            const bool can_create = true;972            VariableListSP comp_unit_varlist_sp(973                sc.comp_unit->GetVariableList(can_create));974            if (comp_unit_varlist_sp)975              DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,976                                     result);977          } else if (sc.module_sp) {978            // Get all global variables for this module979            lldb_private::RegularExpression all_globals_regex(980                llvm::StringRef(".")); // Any global with at least one character981            VariableList variable_list;982            sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,983                                              variable_list);984            DumpGlobalVariableList(m_exe_ctx, sc, variable_list, result);985          }986        }987      }988    }989 990    m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),991                                           m_cmd_name);992  }993 994  OptionGroupOptions m_option_group;995  OptionGroupVariable m_option_variable;996  OptionGroupFormat m_option_format;997  OptionGroupFileList m_option_compile_units;998  OptionGroupFileList m_option_shared_libraries;999  OptionGroupValueObjectDisplay m_varobj_options;1000};1001 1002#pragma mark CommandObjectTargetModulesSearchPathsAdd1003 1004class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {1005public:1006  CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)1007      : CommandObjectParsed(interpreter, "target modules search-paths add",1008                            "Add new image search paths substitution pairs to "1009                            "the current target.",1010                            nullptr, eCommandRequiresTarget) {1011    CommandArgumentEntry arg;1012    CommandArgumentData old_prefix_arg;1013    CommandArgumentData new_prefix_arg;1014 1015    // Define the first variant of this arg pair.1016    old_prefix_arg.arg_type = eArgTypeOldPathPrefix;1017    old_prefix_arg.arg_repetition = eArgRepeatPairPlus;1018 1019    // Define the first variant of this arg pair.1020    new_prefix_arg.arg_type = eArgTypeNewPathPrefix;1021    new_prefix_arg.arg_repetition = eArgRepeatPairPlus;1022 1023    // There are two required arguments that must always occur together, i.e.1024    // an argument "pair".  Because they must always occur together, they are1025    // treated as two variants of one argument rather than two independent1026    // arguments.  Push them both into the first argument position for1027    // m_arguments...1028 1029    arg.push_back(old_prefix_arg);1030    arg.push_back(new_prefix_arg);1031 1032    m_arguments.push_back(arg);1033  }1034 1035  ~CommandObjectTargetModulesSearchPathsAdd() override = default;1036 1037protected:1038  void DoExecute(Args &command, CommandReturnObject &result) override {1039    Target &target = GetTarget();1040    const size_t argc = command.GetArgumentCount();1041    if (argc & 1) {1042      result.AppendError("add requires an even number of arguments\n");1043    } else {1044      for (size_t i = 0; i < argc; i += 2) {1045        const char *from = command.GetArgumentAtIndex(i);1046        const char *to = command.GetArgumentAtIndex(i + 1);1047 1048        if (from[0] && to[0]) {1049          Log *log = GetLog(LLDBLog::Host);1050          if (log) {1051            LLDB_LOGF(log,1052                      "target modules search path adding ImageSearchPath "1053                      "pair: '%s' -> '%s'",1054                      from, to);1055          }1056          bool last_pair = ((argc - i) == 2);1057          target.GetImageSearchPathList().Append(1058              from, to, last_pair); // Notify if this is the last pair1059          result.SetStatus(eReturnStatusSuccessFinishNoResult);1060        } else {1061          if (from[0])1062            result.AppendError("<path-prefix> can't be empty\n");1063          else1064            result.AppendError("<new-path-prefix> can't be empty\n");1065        }1066      }1067    }1068  }1069};1070 1071#pragma mark CommandObjectTargetModulesSearchPathsClear1072 1073class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {1074public:1075  CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)1076      : CommandObjectParsed(interpreter, "target modules search-paths clear",1077                            "Clear all current image search path substitution "1078                            "pairs from the current target.",1079                            "target modules search-paths clear",1080                            eCommandRequiresTarget) {}1081 1082  ~CommandObjectTargetModulesSearchPathsClear() override = default;1083 1084protected:1085  void DoExecute(Args &command, CommandReturnObject &result) override {1086    Target &target = GetTarget();1087    bool notify = true;1088    target.GetImageSearchPathList().Clear(notify);1089    result.SetStatus(eReturnStatusSuccessFinishNoResult);1090  }1091};1092 1093#pragma mark CommandObjectTargetModulesSearchPathsInsert1094 1095class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {1096public:1097  CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)1098      : CommandObjectParsed(interpreter, "target modules search-paths insert",1099                            "Insert a new image search path substitution pair "1100                            "into the current target at the specified index.",1101                            nullptr, eCommandRequiresTarget) {1102    CommandArgumentEntry arg1;1103    CommandArgumentEntry arg2;1104    CommandArgumentData index_arg;1105    CommandArgumentData old_prefix_arg;1106    CommandArgumentData new_prefix_arg;1107 1108    // Define the first and only variant of this arg.1109    index_arg.arg_type = eArgTypeIndex;1110    index_arg.arg_repetition = eArgRepeatPlain;1111 1112    // Put the one and only variant into the first arg for m_arguments:1113    arg1.push_back(index_arg);1114 1115    // Define the first variant of this arg pair.1116    old_prefix_arg.arg_type = eArgTypeOldPathPrefix;1117    old_prefix_arg.arg_repetition = eArgRepeatPairPlus;1118 1119    // Define the first variant of this arg pair.1120    new_prefix_arg.arg_type = eArgTypeNewPathPrefix;1121    new_prefix_arg.arg_repetition = eArgRepeatPairPlus;1122 1123    // There are two required arguments that must always occur together, i.e.1124    // an argument "pair".  Because they must always occur together, they are1125    // treated as two variants of one argument rather than two independent1126    // arguments.  Push them both into the same argument position for1127    // m_arguments...1128 1129    arg2.push_back(old_prefix_arg);1130    arg2.push_back(new_prefix_arg);1131 1132    // Add arguments to m_arguments.1133    m_arguments.push_back(arg1);1134    m_arguments.push_back(arg2);1135  }1136 1137  ~CommandObjectTargetModulesSearchPathsInsert() override = default;1138 1139  void1140  HandleArgumentCompletion(CompletionRequest &request,1141                           OptionElementVector &opt_element_vector) override {1142    if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)1143      return;1144 1145    Target *target = m_exe_ctx.GetTargetPtr();1146    const PathMappingList &list = target->GetImageSearchPathList();1147    const size_t num = list.GetSize();1148    ConstString old_path, new_path;1149    for (size_t i = 0; i < num; ++i) {1150      if (!list.GetPathsAtIndex(i, old_path, new_path))1151        break;1152      StreamString strm;1153      strm << old_path << " -> " << new_path;1154      request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());1155    }1156  }1157 1158protected:1159  void DoExecute(Args &command, CommandReturnObject &result) override {1160    Target &target = GetTarget();1161    size_t argc = command.GetArgumentCount();1162    // check for at least 3 arguments and an odd number of parameters1163    if (argc >= 3 && argc & 1) {1164      uint32_t insert_idx;1165 1166      if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {1167        result.AppendErrorWithFormat(1168            "<index> parameter is not an integer: '%s'.\n",1169            command.GetArgumentAtIndex(0));1170        return;1171      }1172 1173      // shift off the index1174      command.Shift();1175      argc = command.GetArgumentCount();1176 1177      for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {1178        const char *from = command.GetArgumentAtIndex(i);1179        const char *to = command.GetArgumentAtIndex(i + 1);1180 1181        if (from[0] && to[0]) {1182          bool last_pair = ((argc - i) == 2);1183          target.GetImageSearchPathList().Insert(from, to, insert_idx,1184                                                 last_pair);1185          result.SetStatus(eReturnStatusSuccessFinishNoResult);1186        } else {1187          if (from[0])1188            result.AppendError("<path-prefix> can't be empty\n");1189          else1190            result.AppendError("<new-path-prefix> can't be empty\n");1191          return;1192        }1193      }1194    } else {1195      result.AppendError("insert requires at least three arguments\n");1196    }1197  }1198};1199 1200#pragma mark CommandObjectTargetModulesSearchPathsList1201 1202class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {1203public:1204  CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)1205      : CommandObjectParsed(interpreter, "target modules search-paths list",1206                            "List all current image search path substitution "1207                            "pairs in the current target.",1208                            "target modules search-paths list",1209                            eCommandRequiresTarget) {}1210 1211  ~CommandObjectTargetModulesSearchPathsList() override = default;1212 1213protected:1214  void DoExecute(Args &command, CommandReturnObject &result) override {1215    Target &target = GetTarget();1216    target.GetImageSearchPathList().Dump(&result.GetOutputStream());1217    result.SetStatus(eReturnStatusSuccessFinishResult);1218  }1219};1220 1221#pragma mark CommandObjectTargetModulesSearchPathsQuery1222 1223class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {1224public:1225  CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)1226      : CommandObjectParsed(1227            interpreter, "target modules search-paths query",1228            "Transform a path using the first applicable image search path.",1229            nullptr, eCommandRequiresTarget) {1230    AddSimpleArgumentList(eArgTypeDirectoryName);1231  }1232 1233  ~CommandObjectTargetModulesSearchPathsQuery() override = default;1234 1235protected:1236  void DoExecute(Args &command, CommandReturnObject &result) override {1237    Target &target = GetTarget();1238    if (command.GetArgumentCount() != 1) {1239      result.AppendError("query requires one argument\n");1240      return;1241    }1242 1243    ConstString orig(command.GetArgumentAtIndex(0));1244    ConstString transformed;1245    if (target.GetImageSearchPathList().RemapPath(orig, transformed))1246      result.GetOutputStream().Printf("%s\n", transformed.GetCString());1247    else1248      result.GetOutputStream().Printf("%s\n", orig.GetCString());1249 1250    result.SetStatus(eReturnStatusSuccessFinishResult);1251  }1252};1253 1254// Static Helper functions1255static void DumpModuleArchitecture(Stream &strm, Module *module,1256                                   bool full_triple, uint32_t width) {1257  if (module) {1258    StreamString arch_strm;1259 1260    if (full_triple)1261      module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());1262    else1263      arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());1264    std::string arch_str = std::string(arch_strm.GetString());1265 1266    if (width)1267      strm.Printf("%-*s", width, arch_str.c_str());1268    else1269      strm.PutCString(arch_str);1270  }1271}1272 1273static void DumpModuleUUID(Stream &strm, Module *module) {1274  if (module && module->GetUUID().IsValid())1275    module->GetUUID().Dump(strm);1276  else1277    strm.PutCString("                                    ");1278}1279 1280static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,1281                                         Stream &strm, Module *module,1282                                         const FileSpec &file_spec,1283                                         lldb::DescriptionLevel desc_level) {1284  uint32_t num_matches = 0;1285  if (module) {1286    SymbolContextList sc_list;1287    num_matches = module->ResolveSymbolContextsForFileSpec(1288        file_spec, 0, false, eSymbolContextCompUnit, sc_list);1289 1290    bool first_module = true;1291    for (const SymbolContext &sc : sc_list) {1292      if (!first_module)1293        strm << "\n\n";1294 1295      strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"1296           << module->GetFileSpec().GetFilename() << "\n";1297      LineTable *line_table = sc.comp_unit->GetLineTable();1298      if (line_table)1299        line_table->GetDescription(1300            &strm, interpreter.GetExecutionContext().GetTargetPtr(),1301            desc_level);1302      else1303        strm << "No line table";1304 1305      first_module = false;1306    }1307  }1308  return num_matches;1309}1310 1311static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,1312                         uint32_t width) {1313  if (file_spec_ptr) {1314    if (width > 0) {1315      std::string fullpath = file_spec_ptr->GetPath();1316      strm.Printf("%-*s", width, fullpath.c_str());1317      return;1318    } else {1319      file_spec_ptr->Dump(strm.AsRawOstream());1320      return;1321    }1322  }1323  // Keep the width spacing correct if things go wrong...1324  if (width > 0)1325    strm.Printf("%-*s", width, "");1326}1327 1328static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,1329                          uint32_t width) {1330  if (file_spec_ptr) {1331    if (width > 0)1332      strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));1333    else1334      file_spec_ptr->GetDirectory().Dump(&strm);1335    return;1336  }1337  // Keep the width spacing correct if things go wrong...1338  if (width > 0)1339    strm.Printf("%-*s", width, "");1340}1341 1342static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,1343                         uint32_t width) {1344  if (file_spec_ptr) {1345    if (width > 0)1346      strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));1347    else1348      file_spec_ptr->GetFilename().Dump(&strm);1349    return;1350  }1351  // Keep the width spacing correct if things go wrong...1352  if (width > 0)1353    strm.Printf("%-*s", width, "");1354}1355 1356static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {1357  std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());1358  const size_t num_modules = module_list.GetSize();1359  if (num_modules == 0)1360    return 0;1361 1362  size_t num_dumped = 0;1363  strm.Format("Dumping headers for {0} module(s).\n", num_modules);1364  strm.IndentMore();1365  for (ModuleSP module_sp : module_list.ModulesNoLocking()) {1366    if (module_sp) {1367      if (num_dumped++ > 0) {1368        strm.EOL();1369        strm.EOL();1370      }1371      ObjectFile *objfile = module_sp->GetObjectFile();1372      if (objfile)1373        objfile->Dump(&strm);1374      else {1375        strm.Format("No object file for module: {0:F}\n",1376                    module_sp->GetFileSpec());1377      }1378    }1379  }1380  strm.IndentLess();1381  return num_dumped;1382}1383 1384static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,1385                             Module *module, SortOrder sort_order,1386                             Mangled::NamePreference name_preference) {1387  if (!module)1388    return;1389  if (Symtab *symtab = module->GetSymtab())1390    symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),1391                 sort_order, name_preference);1392}1393 1394static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,1395                               Module *module) {1396  if (module) {1397    SectionList *section_list = module->GetSectionList();1398    if (section_list) {1399      strm.Printf("Sections for '%s' (%s):\n",1400                  module->GetSpecificationDescription().c_str(),1401                  module->GetArchitecture().GetArchitectureName());1402      section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,1403                         interpreter.GetExecutionContext().GetTargetPtr(), true,1404                         UINT32_MAX);1405    }1406  }1407}1408 1409static bool DumpModuleSymbolFile(Stream &strm, Module *module) {1410  if (module) {1411    if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {1412      symbol_file->Dump(strm);1413      return true;1414    }1415  }1416  return false;1417}1418 1419static bool GetSeparateDebugInfoList(StructuredData::Array &list,1420                                     Module *module, bool errors_only,1421                                     bool load_all_debug_info) {1422  if (module) {1423    if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) {1424      StructuredData::Dictionary d;1425      if (symbol_file->GetSeparateDebugInfo(d, errors_only,1426                                            load_all_debug_info)) {1427        list.AddItem(1428            std::make_shared<StructuredData::Dictionary>(std::move(d)));1429        return true;1430      }1431    }1432  }1433  return false;1434}1435 1436static void DumpDwoFilesTable(Stream &strm,1437                              StructuredData::Array &dwo_listings) {1438  strm.PutCString("Dwo ID             Err Dwo Path");1439  strm.EOL();1440  strm.PutCString(1441      "------------------ --- -----------------------------------------");1442  strm.EOL();1443  dwo_listings.ForEach([&strm](StructuredData::Object *dwo) {1444    StructuredData::Dictionary *dict = dwo->GetAsDictionary();1445    if (!dict)1446      return false;1447 1448    uint64_t dwo_id;1449    if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id))1450      strm.Printf("0x%16.16" PRIx64 " ", dwo_id);1451    else1452      strm.Printf("0x???????????????? ");1453 1454    llvm::StringRef error;1455    if (dict->GetValueForKeyAsString("error", error))1456      strm << "E   " << error;1457    else {1458      llvm::StringRef resolved_dwo_path;1459      if (dict->GetValueForKeyAsString("resolved_dwo_path",1460                                       resolved_dwo_path)) {1461        strm << "    " << resolved_dwo_path;1462        if (resolved_dwo_path.ends_with(".dwp")) {1463          llvm::StringRef dwo_name;1464          if (dict->GetValueForKeyAsString("dwo_name", dwo_name))1465            strm << "(" << dwo_name << ")";1466        }1467      }1468    }1469    strm.EOL();1470    return true;1471  });1472}1473 1474static void DumpOsoFilesTable(Stream &strm,1475                              StructuredData::Array &oso_listings) {1476  strm.PutCString("Mod Time           Err Oso Path");1477  strm.EOL();1478  strm.PutCString("------------------ --- ---------------------");1479  strm.EOL();1480  oso_listings.ForEach([&strm](StructuredData::Object *oso) {1481    StructuredData::Dictionary *dict = oso->GetAsDictionary();1482    if (!dict)1483      return false;1484 1485    uint32_t oso_mod_time;1486    if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time))1487      strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time);1488 1489    llvm::StringRef error;1490    if (dict->GetValueForKeyAsString("error", error))1491      strm << "E   " << error;1492    else {1493      llvm::StringRef oso_path;1494      if (dict->GetValueForKeyAsString("oso_path", oso_path))1495        strm << "    " << oso_path;1496    }1497    strm.EOL();1498    return true;1499  });1500}1501 1502static void1503DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,1504            bool verbose, bool all_ranges, Stream &strm,1505            std::optional<Stream::HighlightSettings> settings = std::nullopt) {1506  strm.IndentMore();1507  strm.Indent("    Address: ");1508  so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);1509  strm.PutCString(" (");1510  so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);1511  strm.PutCString(")\n");1512  strm.Indent("    Summary: ");1513  const uint32_t save_indent = strm.GetIndentLevel();1514  strm.SetIndentLevel(save_indent + 13);1515  so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,1516               Address::DumpStyleInvalid, UINT32_MAX, false, settings);1517  strm.SetIndentLevel(save_indent);1518  // Print out detailed address information when verbose is enabled1519  if (verbose) {1520    strm.EOL();1521    so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,1522                 Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);1523  }1524  strm.IndentLess();1525}1526 1527static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,1528                                  Module *module, uint32_t resolve_mask,1529                                  lldb::addr_t raw_addr, lldb::addr_t offset,1530                                  bool verbose, bool all_ranges) {1531  if (module) {1532    lldb::addr_t addr = raw_addr - offset;1533    Address so_addr;1534    SymbolContext sc;1535    Target *target = interpreter.GetExecutionContext().GetTargetPtr();1536    if (target && target->HasLoadedSections()) {1537      if (!target->ResolveLoadAddress(addr, so_addr))1538        return false;1539      else if (so_addr.GetModule().get() != module)1540        return false;1541    } else {1542      if (!module->ResolveFileAddress(addr, so_addr))1543        return false;1544    }1545 1546    ExecutionContextScope *exe_scope =1547        interpreter.GetExecutionContext().GetBestExecutionContextScope();1548    DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);1549    return true;1550  }1551 1552  return false;1553}1554 1555static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,1556                                     Stream &strm, Module *module,1557                                     const char *name, bool name_is_regex,1558                                     bool verbose, bool all_ranges) {1559  if (!module)1560    return 0;1561 1562  Symtab *symtab = module->GetSymtab();1563  if (!symtab)1564    return 0;1565 1566  SymbolContext sc;1567  const bool use_color = interpreter.GetDebugger().GetUseColor();1568  std::vector<uint32_t> match_indexes;1569  ConstString symbol_name(name);1570  uint32_t num_matches = 0;1571  if (name_is_regex) {1572    RegularExpression name_regexp(symbol_name.GetStringRef());1573    num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(1574        name_regexp, eSymbolTypeAny, match_indexes);1575  } else {1576    num_matches =1577        symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);1578  }1579 1580  if (num_matches > 0) {1581    strm.Indent();1582    strm.Printf("%u symbols match %s'%s' in ", num_matches,1583                name_is_regex ? "the regular expression " : "", name);1584    DumpFullpath(strm, &module->GetFileSpec(), 0);1585    strm.PutCString(":\n");1586    strm.IndentMore();1587    Stream::HighlightSettings settings(1588        name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),1589        interpreter.GetDebugger().GetRegexMatchAnsiSuffix());1590    for (uint32_t i = 0; i < num_matches; ++i) {1591      Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);1592      if (symbol) {1593        if (symbol->ValueIsAddress()) {1594          DumpAddress(1595              interpreter.GetExecutionContext().GetBestExecutionContextScope(),1596              symbol->GetAddressRef(), verbose, all_ranges, strm,1597              use_color && name_is_regex1598                  ? std::optional<Stream::HighlightSettings>{settings}1599                  : std::nullopt);1600          strm.EOL();1601        } else {1602          strm.IndentMore();1603          strm.Indent("    Name: ");1604          strm.PutCStringColorHighlighted(1605              symbol->GetDisplayName().GetStringRef(),1606              use_color && name_is_regex1607                  ? std::optional<Stream::HighlightSettings>{settings}1608                  : std::nullopt);1609          strm.EOL();1610          strm.Indent("    Value: ");1611          strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());1612          if (symbol->GetByteSizeIsValid()) {1613            strm.Indent("    Size: ");1614            strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());1615          }1616          strm.IndentLess();1617        }1618      }1619    }1620    strm.IndentLess();1621  }1622  return num_matches;1623}1624 1625static void DumpSymbolContextList(1626    ExecutionContextScope *exe_scope, Stream &strm,1627    const SymbolContextList &sc_list, bool verbose, bool all_ranges,1628    std::optional<Stream::HighlightSettings> settings = std::nullopt) {1629  strm.IndentMore();1630  bool first_module = true;1631  for (const SymbolContext &sc : sc_list) {1632    if (!first_module)1633      strm.EOL();1634 1635    Address addr;1636    if (sc.line_entry.IsValid())1637      addr = sc.line_entry.range.GetBaseAddress();1638    else if (sc.block && sc.block->GetContainingInlinedBlock())1639      sc.block->GetContainingInlinedBlock()->GetStartAddress(addr);1640    else1641      addr = sc.GetFunctionOrSymbolAddress();1642 1643    DumpAddress(exe_scope, addr, verbose, all_ranges, strm, settings);1644    first_module = false;1645  }1646  strm.IndentLess();1647}1648 1649static size_t LookupFunctionInModule(CommandInterpreter &interpreter,1650                                     Stream &strm, Module *module,1651                                     const char *name, bool name_is_regex,1652                                     const ModuleFunctionSearchOptions &options,1653                                     bool verbose, bool all_ranges) {1654  if (module && name && name[0]) {1655    SymbolContextList sc_list;1656    size_t num_matches = 0;1657    if (name_is_regex) {1658      RegularExpression function_name_regex((llvm::StringRef(name)));1659      module->FindFunctions(function_name_regex, options, sc_list);1660    } else {1661      ConstString function_name(name);1662      module->FindFunctions(function_name, CompilerDeclContext(),1663                            eFunctionNameTypeAuto, options, sc_list);1664    }1665    num_matches = sc_list.GetSize();1666    if (num_matches) {1667      strm.Indent();1668      strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,1669                  num_matches > 1 ? "es" : "");1670      DumpFullpath(strm, &module->GetFileSpec(), 0);1671      strm.PutCString(":\n");1672      DumpSymbolContextList(1673          interpreter.GetExecutionContext().GetBestExecutionContextScope(),1674          strm, sc_list, verbose, all_ranges);1675    }1676    return num_matches;1677  }1678  return 0;1679}1680 1681static size_t LookupTypeInModule(Target *target,1682                                 CommandInterpreter &interpreter, Stream &strm,1683                                 Module *module, const char *name_cstr,1684                                 bool name_is_regex) {1685  if (module && name_cstr && name_cstr[0]) {1686    TypeQuery query(name_cstr);1687    TypeResults results;1688    module->FindTypes(query, results);1689 1690    TypeList type_list;1691    SymbolContext sc;1692    if (module)1693      sc.module_sp = module->shared_from_this();1694    // Sort the type results and put the results that matched in \a module1695    // first if \a module was specified.1696    sc.SortTypeList(results.GetTypeMap(), type_list);1697    if (type_list.Empty())1698      return 0;1699 1700    const uint64_t num_matches = type_list.GetSize();1701 1702    strm.Indent();1703    strm.Printf("%" PRIu64 " match%s found in ", num_matches,1704                num_matches > 1 ? "es" : "");1705    DumpFullpath(strm, &module->GetFileSpec(), 0);1706    strm.PutCString(":\n");1707    for (TypeSP type_sp : type_list.Types()) {1708      if (!type_sp)1709        continue;1710      // Resolve the clang type so that any forward references to types1711      // that haven't yet been parsed will get parsed.1712      type_sp->GetFullCompilerType();1713      type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);1714      // Print all typedef chains1715      TypeSP typedef_type_sp(type_sp);1716      TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());1717      while (typedefed_type_sp) {1718        strm.EOL();1719        strm.Printf("     typedef '%s': ",1720                    typedef_type_sp->GetName().GetCString());1721        typedefed_type_sp->GetFullCompilerType();1722        typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,1723                                          target);1724        typedef_type_sp = typedefed_type_sp;1725        typedefed_type_sp = typedef_type_sp->GetTypedefType();1726      }1727      strm.EOL();1728    }1729    return type_list.GetSize();1730  }1731  return 0;1732}1733 1734static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,1735                             Stream &strm, Module &module,1736                             const char *name_cstr, bool name_is_regex) {1737  TypeQuery query(name_cstr);1738  TypeResults results;1739  module.FindTypes(query, results);1740  TypeList type_list;1741  SymbolContext sc;1742  sc.module_sp = module.shared_from_this();1743  sc.SortTypeList(results.GetTypeMap(), type_list);1744  if (type_list.Empty())1745    return 0;1746 1747  strm.Indent();1748  strm.PutCString("Best match found in ");1749  DumpFullpath(strm, &module.GetFileSpec(), 0);1750  strm.PutCString(":\n");1751 1752  TypeSP type_sp(type_list.GetTypeAtIndex(0));1753  if (type_sp) {1754    // Resolve the clang type so that any forward references to types that1755    // haven't yet been parsed will get parsed.1756    type_sp->GetFullCompilerType();1757    type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);1758    // Print all typedef chains.1759    TypeSP typedef_type_sp(type_sp);1760    TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());1761    while (typedefed_type_sp) {1762      strm.EOL();1763      strm.Printf("     typedef '%s': ",1764                  typedef_type_sp->GetName().GetCString());1765      typedefed_type_sp->GetFullCompilerType();1766      typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,1767                                        target);1768      typedef_type_sp = typedefed_type_sp;1769      typedefed_type_sp = typedef_type_sp->GetTypedefType();1770    }1771  }1772  strm.EOL();1773  return type_list.GetSize();1774}1775 1776static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,1777                                          Stream &strm, Module *module,1778                                          const FileSpec &file_spec,1779                                          uint32_t line, bool check_inlines,1780                                          bool verbose, bool all_ranges) {1781  if (module && file_spec) {1782    SymbolContextList sc_list;1783    const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(1784        file_spec, line, check_inlines, eSymbolContextEverything, sc_list);1785    if (num_matches > 0) {1786      strm.Indent();1787      strm.Printf("%u match%s found in ", num_matches,1788                  num_matches > 1 ? "es" : "");1789      strm << file_spec;1790      if (line > 0)1791        strm.Printf(":%u", line);1792      strm << " in ";1793      DumpFullpath(strm, &module->GetFileSpec(), 0);1794      strm.PutCString(":\n");1795      DumpSymbolContextList(1796          interpreter.GetExecutionContext().GetBestExecutionContextScope(),1797          strm, sc_list, verbose, all_ranges);1798      return num_matches;1799    }1800  }1801  return 0;1802}1803 1804static size_t FindModulesByName(Target *target, const char *module_name,1805                                ModuleList &module_list,1806                                bool check_global_list) {1807  FileSpec module_file_spec(module_name);1808  ModuleSpec module_spec(module_file_spec);1809 1810  const size_t initial_size = module_list.GetSize();1811 1812  if (check_global_list) {1813    // Check the global list1814    std::lock_guard<std::recursive_mutex> guard(1815        Module::GetAllocationModuleCollectionMutex());1816    const size_t num_modules = Module::GetNumberAllocatedModules();1817    ModuleSP module_sp;1818    for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {1819      Module *module = Module::GetAllocatedModuleAtIndex(image_idx);1820 1821      if (module) {1822        if (module->MatchesModuleSpec(module_spec)) {1823          module_sp = module->shared_from_this();1824          module_list.AppendIfNeeded(module_sp);1825        }1826      }1827    }1828  } else {1829    if (target) {1830      target->GetImages().FindModules(module_spec, module_list);1831      const size_t num_matches = module_list.GetSize();1832 1833      // Not found in our module list for our target, check the main shared1834      // module list in case it is a extra file used somewhere else1835      if (num_matches == 0) {1836        module_spec.GetArchitecture() = target->GetArchitecture();1837        ModuleList::FindSharedModules(module_spec, module_list);1838      }1839    } else {1840      ModuleList::FindSharedModules(module_spec, module_list);1841    }1842  }1843 1844  return module_list.GetSize() - initial_size;1845}1846 1847#pragma mark CommandObjectTargetModulesModuleAutoComplete1848 1849// A base command object class that can auto complete with module file1850// paths1851 1852class CommandObjectTargetModulesModuleAutoComplete1853    : public CommandObjectParsed {1854public:1855  CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,1856                                               const char *name,1857                                               const char *help,1858                                               const char *syntax,1859                                               uint32_t flags = 0)1860      : CommandObjectParsed(interpreter, name, help, syntax, flags) {1861    AddSimpleArgumentList(eArgTypeFilename, eArgRepeatStar);1862  }1863 1864  ~CommandObjectTargetModulesModuleAutoComplete() override = default;1865 1866  void1867  HandleArgumentCompletion(CompletionRequest &request,1868                           OptionElementVector &opt_element_vector) override {1869    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(1870        GetCommandInterpreter(), lldb::eModuleCompletion, request, nullptr);1871  }1872};1873 1874#pragma mark CommandObjectTargetModulesSourceFileAutoComplete1875 1876// A base command object class that can auto complete with module source1877// file paths1878 1879class CommandObjectTargetModulesSourceFileAutoComplete1880    : public CommandObjectParsed {1881public:1882  CommandObjectTargetModulesSourceFileAutoComplete(1883      CommandInterpreter &interpreter, const char *name, const char *help,1884      const char *syntax, uint32_t flags)1885      : CommandObjectParsed(interpreter, name, help, syntax, flags) {1886    AddSimpleArgumentList(eArgTypeSourceFile, eArgRepeatPlus);1887  }1888 1889  ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;1890 1891  void1892  HandleArgumentCompletion(CompletionRequest &request,1893                           OptionElementVector &opt_element_vector) override {1894    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(1895        GetCommandInterpreter(), lldb::eSourceFileCompletion, request, nullptr);1896  }1897};1898 1899#pragma mark CommandObjectTargetModulesDumpObjfile1900 1901class CommandObjectTargetModulesDumpObjfile1902    : public CommandObjectTargetModulesModuleAutoComplete {1903public:1904  CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)1905      : CommandObjectTargetModulesModuleAutoComplete(1906            interpreter, "target modules dump objfile",1907            "Dump the object file headers from one or more target modules.",1908            nullptr, eCommandRequiresTarget) {}1909 1910  ~CommandObjectTargetModulesDumpObjfile() override = default;1911 1912protected:1913  void DoExecute(Args &command, CommandReturnObject &result) override {1914    Target &target = GetTarget();1915 1916    uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();1917    result.GetOutputStream().SetAddressByteSize(addr_byte_size);1918    result.GetErrorStream().SetAddressByteSize(addr_byte_size);1919 1920    size_t num_dumped = 0;1921    if (command.GetArgumentCount() == 0) {1922      // Dump all headers for all modules images1923      num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),1924                                            target.GetImages());1925      if (num_dumped == 0) {1926        result.AppendError("the target has no associated executable images");1927      }1928    } else {1929      // Find the modules that match the basename or full path.1930      ModuleList module_list;1931      const char *arg_cstr;1932      for (int arg_idx = 0;1933           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;1934           ++arg_idx) {1935        size_t num_matched =1936            FindModulesByName(&target, arg_cstr, module_list, true);1937        if (num_matched == 0) {1938          result.AppendWarningWithFormat(1939              "Unable to find an image that matches '%s'.\n", arg_cstr);1940        }1941      }1942      // Dump all the modules we found.1943      num_dumped =1944          DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);1945    }1946 1947    if (num_dumped > 0) {1948      result.SetStatus(eReturnStatusSuccessFinishResult);1949    } else {1950      result.AppendError("no matching executable images found");1951    }1952  }1953};1954 1955#define LLDB_OPTIONS_target_modules_dump_symtab1956#include "CommandOptions.inc"1957 1958class CommandObjectTargetModulesDumpSymtab1959    : public CommandObjectTargetModulesModuleAutoComplete {1960public:1961  CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)1962      : CommandObjectTargetModulesModuleAutoComplete(1963            interpreter, "target modules dump symtab",1964            "Dump the symbol table from one or more target modules.", nullptr,1965            eCommandRequiresTarget) {}1966 1967  ~CommandObjectTargetModulesDumpSymtab() override = default;1968 1969  Options *GetOptions() override { return &m_options; }1970 1971  class CommandOptions : public Options {1972  public:1973    CommandOptions() = default;1974 1975    ~CommandOptions() override = default;1976 1977    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,1978                          ExecutionContext *execution_context) override {1979      Status error;1980      const int short_option = m_getopt_table[option_idx].val;1981 1982      switch (short_option) {1983      case 'm':1984        m_prefer_mangled.SetCurrentValue(true);1985        m_prefer_mangled.SetOptionWasSet();1986        break;1987 1988      case 's':1989        m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(1990            option_arg, GetDefinitions()[option_idx].enum_values,1991            eSortOrderNone, error);1992        break;1993 1994      default:1995        llvm_unreachable("Unimplemented option");1996      }1997      return error;1998    }1999 2000    void OptionParsingStarting(ExecutionContext *execution_context) override {2001      m_sort_order = eSortOrderNone;2002      m_prefer_mangled.Clear();2003    }2004 2005    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {2006      return llvm::ArrayRef(g_target_modules_dump_symtab_options);2007    }2008 2009    SortOrder m_sort_order = eSortOrderNone;2010    OptionValueBoolean m_prefer_mangled = {false, false};2011  };2012 2013protected:2014  void DoExecute(Args &command, CommandReturnObject &result) override {2015    Target &target = GetTarget();2016    uint32_t num_dumped = 0;2017    Mangled::NamePreference name_preference =2018        (m_options.m_prefer_mangled ? Mangled::ePreferMangled2019                                    : Mangled::ePreferDemangled);2020 2021    uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();2022    result.GetOutputStream().SetAddressByteSize(addr_byte_size);2023    result.GetErrorStream().SetAddressByteSize(addr_byte_size);2024 2025    if (command.GetArgumentCount() == 0) {2026      // Dump all sections for all modules images2027      const ModuleList &module_list = target.GetImages();2028      std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());2029      const size_t num_modules = module_list.GetSize();2030      if (num_modules > 0) {2031        result.GetOutputStream().Format(2032            "Dumping symbol table for {0} modules.\n", num_modules);2033        for (ModuleSP module_sp : module_list.ModulesNoLocking()) {2034          if (num_dumped > 0) {2035            result.GetOutputStream().EOL();2036            result.GetOutputStream().EOL();2037          }2038          if (INTERRUPT_REQUESTED(GetDebugger(),2039                                  "Interrupted in dump all symtabs with {0} "2040                                  "of {1} dumped.", num_dumped, num_modules))2041            break;2042 2043          num_dumped++;2044          DumpModuleSymtab(m_interpreter, result.GetOutputStream(),2045                           module_sp.get(), m_options.m_sort_order,2046                           name_preference);2047        }2048      } else {2049        result.AppendError("the target has no associated executable images");2050        return;2051      }2052    } else {2053      // Dump specified images (by basename or fullpath)2054      const char *arg_cstr;2055      for (int arg_idx = 0;2056           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;2057           ++arg_idx) {2058        ModuleList module_list;2059        const size_t num_matches =2060            FindModulesByName(&target, arg_cstr, module_list, true);2061        if (num_matches > 0) {2062          for (ModuleSP module_sp : module_list.Modules()) {2063            if (module_sp) {2064              if (num_dumped > 0) {2065                result.GetOutputStream().EOL();2066                result.GetOutputStream().EOL();2067              }2068              if (INTERRUPT_REQUESTED(GetDebugger(),2069                    "Interrupted in dump symtab list with {0} of {1} dumped.",2070                    num_dumped, num_matches))2071                break;2072 2073              num_dumped++;2074              DumpModuleSymtab(m_interpreter, result.GetOutputStream(),2075                               module_sp.get(), m_options.m_sort_order,2076                               name_preference);2077            }2078          }2079        } else2080          result.AppendWarningWithFormat(2081              "Unable to find an image that matches '%s'.\n", arg_cstr);2082      }2083    }2084 2085    if (num_dumped > 0)2086      result.SetStatus(eReturnStatusSuccessFinishResult);2087    else {2088      result.AppendError("no matching executable images found");2089    }2090  }2091 2092  CommandOptions m_options;2093};2094 2095#pragma mark CommandObjectTargetModulesDumpSections2096 2097// Image section dumping command2098 2099class CommandObjectTargetModulesDumpSections2100    : public CommandObjectTargetModulesModuleAutoComplete {2101public:2102  CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)2103      : CommandObjectTargetModulesModuleAutoComplete(2104            interpreter, "target modules dump sections",2105            "Dump the sections from one or more target modules.",2106            //"target modules dump sections [<file1> ...]")2107            nullptr, eCommandRequiresTarget) {}2108 2109  ~CommandObjectTargetModulesDumpSections() override = default;2110 2111protected:2112  void DoExecute(Args &command, CommandReturnObject &result) override {2113    Target &target = GetTarget();2114    uint32_t num_dumped = 0;2115 2116    uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();2117    result.GetOutputStream().SetAddressByteSize(addr_byte_size);2118    result.GetErrorStream().SetAddressByteSize(addr_byte_size);2119 2120    if (command.GetArgumentCount() == 0) {2121      // Dump all sections for all modules images2122      const size_t num_modules = target.GetImages().GetSize();2123      if (num_modules == 0) {2124        result.AppendError("the target has no associated executable images");2125        return;2126      }2127 2128      result.GetOutputStream().Format("Dumping sections for {0} modules.\n",2129                                      num_modules);2130      for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {2131        if (INTERRUPT_REQUESTED(GetDebugger(),2132              "Interrupted in dump all sections with {0} of {1} dumped",2133              image_idx, num_modules))2134          break;2135 2136        num_dumped++;2137        DumpModuleSections(2138            m_interpreter, result.GetOutputStream(),2139            target.GetImages().GetModulePointerAtIndex(image_idx));2140      }2141    } else {2142      // Dump specified images (by basename or fullpath)2143      const char *arg_cstr;2144      for (int arg_idx = 0;2145           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;2146           ++arg_idx) {2147        ModuleList module_list;2148        const size_t num_matches =2149            FindModulesByName(&target, arg_cstr, module_list, true);2150        if (num_matches > 0) {2151          for (size_t i = 0; i < num_matches; ++i) {2152            if (INTERRUPT_REQUESTED(GetDebugger(),2153                  "Interrupted in dump section list with {0} of {1} dumped.",2154                  i, num_matches))2155              break;2156 2157            Module *module = module_list.GetModulePointerAtIndex(i);2158            if (module) {2159              num_dumped++;2160              DumpModuleSections(m_interpreter, result.GetOutputStream(),2161                                 module);2162            }2163          }2164        } else {2165          // Check the global list2166          std::lock_guard<std::recursive_mutex> guard(2167              Module::GetAllocationModuleCollectionMutex());2168 2169          result.AppendWarningWithFormat(2170              "Unable to find an image that matches '%s'.\n", arg_cstr);2171        }2172      }2173    }2174 2175    if (num_dumped > 0)2176      result.SetStatus(eReturnStatusSuccessFinishResult);2177    else {2178      result.AppendError("no matching executable images found");2179    }2180  }2181};2182 2183class CommandObjectTargetModulesDumpClangPCMInfo : public CommandObjectParsed {2184public:2185  CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter)2186      : CommandObjectParsed(2187            interpreter, "target modules dump pcm-info",2188            "Dump information about the given clang module (pcm).") {2189    // Take a single file argument.2190    AddSimpleArgumentList(eArgTypeFilename);2191  }2192 2193  ~CommandObjectTargetModulesDumpClangPCMInfo() override = default;2194 2195protected:2196  void DoExecute(Args &command, CommandReturnObject &result) override {2197    if (command.GetArgumentCount() != 1) {2198      result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",2199                                   m_cmd_name.c_str());2200      return;2201    }2202 2203    const char *pcm_path = command.GetArgumentAtIndex(0);2204    const FileSpec pcm_file{pcm_path};2205 2206    if (pcm_file.GetFileNameExtension() != ".pcm") {2207      result.AppendError("file must have a .pcm extension");2208      return;2209    }2210 2211    if (!FileSystem::Instance().Exists(pcm_file)) {2212      result.AppendError("pcm file does not exist");2213      return;2214    }2215 2216    const char *clang_args[] = {"clang", pcm_path};2217    clang::CompilerInstance compiler(clang::createInvocation(clang_args));2218    compiler.setVirtualFileSystem(2219        FileSystem::Instance().GetVirtualFileSystem());2220    compiler.createDiagnostics();2221 2222    // Pass empty deleter to not attempt to free memory that was allocated2223    // outside of the current scope, possibly statically.2224    std::shared_ptr<llvm::raw_ostream> Out(2225        &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});2226    clang::DumpModuleInfoAction dump_module_info(Out);2227    // DumpModuleInfoAction requires ObjectFilePCHContainerReader.2228    compiler.getPCHContainerOperations()->registerReader(2229        std::make_unique<clang::ObjectFilePCHContainerReader>());2230 2231    if (compiler.ExecuteAction(dump_module_info))2232      result.SetStatus(eReturnStatusSuccessFinishResult);2233  }2234};2235 2236#pragma mark CommandObjectTargetModulesDumpClangAST2237 2238// Clang AST dumping command2239 2240class CommandObjectTargetModulesDumpClangAST2241    : public CommandObjectTargetModulesModuleAutoComplete {2242public:2243  CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)2244      : CommandObjectTargetModulesModuleAutoComplete(2245            interpreter, "target modules dump ast",2246            "Dump the clang ast for a given module's symbol file.",2247            "target modules dump ast [--filter <name>] [<file1> ...]",2248            eCommandRequiresTarget),2249        m_filter(LLDB_OPT_SET_1, false, "filter", 'f', 0, eArgTypeName,2250                 "Dump only the decls whose names contain the specified filter "2251                 "string.",2252                 /*default_value=*/"") {2253    m_option_group.Append(&m_filter, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);2254    m_option_group.Finalize();2255  }2256 2257  Options *GetOptions() override { return &m_option_group; }2258 2259  ~CommandObjectTargetModulesDumpClangAST() override = default;2260 2261  OptionGroupOptions m_option_group;2262  OptionGroupString m_filter;2263 2264protected:2265  void DoExecute(Args &command, CommandReturnObject &result) override {2266    Target &target = GetTarget();2267 2268    const ModuleList &module_list = target.GetImages();2269    const size_t num_modules = module_list.GetSize();2270    if (num_modules == 0) {2271      result.AppendError("the target has no associated executable images");2272      return;2273    }2274 2275    llvm::StringRef filter = m_filter.GetOptionValue().GetCurrentValueAsRef();2276 2277    if (command.GetArgumentCount() == 0) {2278      // Dump all ASTs for all modules images2279      result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",2280                                      num_modules);2281      for (ModuleSP module_sp : module_list.ModulesNoLocking()) {2282        if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))2283          break;2284        if (SymbolFile *sf = module_sp->GetSymbolFile())2285          sf->DumpClangAST(result.GetOutputStream(), filter,2286                           GetCommandInterpreter().GetDebugger().GetUseColor());2287      }2288      result.SetStatus(eReturnStatusSuccessFinishResult);2289      return;2290    }2291 2292    // Dump specified ASTs (by basename or fullpath)2293    for (const Args::ArgEntry &arg : command.entries()) {2294      ModuleList module_list;2295      const size_t num_matches =2296          FindModulesByName(&target, arg.c_str(), module_list, true);2297      if (num_matches == 0) {2298        // Check the global list2299        std::lock_guard<std::recursive_mutex> guard(2300            Module::GetAllocationModuleCollectionMutex());2301 2302        result.AppendWarningWithFormat(2303            "Unable to find an image that matches '%s'.\n", arg.c_str());2304        continue;2305      }2306 2307      for (size_t i = 0; i < num_matches; ++i) {2308        if (INTERRUPT_REQUESTED(GetDebugger(),2309              "Interrupted in dump clang ast list with {0} of {1} dumped.",2310              i, num_matches))2311          break;2312 2313        Module *m = module_list.GetModulePointerAtIndex(i);2314        if (SymbolFile *sf = m->GetSymbolFile())2315          sf->DumpClangAST(result.GetOutputStream(), filter,2316                           GetCommandInterpreter().GetDebugger().GetUseColor());2317      }2318    }2319    result.SetStatus(eReturnStatusSuccessFinishResult);2320  }2321};2322 2323#pragma mark CommandObjectTargetModulesDumpSymfile2324 2325// Image debug symbol dumping command2326 2327class CommandObjectTargetModulesDumpSymfile2328    : public CommandObjectTargetModulesModuleAutoComplete {2329public:2330  CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)2331      : CommandObjectTargetModulesModuleAutoComplete(2332            interpreter, "target modules dump symfile",2333            "Dump the debug symbol file for one or more target modules.",2334            //"target modules dump symfile [<file1> ...]")2335            nullptr, eCommandRequiresTarget) {}2336 2337  ~CommandObjectTargetModulesDumpSymfile() override = default;2338 2339protected:2340  void DoExecute(Args &command, CommandReturnObject &result) override {2341    Target &target = GetTarget();2342    uint32_t num_dumped = 0;2343 2344    uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();2345    result.GetOutputStream().SetAddressByteSize(addr_byte_size);2346    result.GetErrorStream().SetAddressByteSize(addr_byte_size);2347 2348    if (command.GetArgumentCount() == 0) {2349      // Dump all sections for all modules images2350      const ModuleList &target_modules = target.GetImages();2351      std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());2352      const size_t num_modules = target_modules.GetSize();2353      if (num_modules == 0) {2354        result.AppendError("the target has no associated executable images");2355        return;2356      }2357      result.GetOutputStream().Format(2358          "Dumping debug symbols for {0} modules.\n", num_modules);2359      for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {2360        if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "2361                                "debug symbols with {0} of {1} modules dumped",2362                                 num_dumped, num_modules))2363          break;2364 2365        if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))2366          num_dumped++;2367      }2368    } else {2369      // Dump specified images (by basename or fullpath)2370      const char *arg_cstr;2371      for (int arg_idx = 0;2372           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;2373           ++arg_idx) {2374        ModuleList module_list;2375        const size_t num_matches =2376            FindModulesByName(&target, arg_cstr, module_list, true);2377        if (num_matches > 0) {2378          for (size_t i = 0; i < num_matches; ++i) {2379            if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "2380                                                   "of {1} requested modules",2381                                                   i, num_matches))2382              break;2383            Module *module = module_list.GetModulePointerAtIndex(i);2384            if (module) {2385              if (DumpModuleSymbolFile(result.GetOutputStream(), module))2386                num_dumped++;2387            }2388          }2389        } else2390          result.AppendWarningWithFormat(2391              "Unable to find an image that matches '%s'.\n", arg_cstr);2392      }2393    }2394 2395    if (num_dumped > 0)2396      result.SetStatus(eReturnStatusSuccessFinishResult);2397    else {2398      result.AppendError("no matching executable images found");2399    }2400  }2401};2402 2403#pragma mark CommandObjectTargetModulesDumpLineTable2404#define LLDB_OPTIONS_target_modules_dump2405#include "CommandOptions.inc"2406 2407// Image debug line table dumping command2408 2409class CommandObjectTargetModulesDumpLineTable2410    : public CommandObjectTargetModulesSourceFileAutoComplete {2411public:2412  CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)2413      : CommandObjectTargetModulesSourceFileAutoComplete(2414            interpreter, "target modules dump line-table",2415            "Dump the line table for one or more compilation units.", nullptr,2416            eCommandRequiresTarget) {}2417 2418  ~CommandObjectTargetModulesDumpLineTable() override = default;2419 2420  Options *GetOptions() override { return &m_options; }2421 2422protected:2423  void DoExecute(Args &command, CommandReturnObject &result) override {2424    Target *target = m_exe_ctx.GetTargetPtr();2425    uint32_t total_num_dumped = 0;2426 2427    uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();2428    result.GetOutputStream().SetAddressByteSize(addr_byte_size);2429    result.GetErrorStream().SetAddressByteSize(addr_byte_size);2430 2431    if (command.GetArgumentCount() == 0) {2432      result.AppendError("file option must be specified");2433      return;2434    } else {2435      // Dump specified images (by basename or fullpath)2436      const char *arg_cstr;2437      for (int arg_idx = 0;2438           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;2439           ++arg_idx) {2440        FileSpec file_spec(arg_cstr);2441 2442        const ModuleList &target_modules = target->GetImages();2443        std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());2444        size_t num_modules = target_modules.GetSize();2445        if (num_modules > 0) {2446          uint32_t num_dumped = 0;2447          for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {2448            if (INTERRUPT_REQUESTED(GetDebugger(),2449                                    "Interrupted in dump all line tables with "2450                                    "{0} of {1} dumped", num_dumped,2451                                    num_modules))2452              break;2453 2454            if (DumpCompileUnitLineTable(2455                    m_interpreter, result.GetOutputStream(), module_sp.get(),2456                    file_spec,2457                    m_options.m_verbose ? eDescriptionLevelFull2458                                        : eDescriptionLevelBrief))2459              num_dumped++;2460          }2461          if (num_dumped == 0)2462            result.AppendWarningWithFormat(2463                "No source filenames matched '%s'.\n", arg_cstr);2464          else2465            total_num_dumped += num_dumped;2466        }2467      }2468    }2469 2470    if (total_num_dumped > 0)2471      result.SetStatus(eReturnStatusSuccessFinishResult);2472    else {2473      result.AppendError("no source filenames matched any command arguments");2474    }2475  }2476 2477  class CommandOptions : public Options {2478  public:2479    CommandOptions() { OptionParsingStarting(nullptr); }2480 2481    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,2482                          ExecutionContext *execution_context) override {2483      assert(option_idx == 0 && "We only have one option.");2484      m_verbose = true;2485 2486      return Status();2487    }2488 2489    void OptionParsingStarting(ExecutionContext *execution_context) override {2490      m_verbose = false;2491    }2492 2493    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {2494      return llvm::ArrayRef(g_target_modules_dump_options);2495    }2496 2497    bool m_verbose;2498  };2499 2500  CommandOptions m_options;2501};2502 2503#pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles2504#define LLDB_OPTIONS_target_modules_dump_separate_debug_info2505#include "CommandOptions.inc"2506 2507// Image debug separate debug info dumping command2508 2509class CommandObjectTargetModulesDumpSeparateDebugInfoFiles2510    : public CommandObjectTargetModulesModuleAutoComplete {2511public:2512  CommandObjectTargetModulesDumpSeparateDebugInfoFiles(2513      CommandInterpreter &interpreter)2514      : CommandObjectTargetModulesModuleAutoComplete(2515            interpreter, "target modules dump separate-debug-info",2516            "List the separate debug info symbol files for one or more target "2517            "modules.",2518            nullptr, eCommandRequiresTarget) {}2519 2520  ~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override = default;2521 2522  Options *GetOptions() override { return &m_options; }2523 2524  class CommandOptions : public Options {2525  public:2526    CommandOptions() = default;2527 2528    ~CommandOptions() override = default;2529 2530    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,2531                          ExecutionContext *execution_context) override {2532      Status error;2533      const int short_option = m_getopt_table[option_idx].val;2534 2535      switch (short_option) {2536      case 'f':2537        m_load_all_debug_info.SetCurrentValue(true);2538        m_load_all_debug_info.SetOptionWasSet();2539        break;2540      case 'j':2541        m_json.SetCurrentValue(true);2542        m_json.SetOptionWasSet();2543        break;2544      case 'e':2545        m_errors_only.SetCurrentValue(true);2546        m_errors_only.SetOptionWasSet();2547        break;2548      default:2549        llvm_unreachable("Unimplemented option");2550      }2551      return error;2552    }2553 2554    void OptionParsingStarting(ExecutionContext *execution_context) override {2555      m_json.Clear();2556      m_errors_only.Clear();2557      m_load_all_debug_info.Clear();2558    }2559 2560    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {2561      return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options);2562    }2563 2564    OptionValueBoolean m_json = false;2565    OptionValueBoolean m_errors_only = false;2566    OptionValueBoolean m_load_all_debug_info = false;2567  };2568 2569protected:2570  void DoExecute(Args &command, CommandReturnObject &result) override {2571    Target &target = GetTarget();2572    uint32_t num_dumped = 0;2573 2574    uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();2575    result.GetOutputStream().SetAddressByteSize(addr_byte_size);2576    result.GetErrorStream().SetAddressByteSize(addr_byte_size);2577 2578    StructuredData::Array separate_debug_info_lists_by_module;2579    if (command.GetArgumentCount() == 0) {2580      // Dump all sections for all modules images2581      const ModuleList &target_modules = target.GetImages();2582      std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());2583      const size_t num_modules = target_modules.GetSize();2584      if (num_modules == 0) {2585        result.AppendError("the target has no associated executable images");2586        return;2587      }2588      for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {2589        if (INTERRUPT_REQUESTED(2590                GetDebugger(),2591                "Interrupted in dumping all "2592                "separate debug info with {0} of {1} modules dumped",2593                num_dumped, num_modules))2594          break;2595 2596        if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,2597                                     module_sp.get(),2598                                     bool(m_options.m_errors_only),2599                                     bool(m_options.m_load_all_debug_info)))2600          num_dumped++;2601      }2602    } else {2603      // Dump specified images (by basename or fullpath)2604      const char *arg_cstr;2605      for (int arg_idx = 0;2606           (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;2607           ++arg_idx) {2608        ModuleList module_list;2609        const size_t num_matches =2610            FindModulesByName(&target, arg_cstr, module_list, true);2611        if (num_matches > 0) {2612          for (size_t i = 0; i < num_matches; ++i) {2613            if (INTERRUPT_REQUESTED(GetDebugger(),2614                                    "Interrupted dumping {0} "2615                                    "of {1} requested modules",2616                                    i, num_matches))2617              break;2618            Module *module = module_list.GetModulePointerAtIndex(i);2619            if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,2620                                         module, bool(m_options.m_errors_only),2621                                         bool(m_options.m_load_all_debug_info)))2622              num_dumped++;2623          }2624        } else2625          result.AppendWarningWithFormat(2626              "Unable to find an image that matches '%s'.\n", arg_cstr);2627      }2628    }2629 2630    if (num_dumped > 0) {2631      Stream &strm = result.GetOutputStream();2632      // Display the debug info files in some format.2633      if (m_options.m_json) {2634        // JSON format2635        separate_debug_info_lists_by_module.Dump(strm,2636                                                 /*pretty_print=*/true);2637      } else {2638        // Human-readable table format2639        separate_debug_info_lists_by_module.ForEach(2640            [&result, &strm](StructuredData::Object *obj) {2641              if (!obj) {2642                return false;2643              }2644 2645              // Each item in `separate_debug_info_lists_by_module` should be a2646              // valid structured data dictionary.2647              StructuredData::Dictionary *separate_debug_info_list =2648                  obj->GetAsDictionary();2649              if (!separate_debug_info_list) {2650                return false;2651              }2652 2653              llvm::StringRef type;2654              llvm::StringRef symfile;2655              StructuredData::Array *files;2656              if (!(separate_debug_info_list->GetValueForKeyAsString("type",2657                                                                     type) &&2658                    separate_debug_info_list->GetValueForKeyAsString("symfile",2659                                                                     symfile) &&2660                    separate_debug_info_list->GetValueForKeyAsArray(2661                        "separate-debug-info-files", files))) {2662                assert(false);2663              }2664 2665              strm << "Symbol file: " << symfile;2666              strm.EOL();2667              strm << "Type: \"" << type << "\"";2668              strm.EOL();2669              if (type == "dwo") {2670                DumpDwoFilesTable(strm, *files);2671              } else if (type == "oso") {2672                DumpOsoFilesTable(strm, *files);2673              } else {2674                result.AppendWarningWithFormat(2675                    "Found unsupported debug info type '%s'.\n",2676                    type.str().c_str());2677              }2678              return true;2679            });2680      }2681      result.SetStatus(eReturnStatusSuccessFinishResult);2682    } else {2683      result.AppendError("no matching executable images found");2684    }2685  }2686 2687  CommandOptions m_options;2688};2689 2690#pragma mark CommandObjectTargetModulesDump2691 2692// Dump multi-word command for target modules2693 2694class CommandObjectTargetModulesDump : public CommandObjectMultiword {2695public:2696  // Constructors and Destructors2697  CommandObjectTargetModulesDump(CommandInterpreter &interpreter)2698      : CommandObjectMultiword(2699            interpreter, "target modules dump",2700            "Commands for dumping information about one or more target "2701            "modules.",2702            "target modules dump "2703            "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"2704            "debug-info] "2705            "[<file1> <file2> ...]") {2706    LoadSubCommand("objfile",2707                   CommandObjectSP(2708                       new CommandObjectTargetModulesDumpObjfile(interpreter)));2709    LoadSubCommand(2710        "symtab",2711        CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));2712    LoadSubCommand("sections",2713                   CommandObjectSP(new CommandObjectTargetModulesDumpSections(2714                       interpreter)));2715    LoadSubCommand("symfile",2716                   CommandObjectSP(2717                       new CommandObjectTargetModulesDumpSymfile(interpreter)));2718    LoadSubCommand(2719        "ast", CommandObjectSP(2720                   new CommandObjectTargetModulesDumpClangAST(interpreter)));2721    LoadSubCommand("line-table",2722                   CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(2723                       interpreter)));2724    LoadSubCommand(2725        "pcm-info",2726        CommandObjectSP(2727            new CommandObjectTargetModulesDumpClangPCMInfo(interpreter)));2728    LoadSubCommand("separate-debug-info",2729                   CommandObjectSP(2730                       new CommandObjectTargetModulesDumpSeparateDebugInfoFiles(2731                           interpreter)));2732  }2733 2734  ~CommandObjectTargetModulesDump() override = default;2735};2736 2737class CommandObjectTargetModulesAdd : public CommandObjectParsed {2738public:2739  CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)2740      : CommandObjectParsed(interpreter, "target modules add",2741                            "Add a new module to the current target's modules.",2742                            "target modules add [<module>]",2743                            eCommandRequiresTarget),2744        m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,2745                      eArgTypeFilename,2746                      "Fullpath to a stand alone debug "2747                      "symbols file for when debug symbols "2748                      "are not in the executable.") {2749    m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,2750                          LLDB_OPT_SET_1);2751    m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);2752    m_option_group.Finalize();2753    AddSimpleArgumentList(eArgTypePath, eArgRepeatStar);2754  }2755 2756  ~CommandObjectTargetModulesAdd() override = default;2757 2758  Options *GetOptions() override { return &m_option_group; }2759 2760protected:2761  OptionGroupOptions m_option_group;2762  OptionGroupUUID m_uuid_option_group;2763  OptionGroupFile m_symbol_file;2764 2765  void DoExecute(Args &args, CommandReturnObject &result) override {2766    Target &target = GetTarget();2767    bool flush = false;2768 2769    const size_t argc = args.GetArgumentCount();2770    if (argc == 0) {2771      if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {2772        // We are given a UUID only, go locate the file2773        ModuleSpec module_spec;2774        module_spec.GetUUID() =2775            m_uuid_option_group.GetOptionValue().GetCurrentValue();2776        if (m_symbol_file.GetOptionValue().OptionWasSet())2777          module_spec.GetSymbolFileSpec() =2778              m_symbol_file.GetOptionValue().GetCurrentValue();2779        Status error;2780        if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) {2781          ModuleSP module_sp(2782              target.GetOrCreateModule(module_spec, true /* notify */));2783          if (module_sp) {2784            result.SetStatus(eReturnStatusSuccessFinishResult);2785            return;2786          } else {2787            StreamString strm;2788            module_spec.GetUUID().Dump(strm);2789            if (module_spec.GetFileSpec()) {2790              if (module_spec.GetSymbolFileSpec()) {2791                result.AppendErrorWithFormat(2792                    "Unable to create the executable or symbol file with "2793                    "UUID %s with path %s and symbol file %s",2794                    strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),2795                    module_spec.GetSymbolFileSpec().GetPath().c_str());2796              } else {2797                result.AppendErrorWithFormat(2798                    "Unable to create the executable or symbol file with "2799                    "UUID %s with path %s",2800                    strm.GetData(),2801                    module_spec.GetFileSpec().GetPath().c_str());2802              }2803            } else {2804              result.AppendErrorWithFormat("Unable to create the executable "2805                                           "or symbol file with UUID %s",2806                                           strm.GetData());2807            }2808            return;2809          }2810        } else {2811          StreamString strm;2812          module_spec.GetUUID().Dump(strm);2813          result.AppendErrorWithFormat(2814              "Unable to locate the executable or symbol file with UUID %s",2815              strm.GetData());2816          result.SetError(std::move(error));2817          return;2818        }2819      } else {2820        result.AppendError(2821            "one or more executable image paths must be specified");2822        return;2823      }2824    } else {2825      for (auto &entry : args.entries()) {2826        if (entry.ref().empty())2827          continue;2828 2829        FileSpec file_spec(entry.ref());2830        if (FileSystem::Instance().Exists(file_spec)) {2831          ModuleSpec module_spec(file_spec);2832          if (m_uuid_option_group.GetOptionValue().OptionWasSet())2833            module_spec.GetUUID() =2834                m_uuid_option_group.GetOptionValue().GetCurrentValue();2835          if (m_symbol_file.GetOptionValue().OptionWasSet())2836            module_spec.GetSymbolFileSpec() =2837                m_symbol_file.GetOptionValue().GetCurrentValue();2838          if (!module_spec.GetArchitecture().IsValid())2839            module_spec.GetArchitecture() = target.GetArchitecture();2840          Status error;2841          ModuleSP module_sp(2842              target.GetOrCreateModule(module_spec, true /* notify */, &error));2843          if (!module_sp) {2844            const char *error_cstr = error.AsCString();2845            if (error_cstr)2846              result.AppendError(error_cstr);2847            else2848              result.AppendErrorWithFormat("unsupported module: %s",2849                                           entry.c_str());2850            return;2851          } else {2852            flush = true;2853          }2854          result.SetStatus(eReturnStatusSuccessFinishResult);2855        } else {2856          std::string resolved_path = file_spec.GetPath();2857          if (resolved_path != entry.ref()) {2858            result.AppendErrorWithFormat(2859                "invalid module path '%s' with resolved path '%s'\n",2860                entry.ref().str().c_str(), resolved_path.c_str());2861            break;2862          }2863          result.AppendErrorWithFormat("invalid module path '%s'\n",2864                                       entry.c_str());2865          break;2866        }2867      }2868    }2869 2870    if (flush) {2871      ProcessSP process = target.GetProcessSP();2872      if (process)2873        process->Flush();2874    }2875  }2876};2877 2878class CommandObjectTargetModulesLoad2879    : public CommandObjectTargetModulesModuleAutoComplete {2880public:2881  CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)2882      : CommandObjectTargetModulesModuleAutoComplete(2883            interpreter, "target modules load",2884            "Set the load addresses for one or more sections in a target "2885            "module.",2886            "target modules load [--file <module> --uuid <uuid>] <sect-name> "2887            "<address> [<sect-name> <address> ....]",2888            eCommandRequiresTarget),2889        m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,2890                      "Fullpath or basename for module to load.", ""),2891        m_load_option(LLDB_OPT_SET_1, false, "load", 'l',2892                      "Write file contents to the memory.", false, true),2893        m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',2894                    "Set PC to the entry point."2895                    " Only applicable with '--load' option.",2896                    false, true),2897        m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,2898                       "Set the load address for all sections to be the "2899                       "virtual address in the file plus the offset.",2900                       0) {2901    m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,2902                          LLDB_OPT_SET_1);2903    m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);2904    m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);2905    m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);2906    m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);2907    m_option_group.Finalize();2908  }2909 2910  ~CommandObjectTargetModulesLoad() override = default;2911 2912  Options *GetOptions() override { return &m_option_group; }2913 2914protected:2915  void DoExecute(Args &args, CommandReturnObject &result) override {2916    Target &target = GetTarget();2917    const bool load = m_load_option.GetOptionValue().GetCurrentValue();2918    const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();2919 2920    const size_t argc = args.GetArgumentCount();2921    ModuleSpec module_spec;2922    bool search_using_module_spec = false;2923 2924    // Allow "load" option to work without --file or --uuid option.2925    if (load) {2926      if (!m_file_option.GetOptionValue().OptionWasSet() &&2927          !m_uuid_option_group.GetOptionValue().OptionWasSet()) {2928        ModuleList &module_list = target.GetImages();2929        if (module_list.GetSize() == 1) {2930          search_using_module_spec = true;2931          module_spec.GetFileSpec() =2932              module_list.GetModuleAtIndex(0)->GetFileSpec();2933        }2934      }2935    }2936 2937    if (m_file_option.GetOptionValue().OptionWasSet()) {2938      search_using_module_spec = true;2939      const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();2940      const bool use_global_module_list = true;2941      ModuleList module_list;2942      const size_t num_matches = FindModulesByName(2943          &target, arg_cstr, module_list, use_global_module_list);2944      if (num_matches == 1) {2945        module_spec.GetFileSpec() =2946            module_list.GetModuleAtIndex(0)->GetFileSpec();2947      } else if (num_matches > 1) {2948        search_using_module_spec = false;2949        result.AppendErrorWithFormat(2950            "more than 1 module matched by name '%s'\n", arg_cstr);2951      } else {2952        search_using_module_spec = false;2953        result.AppendErrorWithFormat("no object file for module '%s'\n",2954                                     arg_cstr);2955      }2956    }2957 2958    if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {2959      search_using_module_spec = true;2960      module_spec.GetUUID() =2961          m_uuid_option_group.GetOptionValue().GetCurrentValue();2962    }2963 2964    if (search_using_module_spec) {2965      ModuleList matching_modules;2966      target.GetImages().FindModules(module_spec, matching_modules);2967      const size_t num_matches = matching_modules.GetSize();2968 2969      char path[PATH_MAX];2970      if (num_matches == 1) {2971        Module *module = matching_modules.GetModulePointerAtIndex(0);2972        if (module) {2973          ObjectFile *objfile = module->GetObjectFile();2974          if (objfile) {2975            SectionList *section_list = module->GetSectionList();2976            if (section_list) {2977              bool changed = false;2978              if (argc == 0) {2979                if (m_slide_option.GetOptionValue().OptionWasSet()) {2980                  const addr_t slide =2981                      m_slide_option.GetOptionValue().GetCurrentValue();2982                  const bool slide_is_offset = true;2983                  module->SetLoadAddress(target, slide, slide_is_offset,2984                                         changed);2985                } else {2986                  result.AppendError("one or more section name + load "2987                                     "address pair must be specified");2988                  return;2989                }2990              } else {2991                if (m_slide_option.GetOptionValue().OptionWasSet()) {2992                  result.AppendError("The \"--slide <offset>\" option can't "2993                                     "be used in conjunction with setting "2994                                     "section load addresses.\n");2995                  return;2996                }2997 2998                for (size_t i = 0; i < argc; i += 2) {2999                  const char *sect_name = args.GetArgumentAtIndex(i);3000                  const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);3001                  if (sect_name && load_addr_cstr) {3002                    ConstString const_sect_name(sect_name);3003                    addr_t load_addr;3004                    if (llvm::to_integer(load_addr_cstr, load_addr)) {3005                      SectionSP section_sp(3006                          section_list->FindSectionByName(const_sect_name));3007                      if (section_sp) {3008                        if (section_sp->IsThreadSpecific()) {3009                          result.AppendErrorWithFormat(3010                              "thread specific sections are not yet "3011                              "supported (section '%s')\n",3012                              sect_name);3013                          break;3014                        } else {3015                          if (target.SetSectionLoadAddress(section_sp,3016                                                           load_addr))3017                            changed = true;3018                          result.AppendMessageWithFormat(3019                              "section '%s' loaded at 0x%" PRIx64 "\n",3020                              sect_name, load_addr);3021                        }3022                      } else {3023                        result.AppendErrorWithFormat("no section found that "3024                                                     "matches the section "3025                                                     "name '%s'\n",3026                                                     sect_name);3027                        break;3028                      }3029                    } else {3030                      result.AppendErrorWithFormat(3031                          "invalid load address string '%s'\n", load_addr_cstr);3032                      break;3033                    }3034                  } else {3035                    if (sect_name)3036                      result.AppendError("section names must be followed by "3037                                         "a load address.\n");3038                    else3039                      result.AppendError("one or more section name + load "3040                                         "address pair must be specified.\n");3041                    break;3042                  }3043                }3044              }3045 3046              if (changed) {3047                target.ModulesDidLoad(matching_modules);3048                Process *process = m_exe_ctx.GetProcessPtr();3049                if (process)3050                  process->Flush();3051              }3052              if (load) {3053                ProcessSP process = target.CalculateProcess();3054                Address file_entry = objfile->GetEntryPointAddress();3055                if (!process) {3056                  result.AppendError("No process");3057                  return;3058                }3059                if (set_pc && !file_entry.IsValid()) {3060                  result.AppendError("No entry address in object file");3061                  return;3062                }3063                std::vector<ObjectFile::LoadableData> loadables(3064                    objfile->GetLoadableData(target));3065                if (loadables.size() == 0) {3066                  result.AppendError("No loadable sections");3067                  return;3068                }3069                Status error = process->WriteObjectFile(std::move(loadables));3070                if (error.Fail()) {3071                  result.AppendError(error.AsCString());3072                  return;3073                }3074                if (set_pc) {3075                  ThreadList &thread_list = process->GetThreadList();3076                  RegisterContextSP reg_context(3077                      thread_list.GetSelectedThread()->GetRegisterContext());3078                  addr_t file_entry_addr = file_entry.GetLoadAddress(&target);3079                  if (!reg_context->SetPC(file_entry_addr)) {3080                    result.AppendErrorWithFormat("failed to set PC value to "3081                                                 "0x%" PRIx64 "\n",3082                                                 file_entry_addr);3083                  }3084                }3085              }3086            } else {3087              module->GetFileSpec().GetPath(path, sizeof(path));3088              result.AppendErrorWithFormat("no sections in object file '%s'\n",3089                                           path);3090            }3091          } else {3092            module->GetFileSpec().GetPath(path, sizeof(path));3093            result.AppendErrorWithFormat("no object file for module '%s'\n",3094                                         path);3095          }3096        } else {3097          FileSpec *module_spec_file = module_spec.GetFileSpecPtr();3098          if (module_spec_file) {3099            module_spec_file->GetPath(path, sizeof(path));3100            result.AppendErrorWithFormat("invalid module '%s'.\n", path);3101          } else3102            result.AppendError("no module spec");3103        }3104      } else {3105        std::string uuid_str;3106 3107        if (module_spec.GetFileSpec())3108          module_spec.GetFileSpec().GetPath(path, sizeof(path));3109        else3110          path[0] = '\0';3111 3112        if (module_spec.GetUUIDPtr())3113          uuid_str = module_spec.GetUUID().GetAsString();3114        if (num_matches > 1) {3115          result.AppendErrorWithFormat(3116              "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",3117              path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());3118          for (size_t i = 0; i < num_matches; ++i) {3119            if (matching_modules.GetModulePointerAtIndex(i)3120                    ->GetFileSpec()3121                    .GetPath(path, sizeof(path)))3122              result.AppendMessageWithFormat("%s\n", path);3123          }3124        } else {3125          result.AppendErrorWithFormat(3126              "no modules were found  that match%s%s%s%s.\n",3127              path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",3128              uuid_str.c_str());3129        }3130      }3131    } else {3132      result.AppendError("either the \"--file <module>\" or the \"--uuid "3133                         "<uuid>\" option must be specified.\n");3134    }3135  }3136 3137  OptionGroupOptions m_option_group;3138  OptionGroupUUID m_uuid_option_group;3139  OptionGroupString m_file_option;3140  OptionGroupBoolean m_load_option;3141  OptionGroupBoolean m_pc_option;3142  OptionGroupUInt64 m_slide_option;3143};3144 3145#pragma mark CommandObjectTargetModulesList3146// List images with associated information3147#define LLDB_OPTIONS_target_modules_list3148#include "CommandOptions.inc"3149 3150class CommandObjectTargetModulesList : public CommandObjectParsed {3151public:3152  class CommandOptions : public Options {3153  public:3154    CommandOptions() = default;3155 3156    ~CommandOptions() override = default;3157 3158    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,3159                          ExecutionContext *execution_context) override {3160      Status error;3161 3162      const int short_option = m_getopt_table[option_idx].val;3163      if (short_option == 'g') {3164        m_use_global_module_list = true;3165      } else if (short_option == 'a') {3166        m_module_addr = OptionArgParser::ToAddress(3167            execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);3168      } else {3169        unsigned long width = 0;3170        option_arg.getAsInteger(0, width);3171        m_format_array.push_back(std::make_pair(short_option, width));3172      }3173      return error;3174    }3175 3176    void OptionParsingStarting(ExecutionContext *execution_context) override {3177      m_format_array.clear();3178      m_use_global_module_list = false;3179      m_module_addr = LLDB_INVALID_ADDRESS;3180    }3181 3182    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {3183      return llvm::ArrayRef(g_target_modules_list_options);3184    }3185 3186    // Instance variables to hold the values for command options.3187    typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;3188    FormatWidthCollection m_format_array;3189    bool m_use_global_module_list = false;3190    lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;3191  };3192 3193  CommandObjectTargetModulesList(CommandInterpreter &interpreter)3194      : CommandObjectParsed(3195            interpreter, "target modules list",3196            "List current executable and dependent shared library images.") {3197    AddSimpleArgumentList(eArgTypeModule, eArgRepeatStar);3198  }3199 3200  ~CommandObjectTargetModulesList() override = default;3201 3202  Options *GetOptions() override { return &m_options; }3203 3204protected:3205  void DoExecute(Args &command, CommandReturnObject &result) override {3206    Target &target = GetTarget();3207    const bool use_global_module_list = m_options.m_use_global_module_list;3208    // Define a local module list here to ensure it lives longer than any3209    // "locker" object which might lock its contents below (through the3210    // "module_list_ptr" variable).3211    ModuleList module_list;3212    uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();3213    result.GetOutputStream().SetAddressByteSize(addr_byte_size);3214    result.GetErrorStream().SetAddressByteSize(addr_byte_size);3215    // Dump all sections for all modules images3216    Stream &strm = result.GetOutputStream();3217 3218    if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {3219      Address module_address;3220      if (module_address.SetLoadAddress(m_options.m_module_addr, &target)) {3221        ModuleSP module_sp(module_address.GetModule());3222        if (module_sp) {3223          PrintModule(target, module_sp.get(), 0, strm);3224          result.SetStatus(eReturnStatusSuccessFinishResult);3225        } else {3226          result.AppendErrorWithFormat(3227              "Couldn't find module matching address: 0x%" PRIx64 ".",3228              m_options.m_module_addr);3229        }3230      } else {3231        result.AppendErrorWithFormat(3232            "Couldn't find module containing address: 0x%" PRIx64 ".",3233            m_options.m_module_addr);3234      }3235      return;3236    }3237 3238      size_t num_modules = 0;3239 3240      // This locker will be locked on the mutex in module_list_ptr if it is3241      // non-nullptr. Otherwise it will lock the3242      // AllocationModuleCollectionMutex when accessing the global module list3243      // directly.3244      std::unique_lock<std::recursive_mutex> guard(3245          Module::GetAllocationModuleCollectionMutex(), std::defer_lock);3246 3247      const ModuleList *module_list_ptr = nullptr;3248      const size_t argc = command.GetArgumentCount();3249      if (argc == 0) {3250        if (use_global_module_list) {3251          guard.lock();3252          num_modules = Module::GetNumberAllocatedModules();3253        } else {3254          module_list_ptr = &target.GetImages();3255        }3256      } else {3257        for (const Args::ArgEntry &arg : command) {3258          // Dump specified images (by basename or fullpath)3259          const size_t num_matches = FindModulesByName(3260              &target, arg.c_str(), module_list, use_global_module_list);3261          if (num_matches == 0) {3262            if (argc == 1) {3263              result.AppendErrorWithFormat("no modules found that match '%s'",3264                                           arg.c_str());3265              return;3266            }3267          }3268        }3269 3270        module_list_ptr = &module_list;3271      }3272 3273      std::unique_lock<std::recursive_mutex> lock;3274      if (module_list_ptr != nullptr) {3275        lock =3276            std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());3277 3278        num_modules = module_list_ptr->GetSize();3279      }3280 3281      if (num_modules > 0) {3282        for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {3283          ModuleSP module_sp;3284          Module *module;3285          if (module_list_ptr) {3286            module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);3287            module = module_sp.get();3288          } else {3289            module = Module::GetAllocatedModuleAtIndex(image_idx);3290            module_sp = module->shared_from_this();3291          }3292 3293          const size_t indent = strm.Printf("[%3u] ", image_idx);3294          PrintModule(target, module, indent, strm);3295        }3296        result.SetStatus(eReturnStatusSuccessFinishResult);3297      } else {3298        if (argc) {3299          if (use_global_module_list)3300            result.AppendError(3301                "the global module list has no matching modules");3302          else3303            result.AppendError("the target has no matching modules");3304        } else {3305          if (use_global_module_list)3306            result.AppendError("the global module list is empty");3307          else3308            result.AppendError(3309                "the target has no associated executable images");3310        }3311        return;3312      }3313  }3314 3315  void PrintModule(Target &target, Module *module, int indent, Stream &strm) {3316    if (module == nullptr) {3317      strm.PutCString("Null module");3318      return;3319    }3320 3321    bool dump_object_name = false;3322    if (m_options.m_format_array.empty()) {3323      m_options.m_format_array.push_back(std::make_pair('u', 0));3324      m_options.m_format_array.push_back(std::make_pair('h', 0));3325      m_options.m_format_array.push_back(std::make_pair('f', 0));3326      m_options.m_format_array.push_back(std::make_pair('S', 0));3327    }3328    const size_t num_entries = m_options.m_format_array.size();3329    bool print_space = false;3330    for (size_t i = 0; i < num_entries; ++i) {3331      if (print_space)3332        strm.PutChar(' ');3333      print_space = true;3334      const char format_char = m_options.m_format_array[i].first;3335      uint32_t width = m_options.m_format_array[i].second;3336      switch (format_char) {3337      case 'A':3338        DumpModuleArchitecture(strm, module, false, width);3339        break;3340 3341      case 't':3342        DumpModuleArchitecture(strm, module, true, width);3343        break;3344 3345      case 'f':3346        DumpFullpath(strm, &module->GetFileSpec(), width);3347        dump_object_name = true;3348        break;3349 3350      case 'd':3351        DumpDirectory(strm, &module->GetFileSpec(), width);3352        break;3353 3354      case 'b':3355        DumpBasename(strm, &module->GetFileSpec(), width);3356        dump_object_name = true;3357        break;3358 3359      case 'h':3360      case 'o':3361        // Image header address3362        {3363          uint32_t addr_nibble_width =3364              target.GetArchitecture().GetAddressByteSize() * 2;3365 3366          ObjectFile *objfile = module->GetObjectFile();3367          if (objfile) {3368            Address base_addr(objfile->GetBaseAddress());3369            if (base_addr.IsValid()) {3370              if (target.HasLoadedSections()) {3371                lldb::addr_t load_addr = base_addr.GetLoadAddress(&target);3372                if (load_addr == LLDB_INVALID_ADDRESS) {3373                  base_addr.Dump(&strm, &target,3374                                 Address::DumpStyleModuleWithFileAddress,3375                                 Address::DumpStyleFileAddress);3376                } else {3377                  if (format_char == 'o') {3378                    // Show the offset of slide for the image3379                    strm.Printf("0x%*.*" PRIx64, addr_nibble_width,3380                                addr_nibble_width,3381                                load_addr - base_addr.GetFileAddress());3382                  } else {3383                    // Show the load address of the image3384                    strm.Printf("0x%*.*" PRIx64, addr_nibble_width,3385                                addr_nibble_width, load_addr);3386                  }3387                }3388                break;3389              }3390              // The address was valid, but the image isn't loaded, output the3391              // address in an appropriate format3392              base_addr.Dump(&strm, &target, Address::DumpStyleFileAddress);3393              break;3394            }3395          }3396          strm.Printf("%*s", addr_nibble_width + 2, "");3397        }3398        break;3399 3400      case 'r': {3401        size_t ref_count = 0;3402        char in_shared_cache = 'Y';3403 3404        ModuleSP module_sp(module->shared_from_this());3405        if (!ModuleList::ModuleIsInCache(module))3406          in_shared_cache = 'N';3407        if (module_sp) {3408          // Take one away to make sure we don't count our local "module_sp"3409          ref_count = module_sp.use_count() - 1;3410        }3411        if (width)3412          strm.Printf("{%c %*" PRIu64 "}", in_shared_cache, width, (uint64_t)ref_count);3413        else3414          strm.Printf("{%c %" PRIu64 "}", in_shared_cache, (uint64_t)ref_count);3415      } break;3416 3417      case 's':3418      case 'S': {3419        if (const SymbolFile *symbol_file = module->GetSymbolFile()) {3420          const FileSpec symfile_spec =3421              symbol_file->GetObjectFile()->GetFileSpec();3422          if (format_char == 'S') {3423            // Dump symbol file only if different from module file3424            if (!symfile_spec || symfile_spec == module->GetFileSpec()) {3425              print_space = false;3426              break;3427            }3428            // Add a newline and indent past the index3429            strm.Printf("\n%*s", indent, "");3430          }3431          DumpFullpath(strm, &symfile_spec, width);3432          dump_object_name = true;3433          break;3434        }3435        strm.Printf("%.*s", width, "<NONE>");3436      } break;3437 3438      case 'm':3439        strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),3440                                              llvm::AlignStyle::Left, width));3441        break;3442 3443      case 'p':3444        strm.Printf("%p", static_cast<void *>(module));3445        break;3446 3447      case 'u':3448        DumpModuleUUID(strm, module);3449        break;3450 3451      default:3452        break;3453      }3454    }3455    if (dump_object_name) {3456      const char *object_name = module->GetObjectName().GetCString();3457      if (object_name)3458        strm.Printf("(%s)", object_name);3459    }3460    strm.EOL();3461  }3462 3463  CommandOptions m_options;3464};3465 3466#pragma mark CommandObjectTargetModulesShowUnwind3467 3468// Lookup unwind information in images3469#define LLDB_OPTIONS_target_modules_show_unwind3470#include "CommandOptions.inc"3471 3472class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {3473public:3474  enum {3475    eLookupTypeInvalid = -1,3476    eLookupTypeAddress = 0,3477    eLookupTypeSymbol,3478    eLookupTypeFunction,3479    eLookupTypeFunctionOrSymbol,3480    kNumLookupTypes3481  };3482 3483  class CommandOptions : public Options {3484  public:3485    CommandOptions() = default;3486 3487    ~CommandOptions() override = default;3488 3489    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,3490                          ExecutionContext *execution_context) override {3491      Status error;3492 3493      const int short_option = m_getopt_table[option_idx].val;3494 3495      switch (short_option) {3496      case 'a': {3497        m_str = std::string(option_arg);3498        m_type = eLookupTypeAddress;3499        m_addr = OptionArgParser::ToAddress(execution_context, option_arg,3500                                            LLDB_INVALID_ADDRESS, &error);3501        if (m_addr == LLDB_INVALID_ADDRESS)3502          error = Status::FromErrorStringWithFormat(3503              "invalid address string '%s'", option_arg.str().c_str());3504        break;3505      }3506 3507      case 'n':3508        m_str = std::string(option_arg);3509        m_type = eLookupTypeFunctionOrSymbol;3510        break;3511 3512      case 'c':3513        bool value, success;3514        value = OptionArgParser::ToBoolean(option_arg, false, &success);3515        if (success) {3516          m_cached = value;3517        } else {3518          return Status::FromErrorStringWithFormatv(3519              "invalid boolean value '%s' passed for -c option", option_arg);3520        }3521        break;3522 3523      default:3524        llvm_unreachable("Unimplemented option");3525      }3526 3527      return error;3528    }3529 3530    void OptionParsingStarting(ExecutionContext *execution_context) override {3531      m_type = eLookupTypeInvalid;3532      m_str.clear();3533      m_addr = LLDB_INVALID_ADDRESS;3534      m_cached = false;3535    }3536 3537    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {3538      return llvm::ArrayRef(g_target_modules_show_unwind_options);3539    }3540 3541    // Instance variables to hold the values for command options.3542 3543    int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after3544                                     // parsing options3545    std::string m_str; // Holds name lookup3546    lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup3547    bool m_cached = true;3548  };3549 3550  CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)3551      : CommandObjectParsed(3552            interpreter, "target modules show-unwind",3553            "Show synthesized unwind instructions for a function.", nullptr,3554            eCommandRequiresTarget | eCommandRequiresProcess |3555                eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}3556 3557  ~CommandObjectTargetModulesShowUnwind() override = default;3558 3559  Options *GetOptions() override { return &m_options; }3560 3561protected:3562  void DoExecute(Args &command, CommandReturnObject &result) override {3563    Target *target = m_exe_ctx.GetTargetPtr();3564    Process *process = m_exe_ctx.GetProcessPtr();3565    ABI *abi = nullptr;3566    if (process)3567      abi = process->GetABI().get();3568 3569    if (process == nullptr) {3570      result.AppendError(3571          "You must have a process running to use this command.");3572      return;3573    }3574 3575    ThreadList threads(process->GetThreadList());3576    if (threads.GetSize() == 0) {3577      result.AppendError("the process must be paused to use this command");3578      return;3579    }3580 3581    ThreadSP thread(threads.GetThreadAtIndex(0));3582    if (!thread) {3583      result.AppendError("the process must be paused to use this command");3584      return;3585    }3586 3587    SymbolContextList sc_list;3588 3589    if (m_options.m_type == eLookupTypeFunctionOrSymbol) {3590      ConstString function_name(m_options.m_str.c_str());3591      ModuleFunctionSearchOptions function_options;3592      function_options.include_symbols = true;3593      function_options.include_inlines = false;3594      target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,3595                                        function_options, sc_list);3596    } else if (m_options.m_type == eLookupTypeAddress && target) {3597      Address addr;3598      if (target->ResolveLoadAddress(m_options.m_addr, addr)) {3599        SymbolContext sc;3600        ModuleSP module_sp(addr.GetModule());3601        module_sp->ResolveSymbolContextForAddress(addr,3602                                                  eSymbolContextEverything, sc);3603        if (sc.function || sc.symbol) {3604          sc_list.Append(sc);3605        }3606      }3607    } else {3608      result.AppendError(3609          "address-expression or function name option must be specified.");3610      return;3611    }3612 3613    if (sc_list.GetSize() == 0) {3614      result.AppendErrorWithFormat("no unwind data found that matches '%s'.",3615                                   m_options.m_str.c_str());3616      return;3617    }3618 3619    for (const SymbolContext &sc : sc_list) {3620      if (sc.symbol == nullptr && sc.function == nullptr)3621        continue;3622      if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)3623        continue;3624      Address addr = sc.GetFunctionOrSymbolAddress();3625      if (!addr.IsValid())3626        continue;3627      ConstString funcname(sc.GetFunctionName());3628      if (funcname.IsEmpty())3629        continue;3630      addr_t start_addr = addr.GetLoadAddress(target);3631      if (abi)3632        start_addr = abi->FixCodeAddress(start_addr);3633 3634      UnwindTable &uw_table = sc.module_sp->GetUnwindTable();3635      FuncUnwindersSP func_unwinders_sp =3636          m_options.m_cached3637              ? uw_table.GetFuncUnwindersContainingAddress(start_addr, sc)3638              : uw_table.GetUncachedFuncUnwindersContainingAddress(start_addr,3639                                                                   sc);3640      if (!func_unwinders_sp)3641        continue;3642 3643      result.GetOutputStream().Printf(3644          "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",3645          sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),3646          funcname.AsCString(), start_addr);3647 3648      Args args;3649      target->GetUserSpecifiedTrapHandlerNames(args);3650      size_t count = args.GetArgumentCount();3651      for (size_t i = 0; i < count; i++) {3652        const char *trap_func_name = args.GetArgumentAtIndex(i);3653        if (strcmp(funcname.GetCString(), trap_func_name) == 0)3654          result.GetOutputStream().Printf(3655              "This function is "3656              "treated as a trap handler function via user setting.\n");3657      }3658      PlatformSP platform_sp(target->GetPlatform());3659      if (platform_sp) {3660        const std::vector<ConstString> trap_handler_names(3661            platform_sp->GetTrapHandlerSymbolNames());3662        for (ConstString trap_name : trap_handler_names) {3663          if (trap_name == funcname) {3664            result.GetOutputStream().Printf(3665                "This function's "3666                "name is listed by the platform as a trap handler.\n");3667          }3668        }3669      }3670 3671      result.GetOutputStream().Printf("\n");3672 3673      if (std::shared_ptr<const UnwindPlan> plan_sp =3674              func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread)) {3675        result.GetOutputStream().Printf(3676            "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",3677            plan_sp->GetSourceName().AsCString());3678      }3679      if (std::shared_ptr<const UnwindPlan> plan_sp =3680              func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread)) {3681        result.GetOutputStream().Printf(3682            "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",3683            plan_sp->GetSourceName().AsCString());3684      }3685      if (std::shared_ptr<const UnwindPlan> plan_sp =3686              func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {3687        result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n",3688                                        plan_sp->GetSourceName().AsCString());3689      }3690 3691      result.GetOutputStream().Printf("\n");3692 3693      if (std::shared_ptr<const UnwindPlan> plan_sp =3694              func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread)) {3695        result.GetOutputStream().Printf(3696            "Assembly language inspection UnwindPlan:\n");3697        plan_sp->Dump(result.GetOutputStream(), thread.get(),3698                      LLDB_INVALID_ADDRESS);3699        result.GetOutputStream().Printf("\n");3700      }3701 3702      if (std::shared_ptr<const UnwindPlan> plan_sp =3703              func_unwinders_sp->GetObjectFileUnwindPlan(*target)) {3704        result.GetOutputStream().Printf("object file UnwindPlan:\n");3705        plan_sp->Dump(result.GetOutputStream(), thread.get(),3706                      LLDB_INVALID_ADDRESS);3707        result.GetOutputStream().Printf("\n");3708      }3709 3710      if (std::shared_ptr<const UnwindPlan> plan_sp =3711              func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,3712                                                                  *thread)) {3713        result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");3714        plan_sp->Dump(result.GetOutputStream(), thread.get(),3715                      LLDB_INVALID_ADDRESS);3716        result.GetOutputStream().Printf("\n");3717      }3718 3719      if (std::shared_ptr<const UnwindPlan> plan_sp =3720              func_unwinders_sp->GetEHFrameUnwindPlan(*target)) {3721        result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");3722        plan_sp->Dump(result.GetOutputStream(), thread.get(),3723                      LLDB_INVALID_ADDRESS);3724        result.GetOutputStream().Printf("\n");3725      }3726 3727      if (std::shared_ptr<const UnwindPlan> plan_sp =3728              func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target,3729                                                               *thread)) {3730        result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");3731        plan_sp->Dump(result.GetOutputStream(), thread.get(),3732                      LLDB_INVALID_ADDRESS);3733        result.GetOutputStream().Printf("\n");3734      }3735 3736      if (std::shared_ptr<const UnwindPlan> plan_sp =3737              func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {3738        result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");3739        plan_sp->Dump(result.GetOutputStream(), thread.get(),3740                      LLDB_INVALID_ADDRESS);3741        result.GetOutputStream().Printf("\n");3742      }3743 3744      if (std::shared_ptr<const UnwindPlan> plan_sp =3745              func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,3746                                                                  *thread)) {3747        result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");3748        plan_sp->Dump(result.GetOutputStream(), thread.get(),3749                      LLDB_INVALID_ADDRESS);3750        result.GetOutputStream().Printf("\n");3751      }3752 3753      if (std::shared_ptr<const UnwindPlan> plan_sp =3754              func_unwinders_sp->GetArmUnwindUnwindPlan(*target)) {3755        result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");3756        plan_sp->Dump(result.GetOutputStream(), thread.get(),3757                      LLDB_INVALID_ADDRESS);3758        result.GetOutputStream().Printf("\n");3759      }3760 3761      if (std::shared_ptr<const UnwindPlan> plan_sp =3762              func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {3763        result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");3764        plan_sp->Dump(result.GetOutputStream(), thread.get(),3765                      LLDB_INVALID_ADDRESS);3766        result.GetOutputStream().Printf("\n");3767      }3768 3769      if (std::shared_ptr<const UnwindPlan> plan_sp =3770              func_unwinders_sp->GetCompactUnwindUnwindPlan(*target)) {3771        result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");3772        plan_sp->Dump(result.GetOutputStream(), thread.get(),3773                      LLDB_INVALID_ADDRESS);3774        result.GetOutputStream().Printf("\n");3775      }3776 3777      if (std::shared_ptr<const UnwindPlan> plan_sp =3778              func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {3779        result.GetOutputStream().Printf("Fast UnwindPlan:\n");3780        plan_sp->Dump(result.GetOutputStream(), thread.get(),3781                      LLDB_INVALID_ADDRESS);3782        result.GetOutputStream().Printf("\n");3783      }3784 3785      ABISP abi_sp = process->GetABI();3786      if (abi_sp) {3787        if (UnwindPlanSP plan_sp = abi_sp->CreateDefaultUnwindPlan()) {3788          result.GetOutputStream().Printf("Arch default UnwindPlan:\n");3789          plan_sp->Dump(result.GetOutputStream(), thread.get(),3790                        LLDB_INVALID_ADDRESS);3791          result.GetOutputStream().Printf("\n");3792        }3793 3794        if (UnwindPlanSP plan_sp = abi_sp->CreateFunctionEntryUnwindPlan()) {3795          result.GetOutputStream().Printf(3796              "Arch default at entry point UnwindPlan:\n");3797          plan_sp->Dump(result.GetOutputStream(), thread.get(),3798                        LLDB_INVALID_ADDRESS);3799          result.GetOutputStream().Printf("\n");3800        }3801      }3802 3803      result.GetOutputStream().Printf("\n");3804    }3805  }3806 3807  CommandOptions m_options;3808};3809 3810// Lookup information in images3811#define LLDB_OPTIONS_target_modules_lookup3812#include "CommandOptions.inc"3813 3814class CommandObjectTargetModulesLookup : public CommandObjectParsed {3815public:3816  enum {3817    eLookupTypeInvalid = -1,3818    eLookupTypeAddress = 0,3819    eLookupTypeSymbol,3820    eLookupTypeFileLine, // Line is optional3821    eLookupTypeFunction,3822    eLookupTypeFunctionOrSymbol,3823    eLookupTypeType,3824    kNumLookupTypes3825  };3826 3827  class CommandOptions : public Options {3828  public:3829    CommandOptions() { OptionParsingStarting(nullptr); }3830 3831    ~CommandOptions() override = default;3832 3833    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,3834                          ExecutionContext *execution_context) override {3835      Status error;3836 3837      const int short_option = m_getopt_table[option_idx].val;3838 3839      switch (short_option) {3840      case 'a': {3841        m_type = eLookupTypeAddress;3842        m_addr = OptionArgParser::ToAddress(execution_context, option_arg,3843                                            LLDB_INVALID_ADDRESS, &error);3844      } break;3845 3846      case 'o':3847        if (option_arg.getAsInteger(0, m_offset))3848          error = Status::FromErrorStringWithFormat(3849              "invalid offset string '%s'", option_arg.str().c_str());3850        break;3851 3852      case 's':3853        m_str = std::string(option_arg);3854        m_type = eLookupTypeSymbol;3855        break;3856 3857      case 'f':3858        m_file.SetFile(option_arg, FileSpec::Style::native);3859        m_type = eLookupTypeFileLine;3860        break;3861 3862      case 'i':3863        m_include_inlines = false;3864        break;3865 3866      case 'l':3867        if (option_arg.getAsInteger(0, m_line_number))3868          error = Status::FromErrorStringWithFormat(3869              "invalid line number string '%s'", option_arg.str().c_str());3870        else if (m_line_number == 0)3871          error = Status::FromErrorString("zero is an invalid line number");3872        m_type = eLookupTypeFileLine;3873        break;3874 3875      case 'F':3876        m_str = std::string(option_arg);3877        m_type = eLookupTypeFunction;3878        break;3879 3880      case 'n':3881        m_str = std::string(option_arg);3882        m_type = eLookupTypeFunctionOrSymbol;3883        break;3884 3885      case 't':3886        m_str = std::string(option_arg);3887        m_type = eLookupTypeType;3888        break;3889 3890      case 'v':3891        m_verbose = true;3892        break;3893 3894      case 'A':3895        m_print_all = true;3896        break;3897 3898      case 'r':3899        m_use_regex = true;3900        break;3901 3902      case '\x01':3903        m_all_ranges = true;3904        break;3905      default:3906        llvm_unreachable("Unimplemented option");3907      }3908 3909      return error;3910    }3911 3912    void OptionParsingStarting(ExecutionContext *execution_context) override {3913      m_type = eLookupTypeInvalid;3914      m_str.clear();3915      m_file.Clear();3916      m_addr = LLDB_INVALID_ADDRESS;3917      m_offset = 0;3918      m_line_number = 0;3919      m_use_regex = false;3920      m_include_inlines = true;3921      m_all_ranges = false;3922      m_verbose = false;3923      m_print_all = false;3924    }3925 3926    Status OptionParsingFinished(ExecutionContext *execution_context) override {3927      Status status;3928      if (m_all_ranges && !m_verbose) {3929        status =3930            Status::FromErrorString("--show-variable-ranges must be used in "3931                                    "conjunction with --verbose.");3932      }3933      return status;3934    }3935 3936    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {3937      return llvm::ArrayRef(g_target_modules_lookup_options);3938    }3939 3940    int m_type;        // Should be a eLookupTypeXXX enum after parsing options3941    std::string m_str; // Holds name lookup3942    FileSpec m_file;   // Files for file lookups3943    lldb::addr_t m_addr; // Holds the address to lookup3944    lldb::addr_t3945        m_offset; // Subtract this offset from m_addr before doing lookups.3946    uint32_t m_line_number; // Line number for file+line lookups3947    bool m_use_regex;       // Name lookups in m_str are regular expressions.3948    bool m_include_inlines; // Check for inline entries when looking up by3949                            // file/line.3950    bool m_all_ranges;      // Print all ranges or single range.3951    bool m_verbose;         // Enable verbose lookup info3952    bool m_print_all; // Print all matches, even in cases where there's a best3953                      // match.3954  };3955 3956  CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)3957      : CommandObjectParsed(interpreter, "target modules lookup",3958                            "Look up information within executable and "3959                            "dependent shared library images.",3960                            nullptr, eCommandRequiresTarget) {3961    AddSimpleArgumentList(eArgTypeFilename, eArgRepeatStar);3962  }3963 3964  ~CommandObjectTargetModulesLookup() override = default;3965 3966  Options *GetOptions() override { return &m_options; }3967 3968  bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,3969                  bool &syntax_error) {3970    switch (m_options.m_type) {3971    case eLookupTypeAddress:3972    case eLookupTypeFileLine:3973    case eLookupTypeFunction:3974    case eLookupTypeFunctionOrSymbol:3975    case eLookupTypeSymbol:3976    default:3977      return false;3978    case eLookupTypeType:3979      break;3980    }3981 3982    StackFrameSP frame = m_exe_ctx.GetFrameSP();3983 3984    if (!frame)3985      return false;3986 3987    const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));3988 3989    if (!sym_ctx.module_sp)3990      return false;3991 3992    switch (m_options.m_type) {3993    default:3994      return false;3995    case eLookupTypeType:3996      if (!m_options.m_str.empty()) {3997        if (LookupTypeHere(&GetTarget(), m_interpreter,3998                           result.GetOutputStream(), *sym_ctx.module_sp,3999                           m_options.m_str.c_str(), m_options.m_use_regex)) {4000          result.SetStatus(eReturnStatusSuccessFinishResult);4001          return true;4002        }4003      }4004      break;4005    }4006 4007    return false;4008  }4009 4010  bool LookupInModule(CommandInterpreter &interpreter, Module *module,4011                      CommandReturnObject &result, bool &syntax_error) {4012    switch (m_options.m_type) {4013    case eLookupTypeAddress:4014      if (m_options.m_addr != LLDB_INVALID_ADDRESS) {4015        if (LookupAddressInModule(4016                m_interpreter, result.GetOutputStream(), module,4017                eSymbolContextEverything |4018                    (m_options.m_verbose4019                         ? static_cast<int>(eSymbolContextVariable)4020                         : 0),4021                m_options.m_addr, m_options.m_offset, m_options.m_verbose,4022                m_options.m_all_ranges)) {4023          result.SetStatus(eReturnStatusSuccessFinishResult);4024          return true;4025        }4026      }4027      break;4028 4029    case eLookupTypeSymbol:4030      if (!m_options.m_str.empty()) {4031        if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),4032                                 module, m_options.m_str.c_str(),4033                                 m_options.m_use_regex, m_options.m_verbose,4034                                 m_options.m_all_ranges)) {4035          result.SetStatus(eReturnStatusSuccessFinishResult);4036          return true;4037        }4038      }4039      break;4040 4041    case eLookupTypeFileLine:4042      if (m_options.m_file) {4043        if (LookupFileAndLineInModule(4044                m_interpreter, result.GetOutputStream(), module,4045                m_options.m_file, m_options.m_line_number,4046                m_options.m_include_inlines, m_options.m_verbose,4047                m_options.m_all_ranges)) {4048          result.SetStatus(eReturnStatusSuccessFinishResult);4049          return true;4050        }4051      }4052      break;4053 4054    case eLookupTypeFunctionOrSymbol:4055    case eLookupTypeFunction:4056      if (!m_options.m_str.empty()) {4057        ModuleFunctionSearchOptions function_options;4058        function_options.include_symbols =4059            m_options.m_type == eLookupTypeFunctionOrSymbol;4060        function_options.include_inlines = m_options.m_include_inlines;4061 4062        if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),4063                                   module, m_options.m_str.c_str(),4064                                   m_options.m_use_regex, function_options,4065                                   m_options.m_verbose,4066                                   m_options.m_all_ranges)) {4067          result.SetStatus(eReturnStatusSuccessFinishResult);4068          return true;4069        }4070      }4071      break;4072 4073    case eLookupTypeType:4074      if (!m_options.m_str.empty()) {4075        if (LookupTypeInModule(4076                &GetTarget(), m_interpreter, result.GetOutputStream(), module,4077                m_options.m_str.c_str(), m_options.m_use_regex)) {4078          result.SetStatus(eReturnStatusSuccessFinishResult);4079          return true;4080        }4081      }4082      break;4083 4084    default:4085      m_options.GenerateOptionUsage(4086          result.GetErrorStream(), *this,4087          GetCommandInterpreter().GetDebugger().GetTerminalWidth(),4088          GetCommandInterpreter().GetDebugger().GetUseColor());4089      syntax_error = true;4090      break;4091    }4092 4093    result.SetStatus(eReturnStatusFailed);4094    return false;4095  }4096 4097protected:4098  void DoExecute(Args &command, CommandReturnObject &result) override {4099    Target &target = GetTarget();4100    bool syntax_error = false;4101    uint32_t i;4102    uint32_t num_successful_lookups = 0;4103    uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();4104    result.GetOutputStream().SetAddressByteSize(addr_byte_size);4105    result.GetErrorStream().SetAddressByteSize(addr_byte_size);4106    // Dump all sections for all modules images4107 4108    if (command.GetArgumentCount() == 0) {4109      // Where it is possible to look in the current symbol context first,4110      // try that.  If this search was successful and --all was not passed,4111      // don't print anything else.4112      if (LookupHere(m_interpreter, result, syntax_error)) {4113        result.GetOutputStream().EOL();4114        num_successful_lookups++;4115        if (!m_options.m_print_all) {4116          result.SetStatus(eReturnStatusSuccessFinishResult);4117          return;4118        }4119      }4120 4121      // Dump all sections for all other modules4122 4123      const ModuleList &target_modules = target.GetImages();4124      std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());4125      if (target_modules.GetSize() == 0) {4126        result.AppendError("the target has no associated executable images");4127        return;4128      }4129 4130      for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {4131        if (LookupInModule(m_interpreter, module_sp.get(), result,4132                           syntax_error)) {4133          result.GetOutputStream().EOL();4134          num_successful_lookups++;4135        }4136      }4137    } else {4138      // Dump specified images (by basename or fullpath)4139      const char *arg_cstr;4140      for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&4141                  !syntax_error;4142           ++i) {4143        ModuleList module_list;4144        const size_t num_matches =4145            FindModulesByName(&target, arg_cstr, module_list, false);4146        if (num_matches > 0) {4147          for (size_t j = 0; j < num_matches; ++j) {4148            Module *module = module_list.GetModulePointerAtIndex(j);4149            if (module) {4150              if (LookupInModule(m_interpreter, module, result, syntax_error)) {4151                result.GetOutputStream().EOL();4152                num_successful_lookups++;4153              }4154            }4155          }4156        } else4157          result.AppendWarningWithFormat(4158              "Unable to find an image that matches '%s'.\n", arg_cstr);4159      }4160    }4161 4162    if (num_successful_lookups > 0)4163      result.SetStatus(eReturnStatusSuccessFinishResult);4164    else4165      result.SetStatus(eReturnStatusFailed);4166  }4167 4168  CommandOptions m_options;4169};4170 4171#pragma mark CommandObjectMultiwordImageSearchPaths4172 4173// CommandObjectMultiwordImageSearchPaths4174 4175class CommandObjectTargetModulesImageSearchPaths4176    : public CommandObjectMultiword {4177public:4178  CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)4179      : CommandObjectMultiword(4180            interpreter, "target modules search-paths",4181            "Commands for managing module search paths for a target.",4182            "target modules search-paths <subcommand> [<subcommand-options>]") {4183    LoadSubCommand(4184        "add", CommandObjectSP(4185                   new CommandObjectTargetModulesSearchPathsAdd(interpreter)));4186    LoadSubCommand(4187        "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(4188                     interpreter)));4189    LoadSubCommand(4190        "insert",4191        CommandObjectSP(4192            new CommandObjectTargetModulesSearchPathsInsert(interpreter)));4193    LoadSubCommand(4194        "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(4195                    interpreter)));4196    LoadSubCommand(4197        "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(4198                     interpreter)));4199  }4200 4201  ~CommandObjectTargetModulesImageSearchPaths() override = default;4202};4203 4204#pragma mark CommandObjectTargetModules4205 4206// CommandObjectTargetModules4207 4208class CommandObjectTargetModules : public CommandObjectMultiword {4209public:4210  // Constructors and Destructors4211  CommandObjectTargetModules(CommandInterpreter &interpreter)4212      : CommandObjectMultiword(interpreter, "target modules",4213                               "Commands for accessing information for one or "4214                               "more target modules.",4215                               "target modules <sub-command> ...") {4216    LoadSubCommand(4217        "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));4218    LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(4219                               interpreter)));4220    LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(4221                               interpreter)));4222    LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(4223                               interpreter)));4224    LoadSubCommand(4225        "lookup",4226        CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));4227    LoadSubCommand(4228        "search-paths",4229        CommandObjectSP(4230            new CommandObjectTargetModulesImageSearchPaths(interpreter)));4231    LoadSubCommand(4232        "show-unwind",4233        CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));4234  }4235 4236  ~CommandObjectTargetModules() override = default;4237 4238private:4239  // For CommandObjectTargetModules only4240  CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;4241  const CommandObjectTargetModules &4242  operator=(const CommandObjectTargetModules &) = delete;4243};4244 4245class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {4246public:4247  CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)4248      : CommandObjectParsed(4249            interpreter, "target symbols add",4250            "Add a debug symbol file to one of the target's current modules by "4251            "specifying a path to a debug symbols file or by using the options "4252            "to specify a module.",4253            "target symbols add <cmd-options> [<symfile>]",4254            eCommandRequiresTarget),4255        m_file_option(4256            LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,4257            eArgTypeShlibName,4258            "Locate the debug symbols for the shared library specified by "4259            "name."),4260        m_current_frame_option(4261            LLDB_OPT_SET_2, false, "frame", 'F',4262            "Locate the debug symbols for the currently selected frame.", false,4263            true),4264        m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',4265                               "Locate the debug symbols for every frame in "4266                               "the current call stack.",4267                               false, true)4268 4269  {4270    m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,4271                          LLDB_OPT_SET_1);4272    m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);4273    m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,4274                          LLDB_OPT_SET_2);4275    m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,4276                          LLDB_OPT_SET_2);4277    m_option_group.Finalize();4278    AddSimpleArgumentList(eArgTypeFilename);4279  }4280 4281  ~CommandObjectTargetSymbolsAdd() override = default;4282 4283  Options *GetOptions() override { return &m_option_group; }4284 4285protected:4286  bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,4287                        CommandReturnObject &result) {4288    const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();4289    if (!symbol_fspec) {4290      result.AppendError(4291          "one or more executable image paths must be specified");4292      return false;4293    }4294 4295    char symfile_path[PATH_MAX];4296    symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));4297 4298    if (!module_spec.GetUUID().IsValid()) {4299      if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())4300        module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());4301    }4302 4303    // Now module_spec represents a symbol file for a module that might exist4304    // in the current target.  Let's find possible matches.4305    ModuleList matching_modules;4306 4307    // First extract all module specs from the symbol file4308    lldb_private::ModuleSpecList symfile_module_specs;4309    if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),4310                                            0, 0, symfile_module_specs)) {4311      // Now extract the module spec that matches the target architecture4312      ModuleSpec target_arch_module_spec;4313      ModuleSpec symfile_module_spec;4314      target_arch_module_spec.GetArchitecture() = target->GetArchitecture();4315      if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,4316                                                      symfile_module_spec)) {4317        if (symfile_module_spec.GetUUID().IsValid()) {4318          // It has a UUID, look for this UUID in the target modules4319          ModuleSpec symfile_uuid_module_spec;4320          symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();4321          target->GetImages().FindModules(symfile_uuid_module_spec,4322                                          matching_modules);4323        }4324      }4325 4326      if (matching_modules.IsEmpty()) {4327        // No matches yet.  Iterate through the module specs to find a UUID4328        // value that we can match up to an image in our target.4329        const size_t num_symfile_module_specs = symfile_module_specs.GetSize();4330        for (size_t i = 0;4331             i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {4332          if (symfile_module_specs.GetModuleSpecAtIndex(4333                  i, symfile_module_spec)) {4334            if (symfile_module_spec.GetUUID().IsValid()) {4335              // It has a UUID.  Look for this UUID in the target modules.4336              ModuleSpec symfile_uuid_module_spec;4337              symfile_uuid_module_spec.GetUUID() =4338                  symfile_module_spec.GetUUID();4339              target->GetImages().FindModules(symfile_uuid_module_spec,4340                                              matching_modules);4341            }4342          }4343        }4344      }4345    }4346 4347    // Just try to match up the file by basename if we have no matches at4348    // this point.  For example, module foo might have symbols in foo.debug.4349    if (matching_modules.IsEmpty())4350      target->GetImages().FindModules(module_spec, matching_modules);4351 4352    while (matching_modules.IsEmpty()) {4353      ConstString filename_no_extension(4354          module_spec.GetFileSpec().GetFileNameStrippingExtension());4355      // Empty string returned, let's bail4356      if (!filename_no_extension)4357        break;4358 4359      // Check if there was no extension to strip and the basename is the same4360      if (filename_no_extension == module_spec.GetFileSpec().GetFilename())4361        break;4362 4363      // Replace basename with one fewer extension4364      module_spec.GetFileSpec().SetFilename(filename_no_extension);4365      target->GetImages().FindModules(module_spec, matching_modules);4366    }4367 4368    if (matching_modules.GetSize() > 1) {4369      result.AppendErrorWithFormat("multiple modules match symbol file '%s', "4370                                   "use the --uuid option to resolve the "4371                                   "ambiguity.\n",4372                                   symfile_path);4373      return false;4374    }4375 4376    if (matching_modules.GetSize() == 1) {4377      ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));4378 4379      // The module has not yet created its symbol vendor, we can just give4380      // the existing target module the symfile path to use for when it4381      // decides to create it!4382      module_sp->SetSymbolFileFileSpec(symbol_fspec);4383 4384      SymbolFile *symbol_file =4385          module_sp->GetSymbolFile(true, &result.GetErrorStream());4386      if (symbol_file) {4387        ObjectFile *object_file = symbol_file->GetObjectFile();4388        if (object_file && object_file->GetFileSpec() == symbol_fspec) {4389          // Provide feedback that the symfile has been successfully added.4390          const FileSpec &module_fs = module_sp->GetFileSpec();4391          result.AppendMessageWithFormat(4392              "symbol file '%s' has been added to '%s'\n", symfile_path,4393              module_fs.GetPath().c_str());4394 4395          // Let clients know something changed in the module if it is4396          // currently loaded4397          ModuleList module_list;4398          module_list.Append(module_sp);4399          target->SymbolsDidLoad(module_list);4400 4401          // Make sure we load any scripting resources that may be embedded4402          // in the debug info files in case the platform supports that.4403          Status error;4404          StreamString feedback_stream;4405          module_sp->LoadScriptingResourceInTarget(target, error,4406                                                   feedback_stream);4407          if (error.Fail() && error.AsCString())4408            result.AppendWarningWithFormat(4409                "unable to load scripting data for module %s - error "4410                "reported was %s",4411                module_sp->GetFileSpec()4412                    .GetFileNameStrippingExtension()4413                    .GetCString(),4414                error.AsCString());4415          else if (feedback_stream.GetSize())4416            result.AppendWarning(feedback_stream.GetData());4417 4418          flush = true;4419          result.SetStatus(eReturnStatusSuccessFinishResult);4420          return true;4421        }4422      }4423      // Clear the symbol file spec if anything went wrong4424      module_sp->SetSymbolFileFileSpec(FileSpec());4425    }4426 4427    StreamString ss_symfile_uuid;4428    if (module_spec.GetUUID().IsValid()) {4429      ss_symfile_uuid << " (";4430      module_spec.GetUUID().Dump(ss_symfile_uuid);4431      ss_symfile_uuid << ')';4432    }4433    result.AppendErrorWithFormat(4434        "symbol file '%s'%s does not match any existing module%s\n",4435        symfile_path, ss_symfile_uuid.GetData(),4436        !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())4437            ? "\n       please specify the full path to the symbol file"4438            : "");4439    return false;4440  }4441 4442  bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,4443                                   CommandReturnObject &result, bool &flush) {4444    Status error;4445    if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) {4446      if (module_spec.GetSymbolFileSpec())4447        return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,4448                                result);4449    } else {4450      result.SetError(std::move(error));4451    }4452    return false;4453  }4454 4455  bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {4456    assert(m_uuid_option_group.GetOptionValue().OptionWasSet());4457 4458    ModuleSpec module_spec;4459    module_spec.GetUUID() =4460        m_uuid_option_group.GetOptionValue().GetCurrentValue();4461 4462    if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {4463      StreamString error_strm;4464      error_strm.PutCString("unable to find debug symbols for UUID ");4465      module_spec.GetUUID().Dump(error_strm);4466      result.AppendError(error_strm.GetString());4467      return false;4468    }4469 4470    return true;4471  }4472 4473  bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {4474    assert(m_file_option.GetOptionValue().OptionWasSet());4475 4476    ModuleSpec module_spec;4477    module_spec.GetFileSpec() =4478        m_file_option.GetOptionValue().GetCurrentValue();4479 4480    Target *target = m_exe_ctx.GetTargetPtr();4481    ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));4482    if (module_sp) {4483      module_spec.GetFileSpec() = module_sp->GetFileSpec();4484      module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();4485      module_spec.GetUUID() = module_sp->GetUUID();4486      module_spec.GetArchitecture() = module_sp->GetArchitecture();4487    } else {4488      module_spec.GetArchitecture() = target->GetArchitecture();4489    }4490 4491    if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {4492      StreamString error_strm;4493      error_strm.PutCString(4494          "unable to find debug symbols for the executable file ");4495      error_strm << module_spec.GetFileSpec();4496      result.AppendError(error_strm.GetString());4497      return false;4498    }4499 4500    return true;4501  }4502 4503  bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {4504    assert(m_current_frame_option.GetOptionValue().OptionWasSet());4505 4506    Process *process = m_exe_ctx.GetProcessPtr();4507    if (!process) {4508      result.AppendError(4509          "a process must exist in order to use the --frame option");4510      return false;4511    }4512 4513    const StateType process_state = process->GetState();4514    if (!StateIsStoppedState(process_state, true)) {4515      result.AppendErrorWithFormat("process is not stopped: %s",4516                                   StateAsCString(process_state));4517      return false;4518    }4519 4520    StackFrame *frame = m_exe_ctx.GetFramePtr();4521    if (!frame) {4522      result.AppendError("invalid current frame");4523      return false;4524    }4525 4526    ModuleSP frame_module_sp(4527        frame->GetSymbolContext(eSymbolContextModule).module_sp);4528    if (!frame_module_sp) {4529      result.AppendError("frame has no module");4530      return false;4531    }4532 4533    ModuleSpec module_spec;4534    module_spec.GetUUID() = frame_module_sp->GetUUID();4535    module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();4536    module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();4537 4538    if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {4539      result.AppendError("unable to find debug symbols for the current frame");4540      return false;4541    }4542 4543    return true;4544  }4545 4546  bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {4547    assert(m_current_stack_option.GetOptionValue().OptionWasSet());4548 4549    Process *process = m_exe_ctx.GetProcessPtr();4550    if (!process) {4551      result.AppendError(4552          "a process must exist in order to use the --stack option");4553      return false;4554    }4555 4556    const StateType process_state = process->GetState();4557    if (!StateIsStoppedState(process_state, true)) {4558      result.AppendErrorWithFormat("process is not stopped: %s",4559                                   StateAsCString(process_state));4560      return false;4561    }4562 4563    Thread *thread = m_exe_ctx.GetThreadPtr();4564    if (!thread) {4565      result.AppendError("invalid current thread");4566      return false;4567    }4568 4569    bool symbols_found = false;4570    uint32_t frame_count = thread->GetStackFrameCount();4571    for (uint32_t i = 0; i < frame_count; ++i) {4572      lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);4573 4574      ModuleSP frame_module_sp(4575          frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);4576      if (!frame_module_sp)4577        continue;4578 4579      ModuleSpec module_spec;4580      module_spec.GetUUID() = frame_module_sp->GetUUID();4581      module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();4582      module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();4583 4584      bool current_frame_flush = false;4585      if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))4586        symbols_found = true;4587      flush |= current_frame_flush;4588    }4589 4590    if (!symbols_found) {4591      result.AppendError(4592          "unable to find debug symbols in the current call stack");4593      return false;4594    }4595 4596    return true;4597  }4598 4599  void DoExecute(Args &args, CommandReturnObject &result) override {4600    Target *target = m_exe_ctx.GetTargetPtr();4601    result.SetStatus(eReturnStatusFailed);4602    bool flush = false;4603    ModuleSpec module_spec;4604    const bool uuid_option_set =4605        m_uuid_option_group.GetOptionValue().OptionWasSet();4606    const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();4607    const bool frame_option_set =4608        m_current_frame_option.GetOptionValue().OptionWasSet();4609    const bool stack_option_set =4610        m_current_stack_option.GetOptionValue().OptionWasSet();4611    const size_t argc = args.GetArgumentCount();4612 4613    if (argc == 0) {4614      if (uuid_option_set)4615        AddSymbolsForUUID(result, flush);4616      else if (file_option_set)4617        AddSymbolsForFile(result, flush);4618      else if (frame_option_set)4619        AddSymbolsForFrame(result, flush);4620      else if (stack_option_set)4621        AddSymbolsForStack(result, flush);4622      else4623        result.AppendError("one or more symbol file paths must be specified, "4624                           "or options must be specified");4625    } else {4626      if (uuid_option_set) {4627        result.AppendError("specify either one or more paths to symbol files "4628                           "or use the --uuid option without arguments");4629      } else if (frame_option_set) {4630        result.AppendError("specify either one or more paths to symbol files "4631                           "or use the --frame option without arguments");4632      } else if (file_option_set && argc > 1) {4633        result.AppendError("specify at most one symbol file path when "4634                           "--shlib option is set");4635      } else {4636        PlatformSP platform_sp(target->GetPlatform());4637 4638        for (auto &entry : args.entries()) {4639          if (!entry.ref().empty()) {4640            auto &symbol_file_spec = module_spec.GetSymbolFileSpec();4641            symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);4642            FileSystem::Instance().Resolve(symbol_file_spec);4643            if (file_option_set) {4644              module_spec.GetFileSpec() =4645                  m_file_option.GetOptionValue().GetCurrentValue();4646            }4647            if (platform_sp) {4648              FileSpec symfile_spec;4649              if (platform_sp4650                      ->ResolveSymbolFile(*target, module_spec, symfile_spec)4651                      .Success())4652                module_spec.GetSymbolFileSpec() = symfile_spec;4653            }4654 4655            bool symfile_exists =4656                FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());4657 4658            if (symfile_exists) {4659              if (!AddModuleSymbols(target, module_spec, flush, result))4660                break;4661            } else {4662              std::string resolved_symfile_path =4663                  module_spec.GetSymbolFileSpec().GetPath();4664              if (resolved_symfile_path != entry.ref()) {4665                result.AppendErrorWithFormat(4666                    "invalid module path '%s' with resolved path '%s'\n",4667                    entry.c_str(), resolved_symfile_path.c_str());4668                break;4669              }4670              result.AppendErrorWithFormat("invalid module path '%s'\n",4671                                           entry.c_str());4672              break;4673            }4674          }4675        }4676      }4677    }4678 4679    if (flush) {4680      Process *process = m_exe_ctx.GetProcessPtr();4681      if (process)4682        process->Flush();4683    }4684  }4685 4686  OptionGroupOptions m_option_group;4687  OptionGroupUUID m_uuid_option_group;4688  OptionGroupFile m_file_option;4689  OptionGroupBoolean m_current_frame_option;4690  OptionGroupBoolean m_current_stack_option;4691};4692 4693#pragma mark CommandObjectTargetSymbols4694 4695// CommandObjectTargetSymbols4696 4697class CommandObjectTargetSymbols : public CommandObjectMultiword {4698public:4699  // Constructors and Destructors4700  CommandObjectTargetSymbols(CommandInterpreter &interpreter)4701      : CommandObjectMultiword(4702            interpreter, "target symbols",4703            "Commands for adding and managing debug symbol files.",4704            "target symbols <sub-command> ...") {4705    LoadSubCommand(4706        "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));4707  }4708 4709  ~CommandObjectTargetSymbols() override = default;4710 4711private:4712  // For CommandObjectTargetModules only4713  CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;4714  const CommandObjectTargetSymbols &4715  operator=(const CommandObjectTargetSymbols &) = delete;4716};4717 4718#pragma mark CommandObjectTargetStopHookAdd4719 4720// CommandObjectTargetStopHookAdd4721#define LLDB_OPTIONS_target_stop_hook_add4722#include "CommandOptions.inc"4723 4724class CommandObjectTargetStopHookAdd : public CommandObjectParsed,4725                                       public IOHandlerDelegateMultiline {4726public:4727  class CommandOptions : public OptionGroup {4728  public:4729    CommandOptions() : m_line_end(UINT_MAX) {}4730 4731    ~CommandOptions() override = default;4732 4733    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {4734      return llvm::ArrayRef(g_target_stop_hook_add_options);4735    }4736 4737    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,4738                          ExecutionContext *execution_context) override {4739      Status error;4740      const int short_option =4741          g_target_stop_hook_add_options[option_idx].short_option;4742 4743      switch (short_option) {4744      case 'c':4745        m_class_name = std::string(option_arg);4746        m_sym_ctx_specified = true;4747        break;4748 4749      case 'e':4750        if (option_arg.getAsInteger(0, m_line_end)) {4751          error = Status::FromErrorStringWithFormat(4752              "invalid end line number: \"%s\"", option_arg.str().c_str());4753          break;4754        }4755        m_sym_ctx_specified = true;4756        break;4757 4758      case 'G': {4759        bool value, success;4760        value = OptionArgParser::ToBoolean(option_arg, false, &success);4761        if (success) {4762          m_auto_continue = value;4763        } else4764          error = Status::FromErrorStringWithFormat(4765              "invalid boolean value '%s' passed for -G option",4766              option_arg.str().c_str());4767      } break;4768      case 'l':4769        if (option_arg.getAsInteger(0, m_line_start)) {4770          error = Status::FromErrorStringWithFormat(4771              "invalid start line number: \"%s\"", option_arg.str().c_str());4772          break;4773        }4774        m_sym_ctx_specified = true;4775        break;4776 4777      case 'i':4778        m_no_inlines = true;4779        break;4780 4781      case 'n':4782        m_function_name = std::string(option_arg);4783        m_func_name_type_mask |= eFunctionNameTypeAuto;4784        m_sym_ctx_specified = true;4785        break;4786 4787      case 'f':4788        m_file_name = std::string(option_arg);4789        m_sym_ctx_specified = true;4790        break;4791 4792      case 's':4793        m_module_name = std::string(option_arg);4794        m_sym_ctx_specified = true;4795        break;4796 4797      case 't':4798        if (option_arg.getAsInteger(0, m_thread_id))4799          error = Status::FromErrorStringWithFormat(4800              "invalid thread id string '%s'", option_arg.str().c_str());4801        m_thread_specified = true;4802        break;4803 4804      case 'T':4805        m_thread_name = std::string(option_arg);4806        m_thread_specified = true;4807        break;4808 4809      case 'q':4810        m_queue_name = std::string(option_arg);4811        m_thread_specified = true;4812        break;4813 4814      case 'x':4815        if (option_arg.getAsInteger(0, m_thread_index))4816          error = Status::FromErrorStringWithFormat(4817              "invalid thread index string '%s'", option_arg.str().c_str());4818        m_thread_specified = true;4819        break;4820 4821      case 'o':4822        m_use_one_liner = true;4823        m_one_liner.push_back(std::string(option_arg));4824        break;4825 4826      case 'I': {4827        bool value, success;4828        value = OptionArgParser::ToBoolean(option_arg, false, &success);4829        if (success)4830          m_at_initial_stop = value;4831        else4832          error = Status::FromErrorStringWithFormat(4833              "invalid boolean value '%s' passed for -F option",4834              option_arg.str().c_str());4835      } break;4836 4837      default:4838        llvm_unreachable("Unimplemented option");4839      }4840      return error;4841    }4842 4843    void OptionParsingStarting(ExecutionContext *execution_context) override {4844      m_class_name.clear();4845      m_function_name.clear();4846      m_line_start = 0;4847      m_line_end = LLDB_INVALID_LINE_NUMBER;4848      m_file_name.clear();4849      m_module_name.clear();4850      m_func_name_type_mask = eFunctionNameTypeAuto;4851      m_thread_id = LLDB_INVALID_THREAD_ID;4852      m_thread_index = UINT32_MAX;4853      m_thread_name.clear();4854      m_queue_name.clear();4855 4856      m_no_inlines = false;4857      m_sym_ctx_specified = false;4858      m_thread_specified = false;4859 4860      m_use_one_liner = false;4861      m_one_liner.clear();4862      m_auto_continue = false;4863      m_at_initial_stop = true;4864    }4865 4866    std::string m_class_name;4867    std::string m_function_name;4868    uint32_t m_line_start = 0;4869    uint32_t m_line_end = LLDB_INVALID_LINE_NUMBER;4870    std::string m_file_name;4871    std::string m_module_name;4872    uint32_t m_func_name_type_mask =4873        eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.4874    lldb::tid_t m_thread_id = LLDB_INVALID_THREAD_ID;4875    uint32_t m_thread_index = UINT32_MAX;4876    std::string m_thread_name;4877    std::string m_queue_name;4878    bool m_sym_ctx_specified = false;4879    bool m_no_inlines = false;4880    bool m_thread_specified = false;4881    // Instance variables to hold the values for one_liner options.4882    bool m_use_one_liner = false;4883    std::vector<std::string> m_one_liner;4884    bool m_at_initial_stop;4885 4886    bool m_auto_continue = false;4887  };4888 4889  CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)4890      : CommandObjectParsed(interpreter, "target stop-hook add",4891                            "Add a hook to be executed when the target stops."4892                            "The hook can either be a list of commands or an "4893                            "appropriately defined Python class.  You can also "4894                            "add filters so the hook only runs a certain stop "4895                            "points.",4896                            "target stop-hook add"),4897        IOHandlerDelegateMultiline("DONE",4898                                   IOHandlerDelegate::Completion::LLDBCommand),4899        m_python_class_options("scripted stop-hook", true, 'P') {4900    SetHelpLong(4901        R"(4902Command Based stop-hooks:4903-------------------------4904  Stop hooks can run a list of lldb commands by providing one or more4905  --one-liner options.  The commands will get run in the order they are added.4906  Or you can provide no commands, in which case you will enter a command editor4907  where you can enter the commands to be run.4908 4909Python Based Stop Hooks:4910------------------------4911  Stop hooks can be implemented with a suitably defined Python class, whose name4912  is passed in the --python-class option.4913 4914  When the stop hook is added, the class is initialized by calling:4915 4916    def __init__(self, target, extra_args, internal_dict):4917 4918    target: The target that the stop hook is being added to.4919    extra_args: An SBStructuredData Dictionary filled with the -key -value4920                option pairs passed to the command.4921    dict: An implementation detail provided by lldb.4922 4923  Then when the stop-hook triggers, lldb will run the 'handle_stop' method.4924  The method has the signature:4925 4926    def handle_stop(self, exe_ctx, stream):4927 4928    exe_ctx: An SBExecutionContext for the thread that has stopped.4929    stream: An SBStream, anything written to this stream will be printed in the4930            the stop message when the process stops.4931 4932    Return Value: The method returns "should_stop".  If should_stop is false4933                  from all the stop hook executions on threads that stopped4934                  with a reason, then the process will continue.  Note that this4935                  will happen only after all the stop hooks are run.4936 4937Filter Options:4938---------------4939  Stop hooks can be set to always run, or to only run when the stopped thread4940  matches the filter options passed on the command line.  The available filter4941  options include a shared library or a thread or queue specification,4942  a line range in a source file, a function name or a class name.4943            )");4944    m_all_options.Append(&m_python_class_options,4945                         LLDB_OPT_SET_1 | LLDB_OPT_SET_2,4946                         LLDB_OPT_SET_FROM_TO(4, 6));4947    m_all_options.Append(&m_options);4948    m_all_options.Finalize();4949  }4950 4951  ~CommandObjectTargetStopHookAdd() override = default;4952 4953  Options *GetOptions() override { return &m_all_options; }4954 4955protected:4956  void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {4957    if (interactive) {4958      if (lldb::LockableStreamFileSP output_sp =4959              io_handler.GetOutputStreamFileSP()) {4960        LockedStreamFile locked_stream = output_sp->Lock();4961        locked_stream.PutCString(4962            "Enter your stop hook command(s).  Type 'DONE' to end.\n");4963      }4964    }4965  }4966 4967  void IOHandlerInputComplete(IOHandler &io_handler,4968                              std::string &line) override {4969    if (m_stop_hook_sp) {4970      if (line.empty()) {4971        if (lldb::LockableStreamFileSP error_sp =4972                io_handler.GetErrorStreamFileSP()) {4973          LockedStreamFile locked_stream = error_sp->Lock();4974          locked_stream.Printf("error: stop hook #%" PRIu644975                               " aborted, no commands.\n",4976                               m_stop_hook_sp->GetID());4977        }4978        GetTarget().UndoCreateStopHook(m_stop_hook_sp->GetID());4979      } else {4980        // The IOHandler editor is only for command lines stop hooks:4981        Target::StopHookCommandLine *hook_ptr =4982            static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());4983 4984        hook_ptr->SetActionFromString(line);4985        if (lldb::LockableStreamFileSP output_sp =4986                io_handler.GetOutputStreamFileSP()) {4987          LockedStreamFile locked_stream = output_sp->Lock();4988          locked_stream.Printf("Stop hook #%" PRIu64 " added.\n",4989                               m_stop_hook_sp->GetID());4990        }4991      }4992      m_stop_hook_sp.reset();4993    }4994    io_handler.SetIsDone(true);4995  }4996 4997  void DoExecute(Args &command, CommandReturnObject &result) override {4998    m_stop_hook_sp.reset();4999 5000    Target &target = GetTarget();5001    Target::StopHookSP new_hook_sp =5002        target.CreateStopHook(m_python_class_options.GetName().empty() ?5003                               Target::StopHook::StopHookKind::CommandBased5004                               : Target::StopHook::StopHookKind::ScriptBased);5005 5006    //  First step, make the specifier.5007    std::unique_ptr<SymbolContextSpecifier> specifier_up;5008    if (m_options.m_sym_ctx_specified) {5009      specifier_up = std::make_unique<SymbolContextSpecifier>(5010          GetDebugger().GetSelectedTarget());5011 5012      if (!m_options.m_module_name.empty()) {5013        specifier_up->AddSpecification(5014            m_options.m_module_name.c_str(),5015            SymbolContextSpecifier::eModuleSpecified);5016      }5017 5018      if (!m_options.m_class_name.empty()) {5019        specifier_up->AddSpecification(5020            m_options.m_class_name.c_str(),5021            SymbolContextSpecifier::eClassOrNamespaceSpecified);5022      }5023 5024      if (!m_options.m_file_name.empty()) {5025        specifier_up->AddSpecification(m_options.m_file_name.c_str(),5026                                       SymbolContextSpecifier::eFileSpecified);5027      }5028 5029      if (m_options.m_line_start != 0) {5030        specifier_up->AddLineSpecification(5031            m_options.m_line_start,5032            SymbolContextSpecifier::eLineStartSpecified);5033      }5034 5035      if (m_options.m_line_end != UINT_MAX) {5036        specifier_up->AddLineSpecification(5037            m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);5038      }5039 5040      if (!m_options.m_function_name.empty()) {5041        specifier_up->AddSpecification(5042            m_options.m_function_name.c_str(),5043            SymbolContextSpecifier::eFunctionSpecified);5044      }5045    }5046 5047    if (specifier_up)5048      new_hook_sp->SetSpecifier(specifier_up.release());5049 5050    // Should we run at the initial stop:5051    new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);5052 5053    // Next see if any of the thread options have been entered:5054 5055    if (m_options.m_thread_specified) {5056      ThreadSpec *thread_spec = new ThreadSpec();5057 5058      if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {5059        thread_spec->SetTID(m_options.m_thread_id);5060      }5061 5062      if (m_options.m_thread_index != UINT32_MAX)5063        thread_spec->SetIndex(m_options.m_thread_index);5064 5065      if (!m_options.m_thread_name.empty())5066        thread_spec->SetName(m_options.m_thread_name.c_str());5067 5068      if (!m_options.m_queue_name.empty())5069        thread_spec->SetQueueName(m_options.m_queue_name.c_str());5070 5071      new_hook_sp->SetThreadSpecifier(thread_spec);5072    }5073 5074    new_hook_sp->SetAutoContinue(m_options.m_auto_continue);5075    if (m_options.m_use_one_liner) {5076      // This is a command line stop hook:5077      Target::StopHookCommandLine *hook_ptr =5078          static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());5079      hook_ptr->SetActionFromStrings(m_options.m_one_liner);5080      result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",5081                                     new_hook_sp->GetID());5082    } else if (!m_python_class_options.GetName().empty()) {5083      // This is a scripted stop hook:5084      Target::StopHookScripted *hook_ptr =5085          static_cast<Target::StopHookScripted *>(new_hook_sp.get());5086      Status error = hook_ptr->SetScriptCallback(5087          m_python_class_options.GetName(),5088          m_python_class_options.GetStructuredData());5089      if (error.Success())5090        result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",5091                                       new_hook_sp->GetID());5092      else {5093        // FIXME: Set the stop hook ID counter back.5094        result.AppendErrorWithFormat("Couldn't add stop hook: %s",5095                                     error.AsCString());5096        target.UndoCreateStopHook(new_hook_sp->GetID());5097        return;5098      }5099    } else {5100      m_stop_hook_sp = new_hook_sp;5101      m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt5102                                                 *this); // IOHandlerDelegate5103    }5104    result.SetStatus(eReturnStatusSuccessFinishNoResult);5105  }5106 5107private:5108  CommandOptions m_options;5109  OptionGroupPythonClassWithDict m_python_class_options;5110  OptionGroupOptions m_all_options;5111 5112  Target::StopHookSP m_stop_hook_sp;5113};5114 5115#pragma mark CommandObjectTargetStopHookDelete5116 5117// CommandObjectTargetStopHookDelete5118 5119class CommandObjectTargetStopHookDelete : public CommandObjectParsed {5120public:5121  CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)5122      : CommandObjectParsed(interpreter, "target stop-hook delete",5123                            "Delete a stop-hook.",5124                            "target stop-hook delete [<idx>]") {5125    SetHelpLong(5126        R"(5127Deletes the stop hook by index.5128 5129At any given stop, all enabled stop hooks that pass the stop filter will5130get a chance to run.  That means if one stop-hook deletes another stop hook 5131while executing, the deleted stop hook will still fire for the stop at which 5132it was deleted.5133        )");5134    AddSimpleArgumentList(eArgTypeStopHookID, eArgRepeatStar);5135  }5136 5137  ~CommandObjectTargetStopHookDelete() override = default;5138 5139  void5140  HandleArgumentCompletion(CompletionRequest &request,5141                           OptionElementVector &opt_element_vector) override {5142    if (request.GetCursorIndex())5143      return;5144    CommandObject::HandleArgumentCompletion(request, opt_element_vector);5145  }5146 5147protected:5148  void DoExecute(Args &command, CommandReturnObject &result) override {5149    Target &target = GetTarget();5150    // FIXME: see if we can use the breakpoint id style parser?5151    size_t num_args = command.GetArgumentCount();5152    if (num_args == 0) {5153      if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {5154        result.SetStatus(eReturnStatusFailed);5155        return;5156      } else {5157        target.RemoveAllStopHooks();5158      }5159    } else {5160      for (size_t i = 0; i < num_args; i++) {5161        lldb::user_id_t user_id;5162        if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {5163          result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",5164                                       command.GetArgumentAtIndex(i));5165          return;5166        }5167        if (!target.RemoveStopHookByID(user_id)) {5168          result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",5169                                       command.GetArgumentAtIndex(i));5170          return;5171        }5172      }5173    }5174    result.SetStatus(eReturnStatusSuccessFinishNoResult);5175  }5176};5177 5178#pragma mark CommandObjectTargetStopHookEnableDisable5179 5180// CommandObjectTargetStopHookEnableDisable5181 5182class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {5183public:5184  CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,5185                                           bool enable, const char *name,5186                                           const char *help, const char *syntax)5187      : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {5188    AddSimpleArgumentList(eArgTypeStopHookID, eArgRepeatStar);5189  }5190 5191  ~CommandObjectTargetStopHookEnableDisable() override = default;5192 5193  void5194  HandleArgumentCompletion(CompletionRequest &request,5195                           OptionElementVector &opt_element_vector) override {5196    if (request.GetCursorIndex())5197      return;5198    CommandObject::HandleArgumentCompletion(request, opt_element_vector);5199  }5200 5201protected:5202  void DoExecute(Args &command, CommandReturnObject &result) override {5203    Target &target = GetTarget();5204    // FIXME: see if we can use the breakpoint id style parser?5205    size_t num_args = command.GetArgumentCount();5206    bool success;5207 5208    if (num_args == 0) {5209      target.SetAllStopHooksActiveState(m_enable);5210    } else {5211      for (size_t i = 0; i < num_args; i++) {5212        lldb::user_id_t user_id;5213        if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {5214          result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",5215                                       command.GetArgumentAtIndex(i));5216          return;5217        }5218        success = target.SetStopHookActiveStateByID(user_id, m_enable);5219        if (!success) {5220          result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",5221                                       command.GetArgumentAtIndex(i));5222          return;5223        }5224      }5225    }5226    result.SetStatus(eReturnStatusSuccessFinishNoResult);5227  }5228 5229private:5230  bool m_enable;5231};5232 5233#pragma mark CommandObjectTargetStopHookList5234 5235// CommandObjectTargetStopHookList5236#define LLDB_OPTIONS_target_stop_hook_list5237#include "CommandOptions.inc"5238 5239class CommandObjectTargetStopHookList : public CommandObjectParsed {5240public:5241  CommandObjectTargetStopHookList(CommandInterpreter &interpreter)5242      : CommandObjectParsed(interpreter, "target stop-hook list",5243                            "List all stop-hooks.") {}5244 5245  ~CommandObjectTargetStopHookList() override = default;5246 5247  Options *GetOptions() override { return &m_options; }5248 5249  class CommandOptions : public Options {5250  public:5251    CommandOptions() = default;5252    ~CommandOptions() override = default;5253 5254    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,5255                          ExecutionContext *execution_context) override {5256      Status error;5257      const int short_option = m_getopt_table[option_idx].val;5258 5259      switch (short_option) {5260      case 'i':5261        m_internal = true;5262        break;5263      default:5264        llvm_unreachable("Unimplemented option");5265      }5266 5267      return error;5268    }5269 5270    void OptionParsingStarting(ExecutionContext *execution_context) override {5271      m_internal = false;5272    }5273 5274    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {5275      return llvm::ArrayRef(g_target_stop_hook_list_options);5276    }5277 5278    // Instance variables to hold the values for command options.5279    bool m_internal = false;5280  };5281 5282protected:5283  void DoExecute(Args &command, CommandReturnObject &result) override {5284    Target &target = GetTarget();5285 5286    bool printed_hook = false;5287    for (auto &hook : target.GetStopHooks(m_options.m_internal)) {5288      if (printed_hook)5289        result.GetOutputStream().PutCString("\n");5290      hook->GetDescription(result.GetOutputStream(), eDescriptionLevelFull);5291      printed_hook = true;5292    }5293 5294    if (!printed_hook)5295      result.GetOutputStream().PutCString("No stop hooks.\n");5296 5297    result.SetStatus(eReturnStatusSuccessFinishResult);5298  }5299 5300private:5301  CommandOptions m_options;5302};5303 5304#pragma mark CommandObjectMultiwordTargetStopHooks5305 5306// CommandObjectMultiwordTargetStopHooks5307 5308class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {5309public:5310  CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)5311      : CommandObjectMultiword(5312            interpreter, "target stop-hook",5313            "Commands for operating on debugger target stop-hooks.",5314            "target stop-hook <subcommand> [<subcommand-options>]") {5315    LoadSubCommand("add", CommandObjectSP(5316                              new CommandObjectTargetStopHookAdd(interpreter)));5317    LoadSubCommand(5318        "delete",5319        CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));5320    LoadSubCommand("disable",5321                   CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(5322                       interpreter, false, "target stop-hook disable [<id>]",5323                       "Disable a stop-hook.", "target stop-hook disable")));5324    LoadSubCommand("enable",5325                   CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(5326                       interpreter, true, "target stop-hook enable [<id>]",5327                       "Enable a stop-hook.", "target stop-hook enable")));5328    LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(5329                               interpreter)));5330  }5331 5332  ~CommandObjectMultiwordTargetStopHooks() override = default;5333};5334 5335#pragma mark CommandObjectTargetDumpTypesystem5336 5337/// Dumps the TypeSystem of the selected Target.5338class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {5339public:5340  CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)5341      : CommandObjectParsed(5342            interpreter, "target dump typesystem",5343            "Dump the state of the target's internal type system. Intended to "5344            "be used for debugging LLDB itself.",5345            nullptr, eCommandRequiresTarget) {}5346 5347  ~CommandObjectTargetDumpTypesystem() override = default;5348 5349protected:5350  void DoExecute(Args &command, CommandReturnObject &result) override {5351    // Go over every scratch TypeSystem and dump to the command output.5352    for (lldb::TypeSystemSP ts : GetTarget().GetScratchTypeSystems())5353      if (ts)5354        ts->Dump(result.GetOutputStream().AsRawOstream(), "",5355                 GetCommandInterpreter().GetDebugger().GetUseColor());5356 5357    result.SetStatus(eReturnStatusSuccessFinishResult);5358  }5359};5360 5361#pragma mark CommandObjectTargetDumpSectionLoadList5362 5363/// Dumps the SectionLoadList of the selected Target.5364class CommandObjectTargetDumpSectionLoadList : public CommandObjectParsed {5365public:5366  CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter)5367      : CommandObjectParsed(5368            interpreter, "target dump section-load-list",5369            "Dump the state of the target's internal section load list. "5370            "Intended to be used for debugging LLDB itself.",5371            nullptr, eCommandRequiresTarget) {}5372 5373  ~CommandObjectTargetDumpSectionLoadList() override = default;5374 5375protected:5376  void DoExecute(Args &command, CommandReturnObject &result) override {5377    Target &target = GetTarget();5378    target.DumpSectionLoadList(result.GetOutputStream());5379    result.SetStatus(eReturnStatusSuccessFinishResult);5380  }5381};5382 5383#pragma mark CommandObjectTargetDump5384 5385/// Multi-word command for 'target dump'.5386class CommandObjectTargetDump : public CommandObjectMultiword {5387public:5388  // Constructors and Destructors5389  CommandObjectTargetDump(CommandInterpreter &interpreter)5390      : CommandObjectMultiword(5391            interpreter, "target dump",5392            "Commands for dumping information about the target.",5393            "target dump [typesystem|section-load-list]") {5394    LoadSubCommand(5395        "typesystem",5396        CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter)));5397    LoadSubCommand("section-load-list",5398                   CommandObjectSP(new CommandObjectTargetDumpSectionLoadList(5399                       interpreter)));5400  }5401 5402  ~CommandObjectTargetDump() override = default;5403};5404 5405#pragma mark CommandObjectMultiwordTarget5406 5407// CommandObjectMultiwordTarget5408 5409CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(5410    CommandInterpreter &interpreter)5411    : CommandObjectMultiword(interpreter, "target",5412                             "Commands for operating on debugger targets.",5413                             "target <subcommand> [<subcommand-options>]") {5414  LoadSubCommand("create",5415                 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));5416  LoadSubCommand("delete",5417                 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));5418  LoadSubCommand("dump",5419                 CommandObjectSP(new CommandObjectTargetDump(interpreter)));5420  LoadSubCommand("list",5421                 CommandObjectSP(new CommandObjectTargetList(interpreter)));5422  LoadSubCommand("select",5423                 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));5424  LoadSubCommand("show-launch-environment",5425                 CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(5426                     interpreter)));5427  LoadSubCommand(5428      "stop-hook",5429      CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));5430  LoadSubCommand("modules",5431                 CommandObjectSP(new CommandObjectTargetModules(interpreter)));5432  LoadSubCommand("symbols",5433                 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));5434  LoadSubCommand("variable",5435                 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));5436}5437 5438CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;5439