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