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