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