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