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, "target variable",
729                               "Read global variables for the current target, before or while running a process.",
730                               nullptr, eCommandRequiresTarget),
731           m_option_group(interpreter),
732           m_option_variable(false), // Don't include frame options
733           m_option_format(eFormatDefault),
734           m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE, 0, eArgTypeFilename,
735                                  "A basename or fullpath to a file that contains global variables. This option can be "
736                                  "specified multiple times."),
737           m_option_shared_libraries(LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0, eArgTypeFilename,
738                                     "A basename or fullpath to a shared library to use in the search for global "
739                                     "variables. This option can be specified multiple times."),
740           m_varobj_options()
741     {
742         CommandArgumentEntry arg;
743         CommandArgumentData var_name_arg;
744 
745         // Define the first (and only) variant of this arg.
746         var_name_arg.arg_type = eArgTypeVarName;
747         var_name_arg.arg_repetition = eArgRepeatPlus;
748 
749         // There is only one variant this argument could be; put it into the argument entry.
750         arg.push_back (var_name_arg);
751 
752         // Push the data for the first argument into the m_arguments vector.
753         m_arguments.push_back (arg);
754 
755         m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
756         m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
757         m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
758         m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
759         m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
760         m_option_group.Finalize();
761     }
762 
763     ~CommandObjectTargetVariable() override = default;
764 
765     void
766     DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
767     {
768         DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
769 
770         if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
771             valobj_sp->IsRuntimeSupportValue())
772             return;
773 
774         switch (var_sp->GetScope())
775         {
776             case eValueTypeVariableGlobal:
777                 if (m_option_variable.show_scope)
778                     s.PutCString("GLOBAL: ");
779                 break;
780 
781             case eValueTypeVariableStatic:
782                 if (m_option_variable.show_scope)
783                     s.PutCString("STATIC: ");
784                 break;
785 
786             case eValueTypeVariableArgument:
787                 if (m_option_variable.show_scope)
788                     s.PutCString("   ARG: ");
789                 break;
790 
791             case eValueTypeVariableLocal:
792                 if (m_option_variable.show_scope)
793                     s.PutCString(" LOCAL: ");
794                 break;
795 
796             case eValueTypeVariableThreadLocal:
797                 if (m_option_variable.show_scope)
798                     s.PutCString("THREAD: ");
799                 break;
800 
801             default:
802                 break;
803         }
804 
805         if (m_option_variable.show_decl)
806         {
807             bool show_fullpaths = false;
808             bool show_module = true;
809             if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
810                 s.PutCString (": ");
811         }
812 
813         const Format format = m_option_format.GetFormat();
814         if (format != eFormatDefault)
815             options.SetFormat(format);
816 
817         options.SetRootValueObjectName(root_name);
818 
819         valobj_sp->Dump(s,options);
820     }
821 
822     static size_t GetVariableCallback (void *baton,
823                                        const char *name,
824                                        VariableList &variable_list)
825     {
826         Target *target = static_cast<Target *>(baton);
827         if (target)
828         {
829             return target->GetImages().FindGlobalVariables (ConstString(name),
830                                                             true,
831                                                             UINT32_MAX,
832                                                             variable_list);
833         }
834         return 0;
835     }
836 
837     Options *
838     GetOptions () override
839     {
840         return &m_option_group;
841     }
842 
843 protected:
844     void
845     DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s)
846     {
847         size_t count = variable_list.GetSize();
848         if (count > 0)
849         {
850             if (sc.module_sp)
851             {
852                 if (sc.comp_unit)
853                 {
854                     s.Printf ("Global variables for %s in %s:\n",
855                               sc.comp_unit->GetPath().c_str(),
856                               sc.module_sp->GetFileSpec().GetPath().c_str());
857                 }
858                 else
859                 {
860                     s.Printf ("Global variables for %s\n",
861                               sc.module_sp->GetFileSpec().GetPath().c_str());
862                 }
863             }
864             else if (sc.comp_unit)
865             {
866                 s.Printf ("Global variables for %s\n",
867                           sc.comp_unit->GetPath().c_str());
868             }
869 
870             for (uint32_t i = 0; i < count; ++i)
871             {
872                 VariableSP var_sp (variable_list.GetVariableAtIndex(i));
873                 if (var_sp)
874                 {
875                     ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
876 
877                     if (valobj_sp)
878                         DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
879                 }
880             }
881         }
882     }
883 
884     bool
885     DoExecute (Args& args, CommandReturnObject &result) override
886     {
887         Target *target = m_exe_ctx.GetTargetPtr();
888         const size_t argc = args.GetArgumentCount();
889         Stream &s = result.GetOutputStream();
890 
891         if (argc > 0)
892         {
893 
894             for (size_t idx = 0; idx < argc; ++idx)
895             {
896                 VariableList variable_list;
897                 ValueObjectList valobj_list;
898 
899                 const char *arg = args.GetArgumentAtIndex(idx);
900                 size_t matches = 0;
901                 bool use_var_name = false;
902                 if (m_option_variable.use_regex)
903                 {
904                     RegularExpression regex(arg);
905                     if (!regex.IsValid ())
906                     {
907                         result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
908                         result.SetStatus (eReturnStatusFailed);
909                         return false;
910                     }
911                     use_var_name = true;
912                     matches = target->GetImages().FindGlobalVariables (regex,
913                                                                        true,
914                                                                        UINT32_MAX,
915                                                                        variable_list);
916                 }
917                 else
918                 {
919                     Error error (Variable::GetValuesForVariableExpressionPath (arg,
920                                                                                m_exe_ctx.GetBestExecutionContextScope(),
921                                                                                GetVariableCallback,
922                                                                                target,
923                                                                                variable_list,
924                                                                                valobj_list));
925                     matches = variable_list.GetSize();
926                 }
927 
928                 if (matches == 0)
929                 {
930                     result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
931                     result.SetStatus (eReturnStatusFailed);
932                     return false;
933                 }
934                 else
935                 {
936                     for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
937                     {
938                         VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
939                         if (var_sp)
940                         {
941                             ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
942                             if (!valobj_sp)
943                                 valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp);
944 
945                             if (valobj_sp)
946                                 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
947                         }
948                     }
949                 }
950             }
951         }
952         else
953         {
954             const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue();
955             const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue();
956             SymbolContextList sc_list;
957             const size_t num_compile_units = compile_units.GetSize();
958             const size_t num_shlibs = shlibs.GetSize();
959             if (num_compile_units == 0 && num_shlibs == 0)
960             {
961                 bool success = false;
962                 StackFrame *frame = m_exe_ctx.GetFramePtr();
963                 CompileUnit *comp_unit = nullptr;
964                 if (frame)
965                 {
966                     SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit);
967                     if (sc.comp_unit)
968                     {
969                         const bool can_create = true;
970                         VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
971                         if (comp_unit_varlist_sp)
972                         {
973                             size_t count = comp_unit_varlist_sp->GetSize();
974                             if (count > 0)
975                             {
976                                 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
977                                 success = true;
978                             }
979                         }
980                     }
981                 }
982                 if (!success)
983                 {
984                     if (frame)
985                     {
986                         if (comp_unit)
987                             result.AppendErrorWithFormat ("no global variables in current compile unit: %s\n",
988                                                           comp_unit->GetPath().c_str());
989                         else
990                             result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex());
991                     }
992                     else
993                         result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
994                     result.SetStatus (eReturnStatusFailed);
995                 }
996             }
997             else
998             {
999                 SymbolContextList sc_list;
1000                 const bool append = true;
1001                 // We have one or more compile unit or shlib
1002                 if (num_shlibs > 0)
1003                 {
1004                     for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx)
1005                     {
1006                         const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
1007                         ModuleSpec module_spec (module_file);
1008 
1009                         ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
1010                         if (module_sp)
1011                         {
1012                             if (num_compile_units > 0)
1013                             {
1014                                 for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
1015                                     module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
1016                             }
1017                             else
1018                             {
1019                                 SymbolContext sc;
1020                                 sc.module_sp = module_sp;
1021                                 sc_list.Append(sc);
1022                             }
1023                         }
1024                         else
1025                         {
1026                             // Didn't find matching shlib/module in target...
1027                             result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s\n",
1028                                                           module_file.GetPath().c_str());
1029                         }
1030                     }
1031                 }
1032                 else
1033                 {
1034                     // No shared libraries, we just want to find globals for the compile units files that were specified
1035                     for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
1036                         target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
1037                 }
1038 
1039                 const uint32_t num_scs = sc_list.GetSize();
1040                 if (num_scs > 0)
1041                 {
1042                     SymbolContext sc;
1043                     for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx)
1044                     {
1045                         if (sc_list.GetContextAtIndex(sc_idx, sc))
1046                         {
1047                             if (sc.comp_unit)
1048                             {
1049                                 const bool can_create = true;
1050                                 VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
1051                                 if (comp_unit_varlist_sp)
1052                                     DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
1053                             }
1054                             else if (sc.module_sp)
1055                             {
1056                                 // Get all global variables for this module
1057                                 lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character
1058                                 VariableList variable_list;
1059                                 sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list);
1060                                 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1061                             }
1062                         }
1063                     }
1064                 }
1065             }
1066         }
1067 
1068         if (m_interpreter.TruncationWarningNecessary())
1069         {
1070             result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1071                                             m_cmd_name.c_str());
1072             m_interpreter.TruncationWarningGiven();
1073         }
1074 
1075         return result.Succeeded();
1076     }
1077 
1078     OptionGroupOptions m_option_group;
1079     OptionGroupVariable m_option_variable;
1080     OptionGroupFormat m_option_format;
1081     OptionGroupFileList m_option_compile_units;
1082     OptionGroupFileList m_option_shared_libraries;
1083     OptionGroupValueObjectDisplay m_varobj_options;
1084 };
1085 
1086 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1087 
1088 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
1089 {
1090 public:
1091     CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
1092         CommandObjectParsed(interpreter,
1093                             "target modules search-paths add",
1094                             "Add new image search paths substitution pairs to the current target.",
1095                             nullptr)
1096     {
1097         CommandArgumentEntry arg;
1098         CommandArgumentData old_prefix_arg;
1099         CommandArgumentData new_prefix_arg;
1100 
1101         // Define the first variant of this arg pair.
1102         old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1103         old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1104 
1105         // Define the first variant of this arg pair.
1106         new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1107         new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1108 
1109         // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
1110         // must always occur together, they are treated as two variants of one argument rather than two independent
1111         // arguments.  Push them both into the first argument position for m_arguments...
1112 
1113         arg.push_back (old_prefix_arg);
1114         arg.push_back (new_prefix_arg);
1115 
1116         m_arguments.push_back (arg);
1117     }
1118 
1119     ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1120 
1121 protected:
1122     bool
1123     DoExecute (Args& command, CommandReturnObject &result) override
1124     {
1125         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1126         if (target)
1127         {
1128             const size_t argc = command.GetArgumentCount();
1129             if (argc & 1)
1130             {
1131                 result.AppendError ("add requires an even number of arguments\n");
1132                 result.SetStatus (eReturnStatusFailed);
1133             }
1134             else
1135             {
1136                 for (size_t i = 0; i < argc; i+=2)
1137                 {
1138                     const char *from = command.GetArgumentAtIndex(i);
1139                     const char *to = command.GetArgumentAtIndex(i+1);
1140 
1141                     if (from[0] && to[0])
1142                     {
1143                         Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1144                         if (log)
1145                         {
1146                             log->Printf ("target modules search path adding ImageSearchPath pair: '%s' -> '%s'",
1147                                          from, to);
1148                         }
1149                         bool last_pair = ((argc - i) == 2);
1150                         target->GetImageSearchPathList().Append (ConstString(from),
1151                                                                  ConstString(to),
1152                                                                  last_pair); // Notify if this is the last pair
1153                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1154                     }
1155                     else
1156                     {
1157                         if (from[0])
1158                             result.AppendError ("<path-prefix> can't be empty\n");
1159                         else
1160                             result.AppendError ("<new-path-prefix> can't be empty\n");
1161                         result.SetStatus (eReturnStatusFailed);
1162                     }
1163                 }
1164             }
1165         }
1166         else
1167         {
1168             result.AppendError ("invalid target\n");
1169             result.SetStatus (eReturnStatusFailed);
1170         }
1171         return result.Succeeded();
1172     }
1173 };
1174 
1175 #pragma mark CommandObjectTargetModulesSearchPathsClear
1176 
1177 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
1178 {
1179 public:
1180     CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
1181         CommandObjectParsed (interpreter,
1182                              "target modules search-paths clear",
1183                              "Clear all current image search path substitution pairs from the current target.",
1184                              "target modules search-paths clear")
1185     {
1186     }
1187 
1188     ~CommandObjectTargetModulesSearchPathsClear() override = default;
1189 
1190 protected:
1191     bool
1192     DoExecute (Args& command, CommandReturnObject &result) override
1193     {
1194         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1195         if (target)
1196         {
1197             bool notify = true;
1198             target->GetImageSearchPathList().Clear(notify);
1199             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1200         }
1201         else
1202         {
1203             result.AppendError ("invalid target\n");
1204             result.SetStatus (eReturnStatusFailed);
1205         }
1206         return result.Succeeded();
1207     }
1208 };
1209 
1210 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1211 
1212 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
1213 {
1214 public:
1215     CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
1216         CommandObjectParsed(interpreter,
1217                             "target modules search-paths insert",
1218                             "Insert a new image search path substitution pair into the current target at the specified index.",
1219                             nullptr)
1220     {
1221         CommandArgumentEntry arg1;
1222         CommandArgumentEntry arg2;
1223         CommandArgumentData index_arg;
1224         CommandArgumentData old_prefix_arg;
1225         CommandArgumentData new_prefix_arg;
1226 
1227         // Define the first and only variant of this arg.
1228         index_arg.arg_type = eArgTypeIndex;
1229         index_arg.arg_repetition = eArgRepeatPlain;
1230 
1231         // Put the one and only variant into the first arg for m_arguments:
1232         arg1.push_back (index_arg);
1233 
1234         // Define the first variant of this arg pair.
1235         old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1236         old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1237 
1238         // Define the first variant of this arg pair.
1239         new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1240         new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1241 
1242         // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
1243         // must always occur together, they are treated as two variants of one argument rather than two independent
1244         // arguments.  Push them both into the same argument position for m_arguments...
1245 
1246         arg2.push_back (old_prefix_arg);
1247         arg2.push_back (new_prefix_arg);
1248 
1249         // Add arguments to m_arguments.
1250         m_arguments.push_back (arg1);
1251         m_arguments.push_back (arg2);
1252     }
1253 
1254     ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1255 
1256 protected:
1257     bool
1258     DoExecute (Args& command, CommandReturnObject &result) override
1259     {
1260         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1261         if (target)
1262         {
1263             size_t argc = command.GetArgumentCount();
1264             // check for at least 3 arguments and an odd number of parameters
1265             if (argc >= 3 && argc & 1)
1266             {
1267                 bool success = false;
1268 
1269                 uint32_t insert_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1270 
1271                 if (!success)
1272                 {
1273                     result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
1274                     result.SetStatus (eReturnStatusFailed);
1275                     return result.Succeeded();
1276                 }
1277 
1278                 // shift off the index
1279                 command.Shift();
1280                 argc = command.GetArgumentCount();
1281 
1282                 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx)
1283                 {
1284                     const char *from = command.GetArgumentAtIndex(i);
1285                     const char *to = command.GetArgumentAtIndex(i+1);
1286 
1287                     if (from[0] && to[0])
1288                     {
1289                         bool last_pair = ((argc - i) == 2);
1290                         target->GetImageSearchPathList().Insert (ConstString(from),
1291                                                                  ConstString(to),
1292                                                                  insert_idx,
1293                                                                  last_pair);
1294                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1295                     }
1296                     else
1297                     {
1298                         if (from[0])
1299                             result.AppendError ("<path-prefix> can't be empty\n");
1300                         else
1301                             result.AppendError ("<new-path-prefix> can't be empty\n");
1302                         result.SetStatus (eReturnStatusFailed);
1303                         return false;
1304                     }
1305                 }
1306             }
1307             else
1308             {
1309                 result.AppendError ("insert requires at least three arguments\n");
1310                 result.SetStatus (eReturnStatusFailed);
1311                 return result.Succeeded();
1312             }
1313 
1314         }
1315         else
1316         {
1317             result.AppendError ("invalid target\n");
1318             result.SetStatus (eReturnStatusFailed);
1319         }
1320         return result.Succeeded();
1321     }
1322 };
1323 
1324 #pragma mark CommandObjectTargetModulesSearchPathsList
1325 
1326 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
1327 {
1328 public:
1329     CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
1330         CommandObjectParsed (interpreter,
1331                              "target modules search-paths list",
1332                              "List all current image search path substitution pairs in the current target.",
1333                              "target modules search-paths list")
1334     {
1335     }
1336 
1337     ~CommandObjectTargetModulesSearchPathsList() override = default;
1338 
1339 protected:
1340     bool
1341     DoExecute (Args& command, CommandReturnObject &result) override
1342     {
1343         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1344         if (target)
1345         {
1346             if (command.GetArgumentCount() != 0)
1347             {
1348                 result.AppendError ("list takes no arguments\n");
1349                 result.SetStatus (eReturnStatusFailed);
1350                 return result.Succeeded();
1351             }
1352 
1353             target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1354             result.SetStatus (eReturnStatusSuccessFinishResult);
1355         }
1356         else
1357         {
1358             result.AppendError ("invalid target\n");
1359             result.SetStatus (eReturnStatusFailed);
1360         }
1361         return result.Succeeded();
1362     }
1363 };
1364 
1365 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1366 
1367 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
1368 {
1369 public:
1370     CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
1371         CommandObjectParsed(interpreter,
1372                             "target modules search-paths query",
1373                             "Transform a path using the first applicable image search path.",
1374                             nullptr)
1375     {
1376         CommandArgumentEntry arg;
1377         CommandArgumentData path_arg;
1378 
1379         // Define the first (and only) variant of this arg.
1380         path_arg.arg_type = eArgTypeDirectoryName;
1381         path_arg.arg_repetition = eArgRepeatPlain;
1382 
1383         // There is only one variant this argument could be; put it into the argument entry.
1384         arg.push_back (path_arg);
1385 
1386         // Push the data for the first argument into the m_arguments vector.
1387         m_arguments.push_back (arg);
1388     }
1389 
1390     ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1391 
1392 protected:
1393     bool
1394     DoExecute (Args& command, CommandReturnObject &result) override
1395     {
1396         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1397         if (target)
1398         {
1399             if (command.GetArgumentCount() != 1)
1400             {
1401                 result.AppendError ("query requires one argument\n");
1402                 result.SetStatus (eReturnStatusFailed);
1403                 return result.Succeeded();
1404             }
1405 
1406             ConstString orig(command.GetArgumentAtIndex(0));
1407             ConstString transformed;
1408             if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1409                 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1410             else
1411                 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1412 
1413             result.SetStatus (eReturnStatusSuccessFinishResult);
1414         }
1415         else
1416         {
1417             result.AppendError ("invalid target\n");
1418             result.SetStatus (eReturnStatusFailed);
1419         }
1420         return result.Succeeded();
1421     }
1422 };
1423 
1424 //----------------------------------------------------------------------
1425 // Static Helper functions
1426 //----------------------------------------------------------------------
1427 static void
1428 DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1429 {
1430     if (module)
1431     {
1432         StreamString arch_strm;
1433 
1434         if (full_triple)
1435             module->GetArchitecture().DumpTriple(arch_strm);
1436         else
1437             arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1438         std::string arch_str = arch_strm.GetString();
1439 
1440         if (width)
1441             strm.Printf("%-*s", width, arch_str.c_str());
1442         else
1443             strm.PutCString(arch_str.c_str());
1444     }
1445 }
1446 
1447 static void
1448 DumpModuleUUID (Stream &strm, Module *module)
1449 {
1450     if (module && module->GetUUID().IsValid())
1451         module->GetUUID().Dump (&strm);
1452     else
1453         strm.PutCString("                                    ");
1454 }
1455 
1456 static uint32_t
1457 DumpCompileUnitLineTable (CommandInterpreter &interpreter,
1458                           Stream &strm,
1459                           Module *module,
1460                           const FileSpec &file_spec,
1461                           bool load_addresses)
1462 {
1463     uint32_t num_matches = 0;
1464     if (module)
1465     {
1466         SymbolContextList sc_list;
1467         num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1468                                                                 0,
1469                                                                 false,
1470                                                                 eSymbolContextCompUnit,
1471                                                                 sc_list);
1472 
1473         for (uint32_t i = 0; i < num_matches; ++i)
1474         {
1475             SymbolContext sc;
1476             if (sc_list.GetContextAtIndex(i, sc))
1477             {
1478                 if (i > 0)
1479                     strm << "\n\n";
1480 
1481                 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1482                 << module->GetFileSpec().GetFilename() << "\n";
1483                 LineTable *line_table = sc.comp_unit->GetLineTable();
1484                 if (line_table)
1485                     line_table->GetDescription (&strm,
1486                                                 interpreter.GetExecutionContext().GetTargetPtr(),
1487                                                 lldb::eDescriptionLevelBrief);
1488                 else
1489                     strm << "No line table";
1490             }
1491         }
1492     }
1493     return num_matches;
1494 }
1495 
1496 static void
1497 DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1498 {
1499     if (file_spec_ptr)
1500     {
1501         if (width > 0)
1502         {
1503             std::string fullpath = file_spec_ptr->GetPath();
1504             strm.Printf("%-*s", width, fullpath.c_str());
1505             return;
1506         }
1507         else
1508         {
1509             file_spec_ptr->Dump(&strm);
1510             return;
1511         }
1512     }
1513     // Keep the width spacing correct if things go wrong...
1514     if (width > 0)
1515         strm.Printf("%-*s", width, "");
1516 }
1517 
1518 static void
1519 DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1520 {
1521     if (file_spec_ptr)
1522     {
1523         if (width > 0)
1524             strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1525         else
1526             file_spec_ptr->GetDirectory().Dump(&strm);
1527         return;
1528     }
1529     // Keep the width spacing correct if things go wrong...
1530     if (width > 0)
1531         strm.Printf("%-*s", width, "");
1532 }
1533 
1534 static void
1535 DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1536 {
1537     if (file_spec_ptr)
1538     {
1539         if (width > 0)
1540             strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1541         else
1542             file_spec_ptr->GetFilename().Dump(&strm);
1543         return;
1544     }
1545     // Keep the width spacing correct if things go wrong...
1546     if (width > 0)
1547         strm.Printf("%-*s", width, "");
1548 }
1549 
1550 static size_t
1551 DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list)
1552 {
1553     size_t num_dumped = 0;
1554     std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1555     const size_t num_modules = module_list.GetSize();
1556     if (num_modules > 0)
1557     {
1558         strm.Printf("Dumping headers for %" PRIu64 " module(s).\n", static_cast<uint64_t>(num_modules));
1559         strm.IndentMore();
1560         for (size_t image_idx = 0; image_idx < num_modules; ++image_idx)
1561         {
1562             Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1563             if (module)
1564             {
1565                 if (num_dumped++ > 0)
1566                 {
1567                     strm.EOL();
1568                     strm.EOL();
1569                 }
1570                 ObjectFile *objfile = module->GetObjectFile();
1571                 objfile->Dump(&strm);
1572             }
1573         }
1574         strm.IndentLess();
1575     }
1576     return num_dumped;
1577 }
1578 
1579 static void
1580 DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1581 {
1582     if (module)
1583     {
1584         SymbolVendor *sym_vendor = module->GetSymbolVendor ();
1585         if (sym_vendor)
1586         {
1587             Symtab *symtab = sym_vendor->GetSymtab();
1588             if (symtab)
1589                 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
1590         }
1591     }
1592 }
1593 
1594 static void
1595 DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1596 {
1597     if (module)
1598     {
1599         SectionList *section_list = module->GetSectionList();
1600         if (section_list)
1601         {
1602             strm.Printf ("Sections for '%s' (%s):\n",
1603                          module->GetSpecificationDescription().c_str(),
1604                          module->GetArchitecture().GetArchitectureName());
1605             strm.IndentMore();
1606             section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
1607             strm.IndentLess();
1608         }
1609     }
1610 }
1611 
1612 static bool
1613 DumpModuleSymbolVendor (Stream &strm, Module *module)
1614 {
1615     if (module)
1616     {
1617         SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1618         if (symbol_vendor)
1619         {
1620             symbol_vendor->Dump(&strm);
1621             return true;
1622         }
1623     }
1624     return false;
1625 }
1626 
1627 static void
1628 DumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
1629 {
1630     strm.IndentMore();
1631     strm.Indent ("    Address: ");
1632     so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1633     strm.PutCString (" (");
1634     so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1635     strm.PutCString (")\n");
1636     strm.Indent ("    Summary: ");
1637     const uint32_t save_indent = strm.GetIndentLevel ();
1638     strm.SetIndentLevel (save_indent + 13);
1639     so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1640     strm.SetIndentLevel (save_indent);
1641     // Print out detailed address information when verbose is enabled
1642     if (verbose)
1643     {
1644         strm.EOL();
1645         so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1646     }
1647     strm.IndentLess();
1648 }
1649 
1650 static bool
1651 LookupAddressInModule (CommandInterpreter &interpreter,
1652                        Stream &strm,
1653                        Module *module,
1654                        uint32_t resolve_mask,
1655                        lldb::addr_t raw_addr,
1656                        lldb::addr_t offset,
1657                        bool verbose)
1658 {
1659     if (module)
1660     {
1661         lldb::addr_t addr = raw_addr - offset;
1662         Address so_addr;
1663         SymbolContext sc;
1664         Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1665         if (target && !target->GetSectionLoadList().IsEmpty())
1666         {
1667             if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1668                 return false;
1669             else if (so_addr.GetModule().get() != module)
1670                 return false;
1671         }
1672         else
1673         {
1674             if (!module->ResolveFileAddress (addr, so_addr))
1675                 return false;
1676         }
1677 
1678         ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
1679         DumpAddress (exe_scope, so_addr, verbose, strm);
1680 //        strm.IndentMore();
1681 //        strm.Indent ("    Address: ");
1682 //        so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1683 //        strm.PutCString (" (");
1684 //        so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1685 //        strm.PutCString (")\n");
1686 //        strm.Indent ("    Summary: ");
1687 //        const uint32_t save_indent = strm.GetIndentLevel ();
1688 //        strm.SetIndentLevel (save_indent + 13);
1689 //        so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1690 //        strm.SetIndentLevel (save_indent);
1691 //        // Print out detailed address information when verbose is enabled
1692 //        if (verbose)
1693 //        {
1694 //            strm.EOL();
1695 //            so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1696 //        }
1697 //        strm.IndentLess();
1698         return true;
1699     }
1700 
1701     return false;
1702 }
1703 
1704 static uint32_t
1705 LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
1706 {
1707     if (module)
1708     {
1709         SymbolContext sc;
1710 
1711         SymbolVendor *sym_vendor = module->GetSymbolVendor ();
1712         if (sym_vendor)
1713         {
1714             Symtab *symtab = sym_vendor->GetSymtab();
1715             if (symtab)
1716             {
1717                 std::vector<uint32_t> match_indexes;
1718                 ConstString symbol_name (name);
1719                 uint32_t num_matches = 0;
1720                 if (name_is_regex)
1721                 {
1722                     RegularExpression name_regexp(name);
1723                     num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1724                                                                                    eSymbolTypeAny,
1725                                                                                    match_indexes);
1726                 }
1727                 else
1728                 {
1729                     num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1730                 }
1731 
1732                 if (num_matches > 0)
1733                 {
1734                     strm.Indent ();
1735                     strm.Printf("%u symbols match %s'%s' in ", num_matches,
1736                                 name_is_regex ? "the regular expression " : "", name);
1737                     DumpFullpath (strm, &module->GetFileSpec(), 0);
1738                     strm.PutCString(":\n");
1739                     strm.IndentMore ();
1740                     for (uint32_t i = 0; i < num_matches; ++i)
1741                     {
1742                         Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1743                         if (symbol && symbol->ValueIsAddress())
1744                         {
1745                             DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1746                                          symbol->GetAddressRef(),
1747                                          verbose,
1748                                          strm);
1749                         }
1750                     }
1751                     strm.IndentLess ();
1752                     return num_matches;
1753                 }
1754             }
1755         }
1756     }
1757     return 0;
1758 }
1759 
1760 static void
1761 DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
1762 {
1763     strm.IndentMore ();
1764 
1765     const uint32_t num_matches = sc_list.GetSize();
1766 
1767     for (uint32_t i = 0; i < num_matches; ++i)
1768     {
1769         SymbolContext sc;
1770         if (sc_list.GetContextAtIndex(i, sc))
1771         {
1772             AddressRange range;
1773 
1774             sc.GetAddressRange(eSymbolContextEverything,
1775                                0,
1776                                true,
1777                                range);
1778 
1779             DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm);
1780         }
1781     }
1782     strm.IndentLess ();
1783 }
1784 
1785 static size_t
1786 LookupFunctionInModule (CommandInterpreter &interpreter,
1787                         Stream &strm,
1788                         Module *module,
1789                         const char *name,
1790                         bool name_is_regex,
1791                         bool include_inlines,
1792                         bool include_symbols,
1793                         bool verbose)
1794 {
1795     if (module && name && name[0])
1796     {
1797         SymbolContextList sc_list;
1798         const bool append = true;
1799         size_t num_matches = 0;
1800         if (name_is_regex)
1801         {
1802             RegularExpression function_name_regex (name);
1803             num_matches = module->FindFunctions (function_name_regex,
1804                                                  include_symbols,
1805                                                  include_inlines,
1806                                                  append,
1807                                                  sc_list);
1808         }
1809         else
1810         {
1811             ConstString function_name (name);
1812             num_matches = module->FindFunctions(function_name,
1813                                                 nullptr,
1814                                                 eFunctionNameTypeAuto,
1815                                                 include_symbols,
1816                                                 include_inlines,
1817                                                 append,
1818                                                 sc_list);
1819         }
1820 
1821         if (num_matches)
1822         {
1823             strm.Indent ();
1824             strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
1825             DumpFullpath (strm, &module->GetFileSpec(), 0);
1826             strm.PutCString(":\n");
1827             DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
1828         }
1829         return num_matches;
1830     }
1831     return 0;
1832 }
1833 
1834 static size_t
1835 LookupTypeInModule (CommandInterpreter &interpreter,
1836                     Stream &strm,
1837                     Module *module,
1838                     const char *name_cstr,
1839                     bool name_is_regex)
1840 {
1841     if (module && name_cstr && name_cstr[0])
1842     {
1843         TypeList type_list;
1844         const uint32_t max_num_matches = UINT32_MAX;
1845         size_t num_matches = 0;
1846         bool name_is_fully_qualified = false;
1847         SymbolContext sc;
1848 
1849         ConstString name(name_cstr);
1850         llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1851         num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, searched_symbol_files, type_list);
1852 
1853         if (num_matches)
1854         {
1855             strm.Indent ();
1856             strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
1857             DumpFullpath (strm, &module->GetFileSpec(), 0);
1858             strm.PutCString(":\n");
1859             for (TypeSP type_sp : type_list.Types())
1860             {
1861                 if (type_sp)
1862                 {
1863                     // Resolve the clang type so that any forward references
1864                     // to types that haven't yet been parsed will get parsed.
1865                     type_sp->GetFullCompilerType ();
1866                     type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1867                     // Print all typedef chains
1868                     TypeSP typedef_type_sp (type_sp);
1869                     TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1870                     while (typedefed_type_sp)
1871                     {
1872                         strm.EOL();
1873                         strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
1874                         typedefed_type_sp->GetFullCompilerType ();
1875                         typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1876                         typedef_type_sp = typedefed_type_sp;
1877                         typedefed_type_sp = typedef_type_sp->GetTypedefType();
1878                     }
1879                 }
1880                 strm.EOL();
1881             }
1882         }
1883         return num_matches;
1884     }
1885     return 0;
1886 }
1887 
1888 static size_t
1889 LookupTypeHere (CommandInterpreter &interpreter,
1890                 Stream &strm,
1891                 const SymbolContext &sym_ctx,
1892                 const char *name_cstr,
1893                 bool name_is_regex)
1894 {
1895     if (!sym_ctx.module_sp)
1896         return 0;
1897 
1898     TypeList type_list;
1899     const uint32_t max_num_matches = UINT32_MAX;
1900     size_t num_matches = 1;
1901     bool name_is_fully_qualified = false;
1902 
1903     ConstString name(name_cstr);
1904     llvm::DenseSet<SymbolFile *> searched_symbol_files;
1905     num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, searched_symbol_files, type_list);
1906 
1907     if (num_matches)
1908     {
1909         strm.Indent ();
1910         strm.PutCString("Best match found in ");
1911         DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1912         strm.PutCString(":\n");
1913 
1914         TypeSP type_sp (type_list.GetTypeAtIndex(0));
1915         if (type_sp)
1916         {
1917             // Resolve the clang type so that any forward references
1918             // to types that haven't yet been parsed will get parsed.
1919             type_sp->GetFullCompilerType ();
1920             type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1921             // Print all typedef chains
1922             TypeSP typedef_type_sp (type_sp);
1923             TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1924             while (typedefed_type_sp)
1925             {
1926                 strm.EOL();
1927                 strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
1928                 typedefed_type_sp->GetFullCompilerType ();
1929                 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1930                 typedef_type_sp = typedefed_type_sp;
1931                 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1932             }
1933         }
1934         strm.EOL();
1935     }
1936     return num_matches;
1937 }
1938 
1939 static uint32_t
1940 LookupFileAndLineInModule (CommandInterpreter &interpreter,
1941                            Stream &strm,
1942                            Module *module,
1943                            const FileSpec &file_spec,
1944                            uint32_t line,
1945                            bool check_inlines,
1946                            bool verbose)
1947 {
1948     if (module && file_spec)
1949     {
1950         SymbolContextList sc_list;
1951         const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1952                                                                               eSymbolContextEverything, sc_list);
1953         if (num_matches > 0)
1954         {
1955             strm.Indent ();
1956             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1957             strm << file_spec;
1958             if (line > 0)
1959                 strm.Printf (":%u", line);
1960             strm << " in ";
1961             DumpFullpath (strm, &module->GetFileSpec(), 0);
1962             strm.PutCString(":\n");
1963             DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
1964             return num_matches;
1965         }
1966     }
1967     return 0;
1968 }
1969 
1970 static size_t
1971 FindModulesByName (Target *target,
1972                    const char *module_name,
1973                    ModuleList &module_list,
1974                    bool check_global_list)
1975 {
1976     FileSpec module_file_spec(module_name, false);
1977     ModuleSpec module_spec (module_file_spec);
1978 
1979     const size_t initial_size = module_list.GetSize ();
1980 
1981     if (check_global_list)
1982     {
1983         // Check the global list
1984         std::lock_guard<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex());
1985         const size_t num_modules = Module::GetNumberAllocatedModules();
1986         ModuleSP module_sp;
1987         for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
1988         {
1989             Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1990 
1991             if (module)
1992             {
1993                 if (module->MatchesModuleSpec (module_spec))
1994                 {
1995                     module_sp = module->shared_from_this();
1996                     module_list.AppendIfNeeded(module_sp);
1997                 }
1998             }
1999         }
2000     }
2001     else
2002     {
2003         if (target)
2004         {
2005             const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);
2006 
2007             // Not found in our module list for our target, check the main
2008             // shared module list in case it is a extra file used somewhere
2009             // else
2010             if (num_matches == 0)
2011             {
2012                 module_spec.GetArchitecture() = target->GetArchitecture();
2013                 ModuleList::FindSharedModules (module_spec, module_list);
2014             }
2015         }
2016         else
2017         {
2018             ModuleList::FindSharedModules (module_spec,module_list);
2019         }
2020     }
2021 
2022     return module_list.GetSize () - initial_size;
2023 }
2024 
2025 #pragma mark CommandObjectTargetModulesModuleAutoComplete
2026 
2027 //----------------------------------------------------------------------
2028 // A base command object class that can auto complete with module file
2029 // paths
2030 //----------------------------------------------------------------------
2031 
2032 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
2033 {
2034 public:
2035     CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
2036                                       const char *name,
2037                                       const char *help,
2038                                       const char *syntax) :
2039         CommandObjectParsed (interpreter, name, help, syntax)
2040     {
2041         CommandArgumentEntry arg;
2042         CommandArgumentData file_arg;
2043 
2044         // Define the first (and only) variant of this arg.
2045         file_arg.arg_type = eArgTypeFilename;
2046         file_arg.arg_repetition = eArgRepeatStar;
2047 
2048         // There is only one variant this argument could be; put it into the argument entry.
2049         arg.push_back (file_arg);
2050 
2051         // Push the data for the first argument into the m_arguments vector.
2052         m_arguments.push_back (arg);
2053     }
2054 
2055     ~CommandObjectTargetModulesModuleAutoComplete() override = default;
2056 
2057     int
2058     HandleArgumentCompletion (Args &input,
2059                               int &cursor_index,
2060                               int &cursor_char_position,
2061                               OptionElementVector &opt_element_vector,
2062                               int match_start_point,
2063                               int max_return_elements,
2064                               bool &word_complete,
2065                               StringList &matches) override
2066     {
2067         // Arguments are the standard module completer.
2068         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2069         completion_str.erase (cursor_char_position);
2070 
2071         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
2072                                                             CommandCompletions::eModuleCompletion,
2073                                                             completion_str.c_str(),
2074                                                             match_start_point,
2075                                                             max_return_elements,
2076                                                             nullptr,
2077                                                             word_complete,
2078                                                             matches);
2079         return matches.GetSize();
2080     }
2081 };
2082 
2083 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
2084 
2085 //----------------------------------------------------------------------
2086 // A base command object class that can auto complete with module source
2087 // file paths
2088 //----------------------------------------------------------------------
2089 
2090 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
2091 {
2092 public:
2093     CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
2094                                                       const char *name,
2095                                                       const char *help,
2096                                                       const char *syntax,
2097                                                       uint32_t flags) :
2098         CommandObjectParsed (interpreter, name, help, syntax, flags)
2099     {
2100         CommandArgumentEntry arg;
2101         CommandArgumentData source_file_arg;
2102 
2103         // Define the first (and only) variant of this arg.
2104         source_file_arg.arg_type = eArgTypeSourceFile;
2105         source_file_arg.arg_repetition = eArgRepeatPlus;
2106 
2107         // There is only one variant this argument could be; put it into the argument entry.
2108         arg.push_back (source_file_arg);
2109 
2110         // Push the data for the first argument into the m_arguments vector.
2111         m_arguments.push_back (arg);
2112     }
2113 
2114     ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
2115 
2116     int
2117     HandleArgumentCompletion (Args &input,
2118                               int &cursor_index,
2119                               int &cursor_char_position,
2120                               OptionElementVector &opt_element_vector,
2121                               int match_start_point,
2122                               int max_return_elements,
2123                               bool &word_complete,
2124                               StringList &matches) override
2125     {
2126         // Arguments are the standard source file completer.
2127         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2128         completion_str.erase (cursor_char_position);
2129 
2130         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
2131                                                             CommandCompletions::eSourceFileCompletion,
2132                                                             completion_str.c_str(),
2133                                                             match_start_point,
2134                                                             max_return_elements,
2135                                                             nullptr,
2136                                                             word_complete,
2137                                                             matches);
2138         return matches.GetSize();
2139     }
2140 };
2141 
2142 #pragma mark CommandObjectTargetModulesDumpObjfile
2143 
2144 class CommandObjectTargetModulesDumpObjfile : public CommandObjectTargetModulesModuleAutoComplete
2145 {
2146 public:
2147     CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
2148         : CommandObjectTargetModulesModuleAutoComplete(interpreter, "target modules dump objfile",
2149                                                        "Dump the object file headers from one or more target modules.",
2150                                                        nullptr)
2151     {
2152     }
2153 
2154     ~CommandObjectTargetModulesDumpObjfile() override = default;
2155 
2156 protected:
2157     bool
2158     DoExecute(Args &command, CommandReturnObject &result) override
2159     {
2160         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2161         if (target == nullptr)
2162         {
2163             result.AppendError("invalid target, create a debug target using the 'target create' command");
2164             result.SetStatus(eReturnStatusFailed);
2165             return false;
2166         }
2167 
2168         uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2169         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2170         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2171 
2172         size_t num_dumped = 0;
2173         if (command.GetArgumentCount() == 0)
2174         {
2175             // Dump all headers for all modules images
2176             num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), target->GetImages());
2177             if (num_dumped == 0)
2178             {
2179                 result.AppendError("the target has no associated executable images");
2180                 result.SetStatus(eReturnStatusFailed);
2181             }
2182         }
2183         else
2184         {
2185             // Find the modules that match the basename or full path.
2186             ModuleList module_list;
2187             const char *arg_cstr;
2188             for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2189             {
2190                 size_t num_matched = FindModulesByName(target, arg_cstr, module_list, true);
2191                 if (num_matched == 0)
2192                 {
2193                     result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2194                 }
2195             }
2196             // Dump all the modules we found.
2197             num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
2198         }
2199 
2200         if (num_dumped > 0)
2201         {
2202             result.SetStatus(eReturnStatusSuccessFinishResult);
2203         }
2204         else
2205         {
2206             result.AppendError("no matching executable images found");
2207             result.SetStatus(eReturnStatusFailed);
2208         }
2209         return result.Succeeded();
2210     }
2211 };
2212 
2213 #pragma mark CommandObjectTargetModulesDumpSymtab
2214 
2215 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
2216 {
2217 public:
2218     CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
2219         CommandObjectTargetModulesModuleAutoComplete(interpreter,
2220                                                      "target modules dump symtab",
2221                                                      "Dump the symbol table from one or more target modules.",
2222                                                      nullptr),
2223         m_options(interpreter)
2224     {
2225     }
2226 
2227     ~CommandObjectTargetModulesDumpSymtab() override = default;
2228 
2229     Options *
2230     GetOptions () override
2231     {
2232         return &m_options;
2233     }
2234 
2235     class CommandOptions : public Options
2236     {
2237     public:
2238         CommandOptions (CommandInterpreter &interpreter) :
2239         Options(interpreter),
2240         m_sort_order (eSortOrderNone)
2241         {
2242         }
2243 
2244         ~CommandOptions() override = default;
2245 
2246         Error
2247         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2248         {
2249             Error error;
2250             const int short_option = m_getopt_table[option_idx].val;
2251 
2252             switch (short_option)
2253             {
2254                 case 's':
2255                     m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
2256                                                                          g_option_table[option_idx].enum_values,
2257                                                                          eSortOrderNone,
2258                                                                          error);
2259                     break;
2260 
2261                 default:
2262                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2263                     break;
2264             }
2265             return error;
2266         }
2267 
2268         void
2269         OptionParsingStarting () override
2270         {
2271             m_sort_order = eSortOrderNone;
2272         }
2273 
2274         const OptionDefinition*
2275         GetDefinitions () override
2276         {
2277             return g_option_table;
2278         }
2279 
2280         // Options table: Required for subclasses of Options.
2281         static OptionDefinition g_option_table[];
2282 
2283         SortOrder m_sort_order;
2284     };
2285 
2286 protected:
2287     bool
2288     DoExecute (Args& command, CommandReturnObject &result) override
2289     {
2290         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2291         if (target == nullptr)
2292         {
2293             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2294             result.SetStatus (eReturnStatusFailed);
2295             return false;
2296         }
2297         else
2298         {
2299             uint32_t num_dumped = 0;
2300 
2301             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2302             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2303             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2304 
2305             if (command.GetArgumentCount() == 0)
2306             {
2307                 // Dump all sections for all modules images
2308                 std::lock_guard<std::recursive_mutex> guard(target->GetImages().GetMutex());
2309                 const size_t num_modules = target->GetImages().GetSize();
2310                 if (num_modules > 0)
2311                 {
2312                     result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2313                     for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
2314                     {
2315                         if (num_dumped > 0)
2316                         {
2317                             result.GetOutputStream().EOL();
2318                             result.GetOutputStream().EOL();
2319                         }
2320                         num_dumped++;
2321                         DumpModuleSymtab (m_interpreter,
2322                                           result.GetOutputStream(),
2323                                           target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2324                                           m_options.m_sort_order);
2325                     }
2326                 }
2327                 else
2328                 {
2329                     result.AppendError ("the target has no associated executable images");
2330                     result.SetStatus (eReturnStatusFailed);
2331                     return false;
2332                 }
2333             }
2334             else
2335             {
2336                 // Dump specified images (by basename or fullpath)
2337                 const char *arg_cstr;
2338                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2339                 {
2340                     ModuleList module_list;
2341                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2342                     if (num_matches > 0)
2343                     {
2344                         for (size_t i = 0; i < num_matches; ++i)
2345                         {
2346                             Module *module = module_list.GetModulePointerAtIndex(i);
2347                             if (module)
2348                             {
2349                                 if (num_dumped > 0)
2350                                 {
2351                                     result.GetOutputStream().EOL();
2352                                     result.GetOutputStream().EOL();
2353                                 }
2354                                 num_dumped++;
2355                                 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
2356                             }
2357                         }
2358                     }
2359                     else
2360                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2361                 }
2362             }
2363 
2364             if (num_dumped > 0)
2365                 result.SetStatus (eReturnStatusSuccessFinishResult);
2366             else
2367             {
2368                 result.AppendError ("no matching executable images found");
2369                 result.SetStatus (eReturnStatusFailed);
2370             }
2371         }
2372         return result.Succeeded();
2373     }
2374 
2375     CommandOptions m_options;
2376 };
2377 
2378 static OptionEnumValueElement
2379 g_sort_option_enumeration[4] =
2380 {
2381     { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
2382     { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
2383     { eSortOrderByName,     "name",     "Sort output by symbol name."},
2384     { 0,                    nullptr,    nullptr }
2385 };
2386 
2387 OptionDefinition
2388 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2389 {
2390     { 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."},
2391     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
2392 };
2393 
2394 #pragma mark CommandObjectTargetModulesDumpSections
2395 
2396 //----------------------------------------------------------------------
2397 // Image section dumping command
2398 //----------------------------------------------------------------------
2399 
2400 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2401 {
2402 public:
2403     CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2404         CommandObjectTargetModulesModuleAutoComplete(interpreter,
2405                                                      "target modules dump sections",
2406                                                      "Dump the sections from one or more target modules.",
2407                                                      //"target modules dump sections [<file1> ...]")
2408                                                      nullptr)
2409     {
2410     }
2411 
2412     ~CommandObjectTargetModulesDumpSections() override = default;
2413 
2414 protected:
2415     bool
2416     DoExecute (Args& command, CommandReturnObject &result) override
2417     {
2418         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2419         if (target == nullptr)
2420         {
2421             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2422             result.SetStatus (eReturnStatusFailed);
2423             return false;
2424         }
2425         else
2426         {
2427             uint32_t num_dumped = 0;
2428 
2429             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2430             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2431             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2432 
2433             if (command.GetArgumentCount() == 0)
2434             {
2435                 // Dump all sections for all modules images
2436                 const size_t num_modules = target->GetImages().GetSize();
2437                 if (num_modules > 0)
2438                 {
2439                     result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2440                     for (size_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2441                     {
2442                         num_dumped++;
2443                         DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2444                     }
2445                 }
2446                 else
2447                 {
2448                     result.AppendError ("the target has no associated executable images");
2449                     result.SetStatus (eReturnStatusFailed);
2450                     return false;
2451                 }
2452             }
2453             else
2454             {
2455                 // Dump specified images (by basename or fullpath)
2456                 const char *arg_cstr;
2457                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2458                 {
2459                     ModuleList module_list;
2460                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2461                     if (num_matches > 0)
2462                     {
2463                         for (size_t i = 0; i < num_matches; ++i)
2464                         {
2465                             Module *module = module_list.GetModulePointerAtIndex(i);
2466                             if (module)
2467                             {
2468                                 num_dumped++;
2469                                 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
2470                             }
2471                         }
2472                     }
2473                     else
2474                     {
2475                         // Check the global list
2476                         std::lock_guard<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex());
2477 
2478                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2479                     }
2480                 }
2481             }
2482 
2483             if (num_dumped > 0)
2484                 result.SetStatus (eReturnStatusSuccessFinishResult);
2485             else
2486             {
2487                 result.AppendError ("no matching executable images found");
2488                 result.SetStatus (eReturnStatusFailed);
2489             }
2490         }
2491         return result.Succeeded();
2492     }
2493 };
2494 
2495 #pragma mark CommandObjectTargetModulesDumpSymfile
2496 
2497 //----------------------------------------------------------------------
2498 // Image debug symbol dumping command
2499 //----------------------------------------------------------------------
2500 
2501 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2502 {
2503 public:
2504     CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2505         CommandObjectTargetModulesModuleAutoComplete(interpreter,
2506                                                      "target modules dump symfile",
2507                                                      "Dump the debug symbol file for one or more target modules.",
2508                                                      //"target modules dump symfile [<file1> ...]")
2509                                                      nullptr)
2510     {
2511     }
2512 
2513     ~CommandObjectTargetModulesDumpSymfile() override = default;
2514 
2515 protected:
2516     bool
2517     DoExecute (Args& command, CommandReturnObject &result) override
2518     {
2519         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2520         if (target == nullptr)
2521         {
2522             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2523             result.SetStatus (eReturnStatusFailed);
2524             return false;
2525         }
2526         else
2527         {
2528             uint32_t num_dumped = 0;
2529 
2530             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2531             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2532             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2533 
2534             if (command.GetArgumentCount() == 0)
2535             {
2536                 // Dump all sections for all modules images
2537                 const ModuleList &target_modules = target->GetImages();
2538                 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2539                 const size_t num_modules = target_modules.GetSize();
2540                 if (num_modules > 0)
2541                 {
2542                     result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2543                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2544                     {
2545                         if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2546                             num_dumped++;
2547                     }
2548                 }
2549                 else
2550                 {
2551                     result.AppendError ("the target has no associated executable images");
2552                     result.SetStatus (eReturnStatusFailed);
2553                     return false;
2554                 }
2555             }
2556             else
2557             {
2558                 // Dump specified images (by basename or fullpath)
2559                 const char *arg_cstr;
2560                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2561                 {
2562                     ModuleList module_list;
2563                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2564                     if (num_matches > 0)
2565                     {
2566                         for (size_t i = 0; i < num_matches; ++i)
2567                         {
2568                             Module *module = module_list.GetModulePointerAtIndex(i);
2569                             if (module)
2570                             {
2571                                 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
2572                                     num_dumped++;
2573                             }
2574                         }
2575                     }
2576                     else
2577                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2578                 }
2579             }
2580 
2581             if (num_dumped > 0)
2582                 result.SetStatus (eReturnStatusSuccessFinishResult);
2583             else
2584             {
2585                 result.AppendError ("no matching executable images found");
2586                 result.SetStatus (eReturnStatusFailed);
2587             }
2588         }
2589         return result.Succeeded();
2590     }
2591 };
2592 
2593 #pragma mark CommandObjectTargetModulesDumpLineTable
2594 
2595 //----------------------------------------------------------------------
2596 // Image debug line table dumping command
2597 //----------------------------------------------------------------------
2598 
2599 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2600 {
2601 public:
2602     CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2603         CommandObjectTargetModulesSourceFileAutoComplete(interpreter,
2604                                                          "target modules dump line-table",
2605                                                          "Dump the line table for one or more compilation units.",
2606                                                          nullptr,
2607                                                          eCommandRequiresTarget)
2608     {
2609     }
2610 
2611     ~CommandObjectTargetModulesDumpLineTable() override = default;
2612 
2613 protected:
2614     bool
2615     DoExecute (Args& command, CommandReturnObject &result) override
2616     {
2617         Target *target = m_exe_ctx.GetTargetPtr();
2618         uint32_t total_num_dumped = 0;
2619 
2620         uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2621         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2622         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2623 
2624         if (command.GetArgumentCount() == 0)
2625         {
2626             result.AppendError ("file option must be specified.");
2627             result.SetStatus (eReturnStatusFailed);
2628             return result.Succeeded();
2629         }
2630         else
2631         {
2632             // Dump specified images (by basename or fullpath)
2633             const char *arg_cstr;
2634             for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2635             {
2636                 FileSpec file_spec(arg_cstr, false);
2637 
2638                 const ModuleList &target_modules = target->GetImages();
2639                 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2640                 const size_t num_modules = target_modules.GetSize();
2641                 if (num_modules > 0)
2642                 {
2643                     uint32_t num_dumped = 0;
2644                     for (uint32_t i = 0; i<num_modules; ++i)
2645                     {
2646                         if (DumpCompileUnitLineTable (m_interpreter,
2647                                                       result.GetOutputStream(),
2648                                                       target_modules.GetModulePointerAtIndexUnlocked(i),
2649                                                       file_spec,
2650                                                       m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
2651                             num_dumped++;
2652                     }
2653                     if (num_dumped == 0)
2654                         result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2655                     else
2656                         total_num_dumped += num_dumped;
2657                 }
2658             }
2659         }
2660 
2661         if (total_num_dumped > 0)
2662             result.SetStatus (eReturnStatusSuccessFinishResult);
2663         else
2664         {
2665             result.AppendError ("no source filenames matched any command arguments");
2666             result.SetStatus (eReturnStatusFailed);
2667         }
2668         return result.Succeeded();
2669     }
2670 };
2671 
2672 #pragma mark CommandObjectTargetModulesDump
2673 
2674 //----------------------------------------------------------------------
2675 // Dump multi-word command for target modules
2676 //----------------------------------------------------------------------
2677 
2678 class CommandObjectTargetModulesDump : public CommandObjectMultiword
2679 {
2680 public:
2681     //------------------------------------------------------------------
2682     // Constructors and Destructors
2683     //------------------------------------------------------------------
2684     CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2685         : CommandObjectMultiword(
2686               interpreter, "target modules dump", "Commands for dumping information about one or more target modules.",
2687               "target modules dump [headers|symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2688     {
2689         LoadSubCommand("objfile", CommandObjectSP(new CommandObjectTargetModulesDumpObjfile(interpreter)));
2690         LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2691         LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2692         LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2693         LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2694     }
2695 
2696     ~CommandObjectTargetModulesDump() override = default;
2697 };
2698 
2699 class CommandObjectTargetModulesAdd : public CommandObjectParsed
2700 {
2701 public:
2702     CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2703         CommandObjectParsed (interpreter,
2704                              "target modules add",
2705                              "Add a new module to the current target's modules.",
2706                              "target modules add [<module>]"),
2707         m_option_group (interpreter),
2708         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.")
2709     {
2710         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2711         m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2712         m_option_group.Finalize();
2713     }
2714 
2715     ~CommandObjectTargetModulesAdd() override = default;
2716 
2717     Options *
2718     GetOptions () override
2719     {
2720         return &m_option_group;
2721     }
2722 
2723     int
2724     HandleArgumentCompletion (Args &input,
2725                               int &cursor_index,
2726                               int &cursor_char_position,
2727                               OptionElementVector &opt_element_vector,
2728                               int match_start_point,
2729                               int max_return_elements,
2730                               bool &word_complete,
2731                               StringList &matches) override
2732     {
2733         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2734         completion_str.erase (cursor_char_position);
2735 
2736         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
2737                                                             CommandCompletions::eDiskFileCompletion,
2738                                                             completion_str.c_str(),
2739                                                             match_start_point,
2740                                                             max_return_elements,
2741                                                             nullptr,
2742                                                             word_complete,
2743                                                             matches);
2744         return matches.GetSize();
2745     }
2746 
2747 protected:
2748     OptionGroupOptions m_option_group;
2749     OptionGroupUUID m_uuid_option_group;
2750     OptionGroupFile m_symbol_file;
2751 
2752     bool
2753     DoExecute (Args& args, CommandReturnObject &result) override
2754     {
2755         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2756         if (target == nullptr)
2757         {
2758             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2759             result.SetStatus (eReturnStatusFailed);
2760             return false;
2761         }
2762         else
2763         {
2764             bool flush = false;
2765 
2766             const size_t argc = args.GetArgumentCount();
2767             if (argc == 0)
2768             {
2769                 if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2770                 {
2771                     // We are given a UUID only, go locate the file
2772                     ModuleSpec module_spec;
2773                     module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2774                     if (m_symbol_file.GetOptionValue().OptionWasSet())
2775                         module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2776                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
2777                     {
2778                         ModuleSP module_sp (target->GetSharedModule (module_spec));
2779                         if (module_sp)
2780                         {
2781                             result.SetStatus (eReturnStatusSuccessFinishResult);
2782                             return true;
2783                         }
2784                         else
2785                         {
2786                             StreamString strm;
2787                             module_spec.GetUUID().Dump (&strm);
2788                             if (module_spec.GetFileSpec())
2789                             {
2790                                 if (module_spec.GetSymbolFileSpec())
2791                                 {
2792                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s",
2793                                                                   strm.GetString().c_str(),
2794                                                                   module_spec.GetFileSpec().GetPath().c_str(),
2795                                                                   module_spec.GetSymbolFileSpec().GetPath().c_str());
2796                                 }
2797                                 else
2798                                 {
2799                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s",
2800                                                                   strm.GetString().c_str(),
2801                                                                   module_spec.GetFileSpec().GetPath().c_str());
2802                                 }
2803                             }
2804                             else
2805                             {
2806                                 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
2807                                                               strm.GetString().c_str());
2808                             }
2809                             result.SetStatus (eReturnStatusFailed);
2810                             return false;
2811                         }
2812                     }
2813                     else
2814                     {
2815                         StreamString strm;
2816                         module_spec.GetUUID().Dump (&strm);
2817                         result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
2818                         result.SetStatus (eReturnStatusFailed);
2819                         return false;
2820                     }
2821                 }
2822                 else
2823                 {
2824                     result.AppendError ("one or more executable image paths must be specified");
2825                     result.SetStatus (eReturnStatusFailed);
2826                     return false;
2827                 }
2828             }
2829             else
2830             {
2831                 for (size_t i = 0; i < argc; ++i)
2832                 {
2833                     const char *path = args.GetArgumentAtIndex(i);
2834                     if (path)
2835                     {
2836                         FileSpec file_spec(path, true);
2837                         if (file_spec.Exists())
2838                         {
2839                             ModuleSpec module_spec (file_spec);
2840                             if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2841                                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2842                             if (m_symbol_file.GetOptionValue().OptionWasSet())
2843                                 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2844                             if (!module_spec.GetArchitecture().IsValid())
2845                                 module_spec.GetArchitecture() = target->GetArchitecture();
2846                             Error error;
2847                             ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
2848                             if (!module_sp)
2849                             {
2850                                 const char *error_cstr = error.AsCString();
2851                                 if (error_cstr)
2852                                     result.AppendError (error_cstr);
2853                                 else
2854                                     result.AppendErrorWithFormat ("unsupported module: %s", path);
2855                                 result.SetStatus (eReturnStatusFailed);
2856                                 return false;
2857                             }
2858                             else
2859                             {
2860                                 flush = true;
2861                             }
2862                             result.SetStatus (eReturnStatusSuccessFinishResult);
2863                         }
2864                         else
2865                         {
2866                             char resolved_path[PATH_MAX];
2867                             result.SetStatus (eReturnStatusFailed);
2868                             if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2869                             {
2870                                 if (strcmp (resolved_path, path) != 0)
2871                                 {
2872                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2873                                     break;
2874                                 }
2875                             }
2876                             result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2877                             break;
2878                         }
2879                     }
2880                 }
2881             }
2882 
2883             if (flush)
2884             {
2885                 ProcessSP process = target->GetProcessSP();
2886                 if (process)
2887                     process->Flush();
2888             }
2889         }
2890 
2891         return result.Succeeded();
2892     }
2893 };
2894 
2895 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2896 {
2897 public:
2898     CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2899         CommandObjectTargetModulesModuleAutoComplete (interpreter,
2900                                                       "target modules load",
2901                                                       "Set the load addresses for one or more sections in a target module.",
2902                                                       "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2903         m_option_group (interpreter),
2904         m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""),
2905         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)
2906     {
2907         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2908         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2909         m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2910         m_option_group.Finalize();
2911     }
2912 
2913     ~CommandObjectTargetModulesLoad() override = default;
2914 
2915     Options *
2916     GetOptions () override
2917     {
2918         return &m_option_group;
2919     }
2920 
2921 protected:
2922     bool
2923     DoExecute (Args& args, CommandReturnObject &result) override
2924     {
2925         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2926         if (target == nullptr)
2927         {
2928             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2929             result.SetStatus (eReturnStatusFailed);
2930             return false;
2931         }
2932         else
2933         {
2934             const size_t argc = args.GetArgumentCount();
2935             ModuleSpec module_spec;
2936             bool search_using_module_spec = false;
2937             if (m_file_option.GetOptionValue().OptionWasSet())
2938             {
2939                 search_using_module_spec = true;
2940                 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2941                 const bool use_global_module_list = true;
2942                 ModuleList module_list;
2943                 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
2944                 if (num_matches == 1)
2945                 {
2946                     module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec();
2947                 }
2948                 else if (num_matches > 1 )
2949                 {
2950                     search_using_module_spec = false;
2951                     result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr);
2952                     result.SetStatus (eReturnStatusFailed);
2953                 }
2954                 else
2955                 {
2956                     search_using_module_spec = false;
2957                     result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr);
2958                     result.SetStatus (eReturnStatusFailed);
2959                 }
2960             }
2961 
2962             if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2963             {
2964                 search_using_module_spec = true;
2965                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
2966             }
2967 
2968             if (search_using_module_spec)
2969             {
2970                 ModuleList matching_modules;
2971                 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
2972 
2973                 char path[PATH_MAX];
2974                 if (num_matches == 1)
2975                 {
2976                     Module *module = matching_modules.GetModulePointerAtIndex(0);
2977                     if (module)
2978                     {
2979                         ObjectFile *objfile = module->GetObjectFile();
2980                         if (objfile)
2981                         {
2982                             SectionList *section_list = module->GetSectionList();
2983                             if (section_list)
2984                             {
2985                                 bool changed = false;
2986                                 if (argc == 0)
2987                                 {
2988                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2989                                     {
2990                                         const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2991                                         const bool slide_is_offset = true;
2992                                         module->SetLoadAddress (*target, slide, slide_is_offset, changed);
2993                                     }
2994                                     else
2995                                     {
2996                                         result.AppendError ("one or more section name + load address pair must be specified");
2997                                         result.SetStatus (eReturnStatusFailed);
2998                                         return false;
2999                                     }
3000                                 }
3001                                 else
3002                                 {
3003                                     if (m_slide_option.GetOptionValue().OptionWasSet())
3004                                     {
3005                                         result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
3006                                         result.SetStatus (eReturnStatusFailed);
3007                                         return false;
3008                                     }
3009 
3010                                     for (size_t i = 0; i < argc; i += 2)
3011                                     {
3012                                         const char *sect_name = args.GetArgumentAtIndex(i);
3013                                         const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
3014                                         if (sect_name && load_addr_cstr)
3015                                         {
3016                                             ConstString const_sect_name(sect_name);
3017                                             bool success = false;
3018                                             addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
3019                                             if (success)
3020                                             {
3021                                                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
3022                                                 if (section_sp)
3023                                                 {
3024                                                     if (section_sp->IsThreadSpecific())
3025                                                     {
3026                                                         result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
3027                                                         result.SetStatus (eReturnStatusFailed);
3028                                                         break;
3029                                                     }
3030                                                     else
3031                                                     {
3032                                                         if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
3033                                                             changed = true;
3034                                                         result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
3035                                                     }
3036                                                 }
3037                                                 else
3038                                                 {
3039                                                     result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
3040                                                     result.SetStatus (eReturnStatusFailed);
3041                                                     break;
3042                                                 }
3043                                             }
3044                                             else
3045                                             {
3046                                                 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
3047                                                 result.SetStatus (eReturnStatusFailed);
3048                                                 break;
3049                                             }
3050                                         }
3051                                         else
3052                                         {
3053                                             if (sect_name)
3054                                                 result.AppendError ("section names must be followed by a load address.\n");
3055                                             else
3056                                                 result.AppendError ("one or more section name + load address pair must be specified.\n");
3057                                             result.SetStatus (eReturnStatusFailed);
3058                                             break;
3059                                         }
3060                                     }
3061                                 }
3062 
3063                                 if (changed)
3064                                 {
3065                                     target->ModulesDidLoad (matching_modules);
3066                                     Process *process = m_exe_ctx.GetProcessPtr();
3067                                     if (process)
3068                                         process->Flush();
3069                                 }
3070                             }
3071                             else
3072                             {
3073                                 module->GetFileSpec().GetPath (path, sizeof(path));
3074                                 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
3075                                 result.SetStatus (eReturnStatusFailed);
3076                             }
3077                         }
3078                         else
3079                         {
3080                             module->GetFileSpec().GetPath (path, sizeof(path));
3081                             result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
3082                             result.SetStatus (eReturnStatusFailed);
3083                         }
3084                     }
3085                     else
3086                     {
3087                         FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3088                         if (module_spec_file)
3089                         {
3090                             module_spec_file->GetPath (path, sizeof(path));
3091                             result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
3092                         }
3093                         else
3094                             result.AppendError ("no module spec");
3095                         result.SetStatus (eReturnStatusFailed);
3096                     }
3097                 }
3098                 else
3099                 {
3100                     std::string uuid_str;
3101 
3102                     if (module_spec.GetFileSpec())
3103                         module_spec.GetFileSpec().GetPath (path, sizeof(path));
3104                     else
3105                         path[0] = '\0';
3106 
3107                     if (module_spec.GetUUIDPtr())
3108                         uuid_str = module_spec.GetUUID().GetAsString();
3109                     if (num_matches > 1)
3110                     {
3111                         result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
3112                                                       path[0] ? " file=" : "",
3113                                                       path,
3114                                                       !uuid_str.empty() ? " uuid=" : "",
3115                                                       uuid_str.c_str());
3116                         for (size_t i = 0; i < num_matches; ++i)
3117                         {
3118                             if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
3119                                 result.AppendMessageWithFormat("%s\n", path);
3120                         }
3121                     }
3122                     else
3123                     {
3124                         result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
3125                                                       path[0] ? " file=" : "",
3126                                                       path,
3127                                                       !uuid_str.empty() ? " uuid=" : "",
3128                                                       uuid_str.c_str());
3129                     }
3130                     result.SetStatus (eReturnStatusFailed);
3131                 }
3132             }
3133             else
3134             {
3135                 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
3136                 result.SetStatus (eReturnStatusFailed);
3137                 return false;
3138             }
3139         }
3140         return result.Succeeded();
3141     }
3142 
3143     OptionGroupOptions m_option_group;
3144     OptionGroupUUID m_uuid_option_group;
3145     OptionGroupString m_file_option;
3146     OptionGroupUInt64 m_slide_option;
3147 };
3148 
3149 //----------------------------------------------------------------------
3150 // List images with associated information
3151 //----------------------------------------------------------------------
3152 class CommandObjectTargetModulesList : public CommandObjectParsed
3153 {
3154 public:
3155     class CommandOptions : public Options
3156     {
3157     public:
3158         CommandOptions (CommandInterpreter &interpreter) :
3159             Options(interpreter),
3160             m_format_array(),
3161             m_use_global_module_list (false),
3162             m_module_addr (LLDB_INVALID_ADDRESS)
3163         {
3164         }
3165 
3166         ~CommandOptions() override = default;
3167 
3168         Error
3169         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3170         {
3171             Error error;
3172 
3173             const int short_option = m_getopt_table[option_idx].val;
3174             if (short_option == 'g')
3175             {
3176                 m_use_global_module_list = true;
3177             }
3178             else if (short_option == 'a')
3179             {
3180                 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3181                 m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3182             }
3183             else
3184             {
3185                 unsigned long width = 0;
3186                 if (option_arg)
3187                     width = strtoul(option_arg, nullptr, 0);
3188                 m_format_array.push_back(std::make_pair(short_option, width));
3189             }
3190             return error;
3191         }
3192 
3193         void
3194         OptionParsingStarting () override
3195         {
3196             m_format_array.clear();
3197             m_use_global_module_list = false;
3198             m_module_addr = LLDB_INVALID_ADDRESS;
3199         }
3200 
3201         const OptionDefinition*
3202         GetDefinitions () override
3203         {
3204             return g_option_table;
3205         }
3206 
3207         // Options table: Required for subclasses of Options.
3208 
3209         static OptionDefinition g_option_table[];
3210 
3211         // Instance variables to hold the values for command options.
3212         typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
3213         FormatWidthCollection m_format_array;
3214         bool m_use_global_module_list;
3215         lldb::addr_t m_module_addr;
3216     };
3217 
3218     CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
3219         CommandObjectParsed (interpreter,
3220                              "target modules list",
3221                              "List current executable and dependent shared library images.",
3222                              "target modules list [<cmd-options>]"),
3223         m_options (interpreter)
3224     {
3225     }
3226 
3227     ~CommandObjectTargetModulesList() override = default;
3228 
3229     Options *
3230     GetOptions () override
3231     {
3232         return &m_options;
3233     }
3234 
3235 protected:
3236     bool
3237     DoExecute (Args& command, CommandReturnObject &result) override
3238     {
3239         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3240         const bool use_global_module_list = m_options.m_use_global_module_list;
3241         // Define a local module list here to ensure it lives longer than any "locker"
3242         // object which might lock its contents below (through the "module_list_ptr"
3243         // variable).
3244         ModuleList module_list;
3245         if (target == nullptr && !use_global_module_list)
3246         {
3247             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3248             result.SetStatus (eReturnStatusFailed);
3249             return false;
3250         }
3251         else
3252         {
3253             if (target)
3254             {
3255                 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3256                 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3257                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3258             }
3259             // Dump all sections for all modules images
3260             Stream &strm = result.GetOutputStream();
3261 
3262             if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
3263             {
3264                 if (target)
3265                 {
3266                     Address module_address;
3267                     if (module_address.SetLoadAddress(m_options.m_module_addr, target))
3268                     {
3269                         ModuleSP module_sp (module_address.GetModule());
3270                         if (module_sp)
3271                         {
3272                             PrintModule (target, module_sp.get(), 0, strm);
3273                             result.SetStatus (eReturnStatusSuccessFinishResult);
3274                         }
3275                         else
3276                         {
3277                             result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
3278                             result.SetStatus (eReturnStatusFailed);
3279                         }
3280                     }
3281                     else
3282                     {
3283                         result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
3284                         result.SetStatus (eReturnStatusFailed);
3285                     }
3286                 }
3287                 else
3288                 {
3289                     result.AppendError ("Can only look up modules by address with a valid target.");
3290                     result.SetStatus (eReturnStatusFailed);
3291                 }
3292                 return result.Succeeded();
3293             }
3294 
3295             size_t num_modules = 0;
3296 
3297             // This locker will be locked on the mutex in module_list_ptr if it is non-nullptr.
3298             // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
3299             // the global module list directly.
3300             std::unique_lock<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3301 
3302             const ModuleList *module_list_ptr = nullptr;
3303             const size_t argc = command.GetArgumentCount();
3304             if (argc == 0)
3305             {
3306                 if (use_global_module_list)
3307                 {
3308                     guard.lock();
3309                     num_modules = Module::GetNumberAllocatedModules();
3310                 }
3311                 else
3312                 {
3313                     module_list_ptr = &target->GetImages();
3314                 }
3315             }
3316             else
3317             {
3318                 for (size_t i = 0; i < argc; ++i)
3319                 {
3320                     // Dump specified images (by basename or fullpath)
3321                     const char *arg_cstr = command.GetArgumentAtIndex(i);
3322                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
3323                     if (num_matches == 0)
3324                     {
3325                         if (argc == 1)
3326                         {
3327                             result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
3328                             result.SetStatus (eReturnStatusFailed);
3329                             return false;
3330                         }
3331                     }
3332                 }
3333 
3334                 module_list_ptr = &module_list;
3335             }
3336 
3337             std::unique_lock<std::recursive_mutex> lock;
3338             if (module_list_ptr != nullptr)
3339             {
3340                 lock = std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3341 
3342                 num_modules = module_list_ptr->GetSize();
3343             }
3344 
3345             if (num_modules > 0)
3346             {
3347                 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
3348                 {
3349                     ModuleSP module_sp;
3350                     Module *module;
3351                     if (module_list_ptr)
3352                     {
3353                         module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3354                         module = module_sp.get();
3355                     }
3356                     else
3357                     {
3358                         module = Module::GetAllocatedModuleAtIndex(image_idx);
3359                         module_sp = module->shared_from_this();
3360                     }
3361 
3362                     const size_t indent = strm.Printf("[%3u] ", image_idx);
3363                     PrintModule (target, module, indent, strm);
3364 
3365                 }
3366                 result.SetStatus (eReturnStatusSuccessFinishResult);
3367             }
3368             else
3369             {
3370                 if (argc)
3371                 {
3372                     if (use_global_module_list)
3373                         result.AppendError ("the global module list has no matching modules");
3374                     else
3375                         result.AppendError ("the target has no matching modules");
3376                 }
3377                 else
3378                 {
3379                     if (use_global_module_list)
3380                         result.AppendError ("the global module list is empty");
3381                     else
3382                         result.AppendError ("the target has no associated executable images");
3383                 }
3384                 result.SetStatus (eReturnStatusFailed);
3385                 return false;
3386             }
3387         }
3388         return result.Succeeded();
3389     }
3390 
3391     void
3392     PrintModule (Target *target, Module *module, int indent, Stream &strm)
3393     {
3394         if (module == nullptr)
3395         {
3396             strm.PutCString("Null module");
3397             return;
3398         }
3399 
3400         bool dump_object_name = false;
3401         if (m_options.m_format_array.empty())
3402         {
3403             m_options.m_format_array.push_back(std::make_pair('u', 0));
3404             m_options.m_format_array.push_back(std::make_pair('h', 0));
3405             m_options.m_format_array.push_back(std::make_pair('f', 0));
3406             m_options.m_format_array.push_back(std::make_pair('S', 0));
3407         }
3408         const size_t num_entries = m_options.m_format_array.size();
3409         bool print_space = false;
3410         for (size_t i = 0; i < num_entries; ++i)
3411         {
3412             if (print_space)
3413                 strm.PutChar(' ');
3414             print_space = true;
3415             const char format_char = m_options.m_format_array[i].first;
3416             uint32_t width = m_options.m_format_array[i].second;
3417             switch (format_char)
3418             {
3419                 case 'A':
3420                     DumpModuleArchitecture (strm, module, false, width);
3421                     break;
3422 
3423                 case 't':
3424                     DumpModuleArchitecture (strm, module, true, width);
3425                     break;
3426 
3427                 case 'f':
3428                     DumpFullpath (strm, &module->GetFileSpec(), width);
3429                     dump_object_name = true;
3430                     break;
3431 
3432                 case 'd':
3433                     DumpDirectory (strm, &module->GetFileSpec(), width);
3434                     break;
3435 
3436                 case 'b':
3437                     DumpBasename (strm, &module->GetFileSpec(), width);
3438                     dump_object_name = true;
3439                     break;
3440 
3441                 case 'h':
3442                 case 'o':
3443                     // Image header address
3444                     {
3445                         uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
3446 
3447                         ObjectFile *objfile = module->GetObjectFile ();
3448                         if (objfile)
3449                         {
3450                             Address header_addr(objfile->GetHeaderAddress());
3451                             if (header_addr.IsValid())
3452                             {
3453                                 if (target && !target->GetSectionLoadList().IsEmpty())
3454                                 {
3455                                     lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3456                                     if (header_load_addr == LLDB_INVALID_ADDRESS)
3457                                     {
3458                                         header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3459                                     }
3460                                     else
3461                                     {
3462                                         if (format_char == 'o')
3463                                         {
3464                                             // Show the offset of slide for the image
3465                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3466                                         }
3467                                         else
3468                                         {
3469                                             // Show the load address of the image
3470                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
3471                                         }
3472                                     }
3473                                     break;
3474                                 }
3475                                 // The address was valid, but the image isn't loaded, output the address in an appropriate format
3476                                 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3477                                 break;
3478                             }
3479                         }
3480                         strm.Printf ("%*s", addr_nibble_width + 2, "");
3481                     }
3482                     break;
3483 
3484                 case 'r':
3485                     {
3486                         size_t ref_count = 0;
3487                         ModuleSP module_sp (module->shared_from_this());
3488                         if (module_sp)
3489                         {
3490                             // Take one away to make sure we don't count our local "module_sp"
3491                             ref_count = module_sp.use_count() - 1;
3492                         }
3493                         if (width)
3494                             strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3495                         else
3496                             strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3497                     }
3498                     break;
3499 
3500                 case 's':
3501                 case 'S':
3502                     {
3503                         const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3504                         if (symbol_vendor)
3505                         {
3506                             const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3507                             if (format_char == 'S')
3508                             {
3509                                 // Dump symbol file only if different from module file
3510                                 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3511                                 {
3512                                     print_space = false;
3513                                     break;
3514                                 }
3515                                 // Add a newline and indent past the index
3516                                 strm.Printf ("\n%*s", indent, "");
3517                             }
3518                             DumpFullpath (strm, &symfile_spec, width);
3519                             dump_object_name = true;
3520                             break;
3521                         }
3522                         strm.Printf("%.*s", width, "<NONE>");
3523                     }
3524                     break;
3525 
3526                 case 'm':
3527                     module->GetModificationTime().Dump(&strm, width);
3528                     break;
3529 
3530                 case 'p':
3531                     strm.Printf("%p", static_cast<void*>(module));
3532                     break;
3533 
3534                 case 'u':
3535                     DumpModuleUUID(strm, module);
3536                     break;
3537 
3538                 default:
3539                     break;
3540             }
3541         }
3542         if (dump_object_name)
3543         {
3544             const char *object_name = module->GetObjectName().GetCString();
3545             if (object_name)
3546                 strm.Printf ("(%s)", object_name);
3547         }
3548         strm.EOL();
3549     }
3550 
3551     CommandOptions m_options;
3552 };
3553 
3554 OptionDefinition
3555 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3556 {
3557     { LLDB_OPT_SET_1, false, "address",    'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
3558     { LLDB_OPT_SET_1, false, "arch",       'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the architecture when listing images."},
3559     { LLDB_OPT_SET_1, false, "triple",     't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the triple when listing images."},
3560     { 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."},
3561     { 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)."},
3562     { LLDB_OPT_SET_1, false, "uuid",       'u', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,    "Display the UUID when listing images."},
3563     { LLDB_OPT_SET_1, false, "fullpath",   'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3564     { LLDB_OPT_SET_1, false, "directory",  'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3565     { LLDB_OPT_SET_1, false, "basename",   'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3566     { LLDB_OPT_SET_1, false, "symfile",    's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3567     { 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."},
3568     { LLDB_OPT_SET_1, false, "mod-time",   'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3569     { 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."},
3570     { LLDB_OPT_SET_1, false, "pointer",    'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone,    "Display the module pointer."},
3571     { 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."},
3572     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
3573 };
3574 
3575 #pragma mark CommandObjectTargetModulesShowUnwind
3576 
3577 //----------------------------------------------------------------------
3578 // Lookup unwind information in images
3579 //----------------------------------------------------------------------
3580 
3581 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3582 {
3583 public:
3584     enum
3585     {
3586         eLookupTypeInvalid = -1,
3587         eLookupTypeAddress = 0,
3588         eLookupTypeSymbol,
3589         eLookupTypeFunction,
3590         eLookupTypeFunctionOrSymbol,
3591         kNumLookupTypes
3592     };
3593 
3594     class CommandOptions : public Options
3595     {
3596     public:
3597         CommandOptions (CommandInterpreter &interpreter) :
3598             Options(interpreter),
3599             m_type(eLookupTypeInvalid),
3600             m_str(),
3601             m_addr(LLDB_INVALID_ADDRESS)
3602         {
3603         }
3604 
3605         ~CommandOptions() override = default;
3606 
3607         Error
3608         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3609         {
3610             Error error;
3611 
3612             const int short_option = m_getopt_table[option_idx].val;
3613 
3614             switch (short_option)
3615             {
3616                 case 'a':
3617                 {
3618                     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3619                     m_str = option_arg;
3620                     m_type = eLookupTypeAddress;
3621                     m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3622                     if (m_addr == LLDB_INVALID_ADDRESS)
3623                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3624                     break;
3625                 }
3626 
3627                 case 'n':
3628                     m_str = option_arg;
3629                     m_type = eLookupTypeFunctionOrSymbol;
3630                     break;
3631 
3632                 default:
3633                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
3634                     break;
3635             }
3636 
3637             return error;
3638         }
3639 
3640         void
3641         OptionParsingStarting () override
3642         {
3643             m_type = eLookupTypeInvalid;
3644             m_str.clear();
3645             m_addr = LLDB_INVALID_ADDRESS;
3646         }
3647 
3648         const OptionDefinition*
3649         GetDefinitions () override
3650         {
3651             return g_option_table;
3652         }
3653 
3654         // Options table: Required for subclasses of Options.
3655 
3656         static OptionDefinition g_option_table[];
3657 
3658         // Instance variables to hold the values for command options.
3659 
3660         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3661         std::string     m_str;          // Holds name lookup
3662         lldb::addr_t    m_addr;         // Holds the address to lookup
3663     };
3664 
3665     CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3666         CommandObjectParsed(interpreter,
3667                             "target modules show-unwind",
3668                             "Show synthesized unwind instructions for a function.",
3669                             nullptr,
3670                             eCommandRequiresTarget        |
3671                             eCommandRequiresProcess       |
3672                             eCommandProcessMustBeLaunched |
3673                             eCommandProcessMustBePaused   ),
3674         m_options (interpreter)
3675     {
3676     }
3677 
3678     ~CommandObjectTargetModulesShowUnwind() override = default;
3679 
3680     Options *
3681     GetOptions () override
3682     {
3683         return &m_options;
3684     }
3685 
3686 protected:
3687     bool
3688     DoExecute (Args& command, CommandReturnObject &result) override
3689     {
3690         Target *target = m_exe_ctx.GetTargetPtr();
3691         Process *process = m_exe_ctx.GetProcessPtr();
3692         ABI *abi = nullptr;
3693         if (process)
3694           abi = process->GetABI().get();
3695 
3696         if (process == nullptr)
3697         {
3698             result.AppendError ("You must have a process running to use this command.");
3699             result.SetStatus (eReturnStatusFailed);
3700             return false;
3701         }
3702 
3703         ThreadList threads(process->GetThreadList());
3704         if (threads.GetSize() == 0)
3705         {
3706             result.AppendError ("The process must be paused to use this command.");
3707             result.SetStatus (eReturnStatusFailed);
3708             return false;
3709         }
3710 
3711         ThreadSP thread(threads.GetThreadAtIndex(0));
3712         if (!thread)
3713         {
3714             result.AppendError ("The process must be paused to use this command.");
3715             result.SetStatus (eReturnStatusFailed);
3716             return false;
3717         }
3718 
3719         SymbolContextList sc_list;
3720 
3721         if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3722         {
3723             ConstString function_name (m_options.m_str.c_str());
3724             target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3725         }
3726         else if (m_options.m_type == eLookupTypeAddress && target)
3727         {
3728             Address addr;
3729             if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
3730             {
3731                 SymbolContext sc;
3732                 ModuleSP module_sp (addr.GetModule());
3733                 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
3734                 if (sc.function || sc.symbol)
3735                 {
3736                     sc_list.Append(sc);
3737                 }
3738             }
3739         }
3740         else
3741         {
3742             result.AppendError ("address-expression or function name option must be specified.");
3743             result.SetStatus (eReturnStatusFailed);
3744             return false;
3745         }
3746 
3747         size_t num_matches = sc_list.GetSize();
3748         if (num_matches == 0)
3749         {
3750             result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
3751             result.SetStatus (eReturnStatusFailed);
3752             return false;
3753         }
3754 
3755         for (uint32_t idx = 0; idx < num_matches; idx++)
3756         {
3757             SymbolContext sc;
3758             sc_list.GetContextAtIndex(idx, sc);
3759             if (sc.symbol == nullptr && sc.function == nullptr)
3760                 continue;
3761             if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3762                 continue;
3763             AddressRange range;
3764             if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3765                 continue;
3766             if (!range.GetBaseAddress().IsValid())
3767                 continue;
3768             ConstString funcname(sc.GetFunctionName());
3769             if (funcname.IsEmpty())
3770                 continue;
3771             addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3772             if (abi)
3773                 start_addr = abi->FixCodeAddress(start_addr);
3774 
3775             FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3776             if (!func_unwinders_sp)
3777                 continue;
3778 
3779             result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3780 
3781             UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3782             if (non_callsite_unwind_plan)
3783             {
3784                 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
3785             }
3786             UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3787             if (callsite_unwind_plan)
3788             {
3789                 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
3790             }
3791             UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3792             if (fast_unwind_plan)
3793             {
3794                 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
3795             }
3796 
3797             result.GetOutputStream().Printf("\n");
3798 
3799             UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3800             if (assembly_sp)
3801             {
3802                 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
3803                 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3804                 result.GetOutputStream().Printf("\n");
3805             }
3806 
3807             UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3808             if (ehframe_sp)
3809             {
3810                 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3811                 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3812                 result.GetOutputStream().Printf("\n");
3813             }
3814 
3815             UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3816             if (ehframe_augmented_sp)
3817             {
3818                 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3819                 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3820                 result.GetOutputStream().Printf("\n");
3821             }
3822 
3823             UnwindPlanSP arm_unwind_sp = func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3824             if (arm_unwind_sp)
3825             {
3826                 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3827                 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3828                 result.GetOutputStream().Printf("\n");
3829             }
3830 
3831             UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3832             if (compact_unwind_sp)
3833             {
3834                 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3835                 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3836                 result.GetOutputStream().Printf("\n");
3837             }
3838 
3839             if (fast_unwind_plan)
3840             {
3841                 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3842                 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3843                 result.GetOutputStream().Printf("\n");
3844             }
3845 
3846             ABISP abi_sp = process->GetABI();
3847             if (abi_sp)
3848             {
3849                 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3850                 if (abi_sp->CreateDefaultUnwindPlan (arch_default))
3851                 {
3852                     result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3853                     arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3854                     result.GetOutputStream().Printf("\n");
3855                 }
3856 
3857                 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3858                 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
3859                 {
3860                     result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
3861                     arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3862                     result.GetOutputStream().Printf("\n");
3863                 }
3864             }
3865 
3866             result.GetOutputStream().Printf ("\n");
3867         }
3868         return result.Succeeded();
3869     }
3870 
3871     CommandOptions m_options;
3872 };
3873 
3874 OptionDefinition
3875 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3876 {
3877     { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3878     { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3879     { 0,                false, nullptr,           0, 0,                 nullptr, nullptr, 0, eArgTypeNone, nullptr }
3880 };
3881 
3882 //----------------------------------------------------------------------
3883 // Lookup information in images
3884 //----------------------------------------------------------------------
3885 class CommandObjectTargetModulesLookup : public CommandObjectParsed
3886 {
3887 public:
3888     enum
3889     {
3890         eLookupTypeInvalid = -1,
3891         eLookupTypeAddress = 0,
3892         eLookupTypeSymbol,
3893         eLookupTypeFileLine,    // Line is optional
3894         eLookupTypeFunction,
3895         eLookupTypeFunctionOrSymbol,
3896         eLookupTypeType,
3897         kNumLookupTypes
3898     };
3899 
3900     class CommandOptions : public Options
3901     {
3902     public:
3903         CommandOptions (CommandInterpreter &interpreter) :
3904         Options(interpreter)
3905         {
3906             OptionParsingStarting();
3907         }
3908 
3909         ~CommandOptions() override = default;
3910 
3911         Error
3912         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3913         {
3914             Error error;
3915 
3916             const int short_option = m_getopt_table[option_idx].val;
3917 
3918             switch (short_option)
3919             {
3920                 case 'a':
3921                     {
3922                         m_type = eLookupTypeAddress;
3923                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3924                         m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3925                     }
3926                     break;
3927 
3928                 case 'o':
3929                     m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3930                     if (m_offset == LLDB_INVALID_ADDRESS)
3931                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3932                     break;
3933 
3934                 case 's':
3935                     m_str = option_arg;
3936                     m_type = eLookupTypeSymbol;
3937                     break;
3938 
3939                 case 'f':
3940                     m_file.SetFile (option_arg, false);
3941                     m_type = eLookupTypeFileLine;
3942                     break;
3943 
3944                 case 'i':
3945                     m_include_inlines = false;
3946                     break;
3947 
3948                 case 'l':
3949                     m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3950                     if (m_line_number == UINT32_MAX)
3951                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3952                     else if (m_line_number == 0)
3953                         error.SetErrorString ("zero is an invalid line number");
3954                     m_type = eLookupTypeFileLine;
3955                     break;
3956 
3957                 case 'F':
3958                     m_str = option_arg;
3959                     m_type = eLookupTypeFunction;
3960                     break;
3961 
3962                 case 'n':
3963                     m_str = option_arg;
3964                     m_type = eLookupTypeFunctionOrSymbol;
3965                     break;
3966 
3967                 case 't':
3968                     m_str = option_arg;
3969                     m_type = eLookupTypeType;
3970                     break;
3971 
3972                 case 'v':
3973                     m_verbose = 1;
3974                     break;
3975 
3976                 case 'A':
3977                     m_print_all = true;
3978                     break;
3979 
3980                 case 'r':
3981                     m_use_regex = true;
3982                     break;
3983             }
3984 
3985             return error;
3986         }
3987 
3988         void
3989         OptionParsingStarting () override
3990         {
3991             m_type = eLookupTypeInvalid;
3992             m_str.clear();
3993             m_file.Clear();
3994             m_addr = LLDB_INVALID_ADDRESS;
3995             m_offset = 0;
3996             m_line_number = 0;
3997             m_use_regex = false;
3998             m_include_inlines = true;
3999             m_verbose = false;
4000             m_print_all = false;
4001         }
4002 
4003         const OptionDefinition*
4004         GetDefinitions () override
4005         {
4006             return g_option_table;
4007         }
4008 
4009         // Options table: Required for subclasses of Options.
4010 
4011         static OptionDefinition g_option_table[];
4012         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
4013         std::string     m_str;          // Holds name lookup
4014         FileSpec        m_file;         // Files for file lookups
4015         lldb::addr_t    m_addr;         // Holds the address to lookup
4016         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
4017         uint32_t        m_line_number;  // Line number for file+line lookups
4018         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
4019         bool            m_include_inlines;// Check for inline entries when looking up by file/line.
4020         bool            m_verbose;      // Enable verbose lookup info
4021         bool            m_print_all;    // Print all matches, even in cases where there's a best match.
4022     };
4023 
4024     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
4025         CommandObjectParsed(interpreter,
4026                             "target modules lookup",
4027                             "Look up information within executable and dependent shared library images.",
4028                             nullptr,
4029                             eCommandRequiresTarget),
4030         m_options (interpreter)
4031     {
4032         CommandArgumentEntry arg;
4033         CommandArgumentData file_arg;
4034 
4035         // Define the first (and only) variant of this arg.
4036         file_arg.arg_type = eArgTypeFilename;
4037         file_arg.arg_repetition = eArgRepeatStar;
4038 
4039         // There is only one variant this argument could be; put it into the argument entry.
4040         arg.push_back (file_arg);
4041 
4042         // Push the data for the first argument into the m_arguments vector.
4043         m_arguments.push_back (arg);
4044     }
4045 
4046     ~CommandObjectTargetModulesLookup() override = default;
4047 
4048     Options *
4049     GetOptions () override
4050     {
4051         return &m_options;
4052     }
4053 
4054     bool
4055     LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
4056     {
4057         switch (m_options.m_type)
4058         {
4059             case eLookupTypeAddress:
4060             case eLookupTypeFileLine:
4061             case eLookupTypeFunction:
4062             case eLookupTypeFunctionOrSymbol:
4063             case eLookupTypeSymbol:
4064             default:
4065                 return false;
4066             case eLookupTypeType:
4067                 break;
4068         }
4069 
4070         StackFrameSP frame = m_exe_ctx.GetFrameSP();
4071 
4072         if (!frame)
4073             return false;
4074 
4075         const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
4076 
4077         if (!sym_ctx.module_sp)
4078             return false;
4079 
4080         switch (m_options.m_type)
4081         {
4082         default:
4083             return false;
4084         case eLookupTypeType:
4085             if (!m_options.m_str.empty())
4086             {
4087                 if (LookupTypeHere (m_interpreter,
4088                                     result.GetOutputStream(),
4089                                     sym_ctx,
4090                                     m_options.m_str.c_str(),
4091                                     m_options.m_use_regex))
4092                 {
4093                     result.SetStatus(eReturnStatusSuccessFinishResult);
4094                     return true;
4095                 }
4096             }
4097             break;
4098         }
4099 
4100         return true;
4101     }
4102 
4103     bool
4104     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
4105     {
4106         switch (m_options.m_type)
4107         {
4108             case eLookupTypeAddress:
4109                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
4110                 {
4111                     if (LookupAddressInModule (m_interpreter,
4112                                                result.GetOutputStream(),
4113                                                module,
4114                                                eSymbolContextEverything | (m_options.m_verbose ? static_cast<int>(eSymbolContextVariable) : 0),
4115                                                m_options.m_addr,
4116                                                m_options.m_offset,
4117                                                m_options.m_verbose))
4118                     {
4119                         result.SetStatus(eReturnStatusSuccessFinishResult);
4120                         return true;
4121                     }
4122                 }
4123                 break;
4124 
4125             case eLookupTypeSymbol:
4126                 if (!m_options.m_str.empty())
4127                 {
4128                     if (LookupSymbolInModule (m_interpreter,
4129                                               result.GetOutputStream(),
4130                                               module,
4131                                               m_options.m_str.c_str(),
4132                                               m_options.m_use_regex,
4133                                               m_options.m_verbose))
4134                     {
4135                         result.SetStatus(eReturnStatusSuccessFinishResult);
4136                         return true;
4137                     }
4138                 }
4139                 break;
4140 
4141             case eLookupTypeFileLine:
4142                 if (m_options.m_file)
4143                 {
4144                     if (LookupFileAndLineInModule (m_interpreter,
4145                                                    result.GetOutputStream(),
4146                                                    module,
4147                                                    m_options.m_file,
4148                                                    m_options.m_line_number,
4149                                                    m_options.m_include_inlines,
4150                                                    m_options.m_verbose))
4151                     {
4152                         result.SetStatus(eReturnStatusSuccessFinishResult);
4153                         return true;
4154                     }
4155                 }
4156                 break;
4157 
4158             case eLookupTypeFunctionOrSymbol:
4159             case eLookupTypeFunction:
4160                 if (!m_options.m_str.empty())
4161                 {
4162                     if (LookupFunctionInModule (m_interpreter,
4163                                                 result.GetOutputStream(),
4164                                                 module,
4165                                                 m_options.m_str.c_str(),
4166                                                 m_options.m_use_regex,
4167                                                 m_options.m_include_inlines,
4168                                                 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
4169                                                 m_options.m_verbose))
4170                     {
4171                         result.SetStatus(eReturnStatusSuccessFinishResult);
4172                         return true;
4173                     }
4174                 }
4175                 break;
4176 
4177             case eLookupTypeType:
4178                 if (!m_options.m_str.empty())
4179                 {
4180                     if (LookupTypeInModule (m_interpreter,
4181                                             result.GetOutputStream(),
4182                                             module,
4183                                             m_options.m_str.c_str(),
4184                                             m_options.m_use_regex))
4185                     {
4186                         result.SetStatus(eReturnStatusSuccessFinishResult);
4187                         return true;
4188                     }
4189                 }
4190                 break;
4191 
4192             default:
4193                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
4194                 syntax_error = true;
4195                 break;
4196         }
4197 
4198         result.SetStatus (eReturnStatusFailed);
4199         return false;
4200     }
4201 
4202 protected:
4203     bool
4204     DoExecute (Args& command, CommandReturnObject &result) override
4205     {
4206         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4207         if (target == nullptr)
4208         {
4209             result.AppendError ("invalid target, create a debug target using the 'target create' command");
4210             result.SetStatus (eReturnStatusFailed);
4211             return false;
4212         }
4213         else
4214         {
4215             bool syntax_error = false;
4216             uint32_t i;
4217             uint32_t num_successful_lookups = 0;
4218             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4219             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4220             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4221             // Dump all sections for all modules images
4222 
4223             if (command.GetArgumentCount() == 0)
4224             {
4225                 ModuleSP current_module;
4226 
4227                 // Where it is possible to look in the current symbol context
4228                 // first, try that.  If this search was successful and --all
4229                 // was not passed, don't print anything else.
4230                 if (LookupHere (m_interpreter, result, syntax_error))
4231                 {
4232                     result.GetOutputStream().EOL();
4233                     num_successful_lookups++;
4234                     if (!m_options.m_print_all)
4235                     {
4236                         result.SetStatus (eReturnStatusSuccessFinishResult);
4237                         return result.Succeeded();
4238                     }
4239                 }
4240 
4241                 // Dump all sections for all other modules
4242 
4243                 const ModuleList &target_modules = target->GetImages();
4244                 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4245                 const size_t num_modules = target_modules.GetSize();
4246                 if (num_modules > 0)
4247                 {
4248                     for (i = 0; i < num_modules && !syntax_error; ++i)
4249                     {
4250                         Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
4251 
4252                         if (module_pointer != current_module.get() &&
4253                             LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
4254                         {
4255                             result.GetOutputStream().EOL();
4256                             num_successful_lookups++;
4257                         }
4258                     }
4259                 }
4260                 else
4261                 {
4262                     result.AppendError ("the target has no associated executable images");
4263                     result.SetStatus (eReturnStatusFailed);
4264                     return false;
4265                 }
4266             }
4267             else
4268             {
4269                 // Dump specified images (by basename or fullpath)
4270                 const char *arg_cstr;
4271                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && !syntax_error; ++i)
4272                 {
4273                     ModuleList module_list;
4274                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
4275                     if (num_matches > 0)
4276                     {
4277                         for (size_t j=0; j<num_matches; ++j)
4278                         {
4279                             Module *module = module_list.GetModulePointerAtIndex(j);
4280                             if (module)
4281                             {
4282                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
4283                                 {
4284                                     result.GetOutputStream().EOL();
4285                                     num_successful_lookups++;
4286                                 }
4287                             }
4288                         }
4289                     }
4290                     else
4291                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
4292                 }
4293             }
4294 
4295             if (num_successful_lookups > 0)
4296                 result.SetStatus (eReturnStatusSuccessFinishResult);
4297             else
4298                 result.SetStatus (eReturnStatusFailed);
4299         }
4300         return result.Succeeded();
4301     }
4302 
4303     CommandOptions m_options;
4304 };
4305 
4306 OptionDefinition
4307 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
4308 {
4309     { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
4310     { 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."},
4311     { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
4312       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
4313                         false, "regex",      'r', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
4314     { 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."},
4315     { 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."},
4316     { 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)."},
4317     { LLDB_OPT_SET_FROM_TO(3,5),
4318                         false, "no-inlines", 'i', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
4319     { 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."},
4320     { 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."},
4321     { 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."},
4322     { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,             "Enable verbose lookup information."},
4323     { 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."},
4324     { 0,                false, nullptr,           0, 0,                 nullptr, nullptr, 0, eArgTypeNone,             nullptr }
4325 };
4326 
4327 #pragma mark CommandObjectMultiwordImageSearchPaths
4328 
4329 //-------------------------------------------------------------------------
4330 // CommandObjectMultiwordImageSearchPaths
4331 //-------------------------------------------------------------------------
4332 
4333 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
4334 {
4335 public:
4336     CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
4337         : CommandObjectMultiword(interpreter, "target modules search-paths",
4338                                  "Commands for managing module search paths for a target.",
4339                                  "target modules search-paths <subcommand> [<subcommand-options>]")
4340     {
4341         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
4342         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
4343         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
4344         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
4345         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
4346     }
4347 
4348     ~CommandObjectTargetModulesImageSearchPaths() override = default;
4349 };
4350 
4351 #pragma mark CommandObjectTargetModules
4352 
4353 //-------------------------------------------------------------------------
4354 // CommandObjectTargetModules
4355 //-------------------------------------------------------------------------
4356 
4357 class CommandObjectTargetModules : public CommandObjectMultiword
4358 {
4359 public:
4360     //------------------------------------------------------------------
4361     // Constructors and Destructors
4362     //------------------------------------------------------------------
4363     CommandObjectTargetModules(CommandInterpreter &interpreter)
4364         : CommandObjectMultiword(interpreter, "target modules",
4365                                  "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, "target symbols", "Commands for adding and managing debug symbol files.",
4822                                  "target symbols <sub-command> ...")
4823     {
4824         LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4825     }
4826 
4827     ~CommandObjectTargetSymbols() override = default;
4828 
4829 private:
4830     //------------------------------------------------------------------
4831     // For CommandObjectTargetModules only
4832     //------------------------------------------------------------------
4833     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4834 };
4835 
4836 #pragma mark CommandObjectTargetStopHookAdd
4837 
4838 //-------------------------------------------------------------------------
4839 // CommandObjectTargetStopHookAdd
4840 //-------------------------------------------------------------------------
4841 
4842 class CommandObjectTargetStopHookAdd :
4843     public CommandObjectParsed,
4844     public IOHandlerDelegateMultiline
4845 {
4846 public:
4847     class CommandOptions : public Options
4848     {
4849     public:
4850         CommandOptions (CommandInterpreter &interpreter) :
4851             Options(interpreter),
4852             m_line_start(0),
4853             m_line_end (UINT_MAX),
4854             m_func_name_type_mask (eFunctionNameTypeAuto),
4855             m_sym_ctx_specified (false),
4856             m_thread_specified (false),
4857             m_use_one_liner (false),
4858             m_one_liner()
4859         {
4860         }
4861 
4862         ~CommandOptions() override = default;
4863 
4864         const OptionDefinition*
4865         GetDefinitions () override
4866         {
4867             return g_option_table;
4868         }
4869 
4870         Error
4871         SetOptionValue (uint32_t option_idx, const char *option_arg) override
4872         {
4873             Error error;
4874             const int short_option = m_getopt_table[option_idx].val;
4875             bool success;
4876 
4877             switch (short_option)
4878             {
4879                 case 'c':
4880                     m_class_name = option_arg;
4881                     m_sym_ctx_specified = true;
4882                     break;
4883 
4884                 case 'e':
4885                     m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
4886                     if (!success)
4887                     {
4888                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4889                         break;
4890                     }
4891                     m_sym_ctx_specified = true;
4892                     break;
4893 
4894                 case 'l':
4895                     m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
4896                     if (!success)
4897                     {
4898                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4899                         break;
4900                     }
4901                     m_sym_ctx_specified = true;
4902                     break;
4903 
4904                 case 'i':
4905                     m_no_inlines = true;
4906                     break;
4907 
4908                 case 'n':
4909                     m_function_name = option_arg;
4910                     m_func_name_type_mask |= eFunctionNameTypeAuto;
4911                     m_sym_ctx_specified = true;
4912                     break;
4913 
4914                 case 'f':
4915                     m_file_name = option_arg;
4916                     m_sym_ctx_specified = true;
4917                     break;
4918 
4919                 case 's':
4920                     m_module_name = option_arg;
4921                     m_sym_ctx_specified = true;
4922                     break;
4923 
4924                 case 't' :
4925                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4926                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
4927                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4928                     m_thread_specified = true;
4929                     break;
4930 
4931                 case 'T':
4932                     m_thread_name = option_arg;
4933                     m_thread_specified = true;
4934                     break;
4935 
4936                 case 'q':
4937                     m_queue_name = option_arg;
4938                     m_thread_specified = true;
4939                     break;
4940 
4941                 case 'x':
4942                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4943                     if (m_thread_id == UINT32_MAX)
4944                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4945                     m_thread_specified = true;
4946                     break;
4947 
4948                 case 'o':
4949                     m_use_one_liner = true;
4950                     m_one_liner = option_arg;
4951                     break;
4952 
4953                 default:
4954                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4955                     break;
4956             }
4957             return error;
4958         }
4959 
4960         void
4961         OptionParsingStarting () override
4962         {
4963             m_class_name.clear();
4964             m_function_name.clear();
4965             m_line_start = 0;
4966             m_line_end = UINT_MAX;
4967             m_file_name.clear();
4968             m_module_name.clear();
4969             m_func_name_type_mask = eFunctionNameTypeAuto;
4970             m_thread_id = LLDB_INVALID_THREAD_ID;
4971             m_thread_index = UINT32_MAX;
4972             m_thread_name.clear();
4973             m_queue_name.clear();
4974 
4975             m_no_inlines = false;
4976             m_sym_ctx_specified = false;
4977             m_thread_specified = false;
4978 
4979             m_use_one_liner = false;
4980             m_one_liner.clear();
4981         }
4982 
4983         static OptionDefinition g_option_table[];
4984 
4985         std::string m_class_name;
4986         std::string m_function_name;
4987         uint32_t    m_line_start;
4988         uint32_t    m_line_end;
4989         std::string m_file_name;
4990         std::string m_module_name;
4991         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
4992         lldb::tid_t m_thread_id;
4993         uint32_t m_thread_index;
4994         std::string m_thread_name;
4995         std::string m_queue_name;
4996         bool        m_sym_ctx_specified;
4997         bool        m_no_inlines;
4998         bool        m_thread_specified;
4999         // Instance variables to hold the values for one_liner options.
5000         bool m_use_one_liner;
5001         std::string m_one_liner;
5002     };
5003 
5004     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
5005         CommandObjectParsed (interpreter,
5006                              "target stop-hook add",
5007                              "Add a hook to be executed when the target stops.",
5008                              "target stop-hook add"),
5009         IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
5010         m_options (interpreter)
5011     {
5012     }
5013 
5014     ~CommandObjectTargetStopHookAdd() override = default;
5015 
5016     Options *
5017     GetOptions () override
5018     {
5019         return &m_options;
5020     }
5021 
5022 protected:
5023     void
5024     IOHandlerActivated (IOHandler &io_handler) override
5025     {
5026         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5027         if (output_sp)
5028         {
5029             output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
5030             output_sp->Flush();
5031         }
5032     }
5033 
5034     void
5035     IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
5036     {
5037         if (m_stop_hook_sp)
5038         {
5039             if (line.empty())
5040             {
5041                 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
5042                 if (error_sp)
5043                 {
5044                     error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
5045                     error_sp->Flush();
5046                 }
5047                 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5048                 if (target)
5049                     target->RemoveStopHookByID(m_stop_hook_sp->GetID());
5050             }
5051             else
5052             {
5053                 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
5054                 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5055                 if (output_sp)
5056                 {
5057                     output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
5058                     output_sp->Flush();
5059                 }
5060             }
5061             m_stop_hook_sp.reset();
5062         }
5063         io_handler.SetIsDone(true);
5064     }
5065 
5066     bool
5067     DoExecute (Args& command, CommandReturnObject &result) override
5068     {
5069         m_stop_hook_sp.reset();
5070 
5071         Target *target = GetSelectedOrDummyTarget();
5072         if (target)
5073         {
5074             Target::StopHookSP new_hook_sp = target->CreateStopHook();
5075 
5076             //  First step, make the specifier.
5077             std::unique_ptr<SymbolContextSpecifier> specifier_ap;
5078             if (m_options.m_sym_ctx_specified)
5079             {
5080                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
5081 
5082                 if (!m_options.m_module_name.empty())
5083                 {
5084                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
5085                 }
5086 
5087                 if (!m_options.m_class_name.empty())
5088                 {
5089                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
5090                 }
5091 
5092                 if (!m_options.m_file_name.empty())
5093                 {
5094                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
5095                 }
5096 
5097                 if (m_options.m_line_start != 0)
5098                 {
5099                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
5100                 }
5101 
5102                 if (m_options.m_line_end != UINT_MAX)
5103                 {
5104                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5105                 }
5106 
5107                 if (!m_options.m_function_name.empty())
5108                 {
5109                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
5110                 }
5111             }
5112 
5113             if (specifier_ap)
5114                 new_hook_sp->SetSpecifier (specifier_ap.release());
5115 
5116             // Next see if any of the thread options have been entered:
5117 
5118             if (m_options.m_thread_specified)
5119             {
5120                 ThreadSpec *thread_spec = new ThreadSpec();
5121 
5122                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5123                 {
5124                     thread_spec->SetTID (m_options.m_thread_id);
5125                 }
5126 
5127                 if (m_options.m_thread_index != UINT32_MAX)
5128                     thread_spec->SetIndex (m_options.m_thread_index);
5129 
5130                 if (!m_options.m_thread_name.empty())
5131                     thread_spec->SetName (m_options.m_thread_name.c_str());
5132 
5133                 if (!m_options.m_queue_name.empty())
5134                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
5135 
5136                 new_hook_sp->SetThreadSpecifier (thread_spec);
5137 
5138             }
5139             if (m_options.m_use_one_liner)
5140             {
5141                 // Use one-liner.
5142                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
5143                 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
5144             }
5145             else
5146             {
5147                 m_stop_hook_sp = new_hook_sp;
5148                 m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
5149                                                            *this,  // IOHandlerDelegate
5150                                                            true,   // Run IOHandler in async mode
5151                                                            nullptr);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
5152 
5153             }
5154             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5155         }
5156         else
5157         {
5158             result.AppendError ("invalid target\n");
5159             result.SetStatus (eReturnStatusFailed);
5160         }
5161 
5162         return result.Succeeded();
5163     }
5164 
5165 private:
5166     CommandOptions m_options;
5167     Target::StopHookSP m_stop_hook_sp;
5168 };
5169 
5170 OptionDefinition
5171 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
5172 {
5173     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
5174         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
5175     { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
5176         "Set the module within which the stop-hook is to be run."},
5177     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
5178         "The stop hook is run only for the thread whose index matches this argument."},
5179     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
5180         "The stop hook is run only for the thread whose TID matches this argument."},
5181     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
5182         "The stop hook is run only for the thread whose thread name matches this argument."},
5183     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
5184         "The stop hook is run only for threads in the queue whose name is given by this argument."},
5185     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
5186         "Specify the source file within which the stop-hook is to be run." },
5187     { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
5188         "Set the start of the line range for which the stop-hook is to be run."},
5189     { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
5190         "Set the end of the line range for which the stop-hook is to be run."},
5191     { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName,
5192         "Specify the class within which the stop-hook is to be run." },
5193     { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
5194         "Set the function name within which the stop hook will be run." },
5195     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
5196 };
5197 
5198 #pragma mark CommandObjectTargetStopHookDelete
5199 
5200 //-------------------------------------------------------------------------
5201 // CommandObjectTargetStopHookDelete
5202 //-------------------------------------------------------------------------
5203 
5204 class CommandObjectTargetStopHookDelete : public CommandObjectParsed
5205 {
5206 public:
5207     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
5208         CommandObjectParsed (interpreter,
5209                              "target stop-hook delete",
5210                              "Delete a stop-hook.",
5211                              "target stop-hook delete [<idx>]")
5212     {
5213     }
5214 
5215     ~CommandObjectTargetStopHookDelete() override = default;
5216 
5217 protected:
5218     bool
5219     DoExecute (Args& command, CommandReturnObject &result) override
5220     {
5221         Target *target = GetSelectedOrDummyTarget();
5222         if (target)
5223         {
5224             // FIXME: see if we can use the breakpoint id style parser?
5225             size_t num_args = command.GetArgumentCount();
5226             if (num_args == 0)
5227             {
5228                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
5229                 {
5230                     result.SetStatus (eReturnStatusFailed);
5231                     return false;
5232                 }
5233                 else
5234                 {
5235                     target->RemoveAllStopHooks();
5236                 }
5237             }
5238             else
5239             {
5240                 bool success;
5241                 for (size_t i = 0; i < num_args; i++)
5242                 {
5243                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5244                     if (!success)
5245                     {
5246                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5247                         result.SetStatus(eReturnStatusFailed);
5248                         return false;
5249                     }
5250                     success = target->RemoveStopHookByID (user_id);
5251                     if (!success)
5252                     {
5253                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5254                         result.SetStatus(eReturnStatusFailed);
5255                         return false;
5256                     }
5257                 }
5258             }
5259             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5260         }
5261         else
5262         {
5263             result.AppendError ("invalid target\n");
5264             result.SetStatus (eReturnStatusFailed);
5265         }
5266 
5267         return result.Succeeded();
5268     }
5269 };
5270 
5271 #pragma mark CommandObjectTargetStopHookEnableDisable
5272 
5273 //-------------------------------------------------------------------------
5274 // CommandObjectTargetStopHookEnableDisable
5275 //-------------------------------------------------------------------------
5276 
5277 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
5278 {
5279 public:
5280     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
5281         CommandObjectParsed (interpreter,
5282                              name,
5283                              help,
5284                              syntax),
5285         m_enable (enable)
5286     {
5287     }
5288 
5289     ~CommandObjectTargetStopHookEnableDisable() override = default;
5290 
5291 protected:
5292     bool
5293     DoExecute (Args& command, CommandReturnObject &result) override
5294     {
5295         Target *target = GetSelectedOrDummyTarget();
5296         if (target)
5297         {
5298             // FIXME: see if we can use the breakpoint id style parser?
5299             size_t num_args = command.GetArgumentCount();
5300             bool success;
5301 
5302             if (num_args == 0)
5303             {
5304                 target->SetAllStopHooksActiveState (m_enable);
5305             }
5306             else
5307             {
5308                 for (size_t i = 0; i < num_args; i++)
5309                 {
5310                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5311                     if (!success)
5312                     {
5313                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5314                         result.SetStatus(eReturnStatusFailed);
5315                         return false;
5316                     }
5317                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
5318                     if (!success)
5319                     {
5320                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5321                         result.SetStatus(eReturnStatusFailed);
5322                         return false;
5323                     }
5324                 }
5325             }
5326             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5327         }
5328         else
5329         {
5330             result.AppendError ("invalid target\n");
5331             result.SetStatus (eReturnStatusFailed);
5332         }
5333         return result.Succeeded();
5334     }
5335 private:
5336     bool m_enable;
5337 };
5338 
5339 #pragma mark CommandObjectTargetStopHookList
5340 
5341 //-------------------------------------------------------------------------
5342 // CommandObjectTargetStopHookList
5343 //-------------------------------------------------------------------------
5344 
5345 class CommandObjectTargetStopHookList : public CommandObjectParsed
5346 {
5347 public:
5348     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
5349         CommandObjectParsed (interpreter,
5350                              "target stop-hook list",
5351                              "List all stop-hooks.",
5352                              "target stop-hook list [<type>]")
5353     {
5354     }
5355 
5356     ~CommandObjectTargetStopHookList() override = default;
5357 
5358 protected:
5359     bool
5360     DoExecute (Args& command, CommandReturnObject &result) override
5361     {
5362         Target *target = GetSelectedOrDummyTarget();
5363         if (!target)
5364         {
5365             result.AppendError ("invalid target\n");
5366             result.SetStatus (eReturnStatusFailed);
5367             return result.Succeeded();
5368         }
5369 
5370         size_t num_hooks = target->GetNumStopHooks ();
5371         if (num_hooks == 0)
5372         {
5373             result.GetOutputStream().PutCString ("No stop hooks.\n");
5374         }
5375         else
5376         {
5377             for (size_t i = 0; i < num_hooks; i++)
5378             {
5379                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
5380                 if (i > 0)
5381                     result.GetOutputStream().PutCString ("\n");
5382                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
5383             }
5384         }
5385         result.SetStatus (eReturnStatusSuccessFinishResult);
5386         return result.Succeeded();
5387     }
5388 };
5389 
5390 #pragma mark CommandObjectMultiwordTargetStopHooks
5391 
5392 //-------------------------------------------------------------------------
5393 // CommandObjectMultiwordTargetStopHooks
5394 //-------------------------------------------------------------------------
5395 
5396 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
5397 {
5398 public:
5399     CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
5400         : CommandObjectMultiword(interpreter, "target stop-hook",
5401                                  "Commands for operating on debugger target stop-hooks.",
5402                                  "target stop-hook <subcommand> [<subcommand-options>]")
5403     {
5404         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
5405         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
5406         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5407                                                                                                    false,
5408                                                                                                    "target stop-hook disable [<id>]",
5409                                                                                                    "Disable a stop-hook.",
5410                                                                                                    "target stop-hook disable")));
5411         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5412                                                                                                    true,
5413                                                                                                    "target stop-hook enable [<id>]",
5414                                                                                                    "Enable a stop-hook.",
5415                                                                                                    "target stop-hook enable")));
5416         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5417     }
5418 
5419     ~CommandObjectMultiwordTargetStopHooks() override = default;
5420 };
5421 
5422 #pragma mark CommandObjectMultiwordTarget
5423 
5424 //-------------------------------------------------------------------------
5425 // CommandObjectMultiwordTarget
5426 //-------------------------------------------------------------------------
5427 
5428 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(CommandInterpreter &interpreter)
5429     : CommandObjectMultiword(interpreter, "target", "Commands for operating on debugger targets.",
5430                              "target <subcommand> [<subcommand-options>]")
5431 {
5432     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5433     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5434     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5435     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5436     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5437     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5438     LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5439     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5440 }
5441 
5442 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5443