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