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