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