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