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 (),
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(GetCommandInterpreter(),
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(LLVM_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(),
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(),
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(GetCommandInterpreter(),
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(GetCommandInterpreter(),
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()
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() :
2239         Options(),
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,
2248                        ExecutionContext *execution_context) override
2249         {
2250             Error error;
2251             const int short_option = m_getopt_table[option_idx].val;
2252 
2253             switch (short_option)
2254             {
2255                 case 's':
2256                     m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
2257                                                                          g_option_table[option_idx].enum_values,
2258                                                                          eSortOrderNone,
2259                                                                          error);
2260                     break;
2261 
2262                 default:
2263                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2264                     break;
2265             }
2266             return error;
2267         }
2268 
2269         void
2270         OptionParsingStarting(ExecutionContext *execution_context) override
2271         {
2272             m_sort_order = eSortOrderNone;
2273         }
2274 
2275         const OptionDefinition*
2276         GetDefinitions () override
2277         {
2278             return g_option_table;
2279         }
2280 
2281         // Options table: Required for subclasses of Options.
2282         static OptionDefinition g_option_table[];
2283 
2284         SortOrder m_sort_order;
2285     };
2286 
2287 protected:
2288     bool
2289     DoExecute (Args& command, CommandReturnObject &result) override
2290     {
2291         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2292         if (target == nullptr)
2293         {
2294             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2295             result.SetStatus (eReturnStatusFailed);
2296             return false;
2297         }
2298         else
2299         {
2300             uint32_t num_dumped = 0;
2301 
2302             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2303             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2304             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2305 
2306             if (command.GetArgumentCount() == 0)
2307             {
2308                 // Dump all sections for all modules images
2309                 std::lock_guard<std::recursive_mutex> guard(target->GetImages().GetMutex());
2310                 const size_t num_modules = target->GetImages().GetSize();
2311                 if (num_modules > 0)
2312                 {
2313                     result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2314                     for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
2315                     {
2316                         if (num_dumped > 0)
2317                         {
2318                             result.GetOutputStream().EOL();
2319                             result.GetOutputStream().EOL();
2320                         }
2321                         num_dumped++;
2322                         DumpModuleSymtab (m_interpreter,
2323                                           result.GetOutputStream(),
2324                                           target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2325                                           m_options.m_sort_order);
2326                     }
2327                 }
2328                 else
2329                 {
2330                     result.AppendError ("the target has no associated executable images");
2331                     result.SetStatus (eReturnStatusFailed);
2332                     return false;
2333                 }
2334             }
2335             else
2336             {
2337                 // Dump specified images (by basename or fullpath)
2338                 const char *arg_cstr;
2339                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2340                 {
2341                     ModuleList module_list;
2342                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2343                     if (num_matches > 0)
2344                     {
2345                         for (size_t i = 0; i < num_matches; ++i)
2346                         {
2347                             Module *module = module_list.GetModulePointerAtIndex(i);
2348                             if (module)
2349                             {
2350                                 if (num_dumped > 0)
2351                                 {
2352                                     result.GetOutputStream().EOL();
2353                                     result.GetOutputStream().EOL();
2354                                 }
2355                                 num_dumped++;
2356                                 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
2357                             }
2358                         }
2359                     }
2360                     else
2361                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2362                 }
2363             }
2364 
2365             if (num_dumped > 0)
2366                 result.SetStatus (eReturnStatusSuccessFinishResult);
2367             else
2368             {
2369                 result.AppendError ("no matching executable images found");
2370                 result.SetStatus (eReturnStatusFailed);
2371             }
2372         }
2373         return result.Succeeded();
2374     }
2375 
2376     CommandOptions m_options;
2377 };
2378 
2379 static OptionEnumValueElement
2380 g_sort_option_enumeration[4] =
2381 {
2382     { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
2383     { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
2384     { eSortOrderByName,     "name",     "Sort output by symbol name."},
2385     { 0,                    nullptr,    nullptr }
2386 };
2387 
2388 OptionDefinition
2389 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2390 {
2391     { 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."},
2392     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
2393 };
2394 
2395 #pragma mark CommandObjectTargetModulesDumpSections
2396 
2397 //----------------------------------------------------------------------
2398 // Image section dumping command
2399 //----------------------------------------------------------------------
2400 
2401 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2402 {
2403 public:
2404     CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2405         CommandObjectTargetModulesModuleAutoComplete(interpreter,
2406                                                      "target modules dump sections",
2407                                                      "Dump the sections from one or more target modules.",
2408                                                      //"target modules dump sections [<file1> ...]")
2409                                                      nullptr)
2410     {
2411     }
2412 
2413     ~CommandObjectTargetModulesDumpSections() override = default;
2414 
2415 protected:
2416     bool
2417     DoExecute (Args& command, CommandReturnObject &result) override
2418     {
2419         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2420         if (target == nullptr)
2421         {
2422             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2423             result.SetStatus (eReturnStatusFailed);
2424             return false;
2425         }
2426         else
2427         {
2428             uint32_t num_dumped = 0;
2429 
2430             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2431             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2432             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2433 
2434             if (command.GetArgumentCount() == 0)
2435             {
2436                 // Dump all sections for all modules images
2437                 const size_t num_modules = target->GetImages().GetSize();
2438                 if (num_modules > 0)
2439                 {
2440                     result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2441                     for (size_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2442                     {
2443                         num_dumped++;
2444                         DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2445                     }
2446                 }
2447                 else
2448                 {
2449                     result.AppendError ("the target has no associated executable images");
2450                     result.SetStatus (eReturnStatusFailed);
2451                     return false;
2452                 }
2453             }
2454             else
2455             {
2456                 // Dump specified images (by basename or fullpath)
2457                 const char *arg_cstr;
2458                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2459                 {
2460                     ModuleList module_list;
2461                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2462                     if (num_matches > 0)
2463                     {
2464                         for (size_t i = 0; i < num_matches; ++i)
2465                         {
2466                             Module *module = module_list.GetModulePointerAtIndex(i);
2467                             if (module)
2468                             {
2469                                 num_dumped++;
2470                                 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
2471                             }
2472                         }
2473                     }
2474                     else
2475                     {
2476                         // Check the global list
2477                         std::lock_guard<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex());
2478 
2479                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2480                     }
2481                 }
2482             }
2483 
2484             if (num_dumped > 0)
2485                 result.SetStatus (eReturnStatusSuccessFinishResult);
2486             else
2487             {
2488                 result.AppendError ("no matching executable images found");
2489                 result.SetStatus (eReturnStatusFailed);
2490             }
2491         }
2492         return result.Succeeded();
2493     }
2494 };
2495 
2496 #pragma mark CommandObjectTargetModulesDumpSymfile
2497 
2498 //----------------------------------------------------------------------
2499 // Image debug symbol dumping command
2500 //----------------------------------------------------------------------
2501 
2502 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2503 {
2504 public:
2505     CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2506         CommandObjectTargetModulesModuleAutoComplete(interpreter,
2507                                                      "target modules dump symfile",
2508                                                      "Dump the debug symbol file for one or more target modules.",
2509                                                      //"target modules dump symfile [<file1> ...]")
2510                                                      nullptr)
2511     {
2512     }
2513 
2514     ~CommandObjectTargetModulesDumpSymfile() override = default;
2515 
2516 protected:
2517     bool
2518     DoExecute (Args& command, CommandReturnObject &result) override
2519     {
2520         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2521         if (target == nullptr)
2522         {
2523             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2524             result.SetStatus (eReturnStatusFailed);
2525             return false;
2526         }
2527         else
2528         {
2529             uint32_t num_dumped = 0;
2530 
2531             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2532             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2533             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2534 
2535             if (command.GetArgumentCount() == 0)
2536             {
2537                 // Dump all sections for all modules images
2538                 const ModuleList &target_modules = target->GetImages();
2539                 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2540                 const size_t num_modules = target_modules.GetSize();
2541                 if (num_modules > 0)
2542                 {
2543                     result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2544                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2545                     {
2546                         if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2547                             num_dumped++;
2548                     }
2549                 }
2550                 else
2551                 {
2552                     result.AppendError ("the target has no associated executable images");
2553                     result.SetStatus (eReturnStatusFailed);
2554                     return false;
2555                 }
2556             }
2557             else
2558             {
2559                 // Dump specified images (by basename or fullpath)
2560                 const char *arg_cstr;
2561                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2562                 {
2563                     ModuleList module_list;
2564                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2565                     if (num_matches > 0)
2566                     {
2567                         for (size_t i = 0; i < num_matches; ++i)
2568                         {
2569                             Module *module = module_list.GetModulePointerAtIndex(i);
2570                             if (module)
2571                             {
2572                                 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
2573                                     num_dumped++;
2574                             }
2575                         }
2576                     }
2577                     else
2578                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2579                 }
2580             }
2581 
2582             if (num_dumped > 0)
2583                 result.SetStatus (eReturnStatusSuccessFinishResult);
2584             else
2585             {
2586                 result.AppendError ("no matching executable images found");
2587                 result.SetStatus (eReturnStatusFailed);
2588             }
2589         }
2590         return result.Succeeded();
2591     }
2592 };
2593 
2594 #pragma mark CommandObjectTargetModulesDumpLineTable
2595 
2596 //----------------------------------------------------------------------
2597 // Image debug line table dumping command
2598 //----------------------------------------------------------------------
2599 
2600 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2601 {
2602 public:
2603     CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2604         CommandObjectTargetModulesSourceFileAutoComplete(interpreter,
2605                                                          "target modules dump line-table",
2606                                                          "Dump the line table for one or more compilation units.",
2607                                                          nullptr,
2608                                                          eCommandRequiresTarget)
2609     {
2610     }
2611 
2612     ~CommandObjectTargetModulesDumpLineTable() override = default;
2613 
2614 protected:
2615     bool
2616     DoExecute (Args& command, CommandReturnObject &result) override
2617     {
2618         Target *target = m_exe_ctx.GetTargetPtr();
2619         uint32_t total_num_dumped = 0;
2620 
2621         uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2622         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2623         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2624 
2625         if (command.GetArgumentCount() == 0)
2626         {
2627             result.AppendError ("file option must be specified.");
2628             result.SetStatus (eReturnStatusFailed);
2629             return result.Succeeded();
2630         }
2631         else
2632         {
2633             // Dump specified images (by basename or fullpath)
2634             const char *arg_cstr;
2635             for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
2636             {
2637                 FileSpec file_spec(arg_cstr, false);
2638 
2639                 const ModuleList &target_modules = target->GetImages();
2640                 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2641                 const size_t num_modules = target_modules.GetSize();
2642                 if (num_modules > 0)
2643                 {
2644                     uint32_t num_dumped = 0;
2645                     for (uint32_t i = 0; i<num_modules; ++i)
2646                     {
2647                         if (DumpCompileUnitLineTable (m_interpreter,
2648                                                       result.GetOutputStream(),
2649                                                       target_modules.GetModulePointerAtIndexUnlocked(i),
2650                                                       file_spec,
2651                                                       m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
2652                             num_dumped++;
2653                     }
2654                     if (num_dumped == 0)
2655                         result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2656                     else
2657                         total_num_dumped += num_dumped;
2658                 }
2659             }
2660         }
2661 
2662         if (total_num_dumped > 0)
2663             result.SetStatus (eReturnStatusSuccessFinishResult);
2664         else
2665         {
2666             result.AppendError ("no source filenames matched any command arguments");
2667             result.SetStatus (eReturnStatusFailed);
2668         }
2669         return result.Succeeded();
2670     }
2671 };
2672 
2673 #pragma mark CommandObjectTargetModulesDump
2674 
2675 //----------------------------------------------------------------------
2676 // Dump multi-word command for target modules
2677 //----------------------------------------------------------------------
2678 
2679 class CommandObjectTargetModulesDump : public CommandObjectMultiword
2680 {
2681 public:
2682     //------------------------------------------------------------------
2683     // Constructors and Destructors
2684     //------------------------------------------------------------------
2685     CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2686         : CommandObjectMultiword(
2687               interpreter, "target modules dump", "Commands for dumping information about one or more target modules.",
2688               "target modules dump [headers|symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2689     {
2690         LoadSubCommand("objfile", CommandObjectSP(new CommandObjectTargetModulesDumpObjfile(interpreter)));
2691         LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2692         LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2693         LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2694         LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2695     }
2696 
2697     ~CommandObjectTargetModulesDump() override = default;
2698 };
2699 
2700 class CommandObjectTargetModulesAdd : public CommandObjectParsed
2701 {
2702 public:
2703     CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2704         CommandObjectParsed (interpreter,
2705                              "target modules add",
2706                              "Add a new module to the current target's modules.",
2707                              "target modules add [<module>]"),
2708         m_option_group(),
2709         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.")
2710     {
2711         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2712         m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2713         m_option_group.Finalize();
2714     }
2715 
2716     ~CommandObjectTargetModulesAdd() override = default;
2717 
2718     Options *
2719     GetOptions () override
2720     {
2721         return &m_option_group;
2722     }
2723 
2724     int
2725     HandleArgumentCompletion (Args &input,
2726                               int &cursor_index,
2727                               int &cursor_char_position,
2728                               OptionElementVector &opt_element_vector,
2729                               int match_start_point,
2730                               int max_return_elements,
2731                               bool &word_complete,
2732                               StringList &matches) override
2733     {
2734         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2735         completion_str.erase (cursor_char_position);
2736 
2737         CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(),
2738                                                             CommandCompletions::eDiskFileCompletion,
2739                                                             completion_str.c_str(),
2740                                                             match_start_point,
2741                                                             max_return_elements,
2742                                                             nullptr,
2743                                                             word_complete,
2744                                                             matches);
2745         return matches.GetSize();
2746     }
2747 
2748 protected:
2749     OptionGroupOptions m_option_group;
2750     OptionGroupUUID m_uuid_option_group;
2751     OptionGroupFile m_symbol_file;
2752 
2753     bool
2754     DoExecute (Args& args, CommandReturnObject &result) override
2755     {
2756         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2757         if (target == nullptr)
2758         {
2759             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2760             result.SetStatus (eReturnStatusFailed);
2761             return false;
2762         }
2763         else
2764         {
2765             bool flush = false;
2766 
2767             const size_t argc = args.GetArgumentCount();
2768             if (argc == 0)
2769             {
2770                 if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2771                 {
2772                     // We are given a UUID only, go locate the file
2773                     ModuleSpec module_spec;
2774                     module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2775                     if (m_symbol_file.GetOptionValue().OptionWasSet())
2776                         module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2777                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
2778                     {
2779                         ModuleSP module_sp (target->GetSharedModule (module_spec));
2780                         if (module_sp)
2781                         {
2782                             result.SetStatus (eReturnStatusSuccessFinishResult);
2783                             return true;
2784                         }
2785                         else
2786                         {
2787                             StreamString strm;
2788                             module_spec.GetUUID().Dump (&strm);
2789                             if (module_spec.GetFileSpec())
2790                             {
2791                                 if (module_spec.GetSymbolFileSpec())
2792                                 {
2793                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s",
2794                                                                   strm.GetString().c_str(),
2795                                                                   module_spec.GetFileSpec().GetPath().c_str(),
2796                                                                   module_spec.GetSymbolFileSpec().GetPath().c_str());
2797                                 }
2798                                 else
2799                                 {
2800                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s",
2801                                                                   strm.GetString().c_str(),
2802                                                                   module_spec.GetFileSpec().GetPath().c_str());
2803                                 }
2804                             }
2805                             else
2806                             {
2807                                 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
2808                                                               strm.GetString().c_str());
2809                             }
2810                             result.SetStatus (eReturnStatusFailed);
2811                             return false;
2812                         }
2813                     }
2814                     else
2815                     {
2816                         StreamString strm;
2817                         module_spec.GetUUID().Dump (&strm);
2818                         result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
2819                         result.SetStatus (eReturnStatusFailed);
2820                         return false;
2821                     }
2822                 }
2823                 else
2824                 {
2825                     result.AppendError ("one or more executable image paths must be specified");
2826                     result.SetStatus (eReturnStatusFailed);
2827                     return false;
2828                 }
2829             }
2830             else
2831             {
2832                 for (size_t i = 0; i < argc; ++i)
2833                 {
2834                     const char *path = args.GetArgumentAtIndex(i);
2835                     if (path)
2836                     {
2837                         FileSpec file_spec(path, true);
2838                         if (file_spec.Exists())
2839                         {
2840                             ModuleSpec module_spec (file_spec);
2841                             if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2842                                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2843                             if (m_symbol_file.GetOptionValue().OptionWasSet())
2844                                 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2845                             if (!module_spec.GetArchitecture().IsValid())
2846                                 module_spec.GetArchitecture() = target->GetArchitecture();
2847                             Error error;
2848                             ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
2849                             if (!module_sp)
2850                             {
2851                                 const char *error_cstr = error.AsCString();
2852                                 if (error_cstr)
2853                                     result.AppendError (error_cstr);
2854                                 else
2855                                     result.AppendErrorWithFormat ("unsupported module: %s", path);
2856                                 result.SetStatus (eReturnStatusFailed);
2857                                 return false;
2858                             }
2859                             else
2860                             {
2861                                 flush = true;
2862                             }
2863                             result.SetStatus (eReturnStatusSuccessFinishResult);
2864                         }
2865                         else
2866                         {
2867                             char resolved_path[PATH_MAX];
2868                             result.SetStatus (eReturnStatusFailed);
2869                             if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2870                             {
2871                                 if (strcmp (resolved_path, path) != 0)
2872                                 {
2873                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2874                                     break;
2875                                 }
2876                             }
2877                             result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2878                             break;
2879                         }
2880                     }
2881                 }
2882             }
2883 
2884             if (flush)
2885             {
2886                 ProcessSP process = target->GetProcessSP();
2887                 if (process)
2888                     process->Flush();
2889             }
2890         }
2891 
2892         return result.Succeeded();
2893     }
2894 };
2895 
2896 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2897 {
2898 public:
2899     CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2900         CommandObjectTargetModulesModuleAutoComplete (interpreter,
2901                                                       "target modules load",
2902                                                       "Set the load addresses for one or more sections in a target module.",
2903                                                       "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2904         m_option_group(),
2905         m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""),
2906         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)
2907     {
2908         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2909         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2910         m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2911         m_option_group.Finalize();
2912     }
2913 
2914     ~CommandObjectTargetModulesLoad() override = default;
2915 
2916     Options *
2917     GetOptions () override
2918     {
2919         return &m_option_group;
2920     }
2921 
2922 protected:
2923     bool
2924     DoExecute (Args& args, CommandReturnObject &result) override
2925     {
2926         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2927         if (target == nullptr)
2928         {
2929             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2930             result.SetStatus (eReturnStatusFailed);
2931             return false;
2932         }
2933         else
2934         {
2935             const size_t argc = args.GetArgumentCount();
2936             ModuleSpec module_spec;
2937             bool search_using_module_spec = false;
2938             if (m_file_option.GetOptionValue().OptionWasSet())
2939             {
2940                 search_using_module_spec = true;
2941                 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2942                 const bool use_global_module_list = true;
2943                 ModuleList module_list;
2944                 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
2945                 if (num_matches == 1)
2946                 {
2947                     module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec();
2948                 }
2949                 else if (num_matches > 1 )
2950                 {
2951                     search_using_module_spec = false;
2952                     result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr);
2953                     result.SetStatus (eReturnStatusFailed);
2954                 }
2955                 else
2956                 {
2957                     search_using_module_spec = false;
2958                     result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr);
2959                     result.SetStatus (eReturnStatusFailed);
2960                 }
2961             }
2962 
2963             if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2964             {
2965                 search_using_module_spec = true;
2966                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
2967             }
2968 
2969             if (search_using_module_spec)
2970             {
2971                 ModuleList matching_modules;
2972                 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
2973 
2974                 char path[PATH_MAX];
2975                 if (num_matches == 1)
2976                 {
2977                     Module *module = matching_modules.GetModulePointerAtIndex(0);
2978                     if (module)
2979                     {
2980                         ObjectFile *objfile = module->GetObjectFile();
2981                         if (objfile)
2982                         {
2983                             SectionList *section_list = module->GetSectionList();
2984                             if (section_list)
2985                             {
2986                                 bool changed = false;
2987                                 if (argc == 0)
2988                                 {
2989                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2990                                     {
2991                                         const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2992                                         const bool slide_is_offset = true;
2993                                         module->SetLoadAddress (*target, slide, slide_is_offset, changed);
2994                                     }
2995                                     else
2996                                     {
2997                                         result.AppendError ("one or more section name + load address pair must be specified");
2998                                         result.SetStatus (eReturnStatusFailed);
2999                                         return false;
3000                                     }
3001                                 }
3002                                 else
3003                                 {
3004                                     if (m_slide_option.GetOptionValue().OptionWasSet())
3005                                     {
3006                                         result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
3007                                         result.SetStatus (eReturnStatusFailed);
3008                                         return false;
3009                                     }
3010 
3011                                     for (size_t i = 0; i < argc; i += 2)
3012                                     {
3013                                         const char *sect_name = args.GetArgumentAtIndex(i);
3014                                         const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
3015                                         if (sect_name && load_addr_cstr)
3016                                         {
3017                                             ConstString const_sect_name(sect_name);
3018                                             bool success = false;
3019                                             addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
3020                                             if (success)
3021                                             {
3022                                                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
3023                                                 if (section_sp)
3024                                                 {
3025                                                     if (section_sp->IsThreadSpecific())
3026                                                     {
3027                                                         result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
3028                                                         result.SetStatus (eReturnStatusFailed);
3029                                                         break;
3030                                                     }
3031                                                     else
3032                                                     {
3033                                                         if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
3034                                                             changed = true;
3035                                                         result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
3036                                                     }
3037                                                 }
3038                                                 else
3039                                                 {
3040                                                     result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
3041                                                     result.SetStatus (eReturnStatusFailed);
3042                                                     break;
3043                                                 }
3044                                             }
3045                                             else
3046                                             {
3047                                                 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
3048                                                 result.SetStatus (eReturnStatusFailed);
3049                                                 break;
3050                                             }
3051                                         }
3052                                         else
3053                                         {
3054                                             if (sect_name)
3055                                                 result.AppendError ("section names must be followed by a load address.\n");
3056                                             else
3057                                                 result.AppendError ("one or more section name + load address pair must be specified.\n");
3058                                             result.SetStatus (eReturnStatusFailed);
3059                                             break;
3060                                         }
3061                                     }
3062                                 }
3063 
3064                                 if (changed)
3065                                 {
3066                                     target->ModulesDidLoad (matching_modules);
3067                                     Process *process = m_exe_ctx.GetProcessPtr();
3068                                     if (process)
3069                                         process->Flush();
3070                                 }
3071                             }
3072                             else
3073                             {
3074                                 module->GetFileSpec().GetPath (path, sizeof(path));
3075                                 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
3076                                 result.SetStatus (eReturnStatusFailed);
3077                             }
3078                         }
3079                         else
3080                         {
3081                             module->GetFileSpec().GetPath (path, sizeof(path));
3082                             result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
3083                             result.SetStatus (eReturnStatusFailed);
3084                         }
3085                     }
3086                     else
3087                     {
3088                         FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3089                         if (module_spec_file)
3090                         {
3091                             module_spec_file->GetPath (path, sizeof(path));
3092                             result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
3093                         }
3094                         else
3095                             result.AppendError ("no module spec");
3096                         result.SetStatus (eReturnStatusFailed);
3097                     }
3098                 }
3099                 else
3100                 {
3101                     std::string uuid_str;
3102 
3103                     if (module_spec.GetFileSpec())
3104                         module_spec.GetFileSpec().GetPath (path, sizeof(path));
3105                     else
3106                         path[0] = '\0';
3107 
3108                     if (module_spec.GetUUIDPtr())
3109                         uuid_str = module_spec.GetUUID().GetAsString();
3110                     if (num_matches > 1)
3111                     {
3112                         result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
3113                                                       path[0] ? " file=" : "",
3114                                                       path,
3115                                                       !uuid_str.empty() ? " uuid=" : "",
3116                                                       uuid_str.c_str());
3117                         for (size_t i = 0; i < num_matches; ++i)
3118                         {
3119                             if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
3120                                 result.AppendMessageWithFormat("%s\n", path);
3121                         }
3122                     }
3123                     else
3124                     {
3125                         result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
3126                                                       path[0] ? " file=" : "",
3127                                                       path,
3128                                                       !uuid_str.empty() ? " uuid=" : "",
3129                                                       uuid_str.c_str());
3130                     }
3131                     result.SetStatus (eReturnStatusFailed);
3132                 }
3133             }
3134             else
3135             {
3136                 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
3137                 result.SetStatus (eReturnStatusFailed);
3138                 return false;
3139             }
3140         }
3141         return result.Succeeded();
3142     }
3143 
3144     OptionGroupOptions m_option_group;
3145     OptionGroupUUID m_uuid_option_group;
3146     OptionGroupString m_file_option;
3147     OptionGroupUInt64 m_slide_option;
3148 };
3149 
3150 //----------------------------------------------------------------------
3151 // List images with associated information
3152 //----------------------------------------------------------------------
3153 class CommandObjectTargetModulesList : public CommandObjectParsed
3154 {
3155 public:
3156     class CommandOptions : public Options
3157     {
3158     public:
3159         CommandOptions() :
3160             Options(),
3161             m_format_array(),
3162             m_use_global_module_list (false),
3163             m_module_addr (LLDB_INVALID_ADDRESS)
3164         {
3165         }
3166 
3167         ~CommandOptions() override = default;
3168 
3169         Error
3170         SetOptionValue(uint32_t option_idx, const char *option_arg,
3171                        ExecutionContext *execution_context) override
3172         {
3173             Error error;
3174 
3175             const int short_option = m_getopt_table[option_idx].val;
3176             if (short_option == 'g')
3177             {
3178                 m_use_global_module_list = true;
3179             }
3180             else if (short_option == 'a')
3181             {
3182                 m_module_addr = Args::StringToAddress(execution_context,
3183                                                       option_arg,
3184                                                       LLDB_INVALID_ADDRESS,
3185                                                       &error);
3186             }
3187             else
3188             {
3189                 unsigned long width = 0;
3190                 if (option_arg)
3191                     width = strtoul(option_arg, nullptr, 0);
3192                 m_format_array.push_back(std::make_pair(short_option, width));
3193             }
3194             return error;
3195         }
3196 
3197         void
3198         OptionParsingStarting(ExecutionContext *execution_context) override
3199         {
3200             m_format_array.clear();
3201             m_use_global_module_list = false;
3202             m_module_addr = LLDB_INVALID_ADDRESS;
3203         }
3204 
3205         const OptionDefinition*
3206         GetDefinitions () override
3207         {
3208             return g_option_table;
3209         }
3210 
3211         // Options table: Required for subclasses of Options.
3212 
3213         static OptionDefinition g_option_table[];
3214 
3215         // Instance variables to hold the values for command options.
3216         typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
3217         FormatWidthCollection m_format_array;
3218         bool m_use_global_module_list;
3219         lldb::addr_t m_module_addr;
3220     };
3221 
3222     CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
3223         CommandObjectParsed (interpreter,
3224                              "target modules list",
3225                              "List current executable and dependent shared library images.",
3226                              "target modules list [<cmd-options>]"),
3227         m_options()
3228     {
3229     }
3230 
3231     ~CommandObjectTargetModulesList() override = default;
3232 
3233     Options *
3234     GetOptions () override
3235     {
3236         return &m_options;
3237     }
3238 
3239 protected:
3240     bool
3241     DoExecute (Args& command, CommandReturnObject &result) override
3242     {
3243         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3244         const bool use_global_module_list = m_options.m_use_global_module_list;
3245         // Define a local module list here to ensure it lives longer than any "locker"
3246         // object which might lock its contents below (through the "module_list_ptr"
3247         // variable).
3248         ModuleList module_list;
3249         if (target == nullptr && !use_global_module_list)
3250         {
3251             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3252             result.SetStatus (eReturnStatusFailed);
3253             return false;
3254         }
3255         else
3256         {
3257             if (target)
3258             {
3259                 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3260                 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3261                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3262             }
3263             // Dump all sections for all modules images
3264             Stream &strm = result.GetOutputStream();
3265 
3266             if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
3267             {
3268                 if (target)
3269                 {
3270                     Address module_address;
3271                     if (module_address.SetLoadAddress(m_options.m_module_addr, target))
3272                     {
3273                         ModuleSP module_sp (module_address.GetModule());
3274                         if (module_sp)
3275                         {
3276                             PrintModule (target, module_sp.get(), 0, strm);
3277                             result.SetStatus (eReturnStatusSuccessFinishResult);
3278                         }
3279                         else
3280                         {
3281                             result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
3282                             result.SetStatus (eReturnStatusFailed);
3283                         }
3284                     }
3285                     else
3286                     {
3287                         result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
3288                         result.SetStatus (eReturnStatusFailed);
3289                     }
3290                 }
3291                 else
3292                 {
3293                     result.AppendError ("Can only look up modules by address with a valid target.");
3294                     result.SetStatus (eReturnStatusFailed);
3295                 }
3296                 return result.Succeeded();
3297             }
3298 
3299             size_t num_modules = 0;
3300 
3301             // This locker will be locked on the mutex in module_list_ptr if it is non-nullptr.
3302             // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
3303             // the global module list directly.
3304             std::unique_lock<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3305 
3306             const ModuleList *module_list_ptr = nullptr;
3307             const size_t argc = command.GetArgumentCount();
3308             if (argc == 0)
3309             {
3310                 if (use_global_module_list)
3311                 {
3312                     guard.lock();
3313                     num_modules = Module::GetNumberAllocatedModules();
3314                 }
3315                 else
3316                 {
3317                     module_list_ptr = &target->GetImages();
3318                 }
3319             }
3320             else
3321             {
3322                 for (size_t i = 0; i < argc; ++i)
3323                 {
3324                     // Dump specified images (by basename or fullpath)
3325                     const char *arg_cstr = command.GetArgumentAtIndex(i);
3326                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
3327                     if (num_matches == 0)
3328                     {
3329                         if (argc == 1)
3330                         {
3331                             result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
3332                             result.SetStatus (eReturnStatusFailed);
3333                             return false;
3334                         }
3335                     }
3336                 }
3337 
3338                 module_list_ptr = &module_list;
3339             }
3340 
3341             std::unique_lock<std::recursive_mutex> lock;
3342             if (module_list_ptr != nullptr)
3343             {
3344                 lock = std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3345 
3346                 num_modules = module_list_ptr->GetSize();
3347             }
3348 
3349             if (num_modules > 0)
3350             {
3351                 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
3352                 {
3353                     ModuleSP module_sp;
3354                     Module *module;
3355                     if (module_list_ptr)
3356                     {
3357                         module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3358                         module = module_sp.get();
3359                     }
3360                     else
3361                     {
3362                         module = Module::GetAllocatedModuleAtIndex(image_idx);
3363                         module_sp = module->shared_from_this();
3364                     }
3365 
3366                     const size_t indent = strm.Printf("[%3u] ", image_idx);
3367                     PrintModule (target, module, indent, strm);
3368 
3369                 }
3370                 result.SetStatus (eReturnStatusSuccessFinishResult);
3371             }
3372             else
3373             {
3374                 if (argc)
3375                 {
3376                     if (use_global_module_list)
3377                         result.AppendError ("the global module list has no matching modules");
3378                     else
3379                         result.AppendError ("the target has no matching modules");
3380                 }
3381                 else
3382                 {
3383                     if (use_global_module_list)
3384                         result.AppendError ("the global module list is empty");
3385                     else
3386                         result.AppendError ("the target has no associated executable images");
3387                 }
3388                 result.SetStatus (eReturnStatusFailed);
3389                 return false;
3390             }
3391         }
3392         return result.Succeeded();
3393     }
3394 
3395     void
3396     PrintModule (Target *target, Module *module, int indent, Stream &strm)
3397     {
3398         if (module == nullptr)
3399         {
3400             strm.PutCString("Null module");
3401             return;
3402         }
3403 
3404         bool dump_object_name = false;
3405         if (m_options.m_format_array.empty())
3406         {
3407             m_options.m_format_array.push_back(std::make_pair('u', 0));
3408             m_options.m_format_array.push_back(std::make_pair('h', 0));
3409             m_options.m_format_array.push_back(std::make_pair('f', 0));
3410             m_options.m_format_array.push_back(std::make_pair('S', 0));
3411         }
3412         const size_t num_entries = m_options.m_format_array.size();
3413         bool print_space = false;
3414         for (size_t i = 0; i < num_entries; ++i)
3415         {
3416             if (print_space)
3417                 strm.PutChar(' ');
3418             print_space = true;
3419             const char format_char = m_options.m_format_array[i].first;
3420             uint32_t width = m_options.m_format_array[i].second;
3421             switch (format_char)
3422             {
3423                 case 'A':
3424                     DumpModuleArchitecture (strm, module, false, width);
3425                     break;
3426 
3427                 case 't':
3428                     DumpModuleArchitecture (strm, module, true, width);
3429                     break;
3430 
3431                 case 'f':
3432                     DumpFullpath (strm, &module->GetFileSpec(), width);
3433                     dump_object_name = true;
3434                     break;
3435 
3436                 case 'd':
3437                     DumpDirectory (strm, &module->GetFileSpec(), width);
3438                     break;
3439 
3440                 case 'b':
3441                     DumpBasename (strm, &module->GetFileSpec(), width);
3442                     dump_object_name = true;
3443                     break;
3444 
3445                 case 'h':
3446                 case 'o':
3447                     // Image header address
3448                     {
3449                         uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
3450 
3451                         ObjectFile *objfile = module->GetObjectFile ();
3452                         if (objfile)
3453                         {
3454                             Address header_addr(objfile->GetHeaderAddress());
3455                             if (header_addr.IsValid())
3456                             {
3457                                 if (target && !target->GetSectionLoadList().IsEmpty())
3458                                 {
3459                                     lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3460                                     if (header_load_addr == LLDB_INVALID_ADDRESS)
3461                                     {
3462                                         header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3463                                     }
3464                                     else
3465                                     {
3466                                         if (format_char == 'o')
3467                                         {
3468                                             // Show the offset of slide for the image
3469                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3470                                         }
3471                                         else
3472                                         {
3473                                             // Show the load address of the image
3474                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
3475                                         }
3476                                     }
3477                                     break;
3478                                 }
3479                                 // The address was valid, but the image isn't loaded, output the address in an appropriate format
3480                                 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3481                                 break;
3482                             }
3483                         }
3484                         strm.Printf ("%*s", addr_nibble_width + 2, "");
3485                     }
3486                     break;
3487 
3488                 case 'r':
3489                     {
3490                         size_t ref_count = 0;
3491                         ModuleSP module_sp (module->shared_from_this());
3492                         if (module_sp)
3493                         {
3494                             // Take one away to make sure we don't count our local "module_sp"
3495                             ref_count = module_sp.use_count() - 1;
3496                         }
3497                         if (width)
3498                             strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3499                         else
3500                             strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3501                     }
3502                     break;
3503 
3504                 case 's':
3505                 case 'S':
3506                     {
3507                         const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3508                         if (symbol_vendor)
3509                         {
3510                             const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3511                             if (format_char == 'S')
3512                             {
3513                                 // Dump symbol file only if different from module file
3514                                 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3515                                 {
3516                                     print_space = false;
3517                                     break;
3518                                 }
3519                                 // Add a newline and indent past the index
3520                                 strm.Printf ("\n%*s", indent, "");
3521                             }
3522                             DumpFullpath (strm, &symfile_spec, width);
3523                             dump_object_name = true;
3524                             break;
3525                         }
3526                         strm.Printf("%.*s", width, "<NONE>");
3527                     }
3528                     break;
3529 
3530                 case 'm':
3531                     module->GetModificationTime().Dump(&strm, width);
3532                     break;
3533 
3534                 case 'p':
3535                     strm.Printf("%p", static_cast<void*>(module));
3536                     break;
3537 
3538                 case 'u':
3539                     DumpModuleUUID(strm, module);
3540                     break;
3541 
3542                 default:
3543                     break;
3544             }
3545         }
3546         if (dump_object_name)
3547         {
3548             const char *object_name = module->GetObjectName().GetCString();
3549             if (object_name)
3550                 strm.Printf ("(%s)", object_name);
3551         }
3552         strm.EOL();
3553     }
3554 
3555     CommandOptions m_options;
3556 };
3557 
3558 OptionDefinition
3559 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3560 {
3561     { LLDB_OPT_SET_1, false, "address",    'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
3562     { LLDB_OPT_SET_1, false, "arch",       'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the architecture when listing images."},
3563     { LLDB_OPT_SET_1, false, "triple",     't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the triple when listing images."},
3564     { 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."},
3565     { 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)."},
3566     { LLDB_OPT_SET_1, false, "uuid",       'u', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,    "Display the UUID when listing images."},
3567     { LLDB_OPT_SET_1, false, "fullpath",   'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3568     { LLDB_OPT_SET_1, false, "directory",  'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3569     { LLDB_OPT_SET_1, false, "basename",   'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3570     { LLDB_OPT_SET_1, false, "symfile",    's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3571     { 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."},
3572     { LLDB_OPT_SET_1, false, "mod-time",   'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3573     { 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."},
3574     { LLDB_OPT_SET_1, false, "pointer",    'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone,    "Display the module pointer."},
3575     { 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."},
3576     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
3577 };
3578 
3579 #pragma mark CommandObjectTargetModulesShowUnwind
3580 
3581 //----------------------------------------------------------------------
3582 // Lookup unwind information in images
3583 //----------------------------------------------------------------------
3584 
3585 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3586 {
3587 public:
3588     enum
3589     {
3590         eLookupTypeInvalid = -1,
3591         eLookupTypeAddress = 0,
3592         eLookupTypeSymbol,
3593         eLookupTypeFunction,
3594         eLookupTypeFunctionOrSymbol,
3595         kNumLookupTypes
3596     };
3597 
3598     class CommandOptions : public Options
3599     {
3600     public:
3601         CommandOptions() :
3602             Options(),
3603             m_type(eLookupTypeInvalid),
3604             m_str(),
3605             m_addr(LLDB_INVALID_ADDRESS)
3606         {
3607         }
3608 
3609         ~CommandOptions() override = default;
3610 
3611         Error
3612         SetOptionValue(uint32_t option_idx, const char *option_arg,
3613                        ExecutionContext *execution_context) override
3614         {
3615             Error error;
3616 
3617             const int short_option = m_getopt_table[option_idx].val;
3618 
3619             switch (short_option)
3620             {
3621                 case 'a':
3622                 {
3623                     m_str = option_arg;
3624                     m_type = eLookupTypeAddress;
3625                     m_addr = Args::StringToAddress(execution_context,
3626                                                    option_arg,
3627                                                    LLDB_INVALID_ADDRESS,
3628                                                    &error);
3629                     if (m_addr == LLDB_INVALID_ADDRESS)
3630                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3631                     break;
3632                 }
3633 
3634                 case 'n':
3635                     m_str = option_arg;
3636                     m_type = eLookupTypeFunctionOrSymbol;
3637                     break;
3638 
3639                 default:
3640                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
3641                     break;
3642             }
3643 
3644             return error;
3645         }
3646 
3647         void
3648         OptionParsingStarting(ExecutionContext *execution_context) override
3649         {
3650             m_type = eLookupTypeInvalid;
3651             m_str.clear();
3652             m_addr = LLDB_INVALID_ADDRESS;
3653         }
3654 
3655         const OptionDefinition*
3656         GetDefinitions () override
3657         {
3658             return g_option_table;
3659         }
3660 
3661         // Options table: Required for subclasses of Options.
3662 
3663         static OptionDefinition g_option_table[];
3664 
3665         // Instance variables to hold the values for command options.
3666 
3667         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3668         std::string     m_str;          // Holds name lookup
3669         lldb::addr_t    m_addr;         // Holds the address to lookup
3670     };
3671 
3672     CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3673         CommandObjectParsed(interpreter,
3674                             "target modules show-unwind",
3675                             "Show synthesized unwind instructions for a function.",
3676                             nullptr,
3677                             eCommandRequiresTarget        |
3678                             eCommandRequiresProcess       |
3679                             eCommandProcessMustBeLaunched |
3680                             eCommandProcessMustBePaused   ),
3681         m_options()
3682     {
3683     }
3684 
3685     ~CommandObjectTargetModulesShowUnwind() override = default;
3686 
3687     Options *
3688     GetOptions () override
3689     {
3690         return &m_options;
3691     }
3692 
3693 protected:
3694     bool
3695     DoExecute (Args& command, CommandReturnObject &result) override
3696     {
3697         Target *target = m_exe_ctx.GetTargetPtr();
3698         Process *process = m_exe_ctx.GetProcessPtr();
3699         ABI *abi = nullptr;
3700         if (process)
3701           abi = process->GetABI().get();
3702 
3703         if (process == nullptr)
3704         {
3705             result.AppendError ("You must have a process running to use this command.");
3706             result.SetStatus (eReturnStatusFailed);
3707             return false;
3708         }
3709 
3710         ThreadList threads(process->GetThreadList());
3711         if (threads.GetSize() == 0)
3712         {
3713             result.AppendError ("The process must be paused to use this command.");
3714             result.SetStatus (eReturnStatusFailed);
3715             return false;
3716         }
3717 
3718         ThreadSP thread(threads.GetThreadAtIndex(0));
3719         if (!thread)
3720         {
3721             result.AppendError ("The process must be paused to use this command.");
3722             result.SetStatus (eReturnStatusFailed);
3723             return false;
3724         }
3725 
3726         SymbolContextList sc_list;
3727 
3728         if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3729         {
3730             ConstString function_name (m_options.m_str.c_str());
3731             target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3732         }
3733         else if (m_options.m_type == eLookupTypeAddress && target)
3734         {
3735             Address addr;
3736             if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
3737             {
3738                 SymbolContext sc;
3739                 ModuleSP module_sp (addr.GetModule());
3740                 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
3741                 if (sc.function || sc.symbol)
3742                 {
3743                     sc_list.Append(sc);
3744                 }
3745             }
3746         }
3747         else
3748         {
3749             result.AppendError ("address-expression or function name option must be specified.");
3750             result.SetStatus (eReturnStatusFailed);
3751             return false;
3752         }
3753 
3754         size_t num_matches = sc_list.GetSize();
3755         if (num_matches == 0)
3756         {
3757             result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
3758             result.SetStatus (eReturnStatusFailed);
3759             return false;
3760         }
3761 
3762         for (uint32_t idx = 0; idx < num_matches; idx++)
3763         {
3764             SymbolContext sc;
3765             sc_list.GetContextAtIndex(idx, sc);
3766             if (sc.symbol == nullptr && sc.function == nullptr)
3767                 continue;
3768             if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3769                 continue;
3770             AddressRange range;
3771             if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3772                 continue;
3773             if (!range.GetBaseAddress().IsValid())
3774                 continue;
3775             ConstString funcname(sc.GetFunctionName());
3776             if (funcname.IsEmpty())
3777                 continue;
3778             addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3779             if (abi)
3780                 start_addr = abi->FixCodeAddress(start_addr);
3781 
3782             FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3783             if (!func_unwinders_sp)
3784                 continue;
3785 
3786             result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3787 
3788             UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3789             if (non_callsite_unwind_plan)
3790             {
3791                 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
3792             }
3793             UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3794             if (callsite_unwind_plan)
3795             {
3796                 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
3797             }
3798             UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3799             if (fast_unwind_plan)
3800             {
3801                 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
3802             }
3803 
3804             result.GetOutputStream().Printf("\n");
3805 
3806             UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3807             if (assembly_sp)
3808             {
3809                 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
3810                 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3811                 result.GetOutputStream().Printf("\n");
3812             }
3813 
3814             UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3815             if (ehframe_sp)
3816             {
3817                 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3818                 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3819                 result.GetOutputStream().Printf("\n");
3820             }
3821 
3822             UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3823             if (ehframe_augmented_sp)
3824             {
3825                 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3826                 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3827                 result.GetOutputStream().Printf("\n");
3828             }
3829 
3830             UnwindPlanSP arm_unwind_sp = func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3831             if (arm_unwind_sp)
3832             {
3833                 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3834                 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3835                 result.GetOutputStream().Printf("\n");
3836             }
3837 
3838             UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3839             if (compact_unwind_sp)
3840             {
3841                 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3842                 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3843                 result.GetOutputStream().Printf("\n");
3844             }
3845 
3846             if (fast_unwind_plan)
3847             {
3848                 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3849                 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3850                 result.GetOutputStream().Printf("\n");
3851             }
3852 
3853             ABISP abi_sp = process->GetABI();
3854             if (abi_sp)
3855             {
3856                 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3857                 if (abi_sp->CreateDefaultUnwindPlan (arch_default))
3858                 {
3859                     result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3860                     arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3861                     result.GetOutputStream().Printf("\n");
3862                 }
3863 
3864                 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3865                 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
3866                 {
3867                     result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
3868                     arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3869                     result.GetOutputStream().Printf("\n");
3870                 }
3871             }
3872 
3873             result.GetOutputStream().Printf ("\n");
3874         }
3875         return result.Succeeded();
3876     }
3877 
3878     CommandOptions m_options;
3879 };
3880 
3881 OptionDefinition
3882 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3883 {
3884     { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3885     { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3886     { 0,                false, nullptr,           0, 0,                 nullptr, nullptr, 0, eArgTypeNone, nullptr }
3887 };
3888 
3889 //----------------------------------------------------------------------
3890 // Lookup information in images
3891 //----------------------------------------------------------------------
3892 class CommandObjectTargetModulesLookup : public CommandObjectParsed
3893 {
3894 public:
3895     enum
3896     {
3897         eLookupTypeInvalid = -1,
3898         eLookupTypeAddress = 0,
3899         eLookupTypeSymbol,
3900         eLookupTypeFileLine,    // Line is optional
3901         eLookupTypeFunction,
3902         eLookupTypeFunctionOrSymbol,
3903         eLookupTypeType,
3904         kNumLookupTypes
3905     };
3906 
3907     class CommandOptions : public Options
3908     {
3909     public:
3910         CommandOptions() :
3911             Options()
3912         {
3913             OptionParsingStarting(nullptr);
3914         }
3915 
3916         ~CommandOptions() override = default;
3917 
3918         Error
3919         SetOptionValue (uint32_t option_idx, const char *option_arg,
3920                         ExecutionContext *execution_context) override
3921         {
3922             Error error;
3923 
3924             const int short_option = m_getopt_table[option_idx].val;
3925 
3926             switch (short_option)
3927             {
3928                 case 'a':
3929                     {
3930                         m_type = eLookupTypeAddress;
3931                         m_addr = Args::StringToAddress(execution_context,
3932                                                        option_arg,
3933                                                        LLDB_INVALID_ADDRESS,
3934                                                        &error);
3935                     }
3936                     break;
3937 
3938                 case 'o':
3939                     m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3940                     if (m_offset == LLDB_INVALID_ADDRESS)
3941                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3942                     break;
3943 
3944                 case 's':
3945                     m_str = option_arg;
3946                     m_type = eLookupTypeSymbol;
3947                     break;
3948 
3949                 case 'f':
3950                     m_file.SetFile (option_arg, false);
3951                     m_type = eLookupTypeFileLine;
3952                     break;
3953 
3954                 case 'i':
3955                     m_include_inlines = false;
3956                     break;
3957 
3958                 case 'l':
3959                     m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3960                     if (m_line_number == UINT32_MAX)
3961                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3962                     else if (m_line_number == 0)
3963                         error.SetErrorString ("zero is an invalid line number");
3964                     m_type = eLookupTypeFileLine;
3965                     break;
3966 
3967                 case 'F':
3968                     m_str = option_arg;
3969                     m_type = eLookupTypeFunction;
3970                     break;
3971 
3972                 case 'n':
3973                     m_str = option_arg;
3974                     m_type = eLookupTypeFunctionOrSymbol;
3975                     break;
3976 
3977                 case 't':
3978                     m_str = option_arg;
3979                     m_type = eLookupTypeType;
3980                     break;
3981 
3982                 case 'v':
3983                     m_verbose = 1;
3984                     break;
3985 
3986                 case 'A':
3987                     m_print_all = true;
3988                     break;
3989 
3990                 case 'r':
3991                     m_use_regex = true;
3992                     break;
3993             }
3994 
3995             return error;
3996         }
3997 
3998         void
3999         OptionParsingStarting(ExecutionContext *execution_context) override
4000         {
4001             m_type = eLookupTypeInvalid;
4002             m_str.clear();
4003             m_file.Clear();
4004             m_addr = LLDB_INVALID_ADDRESS;
4005             m_offset = 0;
4006             m_line_number = 0;
4007             m_use_regex = false;
4008             m_include_inlines = true;
4009             m_verbose = false;
4010             m_print_all = false;
4011         }
4012 
4013         const OptionDefinition*
4014         GetDefinitions () override
4015         {
4016             return g_option_table;
4017         }
4018 
4019         // Options table: Required for subclasses of Options.
4020 
4021         static OptionDefinition g_option_table[];
4022         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
4023         std::string     m_str;          // Holds name lookup
4024         FileSpec        m_file;         // Files for file lookups
4025         lldb::addr_t    m_addr;         // Holds the address to lookup
4026         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
4027         uint32_t        m_line_number;  // Line number for file+line lookups
4028         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
4029         bool            m_include_inlines;// Check for inline entries when looking up by file/line.
4030         bool            m_verbose;      // Enable verbose lookup info
4031         bool            m_print_all;    // Print all matches, even in cases where there's a best match.
4032     };
4033 
4034     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
4035         CommandObjectParsed(interpreter,
4036                             "target modules lookup",
4037                             "Look up information within executable and dependent shared library images.",
4038                             nullptr,
4039                             eCommandRequiresTarget),
4040         m_options()
4041     {
4042         CommandArgumentEntry arg;
4043         CommandArgumentData file_arg;
4044 
4045         // Define the first (and only) variant of this arg.
4046         file_arg.arg_type = eArgTypeFilename;
4047         file_arg.arg_repetition = eArgRepeatStar;
4048 
4049         // There is only one variant this argument could be; put it into the argument entry.
4050         arg.push_back (file_arg);
4051 
4052         // Push the data for the first argument into the m_arguments vector.
4053         m_arguments.push_back (arg);
4054     }
4055 
4056     ~CommandObjectTargetModulesLookup() override = default;
4057 
4058     Options *
4059     GetOptions () override
4060     {
4061         return &m_options;
4062     }
4063 
4064     bool
4065     LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
4066     {
4067         switch (m_options.m_type)
4068         {
4069             case eLookupTypeAddress:
4070             case eLookupTypeFileLine:
4071             case eLookupTypeFunction:
4072             case eLookupTypeFunctionOrSymbol:
4073             case eLookupTypeSymbol:
4074             default:
4075                 return false;
4076             case eLookupTypeType:
4077                 break;
4078         }
4079 
4080         StackFrameSP frame = m_exe_ctx.GetFrameSP();
4081 
4082         if (!frame)
4083             return false;
4084 
4085         const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
4086 
4087         if (!sym_ctx.module_sp)
4088             return false;
4089 
4090         switch (m_options.m_type)
4091         {
4092         default:
4093             return false;
4094         case eLookupTypeType:
4095             if (!m_options.m_str.empty())
4096             {
4097                 if (LookupTypeHere (m_interpreter,
4098                                     result.GetOutputStream(),
4099                                     sym_ctx,
4100                                     m_options.m_str.c_str(),
4101                                     m_options.m_use_regex))
4102                 {
4103                     result.SetStatus(eReturnStatusSuccessFinishResult);
4104                     return true;
4105                 }
4106             }
4107             break;
4108         }
4109 
4110         return true;
4111     }
4112 
4113     bool
4114     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
4115     {
4116         switch (m_options.m_type)
4117         {
4118             case eLookupTypeAddress:
4119                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
4120                 {
4121                     if (LookupAddressInModule (m_interpreter,
4122                                                result.GetOutputStream(),
4123                                                module,
4124                                                eSymbolContextEverything | (m_options.m_verbose ? static_cast<int>(eSymbolContextVariable) : 0),
4125                                                m_options.m_addr,
4126                                                m_options.m_offset,
4127                                                m_options.m_verbose))
4128                     {
4129                         result.SetStatus(eReturnStatusSuccessFinishResult);
4130                         return true;
4131                     }
4132                 }
4133                 break;
4134 
4135             case eLookupTypeSymbol:
4136                 if (!m_options.m_str.empty())
4137                 {
4138                     if (LookupSymbolInModule (m_interpreter,
4139                                               result.GetOutputStream(),
4140                                               module,
4141                                               m_options.m_str.c_str(),
4142                                               m_options.m_use_regex,
4143                                               m_options.m_verbose))
4144                     {
4145                         result.SetStatus(eReturnStatusSuccessFinishResult);
4146                         return true;
4147                     }
4148                 }
4149                 break;
4150 
4151             case eLookupTypeFileLine:
4152                 if (m_options.m_file)
4153                 {
4154                     if (LookupFileAndLineInModule (m_interpreter,
4155                                                    result.GetOutputStream(),
4156                                                    module,
4157                                                    m_options.m_file,
4158                                                    m_options.m_line_number,
4159                                                    m_options.m_include_inlines,
4160                                                    m_options.m_verbose))
4161                     {
4162                         result.SetStatus(eReturnStatusSuccessFinishResult);
4163                         return true;
4164                     }
4165                 }
4166                 break;
4167 
4168             case eLookupTypeFunctionOrSymbol:
4169             case eLookupTypeFunction:
4170                 if (!m_options.m_str.empty())
4171                 {
4172                     if (LookupFunctionInModule (m_interpreter,
4173                                                 result.GetOutputStream(),
4174                                                 module,
4175                                                 m_options.m_str.c_str(),
4176                                                 m_options.m_use_regex,
4177                                                 m_options.m_include_inlines,
4178                                                 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
4179                                                 m_options.m_verbose))
4180                     {
4181                         result.SetStatus(eReturnStatusSuccessFinishResult);
4182                         return true;
4183                     }
4184                 }
4185                 break;
4186 
4187             case eLookupTypeType:
4188                 if (!m_options.m_str.empty())
4189                 {
4190                     if (LookupTypeInModule (m_interpreter,
4191                                             result.GetOutputStream(),
4192                                             module,
4193                                             m_options.m_str.c_str(),
4194                                             m_options.m_use_regex))
4195                     {
4196                         result.SetStatus(eReturnStatusSuccessFinishResult);
4197                         return true;
4198                     }
4199                 }
4200                 break;
4201 
4202             default:
4203                 m_options.GenerateOptionUsage(result.GetErrorStream(), this,
4204                                               GetCommandInterpreter()
4205                                                 .GetDebugger()
4206                                                 .GetTerminalWidth());
4207                 syntax_error = true;
4208                 break;
4209         }
4210 
4211         result.SetStatus (eReturnStatusFailed);
4212         return false;
4213     }
4214 
4215 protected:
4216     bool
4217     DoExecute (Args& command, CommandReturnObject &result) override
4218     {
4219         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4220         if (target == nullptr)
4221         {
4222             result.AppendError ("invalid target, create a debug target using the 'target create' command");
4223             result.SetStatus (eReturnStatusFailed);
4224             return false;
4225         }
4226         else
4227         {
4228             bool syntax_error = false;
4229             uint32_t i;
4230             uint32_t num_successful_lookups = 0;
4231             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4232             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4233             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4234             // Dump all sections for all modules images
4235 
4236             if (command.GetArgumentCount() == 0)
4237             {
4238                 ModuleSP current_module;
4239 
4240                 // Where it is possible to look in the current symbol context
4241                 // first, try that.  If this search was successful and --all
4242                 // was not passed, don't print anything else.
4243                 if (LookupHere (m_interpreter, result, syntax_error))
4244                 {
4245                     result.GetOutputStream().EOL();
4246                     num_successful_lookups++;
4247                     if (!m_options.m_print_all)
4248                     {
4249                         result.SetStatus (eReturnStatusSuccessFinishResult);
4250                         return result.Succeeded();
4251                     }
4252                 }
4253 
4254                 // Dump all sections for all other modules
4255 
4256                 const ModuleList &target_modules = target->GetImages();
4257                 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4258                 const size_t num_modules = target_modules.GetSize();
4259                 if (num_modules > 0)
4260                 {
4261                     for (i = 0; i < num_modules && !syntax_error; ++i)
4262                     {
4263                         Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
4264 
4265                         if (module_pointer != current_module.get() &&
4266                             LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
4267                         {
4268                             result.GetOutputStream().EOL();
4269                             num_successful_lookups++;
4270                         }
4271                     }
4272                 }
4273                 else
4274                 {
4275                     result.AppendError ("the target has no associated executable images");
4276                     result.SetStatus (eReturnStatusFailed);
4277                     return false;
4278                 }
4279             }
4280             else
4281             {
4282                 // Dump specified images (by basename or fullpath)
4283                 const char *arg_cstr;
4284                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && !syntax_error; ++i)
4285                 {
4286                     ModuleList module_list;
4287                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
4288                     if (num_matches > 0)
4289                     {
4290                         for (size_t j=0; j<num_matches; ++j)
4291                         {
4292                             Module *module = module_list.GetModulePointerAtIndex(j);
4293                             if (module)
4294                             {
4295                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
4296                                 {
4297                                     result.GetOutputStream().EOL();
4298                                     num_successful_lookups++;
4299                                 }
4300                             }
4301                         }
4302                     }
4303                     else
4304                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
4305                 }
4306             }
4307 
4308             if (num_successful_lookups > 0)
4309                 result.SetStatus (eReturnStatusSuccessFinishResult);
4310             else
4311                 result.SetStatus (eReturnStatusFailed);
4312         }
4313         return result.Succeeded();
4314     }
4315 
4316     CommandOptions m_options;
4317 };
4318 
4319 OptionDefinition
4320 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
4321 {
4322     { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
4323     { 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."},
4324     { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
4325       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
4326                         false, "regex",      'r', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
4327     { 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."},
4328     { 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."},
4329     { 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)."},
4330     { LLDB_OPT_SET_FROM_TO(3,5),
4331                         false, "no-inlines", 'i', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
4332     { 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."},
4333     { 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."},
4334     { 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."},
4335     { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,             "Enable verbose lookup information."},
4336     { 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."},
4337     { 0,                false, nullptr,           0, 0,                 nullptr, nullptr, 0, eArgTypeNone,             nullptr }
4338 };
4339 
4340 #pragma mark CommandObjectMultiwordImageSearchPaths
4341 
4342 //-------------------------------------------------------------------------
4343 // CommandObjectMultiwordImageSearchPaths
4344 //-------------------------------------------------------------------------
4345 
4346 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
4347 {
4348 public:
4349     CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
4350         : CommandObjectMultiword(interpreter, "target modules search-paths",
4351                                  "Commands for managing module search paths for a target.",
4352                                  "target modules search-paths <subcommand> [<subcommand-options>]")
4353     {
4354         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
4355         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
4356         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
4357         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
4358         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
4359     }
4360 
4361     ~CommandObjectTargetModulesImageSearchPaths() override = default;
4362 };
4363 
4364 #pragma mark CommandObjectTargetModules
4365 
4366 //-------------------------------------------------------------------------
4367 // CommandObjectTargetModules
4368 //-------------------------------------------------------------------------
4369 
4370 class CommandObjectTargetModules : public CommandObjectMultiword
4371 {
4372 public:
4373     //------------------------------------------------------------------
4374     // Constructors and Destructors
4375     //------------------------------------------------------------------
4376     CommandObjectTargetModules(CommandInterpreter &interpreter)
4377         : CommandObjectMultiword(interpreter, "target modules",
4378                                  "Commands for accessing information for one or more target modules.",
4379                                  "target modules <sub-command> ...")
4380     {
4381         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
4382         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
4383         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
4384         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
4385         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
4386         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
4387         LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
4388 
4389     }
4390 
4391     ~CommandObjectTargetModules() override = default;
4392 
4393 private:
4394     //------------------------------------------------------------------
4395     // For CommandObjectTargetModules only
4396     //------------------------------------------------------------------
4397     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
4398 };
4399 
4400 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
4401 {
4402 public:
4403     CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
4404         CommandObjectParsed (interpreter,
4405                              "target symbols add",
4406                              "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.",
4407                              "target symbols add [<symfile>]", eCommandRequiresTarget),
4408         m_option_group(),
4409         m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4410         m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4411 
4412     {
4413         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4414         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4415         m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4416         m_option_group.Finalize();
4417     }
4418 
4419     ~CommandObjectTargetSymbolsAdd() override = default;
4420 
4421     int
4422     HandleArgumentCompletion (Args &input,
4423                               int &cursor_index,
4424                               int &cursor_char_position,
4425                               OptionElementVector &opt_element_vector,
4426                               int match_start_point,
4427                               int max_return_elements,
4428                               bool &word_complete,
4429                               StringList &matches) override
4430     {
4431         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4432         completion_str.erase (cursor_char_position);
4433 
4434         CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(),
4435                                                             CommandCompletions::eDiskFileCompletion,
4436                                                             completion_str.c_str(),
4437                                                             match_start_point,
4438                                                             max_return_elements,
4439                                                             nullptr,
4440                                                             word_complete,
4441                                                             matches);
4442         return matches.GetSize();
4443     }
4444 
4445     Options *
4446     GetOptions () override
4447     {
4448         return &m_option_group;
4449     }
4450 
4451 protected:
4452     bool
4453     AddModuleSymbols (Target *target,
4454                       ModuleSpec &module_spec,
4455                       bool &flush,
4456                       CommandReturnObject &result)
4457     {
4458         const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4459         if (symbol_fspec)
4460         {
4461             char symfile_path[PATH_MAX];
4462             symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
4463 
4464             if (!module_spec.GetUUID().IsValid())
4465             {
4466                 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4467                     module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4468             }
4469             // We now have a module that represents a symbol file
4470             // that can be used for a module that might exist in the
4471             // current target, so we need to find that module in the
4472             // target
4473             ModuleList matching_module_list;
4474 
4475             size_t num_matches = 0;
4476             // First extract all module specs from the symbol file
4477             lldb_private::ModuleSpecList symfile_module_specs;
4478             if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
4479             {
4480                 // Now extract the module spec that matches the target architecture
4481                 ModuleSpec target_arch_module_spec;
4482                 ModuleSpec symfile_module_spec;
4483                 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4484                 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
4485                 {
4486                     // See if it has a UUID?
4487                     if (symfile_module_spec.GetUUID().IsValid())
4488                     {
4489                         // It has a UUID, look for this UUID in the target modules
4490                         ModuleSpec symfile_uuid_module_spec;
4491                         symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4492                         num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4493                     }
4494                 }
4495 
4496                 if (num_matches == 0)
4497                 {
4498                     // No matches yet, iterate through the module specs to find a UUID value that
4499                     // we can match up to an image in our target
4500                     const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4501                     for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0; ++i)
4502                     {
4503                         if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
4504                         {
4505                             if (symfile_module_spec.GetUUID().IsValid())
4506                             {
4507                                 // It has a UUID, look for this UUID in the target modules
4508                                 ModuleSpec symfile_uuid_module_spec;
4509                                 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4510                                 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4511                             }
4512                         }
4513                     }
4514                 }
4515             }
4516 
4517             // Just try to match up the file by basename if we have no matches at this point
4518             if (num_matches == 0)
4519                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4520 
4521             while (num_matches == 0)
4522             {
4523                 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
4524                 // Empty string returned, lets bail
4525                 if (!filename_no_extension)
4526                     break;
4527 
4528                 // Check if there was no extension to strip and the basename is the same
4529                 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4530                     break;
4531 
4532                 // Replace basename with one less extension
4533                 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4534 
4535                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4536             }
4537 
4538             if (num_matches > 1)
4539             {
4540                 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
4541             }
4542             else if (num_matches == 1)
4543             {
4544                 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
4545 
4546                 // The module has not yet created its symbol vendor, we can just
4547                 // give the existing target module the symfile path to use for
4548                 // when it decides to create it!
4549                 module_sp->SetSymbolFileFileSpec (symbol_fspec);
4550 
4551                 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4552                 if (symbol_vendor)
4553                 {
4554                     SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4555 
4556                     if (symbol_file)
4557                     {
4558                         ObjectFile *object_file = symbol_file->GetObjectFile();
4559 
4560                         if (object_file && object_file->GetFileSpec() == symbol_fspec)
4561                         {
4562                             // Provide feedback that the symfile has been successfully added.
4563                             const FileSpec &module_fs = module_sp->GetFileSpec();
4564                             result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
4565                                                            symfile_path,
4566                                                            module_fs.GetPath().c_str());
4567 
4568                             // Let clients know something changed in the module
4569                             // if it is currently loaded
4570                             ModuleList module_list;
4571                             module_list.Append (module_sp);
4572                             target->SymbolsDidLoad (module_list);
4573 
4574                             // Make sure we load any scripting resources that may be embedded
4575                             // in the debug info files in case the platform supports that.
4576                             Error error;
4577                             StreamString feedback_stream;
4578                             module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
4579                             if (error.Fail() && error.AsCString())
4580                                 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
4581                                                                module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
4582                                                                error.AsCString());
4583                             else if (feedback_stream.GetSize())
4584                                 result.AppendWarningWithFormat("%s",feedback_stream.GetData());
4585 
4586                             flush = true;
4587                             result.SetStatus (eReturnStatusSuccessFinishResult);
4588                             return true;
4589                         }
4590                     }
4591                 }
4592                 // Clear the symbol file spec if anything went wrong
4593                 module_sp->SetSymbolFileFileSpec (FileSpec());
4594             }
4595 
4596             if (module_spec.GetUUID().IsValid())
4597             {
4598                 StreamString ss_symfile_uuid;
4599                 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4600                 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
4601                                               symfile_path,
4602                                               ss_symfile_uuid.GetData(),
4603                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4604                                                 ? "\n       please specify the full path to the symbol file"
4605                                                 : "");
4606             }
4607             else
4608             {
4609                 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
4610                                               symfile_path,
4611                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4612                                                 ? "\n       please specify the full path to the symbol file"
4613                                                 : "");
4614             }
4615         }
4616         else
4617         {
4618             result.AppendError ("one or more executable image paths must be specified");
4619         }
4620         result.SetStatus (eReturnStatusFailed);
4621         return false;
4622     }
4623 
4624     bool
4625     DoExecute (Args& args, CommandReturnObject &result) override
4626     {
4627         Target *target = m_exe_ctx.GetTargetPtr();
4628         result.SetStatus (eReturnStatusFailed);
4629         bool flush = false;
4630         ModuleSpec module_spec;
4631         const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4632         const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4633         const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4634         const size_t argc = args.GetArgumentCount();
4635 
4636         if (argc == 0)
4637         {
4638             if (uuid_option_set || file_option_set || frame_option_set)
4639             {
4640                 bool success = false;
4641                 bool error_set = false;
4642                 if (frame_option_set)
4643                 {
4644                     Process *process = m_exe_ctx.GetProcessPtr();
4645                     if (process)
4646                     {
4647                         const StateType process_state = process->GetState();
4648                         if (StateIsStoppedState (process_state, true))
4649                         {
4650                             StackFrame *frame = m_exe_ctx.GetFramePtr();
4651                             if (frame)
4652                             {
4653                                 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4654                                 if (frame_module_sp)
4655                                 {
4656                                     if (frame_module_sp->GetPlatformFileSpec().Exists())
4657                                     {
4658                                         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4659                                         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4660                                     }
4661                                     module_spec.GetUUID() = frame_module_sp->GetUUID();
4662                                     success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
4663                                 }
4664                                 else
4665                                 {
4666                                     result.AppendError ("frame has no module");
4667                                     error_set = true;
4668                                 }
4669                             }
4670                             else
4671                             {
4672                                 result.AppendError ("invalid current frame");
4673                                 error_set = true;
4674                             }
4675                         }
4676                         else
4677                         {
4678                             result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4679                             error_set = true;
4680                         }
4681                     }
4682                     else
4683                     {
4684                         result.AppendError ("a process must exist in order to use the --frame option");
4685                         error_set = true;
4686                     }
4687                 }
4688                 else
4689                 {
4690                     if (uuid_option_set)
4691                     {
4692                         module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4693                         success |= module_spec.GetUUID().IsValid();
4694                     }
4695                     else if (file_option_set)
4696                     {
4697                         module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4698                         ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
4699                         if (module_sp)
4700                         {
4701                             module_spec.GetFileSpec() = module_sp->GetFileSpec();
4702                             module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4703                             module_spec.GetUUID() = module_sp->GetUUID();
4704                             module_spec.GetArchitecture() = module_sp->GetArchitecture();
4705                         }
4706                         else
4707                         {
4708                             module_spec.GetArchitecture() = target->GetArchitecture();
4709                         }
4710                         success |= module_spec.GetUUID().IsValid() || module_spec.GetFileSpec().Exists();
4711                     }
4712                 }
4713 
4714                 if (success)
4715                 {
4716                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
4717                     {
4718                         if (module_spec.GetSymbolFileSpec())
4719                             success = AddModuleSymbols (target, module_spec, flush, result);
4720                     }
4721                 }
4722 
4723                 if (!success && !error_set)
4724                 {
4725                     StreamString error_strm;
4726                     if (uuid_option_set)
4727                     {
4728                         error_strm.PutCString("unable to find debug symbols for UUID ");
4729                         module_spec.GetUUID().Dump (&error_strm);
4730                     }
4731                     else if (file_option_set)
4732                     {
4733                         error_strm.PutCString("unable to find debug symbols for the executable file ");
4734                         error_strm << module_spec.GetFileSpec();
4735                     }
4736                     else if (frame_option_set)
4737                     {
4738                         error_strm.PutCString("unable to find debug symbols for the current frame");
4739                     }
4740                     result.AppendError (error_strm.GetData());
4741                 }
4742             }
4743             else
4744             {
4745                 result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4746             }
4747         }
4748         else
4749         {
4750             if (uuid_option_set)
4751             {
4752                 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4753             }
4754             else if (file_option_set)
4755             {
4756                 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4757             }
4758             else if (frame_option_set)
4759             {
4760                 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4761             }
4762             else
4763             {
4764                 PlatformSP platform_sp (target->GetPlatform());
4765 
4766                 for (size_t i = 0; i < argc; ++i)
4767                 {
4768                     const char *symfile_path = args.GetArgumentAtIndex(i);
4769                     if (symfile_path)
4770                     {
4771                         module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4772                         if (platform_sp)
4773                         {
4774                             FileSpec symfile_spec;
4775                             if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
4776                                 module_spec.GetSymbolFileSpec() = symfile_spec;
4777                         }
4778 
4779                         ArchSpec arch;
4780                         bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4781 
4782                         if (symfile_exists)
4783                         {
4784                             if (!AddModuleSymbols (target, module_spec, flush, result))
4785                                 break;
4786                         }
4787                         else
4788                         {
4789                             char resolved_symfile_path[PATH_MAX];
4790                             if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4791                             {
4792                                 if (strcmp (resolved_symfile_path, symfile_path) != 0)
4793                                 {
4794                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4795                                     break;
4796                                 }
4797                             }
4798                             result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4799                             break;
4800                         }
4801                     }
4802                 }
4803             }
4804         }
4805 
4806         if (flush)
4807         {
4808             Process *process = m_exe_ctx.GetProcessPtr();
4809             if (process)
4810                 process->Flush();
4811         }
4812         return result.Succeeded();
4813     }
4814 
4815     OptionGroupOptions m_option_group;
4816     OptionGroupUUID m_uuid_option_group;
4817     OptionGroupFile m_file_option;
4818     OptionGroupBoolean m_current_frame_option;
4819 };
4820 
4821 #pragma mark CommandObjectTargetSymbols
4822 
4823 //-------------------------------------------------------------------------
4824 // CommandObjectTargetSymbols
4825 //-------------------------------------------------------------------------
4826 
4827 class CommandObjectTargetSymbols : public CommandObjectMultiword
4828 {
4829 public:
4830     //------------------------------------------------------------------
4831     // Constructors and Destructors
4832     //------------------------------------------------------------------
4833     CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4834         : CommandObjectMultiword(interpreter, "target symbols", "Commands for adding and managing debug symbol files.",
4835                                  "target symbols <sub-command> ...")
4836     {
4837         LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4838     }
4839 
4840     ~CommandObjectTargetSymbols() override = default;
4841 
4842 private:
4843     //------------------------------------------------------------------
4844     // For CommandObjectTargetModules only
4845     //------------------------------------------------------------------
4846     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4847 };
4848 
4849 #pragma mark CommandObjectTargetStopHookAdd
4850 
4851 //-------------------------------------------------------------------------
4852 // CommandObjectTargetStopHookAdd
4853 //-------------------------------------------------------------------------
4854 
4855 class CommandObjectTargetStopHookAdd :
4856     public CommandObjectParsed,
4857     public IOHandlerDelegateMultiline
4858 {
4859 public:
4860     class CommandOptions : public Options
4861     {
4862     public:
4863         CommandOptions() :
4864             Options(),
4865             m_line_start(0),
4866             m_line_end (UINT_MAX),
4867             m_func_name_type_mask (eFunctionNameTypeAuto),
4868             m_sym_ctx_specified (false),
4869             m_thread_specified (false),
4870             m_use_one_liner (false),
4871             m_one_liner()
4872         {
4873         }
4874 
4875         ~CommandOptions() override = default;
4876 
4877         const OptionDefinition*
4878         GetDefinitions () override
4879         {
4880             return g_option_table;
4881         }
4882 
4883         Error
4884         SetOptionValue(uint32_t option_idx, const char *option_arg,
4885                        ExecutionContext *execution_context) override
4886         {
4887             Error error;
4888             const int short_option = m_getopt_table[option_idx].val;
4889             bool success;
4890 
4891             switch (short_option)
4892             {
4893                 case 'c':
4894                     m_class_name = option_arg;
4895                     m_sym_ctx_specified = true;
4896                     break;
4897 
4898                 case 'e':
4899                     m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
4900                     if (!success)
4901                     {
4902                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4903                         break;
4904                     }
4905                     m_sym_ctx_specified = true;
4906                     break;
4907 
4908                 case 'l':
4909                     m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
4910                     if (!success)
4911                     {
4912                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4913                         break;
4914                     }
4915                     m_sym_ctx_specified = true;
4916                     break;
4917 
4918                 case 'i':
4919                     m_no_inlines = true;
4920                     break;
4921 
4922                 case 'n':
4923                     m_function_name = option_arg;
4924                     m_func_name_type_mask |= eFunctionNameTypeAuto;
4925                     m_sym_ctx_specified = true;
4926                     break;
4927 
4928                 case 'f':
4929                     m_file_name = option_arg;
4930                     m_sym_ctx_specified = true;
4931                     break;
4932 
4933                 case 's':
4934                     m_module_name = option_arg;
4935                     m_sym_ctx_specified = true;
4936                     break;
4937 
4938                 case 't' :
4939                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4940                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
4941                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4942                     m_thread_specified = true;
4943                     break;
4944 
4945                 case 'T':
4946                     m_thread_name = option_arg;
4947                     m_thread_specified = true;
4948                     break;
4949 
4950                 case 'q':
4951                     m_queue_name = option_arg;
4952                     m_thread_specified = true;
4953                     break;
4954 
4955                 case 'x':
4956                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4957                     if (m_thread_id == UINT32_MAX)
4958                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4959                     m_thread_specified = true;
4960                     break;
4961 
4962                 case 'o':
4963                     m_use_one_liner = true;
4964                     m_one_liner = option_arg;
4965                     break;
4966 
4967                 default:
4968                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4969                     break;
4970             }
4971             return error;
4972         }
4973 
4974         void
4975         OptionParsingStarting(ExecutionContext *execution_context) override
4976         {
4977             m_class_name.clear();
4978             m_function_name.clear();
4979             m_line_start = 0;
4980             m_line_end = UINT_MAX;
4981             m_file_name.clear();
4982             m_module_name.clear();
4983             m_func_name_type_mask = eFunctionNameTypeAuto;
4984             m_thread_id = LLDB_INVALID_THREAD_ID;
4985             m_thread_index = UINT32_MAX;
4986             m_thread_name.clear();
4987             m_queue_name.clear();
4988 
4989             m_no_inlines = false;
4990             m_sym_ctx_specified = false;
4991             m_thread_specified = false;
4992 
4993             m_use_one_liner = false;
4994             m_one_liner.clear();
4995         }
4996 
4997         static OptionDefinition g_option_table[];
4998 
4999         std::string m_class_name;
5000         std::string m_function_name;
5001         uint32_t    m_line_start;
5002         uint32_t    m_line_end;
5003         std::string m_file_name;
5004         std::string m_module_name;
5005         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
5006         lldb::tid_t m_thread_id;
5007         uint32_t m_thread_index;
5008         std::string m_thread_name;
5009         std::string m_queue_name;
5010         bool        m_sym_ctx_specified;
5011         bool        m_no_inlines;
5012         bool        m_thread_specified;
5013         // Instance variables to hold the values for one_liner options.
5014         bool m_use_one_liner;
5015         std::string m_one_liner;
5016     };
5017 
5018     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
5019         CommandObjectParsed (interpreter,
5020                              "target stop-hook add",
5021                              "Add a hook to be executed when the target stops.",
5022                              "target stop-hook add"),
5023         IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
5024         m_options()
5025     {
5026     }
5027 
5028     ~CommandObjectTargetStopHookAdd() override = default;
5029 
5030     Options *
5031     GetOptions () override
5032     {
5033         return &m_options;
5034     }
5035 
5036 protected:
5037     void
5038     IOHandlerActivated (IOHandler &io_handler) override
5039     {
5040         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5041         if (output_sp)
5042         {
5043             output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
5044             output_sp->Flush();
5045         }
5046     }
5047 
5048     void
5049     IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
5050     {
5051         if (m_stop_hook_sp)
5052         {
5053             if (line.empty())
5054             {
5055                 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
5056                 if (error_sp)
5057                 {
5058                     error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
5059                     error_sp->Flush();
5060                 }
5061                 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5062                 if (target)
5063                     target->RemoveStopHookByID(m_stop_hook_sp->GetID());
5064             }
5065             else
5066             {
5067                 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
5068                 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5069                 if (output_sp)
5070                 {
5071                     output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
5072                     output_sp->Flush();
5073                 }
5074             }
5075             m_stop_hook_sp.reset();
5076         }
5077         io_handler.SetIsDone(true);
5078     }
5079 
5080     bool
5081     DoExecute (Args& command, CommandReturnObject &result) override
5082     {
5083         m_stop_hook_sp.reset();
5084 
5085         Target *target = GetSelectedOrDummyTarget();
5086         if (target)
5087         {
5088             Target::StopHookSP new_hook_sp = target->CreateStopHook();
5089 
5090             //  First step, make the specifier.
5091             std::unique_ptr<SymbolContextSpecifier> specifier_ap;
5092             if (m_options.m_sym_ctx_specified)
5093             {
5094                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
5095 
5096                 if (!m_options.m_module_name.empty())
5097                 {
5098                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
5099                 }
5100 
5101                 if (!m_options.m_class_name.empty())
5102                 {
5103                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
5104                 }
5105 
5106                 if (!m_options.m_file_name.empty())
5107                 {
5108                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
5109                 }
5110 
5111                 if (m_options.m_line_start != 0)
5112                 {
5113                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
5114                 }
5115 
5116                 if (m_options.m_line_end != UINT_MAX)
5117                 {
5118                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5119                 }
5120 
5121                 if (!m_options.m_function_name.empty())
5122                 {
5123                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
5124                 }
5125             }
5126 
5127             if (specifier_ap)
5128                 new_hook_sp->SetSpecifier (specifier_ap.release());
5129 
5130             // Next see if any of the thread options have been entered:
5131 
5132             if (m_options.m_thread_specified)
5133             {
5134                 ThreadSpec *thread_spec = new ThreadSpec();
5135 
5136                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5137                 {
5138                     thread_spec->SetTID (m_options.m_thread_id);
5139                 }
5140 
5141                 if (m_options.m_thread_index != UINT32_MAX)
5142                     thread_spec->SetIndex (m_options.m_thread_index);
5143 
5144                 if (!m_options.m_thread_name.empty())
5145                     thread_spec->SetName (m_options.m_thread_name.c_str());
5146 
5147                 if (!m_options.m_queue_name.empty())
5148                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
5149 
5150                 new_hook_sp->SetThreadSpecifier (thread_spec);
5151 
5152             }
5153             if (m_options.m_use_one_liner)
5154             {
5155                 // Use one-liner.
5156                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
5157                 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
5158             }
5159             else
5160             {
5161                 m_stop_hook_sp = new_hook_sp;
5162                 m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
5163                                                            *this,  // IOHandlerDelegate
5164                                                            true,   // Run IOHandler in async mode
5165                                                            nullptr);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
5166 
5167             }
5168             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5169         }
5170         else
5171         {
5172             result.AppendError ("invalid target\n");
5173             result.SetStatus (eReturnStatusFailed);
5174         }
5175 
5176         return result.Succeeded();
5177     }
5178 
5179 private:
5180     CommandOptions m_options;
5181     Target::StopHookSP m_stop_hook_sp;
5182 };
5183 
5184 OptionDefinition
5185 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
5186 {
5187     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
5188         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
5189     { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
5190         "Set the module within which the stop-hook is to be run."},
5191     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
5192         "The stop hook is run only for the thread whose index matches this argument."},
5193     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
5194         "The stop hook is run only for the thread whose TID matches this argument."},
5195     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
5196         "The stop hook is run only for the thread whose thread name matches this argument."},
5197     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
5198         "The stop hook is run only for threads in the queue whose name is given by this argument."},
5199     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
5200         "Specify the source file within which the stop-hook is to be run." },
5201     { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
5202         "Set the start of the line range for which the stop-hook is to be run."},
5203     { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
5204         "Set the end of the line range for which the stop-hook is to be run."},
5205     { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName,
5206         "Specify the class within which the stop-hook is to be run." },
5207     { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
5208         "Set the function name within which the stop hook will be run." },
5209     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
5210 };
5211 
5212 #pragma mark CommandObjectTargetStopHookDelete
5213 
5214 //-------------------------------------------------------------------------
5215 // CommandObjectTargetStopHookDelete
5216 //-------------------------------------------------------------------------
5217 
5218 class CommandObjectTargetStopHookDelete : public CommandObjectParsed
5219 {
5220 public:
5221     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
5222         CommandObjectParsed (interpreter,
5223                              "target stop-hook delete",
5224                              "Delete a stop-hook.",
5225                              "target stop-hook delete [<idx>]")
5226     {
5227     }
5228 
5229     ~CommandObjectTargetStopHookDelete() override = default;
5230 
5231 protected:
5232     bool
5233     DoExecute (Args& command, CommandReturnObject &result) override
5234     {
5235         Target *target = GetSelectedOrDummyTarget();
5236         if (target)
5237         {
5238             // FIXME: see if we can use the breakpoint id style parser?
5239             size_t num_args = command.GetArgumentCount();
5240             if (num_args == 0)
5241             {
5242                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
5243                 {
5244                     result.SetStatus (eReturnStatusFailed);
5245                     return false;
5246                 }
5247                 else
5248                 {
5249                     target->RemoveAllStopHooks();
5250                 }
5251             }
5252             else
5253             {
5254                 bool success;
5255                 for (size_t i = 0; i < num_args; i++)
5256                 {
5257                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5258                     if (!success)
5259                     {
5260                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5261                         result.SetStatus(eReturnStatusFailed);
5262                         return false;
5263                     }
5264                     success = target->RemoveStopHookByID (user_id);
5265                     if (!success)
5266                     {
5267                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5268                         result.SetStatus(eReturnStatusFailed);
5269                         return false;
5270                     }
5271                 }
5272             }
5273             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5274         }
5275         else
5276         {
5277             result.AppendError ("invalid target\n");
5278             result.SetStatus (eReturnStatusFailed);
5279         }
5280 
5281         return result.Succeeded();
5282     }
5283 };
5284 
5285 #pragma mark CommandObjectTargetStopHookEnableDisable
5286 
5287 //-------------------------------------------------------------------------
5288 // CommandObjectTargetStopHookEnableDisable
5289 //-------------------------------------------------------------------------
5290 
5291 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
5292 {
5293 public:
5294     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
5295         CommandObjectParsed (interpreter,
5296                              name,
5297                              help,
5298                              syntax),
5299         m_enable (enable)
5300     {
5301     }
5302 
5303     ~CommandObjectTargetStopHookEnableDisable() override = default;
5304 
5305 protected:
5306     bool
5307     DoExecute (Args& command, CommandReturnObject &result) override
5308     {
5309         Target *target = GetSelectedOrDummyTarget();
5310         if (target)
5311         {
5312             // FIXME: see if we can use the breakpoint id style parser?
5313             size_t num_args = command.GetArgumentCount();
5314             bool success;
5315 
5316             if (num_args == 0)
5317             {
5318                 target->SetAllStopHooksActiveState (m_enable);
5319             }
5320             else
5321             {
5322                 for (size_t i = 0; i < num_args; i++)
5323                 {
5324                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5325                     if (!success)
5326                     {
5327                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5328                         result.SetStatus(eReturnStatusFailed);
5329                         return false;
5330                     }
5331                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
5332                     if (!success)
5333                     {
5334                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5335                         result.SetStatus(eReturnStatusFailed);
5336                         return false;
5337                     }
5338                 }
5339             }
5340             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5341         }
5342         else
5343         {
5344             result.AppendError ("invalid target\n");
5345             result.SetStatus (eReturnStatusFailed);
5346         }
5347         return result.Succeeded();
5348     }
5349 private:
5350     bool m_enable;
5351 };
5352 
5353 #pragma mark CommandObjectTargetStopHookList
5354 
5355 //-------------------------------------------------------------------------
5356 // CommandObjectTargetStopHookList
5357 //-------------------------------------------------------------------------
5358 
5359 class CommandObjectTargetStopHookList : public CommandObjectParsed
5360 {
5361 public:
5362     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
5363         CommandObjectParsed (interpreter,
5364                              "target stop-hook list",
5365                              "List all stop-hooks.",
5366                              "target stop-hook list [<type>]")
5367     {
5368     }
5369 
5370     ~CommandObjectTargetStopHookList() override = default;
5371 
5372 protected:
5373     bool
5374     DoExecute (Args& command, CommandReturnObject &result) override
5375     {
5376         Target *target = GetSelectedOrDummyTarget();
5377         if (!target)
5378         {
5379             result.AppendError ("invalid target\n");
5380             result.SetStatus (eReturnStatusFailed);
5381             return result.Succeeded();
5382         }
5383 
5384         size_t num_hooks = target->GetNumStopHooks ();
5385         if (num_hooks == 0)
5386         {
5387             result.GetOutputStream().PutCString ("No stop hooks.\n");
5388         }
5389         else
5390         {
5391             for (size_t i = 0; i < num_hooks; i++)
5392             {
5393                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
5394                 if (i > 0)
5395                     result.GetOutputStream().PutCString ("\n");
5396                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
5397             }
5398         }
5399         result.SetStatus (eReturnStatusSuccessFinishResult);
5400         return result.Succeeded();
5401     }
5402 };
5403 
5404 #pragma mark CommandObjectMultiwordTargetStopHooks
5405 
5406 //-------------------------------------------------------------------------
5407 // CommandObjectMultiwordTargetStopHooks
5408 //-------------------------------------------------------------------------
5409 
5410 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
5411 {
5412 public:
5413     CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
5414         : CommandObjectMultiword(interpreter, "target stop-hook",
5415                                  "Commands for operating on debugger target stop-hooks.",
5416                                  "target stop-hook <subcommand> [<subcommand-options>]")
5417     {
5418         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
5419         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
5420         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5421                                                                                                    false,
5422                                                                                                    "target stop-hook disable [<id>]",
5423                                                                                                    "Disable a stop-hook.",
5424                                                                                                    "target stop-hook disable")));
5425         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5426                                                                                                    true,
5427                                                                                                    "target stop-hook enable [<id>]",
5428                                                                                                    "Enable a stop-hook.",
5429                                                                                                    "target stop-hook enable")));
5430         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5431     }
5432 
5433     ~CommandObjectMultiwordTargetStopHooks() override = default;
5434 };
5435 
5436 #pragma mark CommandObjectMultiwordTarget
5437 
5438 //-------------------------------------------------------------------------
5439 // CommandObjectMultiwordTarget
5440 //-------------------------------------------------------------------------
5441 
5442 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(CommandInterpreter &interpreter)
5443     : CommandObjectMultiword(interpreter, "target", "Commands for operating on debugger targets.",
5444                              "target <subcommand> [<subcommand-options>]")
5445 {
5446     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5447     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5448     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5449     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5450     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5451     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5452     LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5453     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5454 }
5455 
5456 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5457