1254721Semaste//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "CommandObjectTarget.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste#include <errno.h>
16254721Semaste
17254721Semaste// C++ Includes
18254721Semaste// Other libraries and framework includes
19254721Semaste// Project includes
20254721Semaste#include "lldb/Interpreter/Args.h"
21254721Semaste#include "lldb/Core/Debugger.h"
22269024Semaste#include "lldb/Core/IOHandler.h"
23254721Semaste#include "lldb/Core/Module.h"
24254721Semaste#include "lldb/Core/ModuleSpec.h"
25254721Semaste#include "lldb/Core/Section.h"
26254721Semaste#include "lldb/Core/State.h"
27254721Semaste#include "lldb/Core/Timer.h"
28254721Semaste#include "lldb/Core/ValueObjectVariable.h"
29263363Semaste#include "lldb/DataFormatters/ValueObjectPrinter.h"
30254721Semaste#include "lldb/Host/Symbols.h"
31254721Semaste#include "lldb/Interpreter/CommandInterpreter.h"
32254721Semaste#include "lldb/Interpreter/CommandReturnObject.h"
33254721Semaste#include "lldb/Interpreter/Options.h"
34254721Semaste#include "lldb/Interpreter/OptionGroupArchitecture.h"
35254721Semaste#include "lldb/Interpreter/OptionGroupBoolean.h"
36254721Semaste#include "lldb/Interpreter/OptionGroupFile.h"
37254721Semaste#include "lldb/Interpreter/OptionGroupFormat.h"
38254721Semaste#include "lldb/Interpreter/OptionGroupVariable.h"
39254721Semaste#include "lldb/Interpreter/OptionGroupPlatform.h"
40254721Semaste#include "lldb/Interpreter/OptionGroupUInt64.h"
41254721Semaste#include "lldb/Interpreter/OptionGroupUUID.h"
42254721Semaste#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
43254721Semaste#include "lldb/Symbol/CompileUnit.h"
44254721Semaste#include "lldb/Symbol/FuncUnwinders.h"
45254721Semaste#include "lldb/Symbol/LineTable.h"
46254721Semaste#include "lldb/Symbol/ObjectFile.h"
47254721Semaste#include "lldb/Symbol/SymbolFile.h"
48254721Semaste#include "lldb/Symbol/SymbolVendor.h"
49254721Semaste#include "lldb/Symbol/UnwindPlan.h"
50254721Semaste#include "lldb/Symbol/VariableList.h"
51254721Semaste#include "lldb/Target/Process.h"
52269024Semaste#include "lldb/Target/SectionLoadList.h"
53254721Semaste#include "lldb/Target/StackFrame.h"
54254721Semaste#include "lldb/Target/Thread.h"
55254721Semaste#include "lldb/Target/ThreadSpec.h"
56254721Semaste
57254721Semasteusing namespace lldb;
58254721Semasteusing namespace lldb_private;
59254721Semaste
60254721Semaste
61254721Semaste
62254721Semastestatic void
63254721SemasteDumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
64254721Semaste{
65254721Semaste    const ArchSpec &target_arch = target->GetArchitecture();
66254721Semaste
67254721Semaste    Module *exe_module = target->GetExecutableModulePointer();
68254721Semaste    char exe_path[PATH_MAX];
69254721Semaste    bool exe_valid = false;
70254721Semaste    if (exe_module)
71254721Semaste        exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
72254721Semaste
73254721Semaste    if (!exe_valid)
74254721Semaste        ::strcpy (exe_path, "<none>");
75254721Semaste
76254721Semaste    strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
77254721Semaste
78254721Semaste    uint32_t properties = 0;
79254721Semaste    if (target_arch.IsValid())
80254721Semaste    {
81254721Semaste        strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
82254721Semaste        properties++;
83254721Semaste    }
84254721Semaste    PlatformSP platform_sp (target->GetPlatform());
85254721Semaste    if (platform_sp)
86254721Semaste        strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName().GetCString());
87254721Semaste
88254721Semaste    ProcessSP process_sp (target->GetProcessSP());
89254721Semaste    bool show_process_status = false;
90254721Semaste    if (process_sp)
91254721Semaste    {
92254721Semaste        lldb::pid_t pid = process_sp->GetID();
93254721Semaste        StateType state = process_sp->GetState();
94254721Semaste        if (show_stopped_process_status)
95254721Semaste            show_process_status = StateIsStoppedState(state, true);
96254721Semaste        const char *state_cstr = StateAsCString (state);
97254721Semaste        if (pid != LLDB_INVALID_PROCESS_ID)
98254721Semaste            strm.Printf ("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
99254721Semaste        strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
100254721Semaste    }
101254721Semaste    if (properties > 0)
102254721Semaste        strm.PutCString (" )\n");
103254721Semaste    else
104254721Semaste        strm.EOL();
105254721Semaste    if (show_process_status)
106254721Semaste    {
107254721Semaste        const bool only_threads_with_stop_reason = true;
108254721Semaste        const uint32_t start_frame = 0;
109254721Semaste        const uint32_t num_frames = 1;
110254721Semaste        const uint32_t num_frames_with_source = 1;
111254721Semaste        process_sp->GetStatus (strm);
112254721Semaste        process_sp->GetThreadStatus (strm,
113254721Semaste                                     only_threads_with_stop_reason,
114254721Semaste                                     start_frame,
115254721Semaste                                     num_frames,
116254721Semaste                                     num_frames_with_source);
117254721Semaste
118254721Semaste    }
119254721Semaste}
120254721Semaste
121254721Semastestatic uint32_t
122254721SemasteDumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
123254721Semaste{
124254721Semaste    const uint32_t num_targets = target_list.GetNumTargets();
125254721Semaste    if (num_targets)
126254721Semaste    {
127254721Semaste        TargetSP selected_target_sp (target_list.GetSelectedTarget());
128254721Semaste        strm.PutCString ("Current targets:\n");
129254721Semaste        for (uint32_t i=0; i<num_targets; ++i)
130254721Semaste        {
131254721Semaste            TargetSP target_sp (target_list.GetTargetAtIndex (i));
132254721Semaste            if (target_sp)
133254721Semaste            {
134254721Semaste                bool is_selected = target_sp.get() == selected_target_sp.get();
135254721Semaste                DumpTargetInfo (i,
136254721Semaste                                target_sp.get(),
137254721Semaste                                is_selected ? "* " : "  ",
138254721Semaste                                show_stopped_process_status,
139254721Semaste                                strm);
140254721Semaste            }
141254721Semaste        }
142254721Semaste    }
143254721Semaste    return num_targets;
144254721Semaste}
145254721Semaste#pragma mark CommandObjectTargetCreate
146254721Semaste
147254721Semaste//-------------------------------------------------------------------------
148254721Semaste// "target create"
149254721Semaste//-------------------------------------------------------------------------
150254721Semaste
151254721Semasteclass CommandObjectTargetCreate : public CommandObjectParsed
152254721Semaste{
153254721Semastepublic:
154254721Semaste    CommandObjectTargetCreate(CommandInterpreter &interpreter) :
155254721Semaste        CommandObjectParsed (interpreter,
156254721Semaste                             "target create",
157254721Semaste                             "Create a target using the argument as the main executable.",
158254721Semaste                             NULL),
159254721Semaste        m_option_group (interpreter),
160254721Semaste        m_arch_option (),
161254721Semaste        m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
162254721Semaste        m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."),
163263363Semaste        m_platform_path (LLDB_OPT_SET_1, false, "platform-path", 'P', 0, eArgTypePath, "Path to the remote file to use for this target."),
164254721Semaste        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."),
165254721Semaste        m_remote_file (LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename, "Fullpath to the file on the remote host if debugging remotely."),
166254721Semaste        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)
167254721Semaste    {
168254721Semaste        CommandArgumentEntry arg;
169254721Semaste        CommandArgumentData file_arg;
170254721Semaste
171254721Semaste        // Define the first (and only) variant of this arg.
172254721Semaste            file_arg.arg_type = eArgTypeFilename;
173254721Semaste        file_arg.arg_repetition = eArgRepeatPlain;
174254721Semaste
175254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
176254721Semaste        arg.push_back (file_arg);
177254721Semaste
178254721Semaste        // Push the data for the first argument into the m_arguments vector.
179254721Semaste        m_arguments.push_back (arg);
180254721Semaste
181254721Semaste        m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
182254721Semaste        m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
183254721Semaste        m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
184263363Semaste        m_option_group.Append (&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
185254721Semaste        m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
186254721Semaste        m_option_group.Append (&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
187254721Semaste        m_option_group.Append (&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
188254721Semaste        m_option_group.Finalize();
189254721Semaste    }
190254721Semaste
191254721Semaste    ~CommandObjectTargetCreate ()
192254721Semaste    {
193254721Semaste    }
194254721Semaste
195254721Semaste    Options *
196254721Semaste    GetOptions ()
197254721Semaste    {
198254721Semaste        return &m_option_group;
199254721Semaste    }
200254721Semaste
201254721Semaste    virtual int
202254721Semaste    HandleArgumentCompletion (Args &input,
203254721Semaste                              int &cursor_index,
204254721Semaste                              int &cursor_char_position,
205254721Semaste                              OptionElementVector &opt_element_vector,
206254721Semaste                              int match_start_point,
207254721Semaste                              int max_return_elements,
208254721Semaste                              bool &word_complete,
209254721Semaste                              StringList &matches)
210254721Semaste    {
211254721Semaste        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
212254721Semaste        completion_str.erase (cursor_char_position);
213254721Semaste
214254721Semaste        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
215254721Semaste                                                             CommandCompletions::eDiskFileCompletion,
216254721Semaste                                                             completion_str.c_str(),
217254721Semaste                                                             match_start_point,
218254721Semaste                                                             max_return_elements,
219254721Semaste                                                             NULL,
220254721Semaste                                                             word_complete,
221254721Semaste                                                             matches);
222254721Semaste        return matches.GetSize();
223254721Semaste    }
224254721Semaste
225254721Semasteprotected:
226254721Semaste    bool
227254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
228254721Semaste    {
229254721Semaste        const size_t argc = command.GetArgumentCount();
230254721Semaste        FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
231254721Semaste        FileSpec remote_file (m_remote_file.GetOptionValue().GetCurrentValue());
232254721Semaste
233263363Semaste        if (argc == 1 || core_file || remote_file)
234254721Semaste        {
235254721Semaste            FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue());
236254721Semaste            if (symfile)
237254721Semaste            {
238254721Semaste                if (!symfile.Exists())
239254721Semaste                {
240254721Semaste                    char symfile_path[PATH_MAX];
241254721Semaste                    symfile.GetPath(symfile_path, sizeof(symfile_path));
242254721Semaste                    result.AppendErrorWithFormat("invalid symbol file path '%s'", symfile_path);
243254721Semaste                    result.SetStatus (eReturnStatusFailed);
244254721Semaste                    return false;
245254721Semaste                }
246254721Semaste            }
247254721Semaste
248254721Semaste            const char *file_path = command.GetArgumentAtIndex(0);
249254721Semaste            Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
250263363Semaste            FileSpec file_spec;
251263363Semaste
252263363Semaste            if (file_path)
253263363Semaste                file_spec.SetFile (file_path, true);
254263363Semaste
255263363Semaste            bool must_set_platform_path = false;
256263363Semaste
257263363Semaste            Debugger &debugger = m_interpreter.GetDebugger();
258263363Semaste            PlatformSP platform_sp(debugger.GetPlatformList().GetSelectedPlatform ());
259263363Semaste
260263363Semaste            if (remote_file)
261263363Semaste            {
262263363Semaste                // I have a remote file.. two possible cases
263263363Semaste                if (file_spec && file_spec.Exists())
264263363Semaste                {
265263363Semaste                    // if the remote file does not exist, push it there
266263363Semaste                    if (!platform_sp->GetFileExists (remote_file))
267263363Semaste                    {
268263363Semaste                        Error err = platform_sp->PutFile(file_spec, remote_file);
269263363Semaste                        if (err.Fail())
270263363Semaste                        {
271263363Semaste                            result.AppendError(err.AsCString());
272263363Semaste                            result.SetStatus (eReturnStatusFailed);
273263363Semaste                            return false;
274263363Semaste                        }
275263363Semaste                    }
276263363Semaste                }
277263363Semaste                else
278263363Semaste                {
279263363Semaste                    // there is no local file and we need one
280263363Semaste                    // in order to make the remote ---> local transfer we need a platform
281263363Semaste                    // TODO: if the user has passed in a --platform argument, use it to fetch the right platform
282263363Semaste                    if (!platform_sp)
283263363Semaste                    {
284263363Semaste                        result.AppendError("unable to perform remote debugging without a platform");
285263363Semaste                        result.SetStatus (eReturnStatusFailed);
286263363Semaste                        return false;
287263363Semaste                    }
288263363Semaste                    if (file_path)
289263363Semaste                    {
290263363Semaste                        // copy the remote file to the local file
291263363Semaste                        Error err = platform_sp->GetFile(remote_file, file_spec);
292263363Semaste                        if (err.Fail())
293263363Semaste                        {
294263363Semaste                            result.AppendError(err.AsCString());
295263363Semaste                            result.SetStatus (eReturnStatusFailed);
296263363Semaste                            return false;
297263363Semaste                        }
298263363Semaste                    }
299263363Semaste                    else
300263363Semaste                    {
301263363Semaste                        // make up a local file
302263363Semaste                        result.AppendError("remote --> local transfer without local path is not implemented yet");
303263363Semaste                        result.SetStatus (eReturnStatusFailed);
304263363Semaste                        return false;
305263363Semaste                    }
306263363Semaste                }
307263363Semaste            }
308263363Semaste
309254721Semaste            TargetSP target_sp;
310254721Semaste            const char *arch_cstr = m_arch_option.GetArchitectureName();
311254721Semaste            const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue();
312254721Semaste            Error error (debugger.GetTargetList().CreateTarget (debugger,
313263363Semaste//                                                                remote_file ? remote_file : file_spec,
314254721Semaste                                                                file_path,
315254721Semaste                                                                arch_cstr,
316254721Semaste                                                                get_dependent_files,
317254721Semaste                                                                &m_platform_options,
318254721Semaste                                                                target_sp));
319254721Semaste
320254721Semaste            if (target_sp)
321254721Semaste            {
322254721Semaste                if (symfile || remote_file)
323254721Semaste                {
324254721Semaste                    ModuleSP module_sp (target_sp->GetExecutableModule());
325254721Semaste                    if (module_sp)
326254721Semaste                    {
327254721Semaste                        if (symfile)
328254721Semaste                            module_sp->SetSymbolFileFileSpec(symfile);
329254721Semaste                        if (remote_file)
330254721Semaste                        {
331254721Semaste                            std::string remote_path = remote_file.GetPath();
332254721Semaste                            target_sp->SetArg0(remote_path.c_str());
333254721Semaste                            module_sp->SetPlatformFileSpec(remote_file);
334254721Semaste                        }
335254721Semaste                    }
336254721Semaste                }
337254721Semaste
338254721Semaste                debugger.GetTargetList().SetSelectedTarget(target_sp.get());
339263363Semaste                if (must_set_platform_path)
340263363Semaste                {
341263363Semaste                    ModuleSpec main_module_spec(file_spec);
342263363Semaste                    ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
343263363Semaste                    if (module_sp)
344263363Semaste                        module_sp->SetPlatformFileSpec(remote_file);
345263363Semaste                }
346254721Semaste                if (core_file)
347254721Semaste                {
348254721Semaste                    char core_path[PATH_MAX];
349254721Semaste                    core_file.GetPath(core_path, sizeof(core_path));
350254721Semaste                    if (core_file.Exists())
351254721Semaste                    {
352254721Semaste                        FileSpec core_file_dir;
353254721Semaste                        core_file_dir.GetDirectory() = core_file.GetDirectory();
354254721Semaste                        target_sp->GetExecutableSearchPaths ().Append (core_file_dir);
355254721Semaste
356254721Semaste                        ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
357254721Semaste
358254721Semaste                        if (process_sp)
359254721Semaste                        {
360254721Semaste                            // Seems wierd that we Launch a core file, but that is
361254721Semaste                            // what we do!
362254721Semaste                            error = process_sp->LoadCore();
363254721Semaste
364254721Semaste                            if (error.Fail())
365254721Semaste                            {
366254721Semaste                                result.AppendError(error.AsCString("can't find plug-in for core file"));
367254721Semaste                                result.SetStatus (eReturnStatusFailed);
368254721Semaste                                return false;
369254721Semaste                            }
370254721Semaste                            else
371254721Semaste                            {
372254721Semaste                                result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
373254721Semaste                                result.SetStatus (eReturnStatusSuccessFinishNoResult);
374254721Semaste                            }
375254721Semaste                        }
376254721Semaste                        else
377254721Semaste                        {
378254721Semaste                            result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
379254721Semaste                            result.SetStatus (eReturnStatusFailed);
380254721Semaste                        }
381254721Semaste                    }
382254721Semaste                    else
383254721Semaste                    {
384254721Semaste                        result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path);
385254721Semaste                        result.SetStatus (eReturnStatusFailed);
386254721Semaste                    }
387254721Semaste                }
388254721Semaste                else
389254721Semaste                {
390254721Semaste                    result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
391254721Semaste                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
392254721Semaste                }
393254721Semaste            }
394254721Semaste            else
395254721Semaste            {
396254721Semaste                result.AppendError(error.AsCString());
397254721Semaste                result.SetStatus (eReturnStatusFailed);
398254721Semaste            }
399254721Semaste        }
400254721Semaste        else
401254721Semaste        {
402254721Semaste            result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str());
403254721Semaste            result.SetStatus (eReturnStatusFailed);
404254721Semaste        }
405254721Semaste        return result.Succeeded();
406254721Semaste
407254721Semaste    }
408254721Semaste
409254721Semasteprivate:
410254721Semaste    OptionGroupOptions m_option_group;
411254721Semaste    OptionGroupArchitecture m_arch_option;
412254721Semaste    OptionGroupPlatform m_platform_options;
413254721Semaste    OptionGroupFile m_core_file;
414263363Semaste    OptionGroupFile m_platform_path;
415254721Semaste    OptionGroupFile m_symbol_file;
416254721Semaste    OptionGroupFile m_remote_file;
417254721Semaste    OptionGroupBoolean m_add_dependents;
418254721Semaste};
419254721Semaste
420254721Semaste#pragma mark CommandObjectTargetList
421254721Semaste
422254721Semaste//----------------------------------------------------------------------
423254721Semaste// "target list"
424254721Semaste//----------------------------------------------------------------------
425254721Semaste
426254721Semasteclass CommandObjectTargetList : public CommandObjectParsed
427254721Semaste{
428254721Semastepublic:
429254721Semaste    CommandObjectTargetList (CommandInterpreter &interpreter) :
430254721Semaste        CommandObjectParsed (interpreter,
431254721Semaste                             "target list",
432254721Semaste                             "List all current targets in the current debug session.",
433254721Semaste                             NULL,
434254721Semaste                             0)
435254721Semaste    {
436254721Semaste    }
437254721Semaste
438254721Semaste    virtual
439254721Semaste    ~CommandObjectTargetList ()
440254721Semaste    {
441254721Semaste    }
442254721Semaste
443254721Semasteprotected:
444254721Semaste    virtual bool
445254721Semaste    DoExecute (Args& args, CommandReturnObject &result)
446254721Semaste    {
447254721Semaste        if (args.GetArgumentCount() == 0)
448254721Semaste        {
449254721Semaste            Stream &strm = result.GetOutputStream();
450254721Semaste
451254721Semaste            bool show_stopped_process_status = false;
452254721Semaste            if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
453254721Semaste            {
454254721Semaste                strm.PutCString ("No targets.\n");
455254721Semaste            }
456254721Semaste            result.SetStatus (eReturnStatusSuccessFinishResult);
457254721Semaste        }
458254721Semaste        else
459254721Semaste        {
460254721Semaste            result.AppendError ("the 'target list' command takes no arguments\n");
461254721Semaste            result.SetStatus (eReturnStatusFailed);
462254721Semaste        }
463254721Semaste        return result.Succeeded();
464254721Semaste    }
465254721Semaste};
466254721Semaste
467254721Semaste
468254721Semaste#pragma mark CommandObjectTargetSelect
469254721Semaste
470254721Semaste//----------------------------------------------------------------------
471254721Semaste// "target select"
472254721Semaste//----------------------------------------------------------------------
473254721Semaste
474254721Semasteclass CommandObjectTargetSelect : public CommandObjectParsed
475254721Semaste{
476254721Semastepublic:
477254721Semaste    CommandObjectTargetSelect (CommandInterpreter &interpreter) :
478254721Semaste        CommandObjectParsed (interpreter,
479254721Semaste                             "target select",
480254721Semaste                             "Select a target as the current target by target index.",
481254721Semaste                             NULL,
482254721Semaste                             0)
483254721Semaste    {
484254721Semaste    }
485254721Semaste
486254721Semaste    virtual
487254721Semaste    ~CommandObjectTargetSelect ()
488254721Semaste    {
489254721Semaste    }
490254721Semaste
491254721Semasteprotected:
492254721Semaste    virtual bool
493254721Semaste    DoExecute (Args& args, CommandReturnObject &result)
494254721Semaste    {
495254721Semaste        if (args.GetArgumentCount() == 1)
496254721Semaste        {
497254721Semaste            bool success = false;
498254721Semaste            const char *target_idx_arg = args.GetArgumentAtIndex(0);
499254721Semaste            uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
500254721Semaste            if (success)
501254721Semaste            {
502254721Semaste                TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
503254721Semaste                const uint32_t num_targets = target_list.GetNumTargets();
504254721Semaste                if (target_idx < num_targets)
505254721Semaste                {
506254721Semaste                    TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
507254721Semaste                    if (target_sp)
508254721Semaste                    {
509254721Semaste                        Stream &strm = result.GetOutputStream();
510254721Semaste                        target_list.SetSelectedTarget (target_sp.get());
511254721Semaste                        bool show_stopped_process_status = false;
512254721Semaste                        DumpTargetList (target_list, show_stopped_process_status, strm);
513254721Semaste                        result.SetStatus (eReturnStatusSuccessFinishResult);
514254721Semaste                    }
515254721Semaste                    else
516254721Semaste                    {
517254721Semaste                        result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
518254721Semaste                        result.SetStatus (eReturnStatusFailed);
519254721Semaste                    }
520254721Semaste                }
521254721Semaste                else
522254721Semaste                {
523254721Semaste                    result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
524254721Semaste                                                  target_idx,
525254721Semaste                                                  num_targets - 1);
526254721Semaste                    result.SetStatus (eReturnStatusFailed);
527254721Semaste                }
528254721Semaste            }
529254721Semaste            else
530254721Semaste            {
531254721Semaste                result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
532254721Semaste                result.SetStatus (eReturnStatusFailed);
533254721Semaste            }
534254721Semaste        }
535254721Semaste        else
536254721Semaste        {
537254721Semaste            result.AppendError ("'target select' takes a single argument: a target index\n");
538254721Semaste            result.SetStatus (eReturnStatusFailed);
539254721Semaste        }
540254721Semaste        return result.Succeeded();
541254721Semaste    }
542254721Semaste};
543254721Semaste
544254721Semaste#pragma mark CommandObjectTargetSelect
545254721Semaste
546254721Semaste//----------------------------------------------------------------------
547254721Semaste// "target delete"
548254721Semaste//----------------------------------------------------------------------
549254721Semaste
550254721Semasteclass CommandObjectTargetDelete : public CommandObjectParsed
551254721Semaste{
552254721Semastepublic:
553254721Semaste    CommandObjectTargetDelete (CommandInterpreter &interpreter) :
554254721Semaste        CommandObjectParsed (interpreter,
555254721Semaste                             "target delete",
556254721Semaste                             "Delete one or more targets by target index.",
557254721Semaste                             NULL,
558254721Semaste                             0),
559254721Semaste        m_option_group (interpreter),
560254721Semaste        m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false)
561254721Semaste    {
562254721Semaste        m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
563254721Semaste        m_option_group.Finalize();
564254721Semaste    }
565254721Semaste
566254721Semaste    virtual
567254721Semaste    ~CommandObjectTargetDelete ()
568254721Semaste    {
569254721Semaste    }
570254721Semaste
571254721Semaste    Options *
572254721Semaste    GetOptions ()
573254721Semaste    {
574254721Semaste        return &m_option_group;
575254721Semaste    }
576254721Semaste
577254721Semasteprotected:
578254721Semaste    virtual bool
579254721Semaste    DoExecute (Args& args, CommandReturnObject &result)
580254721Semaste    {
581254721Semaste        const size_t argc = args.GetArgumentCount();
582254721Semaste        std::vector<TargetSP> delete_target_list;
583254721Semaste        TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
584254721Semaste        bool success = true;
585254721Semaste        TargetSP target_sp;
586254721Semaste        if (argc > 0)
587254721Semaste        {
588254721Semaste            const uint32_t num_targets = target_list.GetNumTargets();
589254721Semaste            // Bail out if don't have any targets.
590254721Semaste            if (num_targets == 0) {
591254721Semaste                result.AppendError("no targets to delete");
592254721Semaste                result.SetStatus(eReturnStatusFailed);
593254721Semaste                success = false;
594254721Semaste            }
595254721Semaste
596254721Semaste            for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
597254721Semaste            {
598254721Semaste                const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
599254721Semaste                uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
600254721Semaste                if (success)
601254721Semaste                {
602254721Semaste                    if (target_idx < num_targets)
603254721Semaste                    {
604254721Semaste                        target_sp = target_list.GetTargetAtIndex (target_idx);
605254721Semaste                        if (target_sp)
606254721Semaste                        {
607254721Semaste                            delete_target_list.push_back (target_sp);
608254721Semaste                            continue;
609254721Semaste                        }
610254721Semaste                    }
611254721Semaste                    if (num_targets > 1)
612254721Semaste                        result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
613254721Semaste                                                      target_idx,
614254721Semaste                                                      num_targets - 1);
615254721Semaste                    else
616254721Semaste                        result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n",
617254721Semaste                                                    target_idx);
618254721Semaste
619254721Semaste                    result.SetStatus (eReturnStatusFailed);
620254721Semaste                    success = false;
621254721Semaste                }
622254721Semaste                else
623254721Semaste                {
624254721Semaste                    result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
625254721Semaste                    result.SetStatus (eReturnStatusFailed);
626254721Semaste                    success = false;
627254721Semaste                }
628254721Semaste            }
629254721Semaste
630254721Semaste        }
631254721Semaste        else
632254721Semaste        {
633254721Semaste            target_sp = target_list.GetSelectedTarget();
634254721Semaste            if (target_sp)
635254721Semaste            {
636254721Semaste                delete_target_list.push_back (target_sp);
637254721Semaste            }
638254721Semaste            else
639254721Semaste            {
640254721Semaste                result.AppendErrorWithFormat("no target is currently selected\n");
641254721Semaste                result.SetStatus (eReturnStatusFailed);
642254721Semaste                success = false;
643254721Semaste            }
644254721Semaste        }
645254721Semaste        if (success)
646254721Semaste        {
647254721Semaste            const size_t num_targets_to_delete = delete_target_list.size();
648254721Semaste            for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
649254721Semaste            {
650254721Semaste                target_sp = delete_target_list[idx];
651254721Semaste                target_list.DeleteTarget(target_sp);
652254721Semaste                target_sp->Destroy();
653254721Semaste            }
654254721Semaste            // If "--clean" was specified, prune any orphaned shared modules from
655254721Semaste            // the global shared module list
656254721Semaste            if (m_cleanup_option.GetOptionValue ())
657254721Semaste            {
658254721Semaste                const bool mandatory = true;
659254721Semaste                ModuleList::RemoveOrphanSharedModules(mandatory);
660254721Semaste            }
661254721Semaste            result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
662254721Semaste            result.SetStatus(eReturnStatusSuccessFinishResult);
663254721Semaste        }
664254721Semaste
665254721Semaste        return result.Succeeded();
666254721Semaste    }
667254721Semaste
668254721Semaste    OptionGroupOptions m_option_group;
669254721Semaste    OptionGroupBoolean m_cleanup_option;
670254721Semaste};
671254721Semaste
672254721Semaste
673254721Semaste#pragma mark CommandObjectTargetVariable
674254721Semaste
675254721Semaste//----------------------------------------------------------------------
676254721Semaste// "target variable"
677254721Semaste//----------------------------------------------------------------------
678254721Semaste
679254721Semasteclass CommandObjectTargetVariable : public CommandObjectParsed
680254721Semaste{
681254721Semastepublic:
682254721Semaste    CommandObjectTargetVariable (CommandInterpreter &interpreter) :
683254721Semaste        CommandObjectParsed (interpreter,
684254721Semaste                             "target variable",
685254721Semaste                             "Read global variable(s) prior to, or while running your binary.",
686254721Semaste                             NULL,
687254721Semaste                             eFlagRequiresTarget),
688254721Semaste        m_option_group (interpreter),
689254721Semaste        m_option_variable (false), // Don't include frame options
690254721Semaste        m_option_format (eFormatDefault),
691254721Semaste        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."),
692254721Semaste        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."),
693254721Semaste        m_varobj_options()
694254721Semaste    {
695254721Semaste        CommandArgumentEntry arg;
696254721Semaste        CommandArgumentData var_name_arg;
697254721Semaste
698254721Semaste        // Define the first (and only) variant of this arg.
699254721Semaste        var_name_arg.arg_type = eArgTypeVarName;
700254721Semaste        var_name_arg.arg_repetition = eArgRepeatPlus;
701254721Semaste
702254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
703254721Semaste        arg.push_back (var_name_arg);
704254721Semaste
705254721Semaste        // Push the data for the first argument into the m_arguments vector.
706254721Semaste        m_arguments.push_back (arg);
707254721Semaste
708254721Semaste        m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
709254721Semaste        m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
710254721Semaste        m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
711254721Semaste        m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
712254721Semaste        m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
713254721Semaste        m_option_group.Finalize();
714254721Semaste    }
715254721Semaste
716254721Semaste    virtual
717254721Semaste    ~CommandObjectTargetVariable ()
718254721Semaste    {
719254721Semaste    }
720254721Semaste
721254721Semaste    void
722254721Semaste    DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
723254721Semaste    {
724263363Semaste        DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
725254721Semaste
726254721Semaste        switch (var_sp->GetScope())
727254721Semaste        {
728254721Semaste            case eValueTypeVariableGlobal:
729254721Semaste                if (m_option_variable.show_scope)
730254721Semaste                    s.PutCString("GLOBAL: ");
731254721Semaste                break;
732254721Semaste
733254721Semaste            case eValueTypeVariableStatic:
734254721Semaste                if (m_option_variable.show_scope)
735254721Semaste                    s.PutCString("STATIC: ");
736254721Semaste                break;
737254721Semaste
738254721Semaste            case eValueTypeVariableArgument:
739254721Semaste                if (m_option_variable.show_scope)
740254721Semaste                    s.PutCString("   ARG: ");
741254721Semaste                break;
742254721Semaste
743254721Semaste            case eValueTypeVariableLocal:
744254721Semaste                if (m_option_variable.show_scope)
745254721Semaste                    s.PutCString(" LOCAL: ");
746254721Semaste                break;
747254721Semaste
748254721Semaste            default:
749254721Semaste                break;
750254721Semaste        }
751254721Semaste
752254721Semaste        if (m_option_variable.show_decl)
753254721Semaste        {
754254721Semaste            bool show_fullpaths = false;
755254721Semaste            bool show_module = true;
756254721Semaste            if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
757254721Semaste                s.PutCString (": ");
758254721Semaste        }
759254721Semaste
760254721Semaste        const Format format = m_option_format.GetFormat();
761254721Semaste        if (format != eFormatDefault)
762254721Semaste            options.SetFormat(format);
763254721Semaste
764254721Semaste        options.SetRootValueObjectName(root_name);
765254721Semaste
766263363Semaste        valobj_sp->Dump(s,options);
767254721Semaste    }
768254721Semaste
769254721Semaste
770254721Semaste    static size_t GetVariableCallback (void *baton,
771254721Semaste                                       const char *name,
772254721Semaste                                       VariableList &variable_list)
773254721Semaste    {
774254721Semaste        Target *target = static_cast<Target *>(baton);
775254721Semaste        if (target)
776254721Semaste        {
777254721Semaste            return target->GetImages().FindGlobalVariables (ConstString(name),
778254721Semaste                                                            true,
779254721Semaste                                                            UINT32_MAX,
780254721Semaste                                                            variable_list);
781254721Semaste        }
782254721Semaste        return 0;
783254721Semaste    }
784254721Semaste
785254721Semaste
786254721Semaste
787254721Semaste    Options *
788254721Semaste    GetOptions ()
789254721Semaste    {
790254721Semaste        return &m_option_group;
791254721Semaste    }
792254721Semaste
793254721Semasteprotected:
794254721Semaste
795254721Semaste    void
796254721Semaste    DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s)
797254721Semaste    {
798254721Semaste        size_t count = variable_list.GetSize();
799254721Semaste        if (count > 0)
800254721Semaste        {
801254721Semaste            if (sc.module_sp)
802254721Semaste            {
803254721Semaste                if (sc.comp_unit)
804254721Semaste                {
805254721Semaste                    s.Printf ("Global variables for %s in %s:\n",
806254721Semaste                              sc.comp_unit->GetPath().c_str(),
807254721Semaste                              sc.module_sp->GetFileSpec().GetPath().c_str());
808254721Semaste                }
809254721Semaste                else
810254721Semaste                {
811254721Semaste                    s.Printf ("Global variables for %s\n",
812254721Semaste                              sc.module_sp->GetFileSpec().GetPath().c_str());
813254721Semaste                }
814254721Semaste            }
815254721Semaste            else if (sc.comp_unit)
816254721Semaste            {
817254721Semaste                s.Printf ("Global variables for %s\n",
818254721Semaste                          sc.comp_unit->GetPath().c_str());
819254721Semaste            }
820254721Semaste
821254721Semaste            for (uint32_t i=0; i<count; ++i)
822254721Semaste            {
823254721Semaste                VariableSP var_sp (variable_list.GetVariableAtIndex(i));
824254721Semaste                if (var_sp)
825254721Semaste                {
826254721Semaste                    ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
827254721Semaste
828254721Semaste                    if (valobj_sp)
829254721Semaste                        DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
830254721Semaste                }
831254721Semaste            }
832254721Semaste        }
833254721Semaste
834254721Semaste    }
835254721Semaste    virtual bool
836254721Semaste    DoExecute (Args& args, CommandReturnObject &result)
837254721Semaste    {
838254721Semaste        Target *target = m_exe_ctx.GetTargetPtr();
839254721Semaste        const size_t argc = args.GetArgumentCount();
840254721Semaste        Stream &s = result.GetOutputStream();
841254721Semaste
842254721Semaste        if (argc > 0)
843254721Semaste        {
844254721Semaste
845254721Semaste            for (size_t idx = 0; idx < argc; ++idx)
846254721Semaste            {
847254721Semaste                VariableList variable_list;
848254721Semaste                ValueObjectList valobj_list;
849254721Semaste
850254721Semaste                const char *arg = args.GetArgumentAtIndex(idx);
851254721Semaste                size_t matches = 0;
852254721Semaste                bool use_var_name = false;
853254721Semaste                if (m_option_variable.use_regex)
854254721Semaste                {
855254721Semaste                    RegularExpression regex(arg);
856254721Semaste                    if (!regex.IsValid ())
857254721Semaste                    {
858254721Semaste                        result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
859254721Semaste                        result.SetStatus (eReturnStatusFailed);
860254721Semaste                        return false;
861254721Semaste                    }
862254721Semaste                    use_var_name = true;
863254721Semaste                    matches = target->GetImages().FindGlobalVariables (regex,
864254721Semaste                                                                       true,
865254721Semaste                                                                       UINT32_MAX,
866254721Semaste                                                                       variable_list);
867254721Semaste                }
868254721Semaste                else
869254721Semaste                {
870254721Semaste                    Error error (Variable::GetValuesForVariableExpressionPath (arg,
871254721Semaste                                                                               m_exe_ctx.GetBestExecutionContextScope(),
872254721Semaste                                                                               GetVariableCallback,
873254721Semaste                                                                               target,
874254721Semaste                                                                               variable_list,
875254721Semaste                                                                               valobj_list));
876254721Semaste                    matches = variable_list.GetSize();
877254721Semaste                }
878254721Semaste
879254721Semaste                if (matches == 0)
880254721Semaste                {
881254721Semaste                    result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
882254721Semaste                    result.SetStatus (eReturnStatusFailed);
883254721Semaste                    return false;
884254721Semaste                }
885254721Semaste                else
886254721Semaste                {
887254721Semaste                    for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
888254721Semaste                    {
889254721Semaste                        VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
890254721Semaste                        if (var_sp)
891254721Semaste                        {
892254721Semaste                            ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
893254721Semaste                            if (!valobj_sp)
894254721Semaste                                valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp);
895254721Semaste
896254721Semaste                            if (valobj_sp)
897254721Semaste                                DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
898254721Semaste                        }
899254721Semaste                    }
900254721Semaste                }
901254721Semaste            }
902254721Semaste        }
903254721Semaste        else
904254721Semaste        {
905254721Semaste            const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue();
906254721Semaste            const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue();
907254721Semaste            SymbolContextList sc_list;
908254721Semaste            const size_t num_compile_units = compile_units.GetSize();
909254721Semaste            const size_t num_shlibs = shlibs.GetSize();
910254721Semaste            if (num_compile_units == 0 && num_shlibs == 0)
911254721Semaste            {
912254721Semaste                bool success = false;
913254721Semaste                StackFrame *frame = m_exe_ctx.GetFramePtr();
914254721Semaste                CompileUnit *comp_unit = NULL;
915254721Semaste                if (frame)
916254721Semaste                {
917254721Semaste                    SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit);
918254721Semaste                    if (sc.comp_unit)
919254721Semaste                    {
920254721Semaste                        const bool can_create = true;
921254721Semaste                        VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
922254721Semaste                        if (comp_unit_varlist_sp)
923254721Semaste                        {
924254721Semaste                            size_t count = comp_unit_varlist_sp->GetSize();
925254721Semaste                            if (count > 0)
926254721Semaste                            {
927254721Semaste                                DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
928254721Semaste                                success = true;
929254721Semaste                            }
930254721Semaste                        }
931254721Semaste                    }
932254721Semaste                }
933254721Semaste                if (!success)
934254721Semaste                {
935254721Semaste                    if (frame)
936254721Semaste                    {
937254721Semaste                        if (comp_unit)
938254721Semaste                            result.AppendErrorWithFormat ("no global variables in current compile unit: %s\n",
939254721Semaste                                                          comp_unit->GetPath().c_str());
940254721Semaste                        else
941254721Semaste                            result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex());
942254721Semaste                    }
943254721Semaste                    else
944254721Semaste                        result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
945254721Semaste                    result.SetStatus (eReturnStatusFailed);
946254721Semaste                }
947254721Semaste            }
948254721Semaste            else
949254721Semaste            {
950254721Semaste                SymbolContextList sc_list;
951254721Semaste                const bool append = true;
952254721Semaste                // We have one or more compile unit or shlib
953254721Semaste                if (num_shlibs > 0)
954254721Semaste                {
955254721Semaste                    for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx)
956254721Semaste                    {
957254721Semaste                        const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
958254721Semaste                        ModuleSpec module_spec (module_file);
959254721Semaste
960254721Semaste                        ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
961254721Semaste                        if (module_sp)
962254721Semaste                        {
963254721Semaste                            if (num_compile_units > 0)
964254721Semaste                            {
965254721Semaste                                for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
966254721Semaste                                    module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
967254721Semaste                            }
968254721Semaste                            else
969254721Semaste                            {
970254721Semaste                                SymbolContext sc;
971254721Semaste                                sc.module_sp = module_sp;
972254721Semaste                                sc_list.Append(sc);
973254721Semaste                            }
974254721Semaste                        }
975254721Semaste                        else
976254721Semaste                        {
977254721Semaste                            // Didn't find matching shlib/module in target...
978254721Semaste                            result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s\n",
979254721Semaste                                                          module_file.GetPath().c_str());
980254721Semaste                        }
981254721Semaste                    }
982254721Semaste                }
983254721Semaste                else
984254721Semaste                {
985254721Semaste                    // No shared libraries, we just want to find globals for the compile units files that were specified
986254721Semaste                    for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
987254721Semaste                        target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
988254721Semaste                }
989254721Semaste
990254721Semaste                const uint32_t num_scs = sc_list.GetSize();
991254721Semaste                if (num_scs > 0)
992254721Semaste                {
993254721Semaste                    SymbolContext sc;
994254721Semaste                    for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx)
995254721Semaste                    {
996254721Semaste                        if (sc_list.GetContextAtIndex(sc_idx, sc))
997254721Semaste                        {
998254721Semaste                            if (sc.comp_unit)
999254721Semaste                            {
1000254721Semaste                                const bool can_create = true;
1001254721Semaste                                VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
1002254721Semaste                                if (comp_unit_varlist_sp)
1003254721Semaste                                    DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
1004254721Semaste                            }
1005254721Semaste                            else if (sc.module_sp)
1006254721Semaste                            {
1007254721Semaste                                // Get all global variables for this module
1008254721Semaste                                lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character
1009254721Semaste                                VariableList variable_list;
1010254721Semaste                                sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list);
1011254721Semaste                                DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1012254721Semaste                            }
1013254721Semaste                        }
1014254721Semaste                    }
1015254721Semaste                }
1016254721Semaste            }
1017254721Semaste        }
1018254721Semaste
1019254721Semaste        if (m_interpreter.TruncationWarningNecessary())
1020254721Semaste        {
1021254721Semaste            result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1022254721Semaste                                            m_cmd_name.c_str());
1023254721Semaste            m_interpreter.TruncationWarningGiven();
1024254721Semaste        }
1025254721Semaste
1026254721Semaste        return result.Succeeded();
1027254721Semaste    }
1028254721Semaste
1029254721Semaste    OptionGroupOptions m_option_group;
1030254721Semaste    OptionGroupVariable m_option_variable;
1031254721Semaste    OptionGroupFormat m_option_format;
1032254721Semaste    OptionGroupFileList m_option_compile_units;
1033254721Semaste    OptionGroupFileList m_option_shared_libraries;
1034254721Semaste    OptionGroupValueObjectDisplay m_varobj_options;
1035254721Semaste
1036254721Semaste};
1037254721Semaste
1038254721Semaste
1039254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsAdd
1040254721Semaste
1041254721Semasteclass CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
1042254721Semaste{
1043254721Semastepublic:
1044254721Semaste
1045254721Semaste    CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
1046254721Semaste        CommandObjectParsed (interpreter,
1047254721Semaste                             "target modules search-paths add",
1048254721Semaste                             "Add new image search paths substitution pairs to the current target.",
1049254721Semaste                             NULL)
1050254721Semaste    {
1051254721Semaste        CommandArgumentEntry arg;
1052254721Semaste        CommandArgumentData old_prefix_arg;
1053254721Semaste        CommandArgumentData new_prefix_arg;
1054254721Semaste
1055254721Semaste        // Define the first variant of this arg pair.
1056254721Semaste        old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1057254721Semaste        old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1058254721Semaste
1059254721Semaste        // Define the first variant of this arg pair.
1060254721Semaste        new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1061254721Semaste        new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1062254721Semaste
1063254721Semaste        // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
1064254721Semaste        // must always occur together, they are treated as two variants of one argument rather than two independent
1065254721Semaste        // arguments.  Push them both into the first argument position for m_arguments...
1066254721Semaste
1067254721Semaste        arg.push_back (old_prefix_arg);
1068254721Semaste        arg.push_back (new_prefix_arg);
1069254721Semaste
1070254721Semaste        m_arguments.push_back (arg);
1071254721Semaste    }
1072254721Semaste
1073254721Semaste    ~CommandObjectTargetModulesSearchPathsAdd ()
1074254721Semaste    {
1075254721Semaste    }
1076254721Semaste
1077254721Semasteprotected:
1078254721Semaste    bool
1079254721Semaste    DoExecute (Args& command,
1080254721Semaste             CommandReturnObject &result)
1081254721Semaste    {
1082254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1083254721Semaste        if (target)
1084254721Semaste        {
1085254721Semaste            const size_t argc = command.GetArgumentCount();
1086254721Semaste            if (argc & 1)
1087254721Semaste            {
1088254721Semaste                result.AppendError ("add requires an even number of arguments\n");
1089254721Semaste                result.SetStatus (eReturnStatusFailed);
1090254721Semaste            }
1091254721Semaste            else
1092254721Semaste            {
1093254721Semaste                for (size_t i=0; i<argc; i+=2)
1094254721Semaste                {
1095254721Semaste                    const char *from = command.GetArgumentAtIndex(i);
1096254721Semaste                    const char *to = command.GetArgumentAtIndex(i+1);
1097254721Semaste
1098254721Semaste                    if (from[0] && to[0])
1099254721Semaste                    {
1100254721Semaste                        bool last_pair = ((argc - i) == 2);
1101254721Semaste                        target->GetImageSearchPathList().Append (ConstString(from),
1102254721Semaste                                                                 ConstString(to),
1103254721Semaste                                                                 last_pair); // Notify if this is the last pair
1104254721Semaste                        result.SetStatus (eReturnStatusSuccessFinishNoResult);
1105254721Semaste                    }
1106254721Semaste                    else
1107254721Semaste                    {
1108254721Semaste                        if (from[0])
1109254721Semaste                            result.AppendError ("<path-prefix> can't be empty\n");
1110254721Semaste                        else
1111254721Semaste                            result.AppendError ("<new-path-prefix> can't be empty\n");
1112254721Semaste                        result.SetStatus (eReturnStatusFailed);
1113254721Semaste                    }
1114254721Semaste                }
1115254721Semaste            }
1116254721Semaste        }
1117254721Semaste        else
1118254721Semaste        {
1119254721Semaste            result.AppendError ("invalid target\n");
1120254721Semaste            result.SetStatus (eReturnStatusFailed);
1121254721Semaste        }
1122254721Semaste        return result.Succeeded();
1123254721Semaste    }
1124254721Semaste};
1125254721Semaste
1126254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsClear
1127254721Semaste
1128254721Semasteclass CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
1129254721Semaste{
1130254721Semastepublic:
1131254721Semaste
1132254721Semaste    CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
1133254721Semaste        CommandObjectParsed (interpreter,
1134254721Semaste                             "target modules search-paths clear",
1135254721Semaste                             "Clear all current image search path substitution pairs from the current target.",
1136254721Semaste                             "target modules search-paths clear")
1137254721Semaste    {
1138254721Semaste    }
1139254721Semaste
1140254721Semaste    ~CommandObjectTargetModulesSearchPathsClear ()
1141254721Semaste    {
1142254721Semaste    }
1143254721Semaste
1144254721Semasteprotected:
1145254721Semaste    bool
1146254721Semaste    DoExecute (Args& command,
1147254721Semaste             CommandReturnObject &result)
1148254721Semaste    {
1149254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1150254721Semaste        if (target)
1151254721Semaste        {
1152254721Semaste            bool notify = true;
1153254721Semaste            target->GetImageSearchPathList().Clear(notify);
1154254721Semaste            result.SetStatus (eReturnStatusSuccessFinishNoResult);
1155254721Semaste        }
1156254721Semaste        else
1157254721Semaste        {
1158254721Semaste            result.AppendError ("invalid target\n");
1159254721Semaste            result.SetStatus (eReturnStatusFailed);
1160254721Semaste        }
1161254721Semaste        return result.Succeeded();
1162254721Semaste    }
1163254721Semaste};
1164254721Semaste
1165254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsInsert
1166254721Semaste
1167254721Semasteclass CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
1168254721Semaste{
1169254721Semastepublic:
1170254721Semaste
1171254721Semaste    CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
1172254721Semaste        CommandObjectParsed (interpreter,
1173254721Semaste                             "target modules search-paths insert",
1174254721Semaste                             "Insert a new image search path substitution pair into the current target at the specified index.",
1175254721Semaste                             NULL)
1176254721Semaste    {
1177254721Semaste        CommandArgumentEntry arg1;
1178254721Semaste        CommandArgumentEntry arg2;
1179254721Semaste        CommandArgumentData index_arg;
1180254721Semaste        CommandArgumentData old_prefix_arg;
1181254721Semaste        CommandArgumentData new_prefix_arg;
1182254721Semaste
1183254721Semaste        // Define the first and only variant of this arg.
1184254721Semaste        index_arg.arg_type = eArgTypeIndex;
1185254721Semaste        index_arg.arg_repetition = eArgRepeatPlain;
1186254721Semaste
1187254721Semaste        // Put the one and only variant into the first arg for m_arguments:
1188254721Semaste        arg1.push_back (index_arg);
1189254721Semaste
1190254721Semaste        // Define the first variant of this arg pair.
1191254721Semaste        old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1192254721Semaste        old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1193254721Semaste
1194254721Semaste        // Define the first variant of this arg pair.
1195254721Semaste        new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1196254721Semaste        new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1197254721Semaste
1198254721Semaste        // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
1199254721Semaste        // must always occur together, they are treated as two variants of one argument rather than two independent
1200254721Semaste        // arguments.  Push them both into the same argument position for m_arguments...
1201254721Semaste
1202254721Semaste        arg2.push_back (old_prefix_arg);
1203254721Semaste        arg2.push_back (new_prefix_arg);
1204254721Semaste
1205254721Semaste        // Add arguments to m_arguments.
1206254721Semaste        m_arguments.push_back (arg1);
1207254721Semaste        m_arguments.push_back (arg2);
1208254721Semaste    }
1209254721Semaste
1210254721Semaste    ~CommandObjectTargetModulesSearchPathsInsert ()
1211254721Semaste    {
1212254721Semaste    }
1213254721Semaste
1214254721Semasteprotected:
1215254721Semaste    bool
1216254721Semaste    DoExecute (Args& command,
1217254721Semaste             CommandReturnObject &result)
1218254721Semaste    {
1219254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1220254721Semaste        if (target)
1221254721Semaste        {
1222254721Semaste            size_t argc = command.GetArgumentCount();
1223254721Semaste            // check for at least 3 arguments and an odd nubmer of parameters
1224254721Semaste            if (argc >= 3 && argc & 1)
1225254721Semaste            {
1226254721Semaste                bool success = false;
1227254721Semaste
1228254721Semaste                uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1229254721Semaste
1230254721Semaste                if (!success)
1231254721Semaste                {
1232254721Semaste                    result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
1233254721Semaste                    result.SetStatus (eReturnStatusFailed);
1234254721Semaste                    return result.Succeeded();
1235254721Semaste                }
1236254721Semaste
1237254721Semaste                // shift off the index
1238254721Semaste                command.Shift();
1239254721Semaste                argc = command.GetArgumentCount();
1240254721Semaste
1241254721Semaste                for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
1242254721Semaste                {
1243254721Semaste                    const char *from = command.GetArgumentAtIndex(i);
1244254721Semaste                    const char *to = command.GetArgumentAtIndex(i+1);
1245254721Semaste
1246254721Semaste                    if (from[0] && to[0])
1247254721Semaste                    {
1248254721Semaste                        bool last_pair = ((argc - i) == 2);
1249254721Semaste                        target->GetImageSearchPathList().Insert (ConstString(from),
1250254721Semaste                                                                 ConstString(to),
1251254721Semaste                                                                 insert_idx,
1252254721Semaste                                                                 last_pair);
1253254721Semaste                        result.SetStatus (eReturnStatusSuccessFinishNoResult);
1254254721Semaste                    }
1255254721Semaste                    else
1256254721Semaste                    {
1257254721Semaste                        if (from[0])
1258254721Semaste                            result.AppendError ("<path-prefix> can't be empty\n");
1259254721Semaste                        else
1260254721Semaste                            result.AppendError ("<new-path-prefix> can't be empty\n");
1261254721Semaste                        result.SetStatus (eReturnStatusFailed);
1262254721Semaste                        return false;
1263254721Semaste                    }
1264254721Semaste                }
1265254721Semaste            }
1266254721Semaste            else
1267254721Semaste            {
1268254721Semaste                result.AppendError ("insert requires at least three arguments\n");
1269254721Semaste                result.SetStatus (eReturnStatusFailed);
1270254721Semaste                return result.Succeeded();
1271254721Semaste            }
1272254721Semaste
1273254721Semaste        }
1274254721Semaste        else
1275254721Semaste        {
1276254721Semaste            result.AppendError ("invalid target\n");
1277254721Semaste            result.SetStatus (eReturnStatusFailed);
1278254721Semaste        }
1279254721Semaste        return result.Succeeded();
1280254721Semaste    }
1281254721Semaste};
1282254721Semaste
1283254721Semaste
1284254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsList
1285254721Semaste
1286254721Semaste
1287254721Semasteclass CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
1288254721Semaste{
1289254721Semastepublic:
1290254721Semaste
1291254721Semaste    CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
1292254721Semaste        CommandObjectParsed (interpreter,
1293254721Semaste                             "target modules search-paths list",
1294254721Semaste                             "List all current image search path substitution pairs in the current target.",
1295254721Semaste                             "target modules search-paths list")
1296254721Semaste    {
1297254721Semaste    }
1298254721Semaste
1299254721Semaste    ~CommandObjectTargetModulesSearchPathsList ()
1300254721Semaste    {
1301254721Semaste    }
1302254721Semaste
1303254721Semasteprotected:
1304254721Semaste    bool
1305254721Semaste    DoExecute (Args& command,
1306254721Semaste             CommandReturnObject &result)
1307254721Semaste    {
1308254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1309254721Semaste        if (target)
1310254721Semaste        {
1311254721Semaste            if (command.GetArgumentCount() != 0)
1312254721Semaste            {
1313254721Semaste                result.AppendError ("list takes no arguments\n");
1314254721Semaste                result.SetStatus (eReturnStatusFailed);
1315254721Semaste                return result.Succeeded();
1316254721Semaste            }
1317254721Semaste
1318254721Semaste            target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1319254721Semaste            result.SetStatus (eReturnStatusSuccessFinishResult);
1320254721Semaste        }
1321254721Semaste        else
1322254721Semaste        {
1323254721Semaste            result.AppendError ("invalid target\n");
1324254721Semaste            result.SetStatus (eReturnStatusFailed);
1325254721Semaste        }
1326254721Semaste        return result.Succeeded();
1327254721Semaste    }
1328254721Semaste};
1329254721Semaste
1330254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsQuery
1331254721Semaste
1332254721Semasteclass CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
1333254721Semaste{
1334254721Semastepublic:
1335254721Semaste
1336254721Semaste    CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
1337254721Semaste        CommandObjectParsed (interpreter,
1338254721Semaste                             "target modules search-paths query",
1339254721Semaste                             "Transform a path using the first applicable image search path.",
1340254721Semaste                             NULL)
1341254721Semaste    {
1342254721Semaste        CommandArgumentEntry arg;
1343254721Semaste        CommandArgumentData path_arg;
1344254721Semaste
1345254721Semaste        // Define the first (and only) variant of this arg.
1346254721Semaste        path_arg.arg_type = eArgTypeDirectoryName;
1347254721Semaste        path_arg.arg_repetition = eArgRepeatPlain;
1348254721Semaste
1349254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
1350254721Semaste        arg.push_back (path_arg);
1351254721Semaste
1352254721Semaste        // Push the data for the first argument into the m_arguments vector.
1353254721Semaste        m_arguments.push_back (arg);
1354254721Semaste    }
1355254721Semaste
1356254721Semaste    ~CommandObjectTargetModulesSearchPathsQuery ()
1357254721Semaste    {
1358254721Semaste    }
1359254721Semaste
1360254721Semasteprotected:
1361254721Semaste    bool
1362254721Semaste    DoExecute (Args& command,
1363254721Semaste             CommandReturnObject &result)
1364254721Semaste    {
1365254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1366254721Semaste        if (target)
1367254721Semaste        {
1368254721Semaste            if (command.GetArgumentCount() != 1)
1369254721Semaste            {
1370254721Semaste                result.AppendError ("query requires one argument\n");
1371254721Semaste                result.SetStatus (eReturnStatusFailed);
1372254721Semaste                return result.Succeeded();
1373254721Semaste            }
1374254721Semaste
1375254721Semaste            ConstString orig(command.GetArgumentAtIndex(0));
1376254721Semaste            ConstString transformed;
1377254721Semaste            if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1378254721Semaste                result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1379254721Semaste            else
1380254721Semaste                result.GetOutputStream().Printf("%s\n", orig.GetCString());
1381254721Semaste
1382254721Semaste            result.SetStatus (eReturnStatusSuccessFinishResult);
1383254721Semaste        }
1384254721Semaste        else
1385254721Semaste        {
1386254721Semaste            result.AppendError ("invalid target\n");
1387254721Semaste            result.SetStatus (eReturnStatusFailed);
1388254721Semaste        }
1389254721Semaste        return result.Succeeded();
1390254721Semaste    }
1391254721Semaste};
1392254721Semaste
1393254721Semaste//----------------------------------------------------------------------
1394254721Semaste// Static Helper functions
1395254721Semaste//----------------------------------------------------------------------
1396254721Semastestatic void
1397254721SemasteDumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1398254721Semaste{
1399254721Semaste    if (module)
1400254721Semaste    {
1401254721Semaste        const char *arch_cstr;
1402254721Semaste        if (full_triple)
1403254721Semaste            arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
1404254721Semaste        else
1405254721Semaste            arch_cstr = module->GetArchitecture().GetArchitectureName();
1406254721Semaste        if (width)
1407254721Semaste            strm.Printf("%-*s", width, arch_cstr);
1408254721Semaste        else
1409254721Semaste            strm.PutCString(arch_cstr);
1410254721Semaste    }
1411254721Semaste}
1412254721Semaste
1413254721Semastestatic void
1414254721SemasteDumpModuleUUID (Stream &strm, Module *module)
1415254721Semaste{
1416254721Semaste    if (module && module->GetUUID().IsValid())
1417254721Semaste        module->GetUUID().Dump (&strm);
1418254721Semaste    else
1419254721Semaste        strm.PutCString("                                    ");
1420254721Semaste}
1421254721Semaste
1422254721Semastestatic uint32_t
1423254721SemasteDumpCompileUnitLineTable (CommandInterpreter &interpreter,
1424254721Semaste                          Stream &strm,
1425254721Semaste                          Module *module,
1426254721Semaste                          const FileSpec &file_spec,
1427254721Semaste                          bool load_addresses)
1428254721Semaste{
1429254721Semaste    uint32_t num_matches = 0;
1430254721Semaste    if (module)
1431254721Semaste    {
1432254721Semaste        SymbolContextList sc_list;
1433254721Semaste        num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1434254721Semaste                                                                0,
1435254721Semaste                                                                false,
1436254721Semaste                                                                eSymbolContextCompUnit,
1437254721Semaste                                                                sc_list);
1438254721Semaste
1439254721Semaste        for (uint32_t i=0; i<num_matches; ++i)
1440254721Semaste        {
1441254721Semaste            SymbolContext sc;
1442254721Semaste            if (sc_list.GetContextAtIndex(i, sc))
1443254721Semaste            {
1444254721Semaste                if (i > 0)
1445254721Semaste                    strm << "\n\n";
1446254721Semaste
1447254721Semaste                strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1448254721Semaste                << module->GetFileSpec().GetFilename() << "\n";
1449254721Semaste                LineTable *line_table = sc.comp_unit->GetLineTable();
1450254721Semaste                if (line_table)
1451254721Semaste                    line_table->GetDescription (&strm,
1452254721Semaste                                                interpreter.GetExecutionContext().GetTargetPtr(),
1453254721Semaste                                                lldb::eDescriptionLevelBrief);
1454254721Semaste                else
1455254721Semaste                    strm << "No line table";
1456254721Semaste            }
1457254721Semaste        }
1458254721Semaste    }
1459254721Semaste    return num_matches;
1460254721Semaste}
1461254721Semaste
1462254721Semastestatic void
1463254721SemasteDumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1464254721Semaste{
1465254721Semaste    if (file_spec_ptr)
1466254721Semaste    {
1467254721Semaste        if (width > 0)
1468254721Semaste        {
1469254721Semaste            std::string fullpath = file_spec_ptr->GetPath();
1470254721Semaste            strm.Printf("%-*s", width, fullpath.c_str());
1471254721Semaste            return;
1472254721Semaste        }
1473254721Semaste        else
1474254721Semaste        {
1475254721Semaste            file_spec_ptr->Dump(&strm);
1476254721Semaste            return;
1477254721Semaste        }
1478254721Semaste    }
1479254721Semaste    // Keep the width spacing correct if things go wrong...
1480254721Semaste    if (width > 0)
1481254721Semaste        strm.Printf("%-*s", width, "");
1482254721Semaste}
1483254721Semaste
1484254721Semastestatic void
1485254721SemasteDumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1486254721Semaste{
1487254721Semaste    if (file_spec_ptr)
1488254721Semaste    {
1489254721Semaste        if (width > 0)
1490254721Semaste            strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1491254721Semaste        else
1492254721Semaste            file_spec_ptr->GetDirectory().Dump(&strm);
1493254721Semaste        return;
1494254721Semaste    }
1495254721Semaste    // Keep the width spacing correct if things go wrong...
1496254721Semaste    if (width > 0)
1497254721Semaste        strm.Printf("%-*s", width, "");
1498254721Semaste}
1499254721Semaste
1500254721Semastestatic void
1501254721SemasteDumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1502254721Semaste{
1503254721Semaste    if (file_spec_ptr)
1504254721Semaste    {
1505254721Semaste        if (width > 0)
1506254721Semaste            strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1507254721Semaste        else
1508254721Semaste            file_spec_ptr->GetFilename().Dump(&strm);
1509254721Semaste        return;
1510254721Semaste    }
1511254721Semaste    // Keep the width spacing correct if things go wrong...
1512254721Semaste    if (width > 0)
1513254721Semaste        strm.Printf("%-*s", width, "");
1514254721Semaste}
1515254721Semaste
1516254721Semaste
1517254721Semastestatic void
1518254721SemasteDumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1519254721Semaste{
1520254721Semaste    if (module)
1521254721Semaste    {
1522254721Semaste        SymbolVendor *sym_vendor = module->GetSymbolVendor ();
1523254721Semaste        if (sym_vendor)
1524254721Semaste        {
1525254721Semaste            Symtab *symtab = sym_vendor->GetSymtab();
1526254721Semaste            if (symtab)
1527254721Semaste                symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
1528254721Semaste        }
1529254721Semaste    }
1530254721Semaste}
1531254721Semaste
1532254721Semastestatic void
1533254721SemasteDumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1534254721Semaste{
1535254721Semaste    if (module)
1536254721Semaste    {
1537254721Semaste        SectionList *section_list = module->GetSectionList();
1538254721Semaste        if (section_list)
1539254721Semaste        {
1540254721Semaste            strm.Printf ("Sections for '%s' (%s):\n",
1541254721Semaste                         module->GetSpecificationDescription().c_str(),
1542254721Semaste                         module->GetArchitecture().GetArchitectureName());
1543254721Semaste            strm.IndentMore();
1544254721Semaste            section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
1545254721Semaste            strm.IndentLess();
1546254721Semaste        }
1547254721Semaste    }
1548254721Semaste}
1549254721Semaste
1550254721Semastestatic bool
1551254721SemasteDumpModuleSymbolVendor (Stream &strm, Module *module)
1552254721Semaste{
1553254721Semaste    if (module)
1554254721Semaste    {
1555254721Semaste        SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1556254721Semaste        if (symbol_vendor)
1557254721Semaste        {
1558254721Semaste            symbol_vendor->Dump(&strm);
1559254721Semaste            return true;
1560254721Semaste        }
1561254721Semaste    }
1562254721Semaste    return false;
1563254721Semaste}
1564254721Semaste
1565254721Semastestatic void
1566254721SemasteDumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
1567254721Semaste{
1568254721Semaste    strm.IndentMore();
1569254721Semaste    strm.Indent ("    Address: ");
1570254721Semaste    so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1571254721Semaste    strm.PutCString (" (");
1572254721Semaste    so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1573254721Semaste    strm.PutCString (")\n");
1574254721Semaste    strm.Indent ("    Summary: ");
1575254721Semaste    const uint32_t save_indent = strm.GetIndentLevel ();
1576254721Semaste    strm.SetIndentLevel (save_indent + 13);
1577254721Semaste    so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1578254721Semaste    strm.SetIndentLevel (save_indent);
1579254721Semaste    // Print out detailed address information when verbose is enabled
1580254721Semaste    if (verbose)
1581254721Semaste    {
1582254721Semaste        strm.EOL();
1583254721Semaste        so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1584254721Semaste    }
1585254721Semaste    strm.IndentLess();
1586254721Semaste}
1587254721Semaste
1588254721Semastestatic bool
1589254721SemasteLookupAddressInModule (CommandInterpreter &interpreter,
1590254721Semaste                       Stream &strm,
1591254721Semaste                       Module *module,
1592254721Semaste                       uint32_t resolve_mask,
1593254721Semaste                       lldb::addr_t raw_addr,
1594254721Semaste                       lldb::addr_t offset,
1595254721Semaste                       bool verbose)
1596254721Semaste{
1597254721Semaste    if (module)
1598254721Semaste    {
1599254721Semaste        lldb::addr_t addr = raw_addr - offset;
1600254721Semaste        Address so_addr;
1601254721Semaste        SymbolContext sc;
1602254721Semaste        Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1603254721Semaste        if (target && !target->GetSectionLoadList().IsEmpty())
1604254721Semaste        {
1605254721Semaste            if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1606254721Semaste                return false;
1607254721Semaste            else if (so_addr.GetModule().get() != module)
1608254721Semaste                return false;
1609254721Semaste        }
1610254721Semaste        else
1611254721Semaste        {
1612254721Semaste            if (!module->ResolveFileAddress (addr, so_addr))
1613254721Semaste                return false;
1614254721Semaste        }
1615254721Semaste
1616254721Semaste        ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
1617254721Semaste        DumpAddress (exe_scope, so_addr, verbose, strm);
1618254721Semaste//        strm.IndentMore();
1619254721Semaste//        strm.Indent ("    Address: ");
1620254721Semaste//        so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1621254721Semaste//        strm.PutCString (" (");
1622254721Semaste//        so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1623254721Semaste//        strm.PutCString (")\n");
1624254721Semaste//        strm.Indent ("    Summary: ");
1625254721Semaste//        const uint32_t save_indent = strm.GetIndentLevel ();
1626254721Semaste//        strm.SetIndentLevel (save_indent + 13);
1627254721Semaste//        so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1628254721Semaste//        strm.SetIndentLevel (save_indent);
1629254721Semaste//        // Print out detailed address information when verbose is enabled
1630254721Semaste//        if (verbose)
1631254721Semaste//        {
1632254721Semaste//            strm.EOL();
1633254721Semaste//            so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1634254721Semaste//        }
1635254721Semaste//        strm.IndentLess();
1636254721Semaste        return true;
1637254721Semaste    }
1638254721Semaste
1639254721Semaste    return false;
1640254721Semaste}
1641254721Semaste
1642254721Semastestatic uint32_t
1643254721SemasteLookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
1644254721Semaste{
1645254721Semaste    if (module)
1646254721Semaste    {
1647254721Semaste        SymbolContext sc;
1648254721Semaste
1649254721Semaste        SymbolVendor *sym_vendor = module->GetSymbolVendor ();
1650254721Semaste        if (sym_vendor)
1651254721Semaste        {
1652254721Semaste            Symtab *symtab = sym_vendor->GetSymtab();
1653254721Semaste            if (symtab)
1654254721Semaste            {
1655254721Semaste                uint32_t i;
1656254721Semaste                std::vector<uint32_t> match_indexes;
1657254721Semaste                ConstString symbol_name (name);
1658254721Semaste                uint32_t num_matches = 0;
1659254721Semaste                if (name_is_regex)
1660254721Semaste                {
1661254721Semaste                    RegularExpression name_regexp(name);
1662254721Semaste                    num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1663254721Semaste                                                                                   eSymbolTypeAny,
1664254721Semaste                                                                                   match_indexes);
1665254721Semaste                }
1666254721Semaste                else
1667254721Semaste                {
1668254721Semaste                    num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1669254721Semaste                }
1670254721Semaste
1671254721Semaste
1672254721Semaste                if (num_matches > 0)
1673254721Semaste                {
1674254721Semaste                    strm.Indent ();
1675254721Semaste                    strm.Printf("%u symbols match %s'%s' in ", num_matches,
1676254721Semaste                                name_is_regex ? "the regular expression " : "", name);
1677254721Semaste                    DumpFullpath (strm, &module->GetFileSpec(), 0);
1678254721Semaste                    strm.PutCString(":\n");
1679254721Semaste                    strm.IndentMore ();
1680254721Semaste                    //Symtab::DumpSymbolHeader (&strm);
1681254721Semaste                    for (i=0; i < num_matches; ++i)
1682254721Semaste                    {
1683254721Semaste                        Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1684254721Semaste                        DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1685254721Semaste                                     symbol->GetAddress(),
1686254721Semaste                                     verbose,
1687254721Semaste                                     strm);
1688254721Semaste
1689254721Semaste//                        strm.Indent ();
1690254721Semaste//                        symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
1691254721Semaste                    }
1692254721Semaste                    strm.IndentLess ();
1693254721Semaste                    return num_matches;
1694254721Semaste                }
1695254721Semaste            }
1696254721Semaste        }
1697254721Semaste    }
1698254721Semaste    return 0;
1699254721Semaste}
1700254721Semaste
1701254721Semaste
1702254721Semastestatic void
1703254721SemasteDumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
1704254721Semaste{
1705254721Semaste    strm.IndentMore ();
1706254721Semaste    uint32_t i;
1707254721Semaste    const uint32_t num_matches = sc_list.GetSize();
1708254721Semaste
1709254721Semaste    for (i=0; i<num_matches; ++i)
1710254721Semaste    {
1711254721Semaste        SymbolContext sc;
1712254721Semaste        if (sc_list.GetContextAtIndex(i, sc))
1713254721Semaste        {
1714254721Semaste            AddressRange range;
1715254721Semaste
1716254721Semaste            sc.GetAddressRange(eSymbolContextEverything,
1717254721Semaste                               0,
1718254721Semaste                               true,
1719254721Semaste                               range);
1720254721Semaste
1721254721Semaste            DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm);
1722254721Semaste        }
1723254721Semaste    }
1724254721Semaste    strm.IndentLess ();
1725254721Semaste}
1726254721Semaste
1727254721Semastestatic size_t
1728254721SemasteLookupFunctionInModule (CommandInterpreter &interpreter,
1729254721Semaste                        Stream &strm,
1730254721Semaste                        Module *module,
1731254721Semaste                        const char *name,
1732254721Semaste                        bool name_is_regex,
1733254721Semaste                        bool include_inlines,
1734254721Semaste                        bool include_symbols,
1735254721Semaste                        bool verbose)
1736254721Semaste{
1737254721Semaste    if (module && name && name[0])
1738254721Semaste    {
1739254721Semaste        SymbolContextList sc_list;
1740254721Semaste        const bool append = true;
1741254721Semaste        size_t num_matches = 0;
1742254721Semaste        if (name_is_regex)
1743254721Semaste        {
1744254721Semaste            RegularExpression function_name_regex (name);
1745254721Semaste            num_matches = module->FindFunctions (function_name_regex,
1746254721Semaste                                                 include_symbols,
1747254721Semaste                                                 include_inlines,
1748254721Semaste                                                 append,
1749254721Semaste                                                 sc_list);
1750254721Semaste        }
1751254721Semaste        else
1752254721Semaste        {
1753254721Semaste            ConstString function_name (name);
1754254721Semaste            num_matches = module->FindFunctions (function_name,
1755254721Semaste                                                 NULL,
1756254721Semaste                                                 eFunctionNameTypeAuto,
1757254721Semaste                                                 include_symbols,
1758254721Semaste                                                 include_inlines,
1759254721Semaste                                                 append,
1760254721Semaste                                                 sc_list);
1761254721Semaste        }
1762254721Semaste
1763254721Semaste        if (num_matches)
1764254721Semaste        {
1765254721Semaste            strm.Indent ();
1766254721Semaste            strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1767254721Semaste            DumpFullpath (strm, &module->GetFileSpec(), 0);
1768254721Semaste            strm.PutCString(":\n");
1769254721Semaste            DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
1770254721Semaste        }
1771254721Semaste        return num_matches;
1772254721Semaste    }
1773254721Semaste    return 0;
1774254721Semaste}
1775254721Semaste
1776254721Semastestatic size_t
1777254721SemasteLookupTypeInModule (CommandInterpreter &interpreter,
1778254721Semaste                    Stream &strm,
1779254721Semaste                    Module *module,
1780254721Semaste                    const char *name_cstr,
1781254721Semaste                    bool name_is_regex)
1782254721Semaste{
1783254721Semaste    if (module && name_cstr && name_cstr[0])
1784254721Semaste    {
1785254721Semaste        TypeList type_list;
1786254721Semaste        const uint32_t max_num_matches = UINT32_MAX;
1787254721Semaste        size_t num_matches = 0;
1788254721Semaste        bool name_is_fully_qualified = false;
1789254721Semaste        SymbolContext sc;
1790254721Semaste
1791254721Semaste        ConstString name(name_cstr);
1792254721Semaste        num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list);
1793254721Semaste
1794254721Semaste        if (num_matches)
1795254721Semaste        {
1796254721Semaste            strm.Indent ();
1797254721Semaste            strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1798254721Semaste            DumpFullpath (strm, &module->GetFileSpec(), 0);
1799254721Semaste            strm.PutCString(":\n");
1800263367Semaste            for (TypeSP type_sp : type_list.Types())
1801254721Semaste            {
1802254721Semaste                if (type_sp)
1803254721Semaste                {
1804254721Semaste                    // Resolve the clang type so that any forward references
1805254721Semaste                    // to types that haven't yet been parsed will get parsed.
1806254721Semaste                    type_sp->GetClangFullType ();
1807254721Semaste                    type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1808254721Semaste                    // Print all typedef chains
1809254721Semaste                    TypeSP typedef_type_sp (type_sp);
1810254721Semaste                    TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1811254721Semaste                    while (typedefed_type_sp)
1812254721Semaste                    {
1813254721Semaste                        strm.EOL();
1814254721Semaste                        strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
1815254721Semaste                        typedefed_type_sp->GetClangFullType ();
1816254721Semaste                        typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1817254721Semaste                        typedef_type_sp = typedefed_type_sp;
1818254721Semaste                        typedefed_type_sp = typedef_type_sp->GetTypedefType();
1819254721Semaste                    }
1820254721Semaste                }
1821254721Semaste                strm.EOL();
1822254721Semaste            }
1823254721Semaste        }
1824254721Semaste        return num_matches;
1825254721Semaste    }
1826254721Semaste    return 0;
1827254721Semaste}
1828254721Semaste
1829254721Semastestatic size_t
1830254721SemasteLookupTypeHere (CommandInterpreter &interpreter,
1831254721Semaste                Stream &strm,
1832254721Semaste                const SymbolContext &sym_ctx,
1833254721Semaste                const char *name_cstr,
1834254721Semaste                bool name_is_regex)
1835254721Semaste{
1836254721Semaste    if (!sym_ctx.module_sp)
1837254721Semaste        return 0;
1838254721Semaste
1839254721Semaste    TypeList type_list;
1840254721Semaste    const uint32_t max_num_matches = UINT32_MAX;
1841254721Semaste    size_t num_matches = 1;
1842254721Semaste    bool name_is_fully_qualified = false;
1843254721Semaste
1844254721Semaste    ConstString name(name_cstr);
1845254721Semaste    num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list);
1846254721Semaste
1847254721Semaste    if (num_matches)
1848254721Semaste    {
1849254721Semaste        strm.Indent ();
1850254721Semaste        strm.PutCString("Best match found in ");
1851254721Semaste        DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1852254721Semaste        strm.PutCString(":\n");
1853254721Semaste
1854254721Semaste        TypeSP type_sp (type_list.GetTypeAtIndex(0));
1855254721Semaste        if (type_sp)
1856254721Semaste        {
1857254721Semaste            // Resolve the clang type so that any forward references
1858254721Semaste            // to types that haven't yet been parsed will get parsed.
1859254721Semaste            type_sp->GetClangFullType ();
1860254721Semaste            type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1861254721Semaste            // Print all typedef chains
1862254721Semaste            TypeSP typedef_type_sp (type_sp);
1863254721Semaste            TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1864254721Semaste            while (typedefed_type_sp)
1865254721Semaste            {
1866254721Semaste                strm.EOL();
1867254721Semaste                strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
1868254721Semaste                typedefed_type_sp->GetClangFullType ();
1869254721Semaste                typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1870254721Semaste                typedef_type_sp = typedefed_type_sp;
1871254721Semaste                typedefed_type_sp = typedef_type_sp->GetTypedefType();
1872254721Semaste            }
1873254721Semaste        }
1874254721Semaste        strm.EOL();
1875254721Semaste    }
1876254721Semaste    return num_matches;
1877254721Semaste}
1878254721Semaste
1879254721Semastestatic uint32_t
1880254721SemasteLookupFileAndLineInModule (CommandInterpreter &interpreter,
1881254721Semaste                           Stream &strm,
1882254721Semaste                           Module *module,
1883254721Semaste                           const FileSpec &file_spec,
1884254721Semaste                           uint32_t line,
1885254721Semaste                           bool check_inlines,
1886254721Semaste                           bool verbose)
1887254721Semaste{
1888254721Semaste    if (module && file_spec)
1889254721Semaste    {
1890254721Semaste        SymbolContextList sc_list;
1891254721Semaste        const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1892254721Semaste                                                                              eSymbolContextEverything, sc_list);
1893254721Semaste        if (num_matches > 0)
1894254721Semaste        {
1895254721Semaste            strm.Indent ();
1896254721Semaste            strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1897254721Semaste            strm << file_spec;
1898254721Semaste            if (line > 0)
1899254721Semaste                strm.Printf (":%u", line);
1900254721Semaste            strm << " in ";
1901254721Semaste            DumpFullpath (strm, &module->GetFileSpec(), 0);
1902254721Semaste            strm.PutCString(":\n");
1903254721Semaste            DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
1904254721Semaste            return num_matches;
1905254721Semaste        }
1906254721Semaste    }
1907254721Semaste    return 0;
1908254721Semaste
1909254721Semaste}
1910254721Semaste
1911254721Semaste
1912254721Semastestatic size_t
1913254721SemasteFindModulesByName (Target *target,
1914254721Semaste                   const char *module_name,
1915254721Semaste                   ModuleList &module_list,
1916254721Semaste                   bool check_global_list)
1917254721Semaste{
1918254721Semaste// Dump specified images (by basename or fullpath)
1919254721Semaste    FileSpec module_file_spec(module_name, false);
1920254721Semaste    ModuleSpec module_spec (module_file_spec);
1921254721Semaste
1922254721Semaste    const size_t initial_size = module_list.GetSize ();
1923254721Semaste
1924254721Semaste    if (check_global_list)
1925254721Semaste    {
1926254721Semaste        // Check the global list
1927254721Semaste        Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
1928254721Semaste        const size_t num_modules = Module::GetNumberAllocatedModules();
1929254721Semaste        ModuleSP module_sp;
1930254721Semaste        for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
1931254721Semaste        {
1932254721Semaste            Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1933254721Semaste
1934254721Semaste            if (module)
1935254721Semaste            {
1936254721Semaste                if (module->MatchesModuleSpec (module_spec))
1937254721Semaste                {
1938254721Semaste                    module_sp = module->shared_from_this();
1939254721Semaste                    module_list.AppendIfNeeded(module_sp);
1940254721Semaste                }
1941254721Semaste            }
1942254721Semaste        }
1943254721Semaste    }
1944254721Semaste    else
1945254721Semaste    {
1946254721Semaste        if (target)
1947254721Semaste        {
1948254721Semaste            const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);
1949254721Semaste
1950254721Semaste            // Not found in our module list for our target, check the main
1951254721Semaste            // shared module list in case it is a extra file used somewhere
1952254721Semaste            // else
1953254721Semaste            if (num_matches == 0)
1954254721Semaste            {
1955254721Semaste                module_spec.GetArchitecture() = target->GetArchitecture();
1956254721Semaste                ModuleList::FindSharedModules (module_spec, module_list);
1957254721Semaste            }
1958254721Semaste        }
1959254721Semaste        else
1960254721Semaste        {
1961254721Semaste            ModuleList::FindSharedModules (module_spec,module_list);
1962254721Semaste        }
1963254721Semaste    }
1964254721Semaste
1965254721Semaste    return module_list.GetSize () - initial_size;
1966254721Semaste}
1967254721Semaste
1968254721Semaste#pragma mark CommandObjectTargetModulesModuleAutoComplete
1969254721Semaste
1970254721Semaste//----------------------------------------------------------------------
1971254721Semaste// A base command object class that can auto complete with module file
1972254721Semaste// paths
1973254721Semaste//----------------------------------------------------------------------
1974254721Semaste
1975254721Semasteclass CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
1976254721Semaste{
1977254721Semastepublic:
1978254721Semaste
1979254721Semaste    CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1980254721Semaste                                      const char *name,
1981254721Semaste                                      const char *help,
1982254721Semaste                                      const char *syntax) :
1983254721Semaste        CommandObjectParsed (interpreter, name, help, syntax)
1984254721Semaste    {
1985254721Semaste        CommandArgumentEntry arg;
1986254721Semaste        CommandArgumentData file_arg;
1987254721Semaste
1988254721Semaste        // Define the first (and only) variant of this arg.
1989254721Semaste        file_arg.arg_type = eArgTypeFilename;
1990254721Semaste        file_arg.arg_repetition = eArgRepeatStar;
1991254721Semaste
1992254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
1993254721Semaste        arg.push_back (file_arg);
1994254721Semaste
1995254721Semaste        // Push the data for the first argument into the m_arguments vector.
1996254721Semaste        m_arguments.push_back (arg);
1997254721Semaste    }
1998254721Semaste
1999254721Semaste    virtual
2000254721Semaste    ~CommandObjectTargetModulesModuleAutoComplete ()
2001254721Semaste    {
2002254721Semaste    }
2003254721Semaste
2004254721Semaste    virtual int
2005254721Semaste    HandleArgumentCompletion (Args &input,
2006254721Semaste                              int &cursor_index,
2007254721Semaste                              int &cursor_char_position,
2008254721Semaste                              OptionElementVector &opt_element_vector,
2009254721Semaste                              int match_start_point,
2010254721Semaste                              int max_return_elements,
2011254721Semaste                              bool &word_complete,
2012254721Semaste                              StringList &matches)
2013254721Semaste    {
2014254721Semaste        // Arguments are the standard module completer.
2015254721Semaste        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2016254721Semaste        completion_str.erase (cursor_char_position);
2017254721Semaste
2018254721Semaste        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2019254721Semaste                                                             CommandCompletions::eModuleCompletion,
2020254721Semaste                                                             completion_str.c_str(),
2021254721Semaste                                                             match_start_point,
2022254721Semaste                                                             max_return_elements,
2023254721Semaste                                                             NULL,
2024254721Semaste                                                             word_complete,
2025254721Semaste                                                             matches);
2026254721Semaste        return matches.GetSize();
2027254721Semaste    }
2028254721Semaste};
2029254721Semaste
2030254721Semaste#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
2031254721Semaste
2032254721Semaste//----------------------------------------------------------------------
2033254721Semaste// A base command object class that can auto complete with module source
2034254721Semaste// file paths
2035254721Semaste//----------------------------------------------------------------------
2036254721Semaste
2037254721Semasteclass CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
2038254721Semaste{
2039254721Semastepublic:
2040254721Semaste
2041254721Semaste    CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
2042254721Semaste                                                      const char *name,
2043254721Semaste                                                      const char *help,
2044254721Semaste                                                      const char *syntax,
2045254721Semaste                                                      uint32_t flags) :
2046254721Semaste        CommandObjectParsed (interpreter, name, help, syntax, flags)
2047254721Semaste    {
2048254721Semaste        CommandArgumentEntry arg;
2049254721Semaste        CommandArgumentData source_file_arg;
2050254721Semaste
2051254721Semaste        // Define the first (and only) variant of this arg.
2052254721Semaste        source_file_arg.arg_type = eArgTypeSourceFile;
2053254721Semaste        source_file_arg.arg_repetition = eArgRepeatPlus;
2054254721Semaste
2055254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
2056254721Semaste        arg.push_back (source_file_arg);
2057254721Semaste
2058254721Semaste        // Push the data for the first argument into the m_arguments vector.
2059254721Semaste        m_arguments.push_back (arg);
2060254721Semaste    }
2061254721Semaste
2062254721Semaste    virtual
2063254721Semaste    ~CommandObjectTargetModulesSourceFileAutoComplete ()
2064254721Semaste    {
2065254721Semaste    }
2066254721Semaste
2067254721Semaste    virtual int
2068254721Semaste    HandleArgumentCompletion (Args &input,
2069254721Semaste                              int &cursor_index,
2070254721Semaste                              int &cursor_char_position,
2071254721Semaste                              OptionElementVector &opt_element_vector,
2072254721Semaste                              int match_start_point,
2073254721Semaste                              int max_return_elements,
2074254721Semaste                              bool &word_complete,
2075254721Semaste                              StringList &matches)
2076254721Semaste    {
2077254721Semaste        // Arguments are the standard source file completer.
2078254721Semaste        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2079254721Semaste        completion_str.erase (cursor_char_position);
2080254721Semaste
2081254721Semaste        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2082254721Semaste                                                             CommandCompletions::eSourceFileCompletion,
2083254721Semaste                                                             completion_str.c_str(),
2084254721Semaste                                                             match_start_point,
2085254721Semaste                                                             max_return_elements,
2086254721Semaste                                                             NULL,
2087254721Semaste                                                             word_complete,
2088254721Semaste                                                             matches);
2089254721Semaste        return matches.GetSize();
2090254721Semaste    }
2091254721Semaste};
2092254721Semaste
2093254721Semaste
2094254721Semaste#pragma mark CommandObjectTargetModulesDumpSymtab
2095254721Semaste
2096254721Semaste
2097254721Semasteclass CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
2098254721Semaste{
2099254721Semastepublic:
2100254721Semaste    CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
2101254721Semaste    CommandObjectTargetModulesModuleAutoComplete (interpreter,
2102254721Semaste                                      "target modules dump symtab",
2103254721Semaste                                      "Dump the symbol table from one or more target modules.",
2104254721Semaste                                      NULL),
2105254721Semaste    m_options (interpreter)
2106254721Semaste    {
2107254721Semaste    }
2108254721Semaste
2109254721Semaste    virtual
2110254721Semaste    ~CommandObjectTargetModulesDumpSymtab ()
2111254721Semaste    {
2112254721Semaste    }
2113254721Semaste
2114254721Semaste    virtual Options *
2115254721Semaste    GetOptions ()
2116254721Semaste    {
2117254721Semaste        return &m_options;
2118254721Semaste    }
2119254721Semaste
2120254721Semaste    class CommandOptions : public Options
2121254721Semaste    {
2122254721Semaste    public:
2123254721Semaste
2124254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
2125254721Semaste        Options(interpreter),
2126254721Semaste        m_sort_order (eSortOrderNone)
2127254721Semaste        {
2128254721Semaste        }
2129254721Semaste
2130254721Semaste        virtual
2131254721Semaste        ~CommandOptions ()
2132254721Semaste        {
2133254721Semaste        }
2134254721Semaste
2135254721Semaste        virtual Error
2136254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
2137254721Semaste        {
2138254721Semaste            Error error;
2139254721Semaste            const int short_option = m_getopt_table[option_idx].val;
2140254721Semaste
2141254721Semaste            switch (short_option)
2142254721Semaste            {
2143254721Semaste                case 's':
2144254721Semaste                    m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
2145254721Semaste                                                                         g_option_table[option_idx].enum_values,
2146254721Semaste                                                                         eSortOrderNone,
2147254721Semaste                                                                         error);
2148254721Semaste                    break;
2149254721Semaste
2150254721Semaste                default:
2151254721Semaste                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2152254721Semaste                    break;
2153254721Semaste
2154254721Semaste            }
2155254721Semaste            return error;
2156254721Semaste        }
2157254721Semaste
2158254721Semaste        void
2159254721Semaste        OptionParsingStarting ()
2160254721Semaste        {
2161254721Semaste            m_sort_order = eSortOrderNone;
2162254721Semaste        }
2163254721Semaste
2164254721Semaste        const OptionDefinition*
2165254721Semaste        GetDefinitions ()
2166254721Semaste        {
2167254721Semaste            return g_option_table;
2168254721Semaste        }
2169254721Semaste
2170254721Semaste        // Options table: Required for subclasses of Options.
2171254721Semaste        static OptionDefinition g_option_table[];
2172254721Semaste
2173254721Semaste        SortOrder m_sort_order;
2174254721Semaste    };
2175254721Semaste
2176254721Semasteprotected:
2177254721Semaste    virtual bool
2178254721Semaste    DoExecute (Args& command,
2179254721Semaste             CommandReturnObject &result)
2180254721Semaste    {
2181254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2182254721Semaste        if (target == NULL)
2183254721Semaste        {
2184254721Semaste            result.AppendError ("invalid target, create a debug target using the 'target create' command");
2185254721Semaste            result.SetStatus (eReturnStatusFailed);
2186254721Semaste            return false;
2187254721Semaste        }
2188254721Semaste        else
2189254721Semaste        {
2190254721Semaste            uint32_t num_dumped = 0;
2191254721Semaste
2192254721Semaste            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2193254721Semaste            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2194254721Semaste            result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2195254721Semaste
2196254721Semaste            if (command.GetArgumentCount() == 0)
2197254721Semaste            {
2198254721Semaste                // Dump all sections for all modules images
2199254721Semaste                Mutex::Locker modules_locker(target->GetImages().GetMutex());
2200254721Semaste                const size_t num_modules = target->GetImages().GetSize();
2201254721Semaste                if (num_modules > 0)
2202254721Semaste                {
2203254721Semaste                    result.GetOutputStream().Printf("Dumping symbol table for %zu modules.\n", num_modules);
2204254721Semaste                    for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
2205254721Semaste                    {
2206254721Semaste                        if (num_dumped > 0)
2207254721Semaste                        {
2208254721Semaste                            result.GetOutputStream().EOL();
2209254721Semaste                            result.GetOutputStream().EOL();
2210254721Semaste                        }
2211254721Semaste                        num_dumped++;
2212254721Semaste                        DumpModuleSymtab (m_interpreter,
2213254721Semaste                                          result.GetOutputStream(),
2214254721Semaste                                          target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2215254721Semaste                                          m_options.m_sort_order);
2216254721Semaste                    }
2217254721Semaste                }
2218254721Semaste                else
2219254721Semaste                {
2220254721Semaste                    result.AppendError ("the target has no associated executable images");
2221254721Semaste                    result.SetStatus (eReturnStatusFailed);
2222254721Semaste                    return false;
2223254721Semaste                }
2224254721Semaste            }
2225254721Semaste            else
2226254721Semaste            {
2227254721Semaste                // Dump specified images (by basename or fullpath)
2228254721Semaste                const char *arg_cstr;
2229254721Semaste                for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2230254721Semaste                {
2231254721Semaste                    ModuleList module_list;
2232254721Semaste                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2233254721Semaste                    if (num_matches > 0)
2234254721Semaste                    {
2235254721Semaste                        for (size_t i=0; i<num_matches; ++i)
2236254721Semaste                        {
2237254721Semaste                            Module *module = module_list.GetModulePointerAtIndex(i);
2238254721Semaste                            if (module)
2239254721Semaste                            {
2240254721Semaste                                if (num_dumped > 0)
2241254721Semaste                                {
2242254721Semaste                                    result.GetOutputStream().EOL();
2243254721Semaste                                    result.GetOutputStream().EOL();
2244254721Semaste                                }
2245254721Semaste                                num_dumped++;
2246254721Semaste                                DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
2247254721Semaste                            }
2248254721Semaste                        }
2249254721Semaste                    }
2250254721Semaste                    else
2251254721Semaste                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2252254721Semaste                }
2253254721Semaste            }
2254254721Semaste
2255254721Semaste            if (num_dumped > 0)
2256254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
2257254721Semaste            else
2258254721Semaste            {
2259254721Semaste                result.AppendError ("no matching executable images found");
2260254721Semaste                result.SetStatus (eReturnStatusFailed);
2261254721Semaste            }
2262254721Semaste        }
2263254721Semaste        return result.Succeeded();
2264254721Semaste    }
2265254721Semaste
2266254721Semaste
2267254721Semaste    CommandOptions m_options;
2268254721Semaste};
2269254721Semaste
2270254721Semastestatic OptionEnumValueElement
2271254721Semasteg_sort_option_enumeration[4] =
2272254721Semaste{
2273254721Semaste    { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
2274254721Semaste    { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
2275254721Semaste    { eSortOrderByName,     "name",     "Sort output by symbol name."},
2276254721Semaste    { 0,                    NULL,       NULL }
2277254721Semaste};
2278254721Semaste
2279254721Semaste
2280254721SemasteOptionDefinition
2281254721SemasteCommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2282254721Semaste{
2283263363Semaste    { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
2284254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2285254721Semaste};
2286254721Semaste
2287254721Semaste#pragma mark CommandObjectTargetModulesDumpSections
2288254721Semaste
2289254721Semaste//----------------------------------------------------------------------
2290254721Semaste// Image section dumping command
2291254721Semaste//----------------------------------------------------------------------
2292254721Semaste
2293254721Semasteclass CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2294254721Semaste{
2295254721Semastepublic:
2296254721Semaste    CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2297254721Semaste    CommandObjectTargetModulesModuleAutoComplete (interpreter,
2298254721Semaste                                      "target modules dump sections",
2299254721Semaste                                      "Dump the sections from one or more target modules.",
2300254721Semaste                                      //"target modules dump sections [<file1> ...]")
2301254721Semaste                                      NULL)
2302254721Semaste    {
2303254721Semaste    }
2304254721Semaste
2305254721Semaste    virtual
2306254721Semaste    ~CommandObjectTargetModulesDumpSections ()
2307254721Semaste    {
2308254721Semaste    }
2309254721Semaste
2310254721Semasteprotected:
2311254721Semaste    virtual bool
2312254721Semaste    DoExecute (Args& command,
2313254721Semaste             CommandReturnObject &result)
2314254721Semaste    {
2315254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2316254721Semaste        if (target == NULL)
2317254721Semaste        {
2318254721Semaste            result.AppendError ("invalid target, create a debug target using the 'target create' command");
2319254721Semaste            result.SetStatus (eReturnStatusFailed);
2320254721Semaste            return false;
2321254721Semaste        }
2322254721Semaste        else
2323254721Semaste        {
2324254721Semaste            uint32_t num_dumped = 0;
2325254721Semaste
2326254721Semaste            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2327254721Semaste            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2328254721Semaste            result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2329254721Semaste
2330254721Semaste            if (command.GetArgumentCount() == 0)
2331254721Semaste            {
2332254721Semaste                // Dump all sections for all modules images
2333254721Semaste                const size_t num_modules = target->GetImages().GetSize();
2334254721Semaste                if (num_modules > 0)
2335254721Semaste                {
2336254721Semaste                    result.GetOutputStream().Printf("Dumping sections for %zu modules.\n", num_modules);
2337254721Semaste                    for (size_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2338254721Semaste                    {
2339254721Semaste                        num_dumped++;
2340254721Semaste                        DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2341254721Semaste                    }
2342254721Semaste                }
2343254721Semaste                else
2344254721Semaste                {
2345254721Semaste                    result.AppendError ("the target has no associated executable images");
2346254721Semaste                    result.SetStatus (eReturnStatusFailed);
2347254721Semaste                    return false;
2348254721Semaste                }
2349254721Semaste            }
2350254721Semaste            else
2351254721Semaste            {
2352254721Semaste                // Dump specified images (by basename or fullpath)
2353254721Semaste                const char *arg_cstr;
2354254721Semaste                for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2355254721Semaste                {
2356254721Semaste                    ModuleList module_list;
2357254721Semaste                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2358254721Semaste                    if (num_matches > 0)
2359254721Semaste                    {
2360254721Semaste                        for (size_t i=0; i<num_matches; ++i)
2361254721Semaste                        {
2362254721Semaste                            Module *module = module_list.GetModulePointerAtIndex(i);
2363254721Semaste                            if (module)
2364254721Semaste                            {
2365254721Semaste                                num_dumped++;
2366254721Semaste                                DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
2367254721Semaste                            }
2368254721Semaste                        }
2369254721Semaste                    }
2370254721Semaste                    else
2371254721Semaste                    {
2372254721Semaste                        // Check the global list
2373254721Semaste                        Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
2374254721Semaste
2375254721Semaste                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2376254721Semaste                    }
2377254721Semaste                }
2378254721Semaste            }
2379254721Semaste
2380254721Semaste            if (num_dumped > 0)
2381254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
2382254721Semaste            else
2383254721Semaste            {
2384254721Semaste                result.AppendError ("no matching executable images found");
2385254721Semaste                result.SetStatus (eReturnStatusFailed);
2386254721Semaste            }
2387254721Semaste        }
2388254721Semaste        return result.Succeeded();
2389254721Semaste    }
2390254721Semaste};
2391254721Semaste
2392254721Semaste
2393254721Semaste#pragma mark CommandObjectTargetModulesDumpSymfile
2394254721Semaste
2395254721Semaste//----------------------------------------------------------------------
2396254721Semaste// Image debug symbol dumping command
2397254721Semaste//----------------------------------------------------------------------
2398254721Semaste
2399254721Semasteclass CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2400254721Semaste{
2401254721Semastepublic:
2402254721Semaste    CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2403254721Semaste    CommandObjectTargetModulesModuleAutoComplete (interpreter,
2404254721Semaste                                      "target modules dump symfile",
2405254721Semaste                                      "Dump the debug symbol file for one or more target modules.",
2406254721Semaste                                      //"target modules dump symfile [<file1> ...]")
2407254721Semaste                                      NULL)
2408254721Semaste    {
2409254721Semaste    }
2410254721Semaste
2411254721Semaste    virtual
2412254721Semaste    ~CommandObjectTargetModulesDumpSymfile ()
2413254721Semaste    {
2414254721Semaste    }
2415254721Semaste
2416254721Semasteprotected:
2417254721Semaste    virtual bool
2418254721Semaste    DoExecute (Args& command,
2419254721Semaste             CommandReturnObject &result)
2420254721Semaste    {
2421254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2422254721Semaste        if (target == NULL)
2423254721Semaste        {
2424254721Semaste            result.AppendError ("invalid target, create a debug target using the 'target create' command");
2425254721Semaste            result.SetStatus (eReturnStatusFailed);
2426254721Semaste            return false;
2427254721Semaste        }
2428254721Semaste        else
2429254721Semaste        {
2430254721Semaste            uint32_t num_dumped = 0;
2431254721Semaste
2432254721Semaste            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2433254721Semaste            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2434254721Semaste            result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2435254721Semaste
2436254721Semaste            if (command.GetArgumentCount() == 0)
2437254721Semaste            {
2438254721Semaste                // Dump all sections for all modules images
2439254721Semaste                const ModuleList &target_modules = target->GetImages();
2440254721Semaste                Mutex::Locker modules_locker (target_modules.GetMutex());
2441254721Semaste                const size_t num_modules = target_modules.GetSize();
2442254721Semaste                if (num_modules > 0)
2443254721Semaste                {
2444254721Semaste                    result.GetOutputStream().Printf("Dumping debug symbols for %zu modules.\n", num_modules);
2445254721Semaste                    for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2446254721Semaste                    {
2447254721Semaste                        if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2448254721Semaste                            num_dumped++;
2449254721Semaste                    }
2450254721Semaste                }
2451254721Semaste                else
2452254721Semaste                {
2453254721Semaste                    result.AppendError ("the target has no associated executable images");
2454254721Semaste                    result.SetStatus (eReturnStatusFailed);
2455254721Semaste                    return false;
2456254721Semaste                }
2457254721Semaste            }
2458254721Semaste            else
2459254721Semaste            {
2460254721Semaste                // Dump specified images (by basename or fullpath)
2461254721Semaste                const char *arg_cstr;
2462254721Semaste                for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2463254721Semaste                {
2464254721Semaste                    ModuleList module_list;
2465254721Semaste                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2466254721Semaste                    if (num_matches > 0)
2467254721Semaste                    {
2468254721Semaste                        for (size_t i=0; i<num_matches; ++i)
2469254721Semaste                        {
2470254721Semaste                            Module *module = module_list.GetModulePointerAtIndex(i);
2471254721Semaste                            if (module)
2472254721Semaste                            {
2473254721Semaste                                if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
2474254721Semaste                                    num_dumped++;
2475254721Semaste                            }
2476254721Semaste                        }
2477254721Semaste                    }
2478254721Semaste                    else
2479254721Semaste                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2480254721Semaste                }
2481254721Semaste            }
2482254721Semaste
2483254721Semaste            if (num_dumped > 0)
2484254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
2485254721Semaste            else
2486254721Semaste            {
2487254721Semaste                result.AppendError ("no matching executable images found");
2488254721Semaste                result.SetStatus (eReturnStatusFailed);
2489254721Semaste            }
2490254721Semaste        }
2491254721Semaste        return result.Succeeded();
2492254721Semaste    }
2493254721Semaste};
2494254721Semaste
2495254721Semaste
2496254721Semaste#pragma mark CommandObjectTargetModulesDumpLineTable
2497254721Semaste
2498254721Semaste//----------------------------------------------------------------------
2499254721Semaste// Image debug line table dumping command
2500254721Semaste//----------------------------------------------------------------------
2501254721Semaste
2502254721Semasteclass CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2503254721Semaste{
2504254721Semastepublic:
2505254721Semaste    CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2506254721Semaste    CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2507254721Semaste                                                      "target modules dump line-table",
2508254721Semaste                                                      "Dump the line table for one or more compilation units.",
2509254721Semaste                                                      NULL,
2510254721Semaste                                                      eFlagRequiresTarget)
2511254721Semaste    {
2512254721Semaste    }
2513254721Semaste
2514254721Semaste    virtual
2515254721Semaste    ~CommandObjectTargetModulesDumpLineTable ()
2516254721Semaste    {
2517254721Semaste    }
2518254721Semaste
2519254721Semasteprotected:
2520254721Semaste    virtual bool
2521254721Semaste    DoExecute (Args& command,
2522254721Semaste             CommandReturnObject &result)
2523254721Semaste    {
2524254721Semaste        Target *target = m_exe_ctx.GetTargetPtr();
2525254721Semaste        uint32_t total_num_dumped = 0;
2526254721Semaste
2527254721Semaste        uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2528254721Semaste        result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2529254721Semaste        result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2530254721Semaste
2531254721Semaste        if (command.GetArgumentCount() == 0)
2532254721Semaste        {
2533254721Semaste            result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2534254721Semaste            result.SetStatus (eReturnStatusFailed);
2535254721Semaste        }
2536254721Semaste        else
2537254721Semaste        {
2538254721Semaste            // Dump specified images (by basename or fullpath)
2539254721Semaste            const char *arg_cstr;
2540254721Semaste            for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2541254721Semaste            {
2542254721Semaste                FileSpec file_spec(arg_cstr, false);
2543254721Semaste
2544254721Semaste                const ModuleList &target_modules = target->GetImages();
2545254721Semaste                Mutex::Locker modules_locker(target_modules.GetMutex());
2546254721Semaste                const size_t num_modules = target_modules.GetSize();
2547254721Semaste                if (num_modules > 0)
2548254721Semaste                {
2549254721Semaste                    uint32_t num_dumped = 0;
2550254721Semaste                    for (uint32_t i = 0; i<num_modules; ++i)
2551254721Semaste                    {
2552254721Semaste                        if (DumpCompileUnitLineTable (m_interpreter,
2553254721Semaste                                                      result.GetOutputStream(),
2554254721Semaste                                                      target_modules.GetModulePointerAtIndexUnlocked(i),
2555254721Semaste                                                      file_spec,
2556254721Semaste                                                      m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
2557254721Semaste                            num_dumped++;
2558254721Semaste                    }
2559254721Semaste                    if (num_dumped == 0)
2560254721Semaste                        result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2561254721Semaste                    else
2562254721Semaste                        total_num_dumped += num_dumped;
2563254721Semaste                }
2564254721Semaste            }
2565254721Semaste        }
2566254721Semaste
2567254721Semaste        if (total_num_dumped > 0)
2568254721Semaste            result.SetStatus (eReturnStatusSuccessFinishResult);
2569254721Semaste        else
2570254721Semaste        {
2571254721Semaste            result.AppendError ("no source filenames matched any command arguments");
2572254721Semaste            result.SetStatus (eReturnStatusFailed);
2573254721Semaste        }
2574254721Semaste        return result.Succeeded();
2575254721Semaste    }
2576254721Semaste};
2577254721Semaste
2578254721Semaste
2579254721Semaste#pragma mark CommandObjectTargetModulesDump
2580254721Semaste
2581254721Semaste//----------------------------------------------------------------------
2582254721Semaste// Dump multi-word command for target modules
2583254721Semaste//----------------------------------------------------------------------
2584254721Semaste
2585254721Semasteclass CommandObjectTargetModulesDump : public CommandObjectMultiword
2586254721Semaste{
2587254721Semastepublic:
2588254721Semaste
2589254721Semaste    //------------------------------------------------------------------
2590254721Semaste    // Constructors and Destructors
2591254721Semaste    //------------------------------------------------------------------
2592254721Semaste    CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2593254721Semaste    CommandObjectMultiword (interpreter,
2594254721Semaste                            "target modules dump",
2595254721Semaste                            "A set of commands for dumping information about one or more target modules.",
2596254721Semaste                            "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2597254721Semaste    {
2598254721Semaste        LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2599254721Semaste        LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2600254721Semaste        LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2601254721Semaste        LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2602254721Semaste    }
2603254721Semaste
2604254721Semaste    virtual
2605254721Semaste    ~CommandObjectTargetModulesDump()
2606254721Semaste    {
2607254721Semaste    }
2608254721Semaste};
2609254721Semaste
2610254721Semasteclass CommandObjectTargetModulesAdd : public CommandObjectParsed
2611254721Semaste{
2612254721Semastepublic:
2613254721Semaste    CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2614254721Semaste        CommandObjectParsed (interpreter,
2615254721Semaste                             "target modules add",
2616254721Semaste                             "Add a new module to the current target's modules.",
2617254721Semaste                             "target modules add [<module>]"),
2618254721Semaste        m_option_group (interpreter),
2619254721Semaste        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.")
2620254721Semaste    {
2621254721Semaste        m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2622254721Semaste        m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2623254721Semaste        m_option_group.Finalize();
2624254721Semaste    }
2625254721Semaste
2626254721Semaste    virtual
2627254721Semaste    ~CommandObjectTargetModulesAdd ()
2628254721Semaste    {
2629254721Semaste    }
2630254721Semaste
2631254721Semaste    virtual Options *
2632254721Semaste    GetOptions ()
2633254721Semaste    {
2634254721Semaste        return &m_option_group;
2635254721Semaste    }
2636254721Semaste
2637254721Semaste    virtual int
2638254721Semaste    HandleArgumentCompletion (Args &input,
2639254721Semaste                              int &cursor_index,
2640254721Semaste                              int &cursor_char_position,
2641254721Semaste                              OptionElementVector &opt_element_vector,
2642254721Semaste                              int match_start_point,
2643254721Semaste                              int max_return_elements,
2644254721Semaste                              bool &word_complete,
2645254721Semaste                              StringList &matches)
2646254721Semaste    {
2647254721Semaste        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2648254721Semaste        completion_str.erase (cursor_char_position);
2649254721Semaste
2650254721Semaste        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2651254721Semaste                                                             CommandCompletions::eDiskFileCompletion,
2652254721Semaste                                                             completion_str.c_str(),
2653254721Semaste                                                             match_start_point,
2654254721Semaste                                                             max_return_elements,
2655254721Semaste                                                             NULL,
2656254721Semaste                                                             word_complete,
2657254721Semaste                                                             matches);
2658254721Semaste        return matches.GetSize();
2659254721Semaste    }
2660254721Semaste
2661254721Semasteprotected:
2662254721Semaste
2663254721Semaste    OptionGroupOptions m_option_group;
2664254721Semaste    OptionGroupUUID m_uuid_option_group;
2665254721Semaste    OptionGroupFile m_symbol_file;
2666254721Semaste
2667254721Semaste
2668254721Semaste    virtual bool
2669254721Semaste    DoExecute (Args& args,
2670254721Semaste             CommandReturnObject &result)
2671254721Semaste    {
2672254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2673254721Semaste        if (target == NULL)
2674254721Semaste        {
2675254721Semaste            result.AppendError ("invalid target, create a debug target using the 'target create' command");
2676254721Semaste            result.SetStatus (eReturnStatusFailed);
2677254721Semaste            return false;
2678254721Semaste        }
2679254721Semaste        else
2680254721Semaste        {
2681254721Semaste            bool flush = false;
2682254721Semaste
2683254721Semaste            const size_t argc = args.GetArgumentCount();
2684254721Semaste            if (argc == 0)
2685254721Semaste            {
2686254721Semaste                if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2687254721Semaste                {
2688254721Semaste                    // We are given a UUID only, go locate the file
2689254721Semaste                    ModuleSpec module_spec;
2690254721Semaste                    module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2691254721Semaste                    if (m_symbol_file.GetOptionValue().OptionWasSet())
2692254721Semaste                        module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2693254721Semaste                    if (Symbols::DownloadObjectAndSymbolFile (module_spec))
2694254721Semaste                    {
2695254721Semaste                        ModuleSP module_sp (target->GetSharedModule (module_spec));
2696254721Semaste                        if (module_sp)
2697254721Semaste                        {
2698254721Semaste                            result.SetStatus (eReturnStatusSuccessFinishResult);
2699254721Semaste                            return true;
2700254721Semaste                        }
2701254721Semaste                        else
2702254721Semaste                        {
2703254721Semaste                            flush = true;
2704254721Semaste
2705254721Semaste                            StreamString strm;
2706254721Semaste                            module_spec.GetUUID().Dump (&strm);
2707254721Semaste                            if (module_spec.GetFileSpec())
2708254721Semaste                            {
2709254721Semaste                                if (module_spec.GetSymbolFileSpec())
2710254721Semaste                                {
2711254721Semaste                                    result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s",
2712254721Semaste                                                                  strm.GetString().c_str(),
2713254721Semaste                                                                  module_spec.GetFileSpec().GetPath().c_str(),
2714254721Semaste                                                                  module_spec.GetSymbolFileSpec().GetPath().c_str());
2715254721Semaste                                }
2716254721Semaste                                else
2717254721Semaste                                {
2718254721Semaste                                    result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s",
2719254721Semaste                                                                  strm.GetString().c_str(),
2720254721Semaste                                                                  module_spec.GetFileSpec().GetPath().c_str());
2721254721Semaste                                }
2722254721Semaste                            }
2723254721Semaste                            else
2724254721Semaste                            {
2725254721Semaste                                result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
2726254721Semaste                                                              strm.GetString().c_str());
2727254721Semaste                            }
2728254721Semaste                            result.SetStatus (eReturnStatusFailed);
2729254721Semaste                            return false;
2730254721Semaste                        }
2731254721Semaste                    }
2732254721Semaste                    else
2733254721Semaste                    {
2734254721Semaste                        StreamString strm;
2735254721Semaste                        module_spec.GetUUID().Dump (&strm);
2736254721Semaste                        result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
2737254721Semaste                        result.SetStatus (eReturnStatusFailed);
2738254721Semaste                        return false;
2739254721Semaste                    }
2740254721Semaste                }
2741254721Semaste                else
2742254721Semaste                {
2743254721Semaste                    result.AppendError ("one or more executable image paths must be specified");
2744254721Semaste                    result.SetStatus (eReturnStatusFailed);
2745254721Semaste                    return false;
2746254721Semaste                }
2747254721Semaste            }
2748254721Semaste            else
2749254721Semaste            {
2750254721Semaste                for (size_t i=0; i<argc; ++i)
2751254721Semaste                {
2752254721Semaste                    const char *path = args.GetArgumentAtIndex(i);
2753254721Semaste                    if (path)
2754254721Semaste                    {
2755254721Semaste                        FileSpec file_spec(path, true);
2756254721Semaste                        if (file_spec.Exists())
2757254721Semaste                        {
2758254721Semaste                            ModuleSpec module_spec (file_spec);
2759254721Semaste                            if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2760254721Semaste                                module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2761254721Semaste                            if (m_symbol_file.GetOptionValue().OptionWasSet())
2762254721Semaste                                module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2763263363Semaste                            if (!module_spec.GetArchitecture().IsValid())
2764263363Semaste                                module_spec.GetArchitecture() = target->GetArchitecture();
2765254721Semaste                            Error error;
2766254721Semaste                            ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
2767254721Semaste                            if (!module_sp)
2768254721Semaste                            {
2769254721Semaste                                const char *error_cstr = error.AsCString();
2770254721Semaste                                if (error_cstr)
2771254721Semaste                                    result.AppendError (error_cstr);
2772254721Semaste                                else
2773254721Semaste                                    result.AppendErrorWithFormat ("unsupported module: %s", path);
2774254721Semaste                                result.SetStatus (eReturnStatusFailed);
2775254721Semaste                                return false;
2776254721Semaste                            }
2777254721Semaste                            else
2778254721Semaste                            {
2779254721Semaste                                flush = true;
2780254721Semaste                            }
2781254721Semaste                            result.SetStatus (eReturnStatusSuccessFinishResult);
2782254721Semaste                        }
2783254721Semaste                        else
2784254721Semaste                        {
2785254721Semaste                            char resolved_path[PATH_MAX];
2786254721Semaste                            result.SetStatus (eReturnStatusFailed);
2787254721Semaste                            if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2788254721Semaste                            {
2789254721Semaste                                if (strcmp (resolved_path, path) != 0)
2790254721Semaste                                {
2791254721Semaste                                    result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2792254721Semaste                                    break;
2793254721Semaste                                }
2794254721Semaste                            }
2795254721Semaste                            result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2796254721Semaste                            break;
2797254721Semaste                        }
2798254721Semaste                    }
2799254721Semaste                }
2800254721Semaste            }
2801254721Semaste
2802254721Semaste            if (flush)
2803254721Semaste            {
2804254721Semaste                ProcessSP process = target->GetProcessSP();
2805254721Semaste                if (process)
2806254721Semaste                    process->Flush();
2807254721Semaste            }
2808254721Semaste        }
2809254721Semaste
2810254721Semaste        return result.Succeeded();
2811254721Semaste    }
2812254721Semaste
2813254721Semaste};
2814254721Semaste
2815254721Semasteclass CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2816254721Semaste{
2817254721Semastepublic:
2818254721Semaste    CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2819254721Semaste        CommandObjectTargetModulesModuleAutoComplete (interpreter,
2820254721Semaste                                                      "target modules load",
2821254721Semaste                                                      "Set the load addresses for one or more sections in a target module.",
2822254721Semaste                                                      "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2823254721Semaste        m_option_group (interpreter),
2824254721Semaste        m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeFilename, "Fullpath or basename for module to load."),
2825254721Semaste        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)
2826254721Semaste    {
2827254721Semaste        m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2828254721Semaste        m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2829254721Semaste        m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2830254721Semaste        m_option_group.Finalize();
2831254721Semaste    }
2832254721Semaste
2833254721Semaste    virtual
2834254721Semaste    ~CommandObjectTargetModulesLoad ()
2835254721Semaste    {
2836254721Semaste    }
2837254721Semaste
2838254721Semaste    virtual Options *
2839254721Semaste    GetOptions ()
2840254721Semaste    {
2841254721Semaste        return &m_option_group;
2842254721Semaste    }
2843254721Semaste
2844254721Semasteprotected:
2845254721Semaste    virtual bool
2846254721Semaste    DoExecute (Args& args,
2847254721Semaste             CommandReturnObject &result)
2848254721Semaste    {
2849254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2850254721Semaste        if (target == NULL)
2851254721Semaste        {
2852254721Semaste            result.AppendError ("invalid target, create a debug target using the 'target create' command");
2853254721Semaste            result.SetStatus (eReturnStatusFailed);
2854254721Semaste            return false;
2855254721Semaste        }
2856254721Semaste        else
2857254721Semaste        {
2858254721Semaste            const size_t argc = args.GetArgumentCount();
2859254721Semaste            ModuleSpec module_spec;
2860254721Semaste            bool search_using_module_spec = false;
2861254721Semaste            if (m_file_option.GetOptionValue().OptionWasSet())
2862254721Semaste            {
2863254721Semaste                search_using_module_spec = true;
2864254721Semaste                module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
2865254721Semaste            }
2866254721Semaste
2867254721Semaste            if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2868254721Semaste            {
2869254721Semaste                search_using_module_spec = true;
2870254721Semaste                module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
2871254721Semaste            }
2872254721Semaste
2873254721Semaste            if (search_using_module_spec)
2874254721Semaste            {
2875254721Semaste
2876254721Semaste                ModuleList matching_modules;
2877254721Semaste                const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
2878254721Semaste
2879254721Semaste                char path[PATH_MAX];
2880254721Semaste                if (num_matches == 1)
2881254721Semaste                {
2882254721Semaste                    Module *module = matching_modules.GetModulePointerAtIndex(0);
2883254721Semaste                    if (module)
2884254721Semaste                    {
2885254721Semaste                        ObjectFile *objfile = module->GetObjectFile();
2886254721Semaste                        if (objfile)
2887254721Semaste                        {
2888254721Semaste                            SectionList *section_list = module->GetSectionList();
2889254721Semaste                            if (section_list)
2890254721Semaste                            {
2891254721Semaste                                bool changed = false;
2892254721Semaste                                if (argc == 0)
2893254721Semaste                                {
2894254721Semaste                                    if (m_slide_option.GetOptionValue().OptionWasSet())
2895254721Semaste                                    {
2896254721Semaste                                        const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2897269024Semaste                                        const bool slide_is_offset = true;
2898269024Semaste                                        module->SetLoadAddress (*target, slide, slide_is_offset, changed);
2899254721Semaste                                    }
2900254721Semaste                                    else
2901254721Semaste                                    {
2902254721Semaste                                        result.AppendError ("one or more section name + load address pair must be specified");
2903254721Semaste                                        result.SetStatus (eReturnStatusFailed);
2904254721Semaste                                        return false;
2905254721Semaste                                    }
2906254721Semaste                                }
2907254721Semaste                                else
2908254721Semaste                                {
2909254721Semaste                                    if (m_slide_option.GetOptionValue().OptionWasSet())
2910254721Semaste                                    {
2911254721Semaste                                        result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2912254721Semaste                                        result.SetStatus (eReturnStatusFailed);
2913254721Semaste                                        return false;
2914254721Semaste                                    }
2915254721Semaste
2916254721Semaste                                    for (size_t i=0; i<argc; i += 2)
2917254721Semaste                                    {
2918254721Semaste                                        const char *sect_name = args.GetArgumentAtIndex(i);
2919254721Semaste                                        const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2920254721Semaste                                        if (sect_name && load_addr_cstr)
2921254721Semaste                                        {
2922254721Semaste                                            ConstString const_sect_name(sect_name);
2923254721Semaste                                            bool success = false;
2924254721Semaste                                            addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2925254721Semaste                                            if (success)
2926254721Semaste                                            {
2927254721Semaste                                                SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2928254721Semaste                                                if (section_sp)
2929254721Semaste                                                {
2930254721Semaste                                                    if (section_sp->IsThreadSpecific())
2931254721Semaste                                                    {
2932254721Semaste                                                        result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
2933254721Semaste                                                        result.SetStatus (eReturnStatusFailed);
2934254721Semaste                                                        break;
2935254721Semaste                                                    }
2936254721Semaste                                                    else
2937254721Semaste                                                    {
2938254721Semaste                                                        if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
2939254721Semaste                                                            changed = true;
2940254721Semaste                                                        result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
2941254721Semaste                                                    }
2942254721Semaste                                                }
2943254721Semaste                                                else
2944254721Semaste                                                {
2945254721Semaste                                                    result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2946254721Semaste                                                    result.SetStatus (eReturnStatusFailed);
2947254721Semaste                                                    break;
2948254721Semaste                                                }
2949254721Semaste                                            }
2950254721Semaste                                            else
2951254721Semaste                                            {
2952254721Semaste                                                result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2953254721Semaste                                                result.SetStatus (eReturnStatusFailed);
2954254721Semaste                                                break;
2955254721Semaste                                            }
2956254721Semaste                                        }
2957254721Semaste                                        else
2958254721Semaste                                        {
2959254721Semaste                                            if (sect_name)
2960254721Semaste                                                result.AppendError ("section names must be followed by a load address.\n");
2961254721Semaste                                            else
2962254721Semaste                                                result.AppendError ("one or more section name + load address pair must be specified.\n");
2963254721Semaste                                            result.SetStatus (eReturnStatusFailed);
2964254721Semaste                                            break;
2965254721Semaste                                        }
2966254721Semaste                                    }
2967254721Semaste                                }
2968254721Semaste
2969254721Semaste                                if (changed)
2970254721Semaste                                {
2971254721Semaste                                    target->ModulesDidLoad (matching_modules);
2972254721Semaste                                    Process *process = m_exe_ctx.GetProcessPtr();
2973254721Semaste                                    if (process)
2974254721Semaste                                        process->Flush();
2975254721Semaste                                }
2976254721Semaste                            }
2977254721Semaste                            else
2978254721Semaste                            {
2979254721Semaste                                module->GetFileSpec().GetPath (path, sizeof(path));
2980254721Semaste                                result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2981254721Semaste                                result.SetStatus (eReturnStatusFailed);
2982254721Semaste                            }
2983254721Semaste                        }
2984254721Semaste                        else
2985254721Semaste                        {
2986254721Semaste                            module->GetFileSpec().GetPath (path, sizeof(path));
2987254721Semaste                            result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2988254721Semaste                            result.SetStatus (eReturnStatusFailed);
2989254721Semaste                        }
2990254721Semaste                    }
2991254721Semaste                    else
2992254721Semaste                    {
2993254721Semaste                        FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2994254721Semaste                        if (module_spec_file)
2995254721Semaste                        {
2996254721Semaste                            module_spec_file->GetPath (path, sizeof(path));
2997254721Semaste                            result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2998254721Semaste                        }
2999254721Semaste                        else
3000254721Semaste                            result.AppendError ("no module spec");
3001254721Semaste                        result.SetStatus (eReturnStatusFailed);
3002254721Semaste                    }
3003254721Semaste                }
3004254721Semaste                else
3005254721Semaste                {
3006254721Semaste                    std::string uuid_str;
3007254721Semaste
3008254721Semaste                    if (module_spec.GetFileSpec())
3009254721Semaste                        module_spec.GetFileSpec().GetPath (path, sizeof(path));
3010254721Semaste                    else
3011254721Semaste                        path[0] = '\0';
3012254721Semaste
3013254721Semaste                    if (module_spec.GetUUIDPtr())
3014254721Semaste                        uuid_str = module_spec.GetUUID().GetAsString();
3015254721Semaste                    if (num_matches > 1)
3016254721Semaste                    {
3017254721Semaste                        result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
3018254721Semaste                                                      path[0] ? " file=" : "",
3019254721Semaste                                                      path,
3020254721Semaste                                                      !uuid_str.empty() ? " uuid=" : "",
3021254721Semaste                                                      uuid_str.c_str());
3022254721Semaste                        for (size_t i=0; i<num_matches; ++i)
3023254721Semaste                        {
3024254721Semaste                            if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
3025254721Semaste                                result.AppendMessageWithFormat("%s\n", path);
3026254721Semaste                        }
3027254721Semaste                    }
3028254721Semaste                    else
3029254721Semaste                    {
3030254721Semaste                        result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
3031254721Semaste                                                      path[0] ? " file=" : "",
3032254721Semaste                                                      path,
3033254721Semaste                                                      !uuid_str.empty() ? " uuid=" : "",
3034254721Semaste                                                      uuid_str.c_str());
3035254721Semaste                    }
3036254721Semaste                    result.SetStatus (eReturnStatusFailed);
3037254721Semaste                }
3038254721Semaste            }
3039254721Semaste            else
3040254721Semaste            {
3041254721Semaste                result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
3042254721Semaste                result.SetStatus (eReturnStatusFailed);
3043254721Semaste                return false;
3044254721Semaste            }
3045254721Semaste        }
3046254721Semaste        return result.Succeeded();
3047254721Semaste    }
3048254721Semaste
3049254721Semaste    OptionGroupOptions m_option_group;
3050254721Semaste    OptionGroupUUID m_uuid_option_group;
3051254721Semaste    OptionGroupFile m_file_option;
3052254721Semaste    OptionGroupUInt64 m_slide_option;
3053254721Semaste};
3054254721Semaste
3055254721Semaste//----------------------------------------------------------------------
3056254721Semaste// List images with associated information
3057254721Semaste//----------------------------------------------------------------------
3058254721Semasteclass CommandObjectTargetModulesList : public CommandObjectParsed
3059254721Semaste{
3060254721Semastepublic:
3061254721Semaste
3062254721Semaste    class CommandOptions : public Options
3063254721Semaste    {
3064254721Semaste    public:
3065254721Semaste
3066254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3067254721Semaste            Options(interpreter),
3068254721Semaste            m_format_array(),
3069254721Semaste            m_use_global_module_list (false),
3070254721Semaste            m_module_addr (LLDB_INVALID_ADDRESS)
3071254721Semaste        {
3072254721Semaste        }
3073254721Semaste
3074254721Semaste        virtual
3075254721Semaste        ~CommandOptions ()
3076254721Semaste        {
3077254721Semaste        }
3078254721Semaste
3079254721Semaste        virtual Error
3080254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3081254721Semaste        {
3082254721Semaste            Error error;
3083254721Semaste
3084254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3085254721Semaste            if (short_option == 'g')
3086254721Semaste            {
3087254721Semaste                m_use_global_module_list = true;
3088254721Semaste            }
3089254721Semaste            else if (short_option == 'a')
3090254721Semaste            {
3091254721Semaste                ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3092254721Semaste                m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3093254721Semaste            }
3094254721Semaste            else
3095254721Semaste            {
3096254721Semaste                unsigned long width = 0;
3097254721Semaste                if (option_arg)
3098254721Semaste                    width = strtoul (option_arg, NULL, 0);
3099254721Semaste                m_format_array.push_back(std::make_pair(short_option, width));
3100254721Semaste            }
3101254721Semaste            return error;
3102254721Semaste        }
3103254721Semaste
3104254721Semaste        void
3105254721Semaste        OptionParsingStarting ()
3106254721Semaste        {
3107254721Semaste            m_format_array.clear();
3108254721Semaste            m_use_global_module_list = false;
3109254721Semaste            m_module_addr = LLDB_INVALID_ADDRESS;
3110254721Semaste        }
3111254721Semaste
3112254721Semaste        const OptionDefinition*
3113254721Semaste        GetDefinitions ()
3114254721Semaste        {
3115254721Semaste            return g_option_table;
3116254721Semaste        }
3117254721Semaste
3118254721Semaste        // Options table: Required for subclasses of Options.
3119254721Semaste
3120254721Semaste        static OptionDefinition g_option_table[];
3121254721Semaste
3122254721Semaste        // Instance variables to hold the values for command options.
3123254721Semaste        typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
3124254721Semaste        FormatWidthCollection m_format_array;
3125254721Semaste        bool m_use_global_module_list;
3126254721Semaste        lldb::addr_t m_module_addr;
3127254721Semaste    };
3128254721Semaste
3129254721Semaste    CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
3130254721Semaste        CommandObjectParsed (interpreter,
3131254721Semaste                             "target modules list",
3132254721Semaste                             "List current executable and dependent shared library images.",
3133254721Semaste                             "target modules list [<cmd-options>]"),
3134254721Semaste        m_options (interpreter)
3135254721Semaste    {
3136254721Semaste    }
3137254721Semaste
3138254721Semaste    virtual
3139254721Semaste    ~CommandObjectTargetModulesList ()
3140254721Semaste    {
3141254721Semaste    }
3142254721Semaste
3143254721Semaste    virtual
3144254721Semaste    Options *
3145254721Semaste    GetOptions ()
3146254721Semaste    {
3147254721Semaste        return &m_options;
3148254721Semaste    }
3149254721Semaste
3150254721Semasteprotected:
3151254721Semaste    virtual bool
3152254721Semaste    DoExecute (Args& command,
3153254721Semaste             CommandReturnObject &result)
3154254721Semaste    {
3155254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3156254721Semaste        const bool use_global_module_list = m_options.m_use_global_module_list;
3157254721Semaste        // Define a local module list here to ensure it lives longer than any "locker"
3158254721Semaste        // object which might lock its contents below (through the "module_list_ptr"
3159254721Semaste        // variable).
3160254721Semaste        ModuleList module_list;
3161254721Semaste        if (target == NULL && use_global_module_list == false)
3162254721Semaste        {
3163254721Semaste            result.AppendError ("invalid target, create a debug target using the 'target create' command");
3164254721Semaste            result.SetStatus (eReturnStatusFailed);
3165254721Semaste            return false;
3166254721Semaste        }
3167254721Semaste        else
3168254721Semaste        {
3169254721Semaste            if (target)
3170254721Semaste            {
3171254721Semaste                uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3172254721Semaste                result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3173254721Semaste                result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3174254721Semaste            }
3175254721Semaste            // Dump all sections for all modules images
3176254721Semaste            Stream &strm = result.GetOutputStream();
3177254721Semaste
3178254721Semaste            if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
3179254721Semaste            {
3180254721Semaste                if (target)
3181254721Semaste                {
3182254721Semaste                    Address module_address;
3183254721Semaste                    if (module_address.SetLoadAddress(m_options.m_module_addr, target))
3184254721Semaste                    {
3185254721Semaste                        ModuleSP module_sp (module_address.GetModule());
3186254721Semaste                        if (module_sp)
3187254721Semaste                        {
3188254721Semaste                            PrintModule (target, module_sp.get(), 0, strm);
3189254721Semaste                            result.SetStatus (eReturnStatusSuccessFinishResult);
3190254721Semaste                        }
3191254721Semaste                        else
3192254721Semaste                        {
3193254721Semaste                            result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
3194254721Semaste                            result.SetStatus (eReturnStatusFailed);
3195254721Semaste                        }
3196254721Semaste                    }
3197254721Semaste                    else
3198254721Semaste                    {
3199254721Semaste                        result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
3200254721Semaste                        result.SetStatus (eReturnStatusFailed);
3201254721Semaste                    }
3202254721Semaste                }
3203254721Semaste                else
3204254721Semaste                {
3205254721Semaste                    result.AppendError ("Can only look up modules by address with a valid target.");
3206254721Semaste                    result.SetStatus (eReturnStatusFailed);
3207254721Semaste                }
3208254721Semaste                return result.Succeeded();
3209254721Semaste            }
3210254721Semaste
3211254721Semaste            size_t num_modules = 0;
3212254721Semaste            Mutex::Locker locker;      // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
3213254721Semaste                                       // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
3214254721Semaste                                       // the global module list directly.
3215254721Semaste            const ModuleList *module_list_ptr = NULL;
3216254721Semaste            const size_t argc = command.GetArgumentCount();
3217254721Semaste            if (argc == 0)
3218254721Semaste            {
3219254721Semaste                if (use_global_module_list)
3220254721Semaste                {
3221254721Semaste                    locker.Lock (Module::GetAllocationModuleCollectionMutex());
3222254721Semaste                    num_modules = Module::GetNumberAllocatedModules();
3223254721Semaste                }
3224254721Semaste                else
3225254721Semaste                {
3226254721Semaste                    module_list_ptr = &target->GetImages();
3227254721Semaste                }
3228254721Semaste            }
3229254721Semaste            else
3230254721Semaste            {
3231254721Semaste                for (size_t i=0; i<argc; ++i)
3232254721Semaste                {
3233254721Semaste                    // Dump specified images (by basename or fullpath)
3234254721Semaste                    const char *arg_cstr = command.GetArgumentAtIndex(i);
3235254721Semaste                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
3236254721Semaste                    if (num_matches == 0)
3237254721Semaste                    {
3238254721Semaste                        if (argc == 1)
3239254721Semaste                        {
3240254721Semaste                            result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
3241254721Semaste                            result.SetStatus (eReturnStatusFailed);
3242254721Semaste                            return false;
3243254721Semaste                        }
3244254721Semaste                    }
3245254721Semaste                }
3246254721Semaste
3247254721Semaste                module_list_ptr = &module_list;
3248254721Semaste            }
3249254721Semaste
3250254721Semaste            if (module_list_ptr != NULL)
3251254721Semaste            {
3252254721Semaste                locker.Lock(module_list_ptr->GetMutex());
3253254721Semaste                num_modules = module_list_ptr->GetSize();
3254254721Semaste            }
3255254721Semaste
3256254721Semaste            if (num_modules > 0)
3257254721Semaste            {
3258254721Semaste                for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
3259254721Semaste                {
3260254721Semaste                    ModuleSP module_sp;
3261254721Semaste                    Module *module;
3262254721Semaste                    if (module_list_ptr)
3263254721Semaste                    {
3264254721Semaste                        module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3265254721Semaste                        module = module_sp.get();
3266254721Semaste                    }
3267254721Semaste                    else
3268254721Semaste                    {
3269254721Semaste                        module = Module::GetAllocatedModuleAtIndex(image_idx);
3270254721Semaste                        module_sp = module->shared_from_this();
3271254721Semaste                    }
3272254721Semaste
3273254721Semaste                    const size_t indent = strm.Printf("[%3u] ", image_idx);
3274254721Semaste                    PrintModule (target, module, indent, strm);
3275254721Semaste
3276254721Semaste                }
3277254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
3278254721Semaste            }
3279254721Semaste            else
3280254721Semaste            {
3281254721Semaste                if (argc)
3282254721Semaste                {
3283254721Semaste                    if (use_global_module_list)
3284254721Semaste                        result.AppendError ("the global module list has no matching modules");
3285254721Semaste                    else
3286254721Semaste                        result.AppendError ("the target has no matching modules");
3287254721Semaste                }
3288254721Semaste                else
3289254721Semaste                {
3290254721Semaste                    if (use_global_module_list)
3291254721Semaste                        result.AppendError ("the global module list is empty");
3292254721Semaste                    else
3293254721Semaste                        result.AppendError ("the target has no associated executable images");
3294254721Semaste                }
3295254721Semaste                result.SetStatus (eReturnStatusFailed);
3296254721Semaste                return false;
3297254721Semaste            }
3298254721Semaste        }
3299254721Semaste        return result.Succeeded();
3300254721Semaste    }
3301254721Semaste
3302254721Semaste    void
3303254721Semaste    PrintModule (Target *target, Module *module, int indent, Stream &strm)
3304254721Semaste    {
3305254721Semaste
3306254721Semaste        if (module == NULL)
3307254721Semaste        {
3308254721Semaste            strm.PutCString("Null module");
3309254721Semaste            return;
3310254721Semaste        }
3311254721Semaste
3312254721Semaste        bool dump_object_name = false;
3313254721Semaste        if (m_options.m_format_array.empty())
3314254721Semaste        {
3315254721Semaste            m_options.m_format_array.push_back(std::make_pair('u', 0));
3316254721Semaste            m_options.m_format_array.push_back(std::make_pair('h', 0));
3317254721Semaste            m_options.m_format_array.push_back(std::make_pair('f', 0));
3318254721Semaste            m_options.m_format_array.push_back(std::make_pair('S', 0));
3319254721Semaste        }
3320254721Semaste        const size_t num_entries = m_options.m_format_array.size();
3321254721Semaste        bool print_space = false;
3322254721Semaste        for (size_t i=0; i<num_entries; ++i)
3323254721Semaste        {
3324254721Semaste            if (print_space)
3325254721Semaste                strm.PutChar(' ');
3326254721Semaste            print_space = true;
3327254721Semaste            const char format_char = m_options.m_format_array[i].first;
3328254721Semaste            uint32_t width = m_options.m_format_array[i].second;
3329254721Semaste            switch (format_char)
3330254721Semaste            {
3331254721Semaste                case 'A':
3332254721Semaste                    DumpModuleArchitecture (strm, module, false, width);
3333254721Semaste                    break;
3334254721Semaste
3335254721Semaste                case 't':
3336254721Semaste                    DumpModuleArchitecture (strm, module, true, width);
3337254721Semaste                    break;
3338254721Semaste
3339254721Semaste                case 'f':
3340254721Semaste                    DumpFullpath (strm, &module->GetFileSpec(), width);
3341254721Semaste                    dump_object_name = true;
3342254721Semaste                    break;
3343254721Semaste
3344254721Semaste                case 'd':
3345254721Semaste                    DumpDirectory (strm, &module->GetFileSpec(), width);
3346254721Semaste                    break;
3347254721Semaste
3348254721Semaste                case 'b':
3349254721Semaste                    DumpBasename (strm, &module->GetFileSpec(), width);
3350254721Semaste                    dump_object_name = true;
3351254721Semaste                    break;
3352254721Semaste
3353254721Semaste                case 'h':
3354254721Semaste                case 'o':
3355254721Semaste                    // Image header address
3356254721Semaste                    {
3357254721Semaste                        uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
3358254721Semaste
3359254721Semaste                        ObjectFile *objfile = module->GetObjectFile ();
3360254721Semaste                        if (objfile)
3361254721Semaste                        {
3362254721Semaste                            Address header_addr(objfile->GetHeaderAddress());
3363254721Semaste                            if (header_addr.IsValid())
3364254721Semaste                            {
3365254721Semaste                                if (target && !target->GetSectionLoadList().IsEmpty())
3366254721Semaste                                {
3367254721Semaste                                    lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3368254721Semaste                                    if (header_load_addr == LLDB_INVALID_ADDRESS)
3369254721Semaste                                    {
3370254721Semaste                                        header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3371254721Semaste                                    }
3372254721Semaste                                    else
3373254721Semaste                                    {
3374254721Semaste                                        if (format_char == 'o')
3375254721Semaste                                        {
3376254721Semaste                                            // Show the offset of slide for the image
3377254721Semaste                                            strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3378254721Semaste                                        }
3379254721Semaste                                        else
3380254721Semaste                                        {
3381254721Semaste                                            // Show the load address of the image
3382254721Semaste                                            strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
3383254721Semaste                                        }
3384254721Semaste                                    }
3385254721Semaste                                    break;
3386254721Semaste                                }
3387254721Semaste                                // The address was valid, but the image isn't loaded, output the address in an appropriate format
3388254721Semaste                                header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3389254721Semaste                                break;
3390254721Semaste                            }
3391254721Semaste                        }
3392254721Semaste                        strm.Printf ("%*s", addr_nibble_width + 2, "");
3393254721Semaste                    }
3394254721Semaste                    break;
3395254721Semaste                case 'r':
3396254721Semaste                    {
3397254721Semaste                        size_t ref_count = 0;
3398254721Semaste                        ModuleSP module_sp (module->shared_from_this());
3399254721Semaste                        if (module_sp)
3400254721Semaste                        {
3401254721Semaste                            // Take one away to make sure we don't count our local "module_sp"
3402254721Semaste                            ref_count = module_sp.use_count() - 1;
3403254721Semaste                        }
3404254721Semaste                        if (width)
3405254721Semaste                            strm.Printf("{%*zu}", width, ref_count);
3406254721Semaste                        else
3407254721Semaste                            strm.Printf("{%zu}", ref_count);
3408254721Semaste                    }
3409254721Semaste                    break;
3410254721Semaste
3411254721Semaste                case 's':
3412254721Semaste                case 'S':
3413254721Semaste                    {
3414254721Semaste                        SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3415254721Semaste                        if (symbol_vendor)
3416254721Semaste                        {
3417254721Semaste                            SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
3418254721Semaste                            if (symbol_file)
3419254721Semaste                            {
3420254721Semaste                                if (format_char == 'S')
3421254721Semaste                                {
3422254721Semaste                                    FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
3423254721Semaste                                    // Dump symbol file only if different from module file
3424254721Semaste                                    if (!symfile_spec || symfile_spec == module->GetFileSpec())
3425254721Semaste                                    {
3426254721Semaste                                        print_space = false;
3427254721Semaste                                        break;
3428254721Semaste                                    }
3429254721Semaste                                    // Add a newline and indent past the index
3430254721Semaste                                    strm.Printf ("\n%*s", indent, "");
3431254721Semaste                                }
3432254721Semaste                                DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
3433254721Semaste                                dump_object_name = true;
3434254721Semaste                                break;
3435254721Semaste                            }
3436254721Semaste                        }
3437254721Semaste                        strm.Printf("%.*s", width, "<NONE>");
3438254721Semaste                    }
3439254721Semaste                    break;
3440254721Semaste
3441254721Semaste                case 'm':
3442254721Semaste                    module->GetModificationTime().Dump(&strm, width);
3443254721Semaste                    break;
3444254721Semaste
3445254721Semaste                case 'p':
3446254721Semaste                    strm.Printf("%p", module);
3447254721Semaste                    break;
3448254721Semaste
3449254721Semaste                case 'u':
3450254721Semaste                    DumpModuleUUID(strm, module);
3451254721Semaste                    break;
3452254721Semaste
3453254721Semaste                default:
3454254721Semaste                    break;
3455254721Semaste            }
3456254721Semaste
3457254721Semaste        }
3458254721Semaste        if (dump_object_name)
3459254721Semaste        {
3460254721Semaste            const char *object_name = module->GetObjectName().GetCString();
3461254721Semaste            if (object_name)
3462254721Semaste                strm.Printf ("(%s)", object_name);
3463254721Semaste        }
3464254721Semaste        strm.EOL();
3465254721Semaste    }
3466254721Semaste
3467254721Semaste    CommandOptions m_options;
3468254721Semaste};
3469254721Semaste
3470254721SemasteOptionDefinition
3471254721SemasteCommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3472254721Semaste{
3473263363Semaste    { LLDB_OPT_SET_1, false, "address",    'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
3474263363Semaste    { LLDB_OPT_SET_1, false, "arch",       'A', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
3475263363Semaste    { LLDB_OPT_SET_1, false, "triple",     't', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
3476263363Semaste    { 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."},
3477263363Semaste    { 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)."},
3478263363Semaste    { LLDB_OPT_SET_1, false, "uuid",       'u', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
3479263363Semaste    { LLDB_OPT_SET_1, false, "fullpath",   'f', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3480263363Semaste    { LLDB_OPT_SET_1, false, "directory",  'd', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3481263363Semaste    { LLDB_OPT_SET_1, false, "basename",   'b', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3482263363Semaste    { LLDB_OPT_SET_1, false, "symfile",    's', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3483263363Semaste    { 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."},
3484263363Semaste    { LLDB_OPT_SET_1, false, "mod-time",   'm', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3485263363Semaste    { 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."},
3486263363Semaste    { LLDB_OPT_SET_1, false, "pointer",    'p', OptionParser::eOptionalArgument, NULL, 0, eArgTypeNone,    "Display the module pointer."},
3487263363Semaste    { 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."},
3488254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3489254721Semaste};
3490254721Semaste
3491254721Semaste#pragma mark CommandObjectTargetModulesShowUnwind
3492254721Semaste
3493254721Semaste//----------------------------------------------------------------------
3494254721Semaste// Lookup unwind information in images
3495254721Semaste//----------------------------------------------------------------------
3496254721Semaste
3497254721Semasteclass CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3498254721Semaste{
3499254721Semastepublic:
3500254721Semaste
3501254721Semaste    enum
3502254721Semaste    {
3503254721Semaste        eLookupTypeInvalid = -1,
3504254721Semaste        eLookupTypeAddress = 0,
3505254721Semaste        eLookupTypeSymbol,
3506254721Semaste        eLookupTypeFunction,
3507254721Semaste        eLookupTypeFunctionOrSymbol,
3508254721Semaste        kNumLookupTypes
3509254721Semaste    };
3510254721Semaste
3511254721Semaste    class CommandOptions : public Options
3512254721Semaste    {
3513254721Semaste    public:
3514254721Semaste
3515254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3516254721Semaste            Options(interpreter),
3517254721Semaste            m_type(eLookupTypeInvalid),
3518254721Semaste            m_str(),
3519254721Semaste            m_addr(LLDB_INVALID_ADDRESS)
3520254721Semaste        {
3521254721Semaste        }
3522254721Semaste
3523254721Semaste        virtual
3524254721Semaste        ~CommandOptions ()
3525254721Semaste        {
3526254721Semaste        }
3527254721Semaste
3528254721Semaste        virtual Error
3529254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3530254721Semaste        {
3531254721Semaste            Error error;
3532254721Semaste
3533254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3534254721Semaste
3535254721Semaste            switch (short_option)
3536254721Semaste            {
3537254721Semaste                case 'a':
3538254721Semaste                {
3539254721Semaste                    ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3540263363Semaste                    m_str = option_arg;
3541254721Semaste                    m_type = eLookupTypeAddress;
3542254721Semaste                    m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3543254721Semaste                    if (m_addr == LLDB_INVALID_ADDRESS)
3544254721Semaste                        error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3545254721Semaste                    break;
3546254721Semaste                }
3547254721Semaste
3548254721Semaste                case 'n':
3549254721Semaste                {
3550254721Semaste                    m_str = option_arg;
3551254721Semaste                    m_type = eLookupTypeFunctionOrSymbol;
3552254721Semaste                    break;
3553254721Semaste                }
3554263363Semaste
3555263363Semaste                default:
3556263363Semaste                    error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
3557263363Semaste                    break;
3558254721Semaste            }
3559254721Semaste
3560254721Semaste            return error;
3561254721Semaste        }
3562254721Semaste
3563254721Semaste        void
3564254721Semaste        OptionParsingStarting ()
3565254721Semaste        {
3566254721Semaste            m_type = eLookupTypeInvalid;
3567254721Semaste            m_str.clear();
3568254721Semaste            m_addr = LLDB_INVALID_ADDRESS;
3569254721Semaste        }
3570254721Semaste
3571254721Semaste        const OptionDefinition*
3572254721Semaste        GetDefinitions ()
3573254721Semaste        {
3574254721Semaste            return g_option_table;
3575254721Semaste        }
3576254721Semaste
3577254721Semaste        // Options table: Required for subclasses of Options.
3578254721Semaste
3579254721Semaste        static OptionDefinition g_option_table[];
3580254721Semaste
3581254721Semaste        // Instance variables to hold the values for command options.
3582254721Semaste
3583254721Semaste        int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3584254721Semaste        std::string     m_str;          // Holds name lookup
3585254721Semaste        lldb::addr_t    m_addr;         // Holds the address to lookup
3586254721Semaste    };
3587254721Semaste
3588254721Semaste    CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3589254721Semaste        CommandObjectParsed (interpreter,
3590254721Semaste                             "target modules show-unwind",
3591254721Semaste                             "Show synthesized unwind instructions for a function.",
3592254721Semaste                             NULL,
3593254721Semaste                             eFlagRequiresTarget        |
3594254721Semaste                             eFlagRequiresProcess       |
3595254721Semaste                             eFlagProcessMustBeLaunched |
3596254721Semaste                             eFlagProcessMustBePaused   ),
3597254721Semaste        m_options (interpreter)
3598254721Semaste    {
3599254721Semaste    }
3600254721Semaste
3601254721Semaste    virtual
3602254721Semaste    ~CommandObjectTargetModulesShowUnwind ()
3603254721Semaste    {
3604254721Semaste    }
3605254721Semaste
3606254721Semaste    virtual
3607254721Semaste    Options *
3608254721Semaste    GetOptions ()
3609254721Semaste    {
3610254721Semaste        return &m_options;
3611254721Semaste    }
3612254721Semaste
3613254721Semasteprotected:
3614254721Semaste    bool
3615254721Semaste    DoExecute (Args& command,
3616254721Semaste             CommandReturnObject &result)
3617254721Semaste    {
3618254721Semaste        Target *target = m_exe_ctx.GetTargetPtr();
3619254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
3620254721Semaste        ABI *abi = NULL;
3621254721Semaste        if (process)
3622254721Semaste          abi = process->GetABI().get();
3623254721Semaste
3624254721Semaste        if (process == NULL)
3625254721Semaste        {
3626254721Semaste            result.AppendError ("You must have a process running to use this command.");
3627254721Semaste            result.SetStatus (eReturnStatusFailed);
3628254721Semaste            return false;
3629254721Semaste        }
3630254721Semaste
3631254721Semaste        ThreadList threads(process->GetThreadList());
3632254721Semaste        if (threads.GetSize() == 0)
3633254721Semaste        {
3634254721Semaste            result.AppendError ("The process must be paused to use this command.");
3635254721Semaste            result.SetStatus (eReturnStatusFailed);
3636254721Semaste            return false;
3637254721Semaste        }
3638254721Semaste
3639254721Semaste        ThreadSP thread(threads.GetThreadAtIndex(0));
3640254721Semaste        if (thread.get() == NULL)
3641254721Semaste        {
3642254721Semaste            result.AppendError ("The process must be paused to use this command.");
3643254721Semaste            result.SetStatus (eReturnStatusFailed);
3644254721Semaste            return false;
3645254721Semaste        }
3646254721Semaste
3647254721Semaste        SymbolContextList sc_list;
3648254721Semaste
3649254721Semaste        if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3650254721Semaste        {
3651254721Semaste            ConstString function_name (m_options.m_str.c_str());
3652254721Semaste            target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3653254721Semaste        }
3654254721Semaste        else if (m_options.m_type == eLookupTypeAddress && target)
3655254721Semaste        {
3656254721Semaste            Address addr;
3657254721Semaste            if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
3658254721Semaste            {
3659254721Semaste                SymbolContext sc;
3660254721Semaste                ModuleSP module_sp (addr.GetModule());
3661254721Semaste                module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
3662254721Semaste                if (sc.function || sc.symbol)
3663254721Semaste                {
3664254721Semaste                    sc_list.Append(sc);
3665254721Semaste                }
3666254721Semaste            }
3667254721Semaste        }
3668263363Semaste        else
3669263363Semaste        {
3670263363Semaste            result.AppendError ("address-expression or function name option must be specified.");
3671263363Semaste            result.SetStatus (eReturnStatusFailed);
3672263363Semaste            return false;
3673263363Semaste        }
3674254721Semaste
3675254721Semaste        size_t num_matches = sc_list.GetSize();
3676263363Semaste        if (num_matches == 0)
3677263363Semaste        {
3678263363Semaste            result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
3679263363Semaste            result.SetStatus (eReturnStatusFailed);
3680263363Semaste            return false;
3681263363Semaste        }
3682263363Semaste
3683254721Semaste        for (uint32_t idx = 0; idx < num_matches; idx++)
3684254721Semaste        {
3685254721Semaste            SymbolContext sc;
3686254721Semaste            sc_list.GetContextAtIndex(idx, sc);
3687254721Semaste            if (sc.symbol == NULL && sc.function == NULL)
3688254721Semaste                continue;
3689254721Semaste            if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
3690254721Semaste                continue;
3691254721Semaste            AddressRange range;
3692254721Semaste            if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3693254721Semaste                continue;
3694254721Semaste            if (!range.GetBaseAddress().IsValid())
3695254721Semaste                continue;
3696254721Semaste            ConstString funcname(sc.GetFunctionName());
3697254721Semaste            if (funcname.IsEmpty())
3698254721Semaste                continue;
3699254721Semaste            addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3700254721Semaste            if (abi)
3701254721Semaste                start_addr = abi->FixCodeAddress(start_addr);
3702254721Semaste
3703254721Semaste            FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3704254721Semaste            if (func_unwinders_sp.get() == NULL)
3705254721Semaste                continue;
3706254721Semaste
3707254721Semaste            Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target));
3708254721Semaste            if (first_non_prologue_insn.IsValid())
3709254721Semaste            {
3710254721Semaste                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);
3711254721Semaste                result.GetOutputStream().Printf ("\n");
3712254721Semaste            }
3713254721Semaste
3714254721Semaste            UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get());
3715254721Semaste            if (non_callsite_unwind_plan.get())
3716254721Semaste            {
3717254721Semaste                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);
3718254721Semaste                non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3719254721Semaste                result.GetOutputStream().Printf ("\n");
3720254721Semaste            }
3721254721Semaste
3722254721Semaste            UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1);
3723254721Semaste            if (callsite_unwind_plan.get())
3724254721Semaste            {
3725254721Semaste                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);
3726254721Semaste                callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3727254721Semaste                result.GetOutputStream().Printf ("\n");
3728254721Semaste            }
3729254721Semaste
3730254721Semaste            UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get());
3731254721Semaste            if (arch_default_unwind_plan.get())
3732254721Semaste            {
3733254721Semaste                result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3734254721Semaste                arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3735254721Semaste                result.GetOutputStream().Printf ("\n");
3736254721Semaste            }
3737254721Semaste
3738254721Semaste            UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
3739254721Semaste            if (fast_unwind_plan.get())
3740254721Semaste            {
3741254721Semaste                result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3742254721Semaste                fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3743254721Semaste                result.GetOutputStream().Printf ("\n");
3744254721Semaste            }
3745254721Semaste
3746254721Semaste
3747254721Semaste            result.GetOutputStream().Printf ("\n");
3748254721Semaste        }
3749254721Semaste        return result.Succeeded();
3750254721Semaste    }
3751254721Semaste
3752254721Semaste    CommandOptions m_options;
3753254721Semaste};
3754254721Semaste
3755254721SemasteOptionDefinition
3756254721SemasteCommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3757254721Semaste{
3758263363Semaste    { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3759263363Semaste    { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3760254721Semaste    { 0,                false, NULL,           0, 0,                 NULL, 0, eArgTypeNone, NULL }
3761254721Semaste};
3762254721Semaste
3763254721Semaste//----------------------------------------------------------------------
3764254721Semaste// Lookup information in images
3765254721Semaste//----------------------------------------------------------------------
3766254721Semasteclass CommandObjectTargetModulesLookup : public CommandObjectParsed
3767254721Semaste{
3768254721Semastepublic:
3769254721Semaste
3770254721Semaste    enum
3771254721Semaste    {
3772254721Semaste        eLookupTypeInvalid = -1,
3773254721Semaste        eLookupTypeAddress = 0,
3774254721Semaste        eLookupTypeSymbol,
3775254721Semaste        eLookupTypeFileLine,    // Line is optional
3776254721Semaste        eLookupTypeFunction,
3777254721Semaste        eLookupTypeFunctionOrSymbol,
3778254721Semaste        eLookupTypeType,
3779254721Semaste        kNumLookupTypes
3780254721Semaste    };
3781254721Semaste
3782254721Semaste    class CommandOptions : public Options
3783254721Semaste    {
3784254721Semaste    public:
3785254721Semaste
3786254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
3787254721Semaste        Options(interpreter)
3788254721Semaste        {
3789254721Semaste            OptionParsingStarting();
3790254721Semaste        }
3791254721Semaste
3792254721Semaste        virtual
3793254721Semaste        ~CommandOptions ()
3794254721Semaste        {
3795254721Semaste        }
3796254721Semaste
3797254721Semaste        virtual Error
3798254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
3799254721Semaste        {
3800254721Semaste            Error error;
3801254721Semaste
3802254721Semaste            const int short_option = m_getopt_table[option_idx].val;
3803254721Semaste
3804254721Semaste            switch (short_option)
3805254721Semaste            {
3806254721Semaste                case 'a':
3807254721Semaste                    {
3808254721Semaste                        m_type = eLookupTypeAddress;
3809254721Semaste                        ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3810254721Semaste                        m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3811254721Semaste                    }
3812254721Semaste                    break;
3813254721Semaste
3814254721Semaste                case 'o':
3815254721Semaste                    m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3816254721Semaste                    if (m_offset == LLDB_INVALID_ADDRESS)
3817254721Semaste                        error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3818254721Semaste                    break;
3819254721Semaste
3820254721Semaste                case 's':
3821254721Semaste                    m_str = option_arg;
3822254721Semaste                    m_type = eLookupTypeSymbol;
3823254721Semaste                    break;
3824254721Semaste
3825254721Semaste                case 'f':
3826254721Semaste                    m_file.SetFile (option_arg, false);
3827254721Semaste                    m_type = eLookupTypeFileLine;
3828254721Semaste                    break;
3829254721Semaste
3830254721Semaste                case 'i':
3831254721Semaste                    m_include_inlines = false;
3832254721Semaste                    break;
3833254721Semaste
3834254721Semaste                case 'l':
3835254721Semaste                    m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3836254721Semaste                    if (m_line_number == UINT32_MAX)
3837254721Semaste                        error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3838254721Semaste                    else if (m_line_number == 0)
3839254721Semaste                        error.SetErrorString ("zero is an invalid line number");
3840254721Semaste                    m_type = eLookupTypeFileLine;
3841254721Semaste                    break;
3842254721Semaste
3843254721Semaste                case 'F':
3844254721Semaste                    m_str = option_arg;
3845254721Semaste                    m_type = eLookupTypeFunction;
3846254721Semaste                    break;
3847254721Semaste
3848254721Semaste                case 'n':
3849254721Semaste                    m_str = option_arg;
3850254721Semaste                    m_type = eLookupTypeFunctionOrSymbol;
3851254721Semaste                    break;
3852254721Semaste
3853254721Semaste                case 't':
3854254721Semaste                    m_str = option_arg;
3855254721Semaste                    m_type = eLookupTypeType;
3856254721Semaste                    break;
3857254721Semaste
3858254721Semaste                case 'v':
3859254721Semaste                    m_verbose = 1;
3860254721Semaste                    break;
3861254721Semaste
3862254721Semaste                case 'A':
3863254721Semaste                    m_print_all = true;
3864254721Semaste                    break;
3865254721Semaste
3866254721Semaste                case 'r':
3867254721Semaste                    m_use_regex = true;
3868254721Semaste                    break;
3869254721Semaste            }
3870254721Semaste
3871254721Semaste            return error;
3872254721Semaste        }
3873254721Semaste
3874254721Semaste        void
3875254721Semaste        OptionParsingStarting ()
3876254721Semaste        {
3877254721Semaste            m_type = eLookupTypeInvalid;
3878254721Semaste            m_str.clear();
3879254721Semaste            m_file.Clear();
3880254721Semaste            m_addr = LLDB_INVALID_ADDRESS;
3881254721Semaste            m_offset = 0;
3882254721Semaste            m_line_number = 0;
3883254721Semaste            m_use_regex = false;
3884254721Semaste            m_include_inlines = true;
3885254721Semaste            m_verbose = false;
3886254721Semaste            m_print_all = false;
3887254721Semaste        }
3888254721Semaste
3889254721Semaste        const OptionDefinition*
3890254721Semaste        GetDefinitions ()
3891254721Semaste        {
3892254721Semaste            return g_option_table;
3893254721Semaste        }
3894254721Semaste
3895254721Semaste        // Options table: Required for subclasses of Options.
3896254721Semaste
3897254721Semaste        static OptionDefinition g_option_table[];
3898254721Semaste        int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3899254721Semaste        std::string     m_str;          // Holds name lookup
3900254721Semaste        FileSpec        m_file;         // Files for file lookups
3901254721Semaste        lldb::addr_t    m_addr;         // Holds the address to lookup
3902254721Semaste        lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
3903254721Semaste        uint32_t        m_line_number;  // Line number for file+line lookups
3904254721Semaste        bool            m_use_regex;    // Name lookups in m_str are regular expressions.
3905254721Semaste        bool            m_include_inlines;// Check for inline entries when looking up by file/line.
3906254721Semaste        bool            m_verbose;      // Enable verbose lookup info
3907254721Semaste        bool            m_print_all;    // Print all matches, even in cases where there's a best match.
3908254721Semaste
3909254721Semaste    };
3910254721Semaste
3911254721Semaste    CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
3912254721Semaste        CommandObjectParsed (interpreter,
3913254721Semaste                             "target modules lookup",
3914254721Semaste                             "Look up information within executable and dependent shared library images.",
3915254721Semaste                             NULL,
3916254721Semaste                             eFlagRequiresTarget),
3917254721Semaste        m_options (interpreter)
3918254721Semaste    {
3919254721Semaste        CommandArgumentEntry arg;
3920254721Semaste        CommandArgumentData file_arg;
3921254721Semaste
3922254721Semaste        // Define the first (and only) variant of this arg.
3923254721Semaste        file_arg.arg_type = eArgTypeFilename;
3924254721Semaste        file_arg.arg_repetition = eArgRepeatStar;
3925254721Semaste
3926254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
3927254721Semaste        arg.push_back (file_arg);
3928254721Semaste
3929254721Semaste        // Push the data for the first argument into the m_arguments vector.
3930254721Semaste        m_arguments.push_back (arg);
3931254721Semaste    }
3932254721Semaste
3933254721Semaste    virtual
3934254721Semaste    ~CommandObjectTargetModulesLookup ()
3935254721Semaste    {
3936254721Semaste    }
3937254721Semaste
3938254721Semaste    virtual Options *
3939254721Semaste    GetOptions ()
3940254721Semaste    {
3941254721Semaste        return &m_options;
3942254721Semaste    }
3943254721Semaste
3944254721Semaste    bool
3945254721Semaste    LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
3946254721Semaste    {
3947254721Semaste        switch (m_options.m_type)
3948254721Semaste        {
3949254721Semaste            case eLookupTypeAddress:
3950254721Semaste            case eLookupTypeFileLine:
3951254721Semaste            case eLookupTypeFunction:
3952254721Semaste            case eLookupTypeFunctionOrSymbol:
3953254721Semaste            case eLookupTypeSymbol:
3954254721Semaste            default:
3955254721Semaste                return false;
3956254721Semaste            case eLookupTypeType:
3957254721Semaste                break;
3958254721Semaste        }
3959254721Semaste
3960254721Semaste        StackFrameSP frame = m_exe_ctx.GetFrameSP();
3961254721Semaste
3962254721Semaste        if (!frame)
3963254721Semaste            return false;
3964254721Semaste
3965254721Semaste        const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3966254721Semaste
3967254721Semaste        if (!sym_ctx.module_sp)
3968254721Semaste            return false;
3969254721Semaste
3970254721Semaste        switch (m_options.m_type)
3971254721Semaste        {
3972254721Semaste        default:
3973254721Semaste            return false;
3974254721Semaste        case eLookupTypeType:
3975254721Semaste            if (!m_options.m_str.empty())
3976254721Semaste            {
3977254721Semaste                if (LookupTypeHere (m_interpreter,
3978254721Semaste                                    result.GetOutputStream(),
3979254721Semaste                                    sym_ctx,
3980254721Semaste                                    m_options.m_str.c_str(),
3981254721Semaste                                    m_options.m_use_regex))
3982254721Semaste                {
3983254721Semaste                    result.SetStatus(eReturnStatusSuccessFinishResult);
3984254721Semaste                    return true;
3985254721Semaste                }
3986254721Semaste            }
3987254721Semaste            break;
3988254721Semaste        }
3989254721Semaste
3990254721Semaste        return true;
3991254721Semaste    }
3992254721Semaste
3993254721Semaste    bool
3994254721Semaste    LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3995254721Semaste    {
3996254721Semaste        switch (m_options.m_type)
3997254721Semaste        {
3998254721Semaste            case eLookupTypeAddress:
3999254721Semaste                if (m_options.m_addr != LLDB_INVALID_ADDRESS)
4000254721Semaste                {
4001254721Semaste                    if (LookupAddressInModule (m_interpreter,
4002254721Semaste                                               result.GetOutputStream(),
4003254721Semaste                                               module,
4004254721Semaste                                               eSymbolContextEverything,
4005254721Semaste                                               m_options.m_addr,
4006254721Semaste                                               m_options.m_offset,
4007254721Semaste                                               m_options.m_verbose))
4008254721Semaste                    {
4009254721Semaste                        result.SetStatus(eReturnStatusSuccessFinishResult);
4010254721Semaste                        return true;
4011254721Semaste                    }
4012254721Semaste                }
4013254721Semaste                break;
4014254721Semaste
4015254721Semaste            case eLookupTypeSymbol:
4016254721Semaste                if (!m_options.m_str.empty())
4017254721Semaste                {
4018254721Semaste                    if (LookupSymbolInModule (m_interpreter,
4019254721Semaste                                              result.GetOutputStream(),
4020254721Semaste                                              module,
4021254721Semaste                                              m_options.m_str.c_str(),
4022254721Semaste                                              m_options.m_use_regex,
4023254721Semaste                                              m_options.m_verbose))
4024254721Semaste                    {
4025254721Semaste                        result.SetStatus(eReturnStatusSuccessFinishResult);
4026254721Semaste                        return true;
4027254721Semaste                    }
4028254721Semaste                }
4029254721Semaste                break;
4030254721Semaste
4031254721Semaste            case eLookupTypeFileLine:
4032254721Semaste                if (m_options.m_file)
4033254721Semaste                {
4034254721Semaste
4035254721Semaste                    if (LookupFileAndLineInModule (m_interpreter,
4036254721Semaste                                                   result.GetOutputStream(),
4037254721Semaste                                                   module,
4038254721Semaste                                                   m_options.m_file,
4039254721Semaste                                                   m_options.m_line_number,
4040254721Semaste                                                   m_options.m_include_inlines,
4041254721Semaste                                                   m_options.m_verbose))
4042254721Semaste                    {
4043254721Semaste                        result.SetStatus(eReturnStatusSuccessFinishResult);
4044254721Semaste                        return true;
4045254721Semaste                    }
4046254721Semaste                }
4047254721Semaste                break;
4048254721Semaste
4049254721Semaste            case eLookupTypeFunctionOrSymbol:
4050254721Semaste            case eLookupTypeFunction:
4051254721Semaste                if (!m_options.m_str.empty())
4052254721Semaste                {
4053254721Semaste                    if (LookupFunctionInModule (m_interpreter,
4054254721Semaste                                                result.GetOutputStream(),
4055254721Semaste                                                module,
4056254721Semaste                                                m_options.m_str.c_str(),
4057254721Semaste                                                m_options.m_use_regex,
4058254721Semaste                                                m_options.m_include_inlines,
4059254721Semaste                                                m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
4060254721Semaste                                                m_options.m_verbose))
4061254721Semaste                    {
4062254721Semaste                        result.SetStatus(eReturnStatusSuccessFinishResult);
4063254721Semaste                        return true;
4064254721Semaste                    }
4065254721Semaste                }
4066254721Semaste                break;
4067254721Semaste
4068254721Semaste
4069254721Semaste            case eLookupTypeType:
4070254721Semaste                if (!m_options.m_str.empty())
4071254721Semaste                {
4072254721Semaste                    if (LookupTypeInModule (m_interpreter,
4073254721Semaste                                            result.GetOutputStream(),
4074254721Semaste                                            module,
4075254721Semaste                                            m_options.m_str.c_str(),
4076254721Semaste                                            m_options.m_use_regex))
4077254721Semaste                    {
4078254721Semaste                        result.SetStatus(eReturnStatusSuccessFinishResult);
4079254721Semaste                        return true;
4080254721Semaste                    }
4081254721Semaste                }
4082254721Semaste                break;
4083254721Semaste
4084254721Semaste            default:
4085254721Semaste                m_options.GenerateOptionUsage (result.GetErrorStream(), this);
4086254721Semaste                syntax_error = true;
4087254721Semaste                break;
4088254721Semaste        }
4089254721Semaste
4090254721Semaste        result.SetStatus (eReturnStatusFailed);
4091254721Semaste        return false;
4092254721Semaste    }
4093254721Semaste
4094254721Semasteprotected:
4095254721Semaste    virtual bool
4096254721Semaste    DoExecute (Args& command,
4097254721Semaste             CommandReturnObject &result)
4098254721Semaste    {
4099254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4100254721Semaste        if (target == NULL)
4101254721Semaste        {
4102254721Semaste            result.AppendError ("invalid target, create a debug target using the 'target create' command");
4103254721Semaste            result.SetStatus (eReturnStatusFailed);
4104254721Semaste            return false;
4105254721Semaste        }
4106254721Semaste        else
4107254721Semaste        {
4108254721Semaste            bool syntax_error = false;
4109254721Semaste            uint32_t i;
4110254721Semaste            uint32_t num_successful_lookups = 0;
4111254721Semaste            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4112254721Semaste            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4113254721Semaste            result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4114254721Semaste            // Dump all sections for all modules images
4115254721Semaste
4116254721Semaste            if (command.GetArgumentCount() == 0)
4117254721Semaste            {
4118254721Semaste                ModuleSP current_module;
4119254721Semaste
4120254721Semaste                // Where it is possible to look in the current symbol context
4121254721Semaste                // first, try that.  If this search was successful and --all
4122254721Semaste                // was not passed, don't print anything else.
4123254721Semaste                if (LookupHere (m_interpreter, result, syntax_error))
4124254721Semaste                {
4125254721Semaste                    result.GetOutputStream().EOL();
4126254721Semaste                    num_successful_lookups++;
4127254721Semaste                    if (!m_options.m_print_all)
4128254721Semaste                    {
4129254721Semaste                        result.SetStatus (eReturnStatusSuccessFinishResult);
4130254721Semaste                        return result.Succeeded();
4131254721Semaste                    }
4132254721Semaste                }
4133254721Semaste
4134254721Semaste                // Dump all sections for all other modules
4135254721Semaste
4136254721Semaste                const ModuleList &target_modules = target->GetImages();
4137254721Semaste                Mutex::Locker modules_locker(target_modules.GetMutex());
4138254721Semaste                const size_t num_modules = target_modules.GetSize();
4139254721Semaste                if (num_modules > 0)
4140254721Semaste                {
4141254721Semaste                    for (i = 0; i<num_modules && syntax_error == false; ++i)
4142254721Semaste                    {
4143254721Semaste                        Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
4144254721Semaste
4145254721Semaste                        if (module_pointer != current_module.get() &&
4146254721Semaste                            LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
4147254721Semaste                        {
4148254721Semaste                            result.GetOutputStream().EOL();
4149254721Semaste                            num_successful_lookups++;
4150254721Semaste                        }
4151254721Semaste                    }
4152254721Semaste                }
4153254721Semaste                else
4154254721Semaste                {
4155254721Semaste                    result.AppendError ("the target has no associated executable images");
4156254721Semaste                    result.SetStatus (eReturnStatusFailed);
4157254721Semaste                    return false;
4158254721Semaste                }
4159254721Semaste            }
4160254721Semaste            else
4161254721Semaste            {
4162254721Semaste                // Dump specified images (by basename or fullpath)
4163254721Semaste                const char *arg_cstr;
4164254721Semaste                for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
4165254721Semaste                {
4166254721Semaste                    ModuleList module_list;
4167254721Semaste                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
4168254721Semaste                    if (num_matches > 0)
4169254721Semaste                    {
4170254721Semaste                        for (size_t j=0; j<num_matches; ++j)
4171254721Semaste                        {
4172254721Semaste                            Module *module = module_list.GetModulePointerAtIndex(j);
4173254721Semaste                            if (module)
4174254721Semaste                            {
4175254721Semaste                                if (LookupInModule (m_interpreter, module, result, syntax_error))
4176254721Semaste                                {
4177254721Semaste                                    result.GetOutputStream().EOL();
4178254721Semaste                                    num_successful_lookups++;
4179254721Semaste                                }
4180254721Semaste                            }
4181254721Semaste                        }
4182254721Semaste                    }
4183254721Semaste                    else
4184254721Semaste                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
4185254721Semaste                }
4186254721Semaste            }
4187254721Semaste
4188254721Semaste            if (num_successful_lookups > 0)
4189254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
4190254721Semaste            else
4191254721Semaste                result.SetStatus (eReturnStatusFailed);
4192254721Semaste        }
4193254721Semaste        return result.Succeeded();
4194254721Semaste    }
4195254721Semaste
4196254721Semaste    CommandOptions m_options;
4197254721Semaste};
4198254721Semaste
4199254721SemasteOptionDefinition
4200254721SemasteCommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
4201254721Semaste{
4202263363Semaste    { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
4203263363Semaste    { 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."},
4204254721Semaste    { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
4205254721Semaste      /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
4206263363Semaste                        false, "regex",      'r', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
4207263363Semaste    { 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."},
4208263363Semaste    { 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."},
4209263363Semaste    { 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)."},
4210254721Semaste    { LLDB_OPT_SET_FROM_TO(3,5),
4211263363Semaste                        false, "no-inlines", 'i', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
4212263363Semaste    { 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."},
4213263363Semaste    { 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."},
4214263363Semaste    { 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."},
4215263363Semaste    { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,             "Enable verbose lookup information."},
4216263363Semaste    { 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."},
4217254721Semaste    { 0,                false, NULL,           0, 0,                 NULL, 0, eArgTypeNone,             NULL }
4218254721Semaste};
4219254721Semaste
4220254721Semaste
4221254721Semaste#pragma mark CommandObjectMultiwordImageSearchPaths
4222254721Semaste
4223254721Semaste//-------------------------------------------------------------------------
4224254721Semaste// CommandObjectMultiwordImageSearchPaths
4225254721Semaste//-------------------------------------------------------------------------
4226254721Semaste
4227254721Semasteclass CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
4228254721Semaste{
4229254721Semastepublic:
4230254721Semaste
4231254721Semaste    CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
4232254721Semaste    CommandObjectMultiword (interpreter,
4233254721Semaste                            "target modules search-paths",
4234254721Semaste                            "A set of commands for operating on debugger target image search paths.",
4235254721Semaste                            "target modules search-paths <subcommand> [<subcommand-options>]")
4236254721Semaste    {
4237254721Semaste        LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
4238254721Semaste        LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
4239254721Semaste        LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
4240254721Semaste        LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
4241254721Semaste        LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
4242254721Semaste    }
4243254721Semaste
4244254721Semaste    ~CommandObjectTargetModulesImageSearchPaths()
4245254721Semaste    {
4246254721Semaste    }
4247254721Semaste};
4248254721Semaste
4249254721Semaste
4250254721Semaste
4251254721Semaste#pragma mark CommandObjectTargetModules
4252254721Semaste
4253254721Semaste//-------------------------------------------------------------------------
4254254721Semaste// CommandObjectTargetModules
4255254721Semaste//-------------------------------------------------------------------------
4256254721Semaste
4257254721Semasteclass CommandObjectTargetModules : public CommandObjectMultiword
4258254721Semaste{
4259254721Semastepublic:
4260254721Semaste    //------------------------------------------------------------------
4261254721Semaste    // Constructors and Destructors
4262254721Semaste    //------------------------------------------------------------------
4263254721Semaste    CommandObjectTargetModules(CommandInterpreter &interpreter) :
4264254721Semaste        CommandObjectMultiword (interpreter,
4265254721Semaste                                "target modules",
4266254721Semaste                                "A set of commands for accessing information for one or more target modules.",
4267254721Semaste                                "target modules <sub-command> ...")
4268254721Semaste    {
4269254721Semaste        LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
4270254721Semaste        LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
4271254721Semaste        LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
4272254721Semaste        LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
4273254721Semaste        LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
4274254721Semaste        LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
4275254721Semaste        LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
4276254721Semaste
4277254721Semaste    }
4278254721Semaste    virtual
4279254721Semaste    ~CommandObjectTargetModules()
4280254721Semaste    {
4281254721Semaste    }
4282254721Semaste
4283254721Semasteprivate:
4284254721Semaste    //------------------------------------------------------------------
4285254721Semaste    // For CommandObjectTargetModules only
4286254721Semaste    //------------------------------------------------------------------
4287254721Semaste    DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
4288254721Semaste};
4289254721Semaste
4290254721Semaste
4291254721Semaste
4292254721Semasteclass CommandObjectTargetSymbolsAdd : public CommandObjectParsed
4293254721Semaste{
4294254721Semastepublic:
4295254721Semaste    CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
4296254721Semaste        CommandObjectParsed (interpreter,
4297254721Semaste                             "target symbols add",
4298254721Semaste                             "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.",
4299254721Semaste                             "target symbols add [<symfile>]", eFlagRequiresTarget),
4300254721Semaste        m_option_group (interpreter),
4301254721Semaste        m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4302254721Semaste        m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4303254721Semaste
4304254721Semaste    {
4305254721Semaste        m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4306254721Semaste        m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4307254721Semaste        m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4308254721Semaste        m_option_group.Finalize();
4309254721Semaste    }
4310254721Semaste
4311254721Semaste    virtual
4312254721Semaste    ~CommandObjectTargetSymbolsAdd ()
4313254721Semaste    {
4314254721Semaste    }
4315254721Semaste
4316254721Semaste    virtual int
4317254721Semaste    HandleArgumentCompletion (Args &input,
4318254721Semaste                              int &cursor_index,
4319254721Semaste                              int &cursor_char_position,
4320254721Semaste                              OptionElementVector &opt_element_vector,
4321254721Semaste                              int match_start_point,
4322254721Semaste                              int max_return_elements,
4323254721Semaste                              bool &word_complete,
4324254721Semaste                              StringList &matches)
4325254721Semaste    {
4326254721Semaste        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4327254721Semaste        completion_str.erase (cursor_char_position);
4328254721Semaste
4329254721Semaste        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4330254721Semaste                                                             CommandCompletions::eDiskFileCompletion,
4331254721Semaste                                                             completion_str.c_str(),
4332254721Semaste                                                             match_start_point,
4333254721Semaste                                                             max_return_elements,
4334254721Semaste                                                             NULL,
4335254721Semaste                                                             word_complete,
4336254721Semaste                                                             matches);
4337254721Semaste        return matches.GetSize();
4338254721Semaste    }
4339254721Semaste
4340254721Semaste    virtual Options *
4341254721Semaste    GetOptions ()
4342254721Semaste    {
4343254721Semaste        return &m_option_group;
4344254721Semaste    }
4345254721Semaste
4346254721Semaste
4347254721Semasteprotected:
4348254721Semaste
4349254721Semaste    bool
4350254721Semaste    AddModuleSymbols (Target *target,
4351254721Semaste                      ModuleSpec &module_spec,
4352254721Semaste                      bool &flush,
4353254721Semaste                      CommandReturnObject &result)
4354254721Semaste    {
4355254721Semaste        const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4356254721Semaste        if (symbol_fspec)
4357254721Semaste        {
4358254721Semaste            char symfile_path[PATH_MAX];
4359254721Semaste            symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
4360254721Semaste
4361254721Semaste            if (!module_spec.GetUUID().IsValid())
4362254721Semaste            {
4363254721Semaste                if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4364254721Semaste                    module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4365254721Semaste            }
4366254721Semaste            // We now have a module that represents a symbol file
4367254721Semaste            // that can be used for a module that might exist in the
4368254721Semaste            // current target, so we need to find that module in the
4369254721Semaste            // target
4370254721Semaste            ModuleList matching_module_list;
4371254721Semaste
4372254721Semaste            size_t num_matches = 0;
4373254721Semaste            // First extract all module specs from the symbol file
4374254721Semaste            lldb_private::ModuleSpecList symfile_module_specs;
4375254721Semaste            if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
4376254721Semaste            {
4377254721Semaste                // Now extract the module spec that matches the target architecture
4378254721Semaste                ModuleSpec target_arch_module_spec;
4379254721Semaste                ModuleSpec symfile_module_spec;
4380254721Semaste                target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4381254721Semaste                if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
4382254721Semaste                {
4383254721Semaste                    // See if it has a UUID?
4384254721Semaste                    if (symfile_module_spec.GetUUID().IsValid())
4385254721Semaste                    {
4386254721Semaste                        // It has a UUID, look for this UUID in the target modules
4387254721Semaste                        ModuleSpec symfile_uuid_module_spec;
4388254721Semaste                        symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4389254721Semaste                        num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4390254721Semaste                    }
4391254721Semaste                }
4392254721Semaste
4393254721Semaste                if (num_matches == 0)
4394254721Semaste                {
4395254721Semaste                    // No matches yet, iterate through the module specs to find a UUID value that
4396254721Semaste                    // we can match up to an image in our target
4397254721Semaste                    const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4398254721Semaste                    for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i)
4399254721Semaste                    {
4400254721Semaste                        if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
4401254721Semaste                        {
4402254721Semaste                            if (symfile_module_spec.GetUUID().IsValid())
4403254721Semaste                            {
4404254721Semaste                                // It has a UUID, look for this UUID in the target modules
4405254721Semaste                                ModuleSpec symfile_uuid_module_spec;
4406254721Semaste                                symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4407254721Semaste                                num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4408254721Semaste                            }
4409254721Semaste                        }
4410254721Semaste                    }
4411254721Semaste                }
4412254721Semaste            }
4413254721Semaste
4414254721Semaste            // Just try to match up the file by basename if we have no matches at this point
4415254721Semaste            if (num_matches == 0)
4416254721Semaste                num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4417254721Semaste
4418254721Semaste            while (num_matches == 0)
4419254721Semaste            {
4420254721Semaste                ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
4421254721Semaste                // Empty string returned, lets bail
4422254721Semaste                if (!filename_no_extension)
4423254721Semaste                    break;
4424254721Semaste
4425254721Semaste                // Check if there was no extension to strip and the basename is the same
4426254721Semaste                if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4427254721Semaste                    break;
4428254721Semaste
4429254721Semaste                // Replace basename with one less extension
4430254721Semaste                module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4431254721Semaste
4432254721Semaste                num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4433254721Semaste
4434254721Semaste            }
4435254721Semaste
4436254721Semaste            if (num_matches > 1)
4437254721Semaste            {
4438254721Semaste                result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
4439254721Semaste            }
4440254721Semaste            else if (num_matches == 1)
4441254721Semaste            {
4442254721Semaste                ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
4443254721Semaste
4444254721Semaste                // The module has not yet created its symbol vendor, we can just
4445254721Semaste                // give the existing target module the symfile path to use for
4446254721Semaste                // when it decides to create it!
4447254721Semaste                module_sp->SetSymbolFileFileSpec (symbol_fspec);
4448254721Semaste
4449254721Semaste                SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4450254721Semaste                if (symbol_vendor)
4451254721Semaste                {
4452254721Semaste                    SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4453254721Semaste
4454254721Semaste                    if (symbol_file)
4455254721Semaste                    {
4456254721Semaste                        ObjectFile *object_file = symbol_file->GetObjectFile();
4457254721Semaste
4458254721Semaste                        if (object_file && object_file->GetFileSpec() == symbol_fspec)
4459254721Semaste                        {
4460254721Semaste                            // Provide feedback that the symfile has been successfully added.
4461254721Semaste                            const FileSpec &module_fs = module_sp->GetFileSpec();
4462254721Semaste                            result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
4463254721Semaste                                                           symfile_path,
4464254721Semaste                                                           module_fs.GetPath().c_str());
4465254721Semaste
4466254721Semaste                            // Let clients know something changed in the module
4467254721Semaste                            // if it is currently loaded
4468254721Semaste                            ModuleList module_list;
4469254721Semaste                            module_list.Append (module_sp);
4470254721Semaste                            target->SymbolsDidLoad (module_list);
4471254721Semaste
4472254721Semaste                            // Make sure we load any scripting resources that may be embedded
4473254721Semaste                            // in the debug info files in case the platform supports that.
4474254721Semaste                            Error error;
4475254721Semaste                            StreamString feedback_stream;
4476254721Semaste                            module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
4477254721Semaste                            if (error.Fail() && error.AsCString())
4478254721Semaste                                result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
4479254721Semaste                                                               module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
4480254721Semaste                                                               error.AsCString());
4481254721Semaste                            else if (feedback_stream.GetSize())
4482254721Semaste                                result.AppendWarningWithFormat("%s",feedback_stream.GetData());
4483254721Semaste
4484254721Semaste                            flush = true;
4485254721Semaste                            result.SetStatus (eReturnStatusSuccessFinishResult);
4486254721Semaste                            return true;
4487254721Semaste                        }
4488254721Semaste                    }
4489254721Semaste                }
4490254721Semaste                // Clear the symbol file spec if anything went wrong
4491254721Semaste                module_sp->SetSymbolFileFileSpec (FileSpec());
4492254721Semaste            }
4493254721Semaste
4494254721Semaste            if (module_spec.GetUUID().IsValid())
4495254721Semaste            {
4496254721Semaste                StreamString ss_symfile_uuid;
4497254721Semaste                module_spec.GetUUID().Dump(&ss_symfile_uuid);
4498254721Semaste                result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
4499254721Semaste                                              symfile_path,
4500254721Semaste                                              ss_symfile_uuid.GetData(),
4501254721Semaste                                              (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4502254721Semaste                                                ? "\n       please specify the full path to the symbol file"
4503254721Semaste                                                : "");
4504254721Semaste            }
4505254721Semaste            else
4506254721Semaste            {
4507254721Semaste                result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
4508254721Semaste                                              symfile_path,
4509254721Semaste                                              (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4510254721Semaste                                                ? "\n       please specify the full path to the symbol file"
4511254721Semaste                                                : "");
4512254721Semaste            }
4513254721Semaste        }
4514254721Semaste        else
4515254721Semaste        {
4516254721Semaste            result.AppendError ("one or more executable image paths must be specified");
4517254721Semaste        }
4518254721Semaste        result.SetStatus (eReturnStatusFailed);
4519254721Semaste        return false;
4520254721Semaste    }
4521254721Semaste
4522254721Semaste    virtual bool
4523254721Semaste    DoExecute (Args& args,
4524254721Semaste             CommandReturnObject &result)
4525254721Semaste    {
4526254721Semaste        Target *target = m_exe_ctx.GetTargetPtr();
4527254721Semaste        result.SetStatus (eReturnStatusFailed);
4528254721Semaste        bool flush = false;
4529254721Semaste        ModuleSpec module_spec;
4530254721Semaste        const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4531254721Semaste        const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4532254721Semaste        const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4533254721Semaste
4534254721Semaste        const size_t argc = args.GetArgumentCount();
4535254721Semaste        if (argc == 0)
4536254721Semaste        {
4537254721Semaste            if (uuid_option_set || file_option_set || frame_option_set)
4538254721Semaste            {
4539254721Semaste                bool success = false;
4540254721Semaste                bool error_set = false;
4541254721Semaste                if (frame_option_set)
4542254721Semaste                {
4543254721Semaste                    Process *process = m_exe_ctx.GetProcessPtr();
4544254721Semaste                    if (process)
4545254721Semaste                    {
4546254721Semaste                        const StateType process_state = process->GetState();
4547254721Semaste                        if (StateIsStoppedState (process_state, true))
4548254721Semaste                        {
4549254721Semaste                            StackFrame *frame = m_exe_ctx.GetFramePtr();
4550254721Semaste                            if (frame)
4551254721Semaste                            {
4552254721Semaste                                ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4553254721Semaste                                if (frame_module_sp)
4554254721Semaste                                {
4555254721Semaste                                    if (frame_module_sp->GetPlatformFileSpec().Exists())
4556254721Semaste                                    {
4557254721Semaste                                        module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4558254721Semaste                                        module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4559254721Semaste                                    }
4560254721Semaste                                    module_spec.GetUUID() = frame_module_sp->GetUUID();
4561254721Semaste                                    success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
4562254721Semaste                                }
4563254721Semaste                                else
4564254721Semaste                                {
4565254721Semaste                                    result.AppendError ("frame has no module");
4566254721Semaste                                    error_set = true;
4567254721Semaste                                }
4568254721Semaste                            }
4569254721Semaste                            else
4570254721Semaste                            {
4571254721Semaste                                result.AppendError ("invalid current frame");
4572254721Semaste                                error_set = true;
4573254721Semaste                            }
4574254721Semaste                        }
4575254721Semaste                        else
4576254721Semaste                        {
4577254721Semaste                            result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4578254721Semaste                            error_set = true;
4579254721Semaste                        }
4580254721Semaste                    }
4581254721Semaste                    else
4582254721Semaste                    {
4583254721Semaste                        result.AppendError ("a process must exist in order to use the --frame option");
4584254721Semaste                        error_set = true;
4585254721Semaste                    }
4586254721Semaste                }
4587254721Semaste                else
4588254721Semaste                {
4589254721Semaste                    if (uuid_option_set)
4590254721Semaste                    {
4591254721Semaste                        module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4592254721Semaste                        success |= module_spec.GetUUID().IsValid();
4593254721Semaste                    }
4594254721Semaste                    else if (file_option_set)
4595254721Semaste                    {
4596254721Semaste                        module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4597254721Semaste                        ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
4598254721Semaste                        if (module_sp)
4599254721Semaste                        {
4600254721Semaste                            module_spec.GetFileSpec() = module_sp->GetFileSpec();
4601254721Semaste                            module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4602254721Semaste                            module_spec.GetUUID() = module_sp->GetUUID();
4603254721Semaste                            module_spec.GetArchitecture() = module_sp->GetArchitecture();
4604254721Semaste                        }
4605254721Semaste                        else
4606254721Semaste                        {
4607254721Semaste                            module_spec.GetArchitecture() = target->GetArchitecture();
4608254721Semaste                        }
4609254721Semaste                        success |= module_spec.GetFileSpec().Exists();
4610254721Semaste                    }
4611254721Semaste                }
4612254721Semaste
4613254721Semaste                if (success)
4614254721Semaste                {
4615254721Semaste                    if (Symbols::DownloadObjectAndSymbolFile (module_spec))
4616254721Semaste                    {
4617254721Semaste                        if (module_spec.GetSymbolFileSpec())
4618254721Semaste                            success = AddModuleSymbols (target, module_spec, flush, result);
4619254721Semaste                    }
4620254721Semaste                }
4621254721Semaste
4622254721Semaste                if (!success && !error_set)
4623254721Semaste                {
4624254721Semaste                    StreamString error_strm;
4625254721Semaste                    if (uuid_option_set)
4626254721Semaste                    {
4627254721Semaste                        error_strm.PutCString("unable to find debug symbols for UUID ");
4628254721Semaste                        module_spec.GetUUID().Dump (&error_strm);
4629254721Semaste                    }
4630254721Semaste                    else if (file_option_set)
4631254721Semaste                    {
4632254721Semaste                        error_strm.PutCString("unable to find debug symbols for the executable file ");
4633254721Semaste                        error_strm << module_spec.GetFileSpec();
4634254721Semaste                    }
4635254721Semaste                    else if (frame_option_set)
4636254721Semaste                    {
4637254721Semaste                        error_strm.PutCString("unable to find debug symbols for the current frame");
4638254721Semaste                    }
4639254721Semaste                    result.AppendError (error_strm.GetData());
4640254721Semaste                }
4641254721Semaste            }
4642254721Semaste            else
4643254721Semaste            {
4644254721Semaste                result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4645254721Semaste            }
4646254721Semaste        }
4647254721Semaste        else
4648254721Semaste        {
4649254721Semaste            if (uuid_option_set)
4650254721Semaste            {
4651254721Semaste                result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4652254721Semaste            }
4653254721Semaste            else if (file_option_set)
4654254721Semaste            {
4655254721Semaste                result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4656254721Semaste            }
4657254721Semaste            else if (frame_option_set)
4658254721Semaste            {
4659254721Semaste                result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4660254721Semaste            }
4661254721Semaste            else
4662254721Semaste            {
4663254721Semaste                PlatformSP platform_sp (target->GetPlatform());
4664254721Semaste
4665254721Semaste                for (size_t i=0; i<argc; ++i)
4666254721Semaste                {
4667254721Semaste                    const char *symfile_path = args.GetArgumentAtIndex(i);
4668254721Semaste                    if (symfile_path)
4669254721Semaste                    {
4670254721Semaste                        module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4671254721Semaste                        if (platform_sp)
4672254721Semaste                        {
4673254721Semaste                            FileSpec symfile_spec;
4674254721Semaste                            if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
4675254721Semaste                                module_spec.GetSymbolFileSpec() = symfile_spec;
4676254721Semaste                        }
4677254721Semaste
4678254721Semaste                        ArchSpec arch;
4679254721Semaste                        bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4680254721Semaste
4681254721Semaste                        if (symfile_exists)
4682254721Semaste                        {
4683254721Semaste                            if (!AddModuleSymbols (target, module_spec, flush, result))
4684254721Semaste                                break;
4685254721Semaste                        }
4686254721Semaste                        else
4687254721Semaste                        {
4688254721Semaste                            char resolved_symfile_path[PATH_MAX];
4689254721Semaste                            if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4690254721Semaste                            {
4691254721Semaste                                if (strcmp (resolved_symfile_path, symfile_path) != 0)
4692254721Semaste                                {
4693254721Semaste                                    result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4694254721Semaste                                    break;
4695254721Semaste                                }
4696254721Semaste                            }
4697254721Semaste                            result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4698254721Semaste                            break;
4699254721Semaste                        }
4700254721Semaste                    }
4701254721Semaste                }
4702254721Semaste            }
4703254721Semaste        }
4704254721Semaste
4705254721Semaste        if (flush)
4706254721Semaste        {
4707254721Semaste            Process *process = m_exe_ctx.GetProcessPtr();
4708254721Semaste            if (process)
4709254721Semaste                process->Flush();
4710254721Semaste        }
4711254721Semaste        return result.Succeeded();
4712254721Semaste    }
4713254721Semaste
4714254721Semaste    OptionGroupOptions m_option_group;
4715254721Semaste    OptionGroupUUID m_uuid_option_group;
4716254721Semaste    OptionGroupFile m_file_option;
4717254721Semaste    OptionGroupBoolean m_current_frame_option;
4718254721Semaste
4719254721Semaste
4720254721Semaste};
4721254721Semaste
4722254721Semaste
4723254721Semaste#pragma mark CommandObjectTargetSymbols
4724254721Semaste
4725254721Semaste//-------------------------------------------------------------------------
4726254721Semaste// CommandObjectTargetSymbols
4727254721Semaste//-------------------------------------------------------------------------
4728254721Semaste
4729254721Semasteclass CommandObjectTargetSymbols : public CommandObjectMultiword
4730254721Semaste{
4731254721Semastepublic:
4732254721Semaste    //------------------------------------------------------------------
4733254721Semaste    // Constructors and Destructors
4734254721Semaste    //------------------------------------------------------------------
4735254721Semaste    CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4736254721Semaste        CommandObjectMultiword (interpreter,
4737254721Semaste                            "target symbols",
4738254721Semaste                            "A set of commands for adding and managing debug symbol files.",
4739254721Semaste                            "target symbols <sub-command> ...")
4740254721Semaste    {
4741254721Semaste        LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4742254721Semaste
4743254721Semaste    }
4744254721Semaste    virtual
4745254721Semaste    ~CommandObjectTargetSymbols()
4746254721Semaste    {
4747254721Semaste    }
4748254721Semaste
4749254721Semasteprivate:
4750254721Semaste    //------------------------------------------------------------------
4751254721Semaste    // For CommandObjectTargetModules only
4752254721Semaste    //------------------------------------------------------------------
4753254721Semaste    DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4754254721Semaste};
4755254721Semaste
4756254721Semaste
4757254721Semaste#pragma mark CommandObjectTargetStopHookAdd
4758254721Semaste
4759254721Semaste//-------------------------------------------------------------------------
4760254721Semaste// CommandObjectTargetStopHookAdd
4761254721Semaste//-------------------------------------------------------------------------
4762254721Semaste
4763269024Semasteclass CommandObjectTargetStopHookAdd :
4764269024Semaste    public CommandObjectParsed,
4765269024Semaste    public IOHandlerDelegateMultiline
4766254721Semaste{
4767254721Semastepublic:
4768254721Semaste
4769254721Semaste    class CommandOptions : public Options
4770254721Semaste    {
4771254721Semaste    public:
4772254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
4773254721Semaste            Options(interpreter),
4774254721Semaste            m_line_start(0),
4775254721Semaste            m_line_end (UINT_MAX),
4776254721Semaste            m_func_name_type_mask (eFunctionNameTypeAuto),
4777254721Semaste            m_sym_ctx_specified (false),
4778254721Semaste            m_thread_specified (false),
4779254721Semaste            m_use_one_liner (false),
4780254721Semaste            m_one_liner()
4781254721Semaste        {
4782254721Semaste        }
4783254721Semaste
4784254721Semaste        ~CommandOptions () {}
4785254721Semaste
4786254721Semaste        const OptionDefinition*
4787254721Semaste        GetDefinitions ()
4788254721Semaste        {
4789254721Semaste            return g_option_table;
4790254721Semaste        }
4791254721Semaste
4792254721Semaste        virtual Error
4793254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
4794254721Semaste        {
4795254721Semaste            Error error;
4796254721Semaste            const int short_option = m_getopt_table[option_idx].val;
4797254721Semaste            bool success;
4798254721Semaste
4799254721Semaste            switch (short_option)
4800254721Semaste            {
4801254721Semaste                case 'c':
4802254721Semaste                    m_class_name = option_arg;
4803254721Semaste                    m_sym_ctx_specified = true;
4804254721Semaste                break;
4805254721Semaste
4806254721Semaste                case 'e':
4807254721Semaste                    m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
4808254721Semaste                    if (!success)
4809254721Semaste                    {
4810254721Semaste                        error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4811254721Semaste                        break;
4812254721Semaste                    }
4813254721Semaste                    m_sym_ctx_specified = true;
4814254721Semaste                break;
4815254721Semaste
4816254721Semaste                case 'l':
4817254721Semaste                    m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
4818254721Semaste                    if (!success)
4819254721Semaste                    {
4820254721Semaste                        error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4821254721Semaste                        break;
4822254721Semaste                    }
4823254721Semaste                    m_sym_ctx_specified = true;
4824254721Semaste                break;
4825254721Semaste
4826254721Semaste                case 'i':
4827254721Semaste                    m_no_inlines = true;
4828254721Semaste                break;
4829254721Semaste
4830254721Semaste                case 'n':
4831254721Semaste                    m_function_name = option_arg;
4832254721Semaste                    m_func_name_type_mask |= eFunctionNameTypeAuto;
4833254721Semaste                    m_sym_ctx_specified = true;
4834254721Semaste                break;
4835254721Semaste
4836254721Semaste                case 'f':
4837254721Semaste                    m_file_name = option_arg;
4838254721Semaste                    m_sym_ctx_specified = true;
4839254721Semaste                break;
4840254721Semaste                case 's':
4841254721Semaste                    m_module_name = option_arg;
4842254721Semaste                    m_sym_ctx_specified = true;
4843254721Semaste                break;
4844254721Semaste                case 't' :
4845254721Semaste                {
4846254721Semaste                    m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4847254721Semaste                    if (m_thread_id == LLDB_INVALID_THREAD_ID)
4848254721Semaste                       error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4849254721Semaste                    m_thread_specified = true;
4850254721Semaste                }
4851254721Semaste                break;
4852254721Semaste                case 'T':
4853254721Semaste                    m_thread_name = option_arg;
4854254721Semaste                    m_thread_specified = true;
4855254721Semaste                break;
4856254721Semaste                case 'q':
4857254721Semaste                    m_queue_name = option_arg;
4858254721Semaste                    m_thread_specified = true;
4859254721Semaste                    break;
4860254721Semaste                case 'x':
4861254721Semaste                {
4862254721Semaste                    m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
4863254721Semaste                    if (m_thread_id == UINT32_MAX)
4864254721Semaste                       error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4865254721Semaste                    m_thread_specified = true;
4866254721Semaste                }
4867254721Semaste                break;
4868254721Semaste                case 'o':
4869254721Semaste                    m_use_one_liner = true;
4870254721Semaste                    m_one_liner = option_arg;
4871254721Semaste                break;
4872254721Semaste                default:
4873254721Semaste                    error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4874254721Semaste                break;
4875254721Semaste            }
4876254721Semaste            return error;
4877254721Semaste        }
4878254721Semaste
4879254721Semaste        void
4880254721Semaste        OptionParsingStarting ()
4881254721Semaste        {
4882254721Semaste            m_class_name.clear();
4883254721Semaste            m_function_name.clear();
4884254721Semaste            m_line_start = 0;
4885254721Semaste            m_line_end = UINT_MAX;
4886254721Semaste            m_file_name.clear();
4887254721Semaste            m_module_name.clear();
4888254721Semaste            m_func_name_type_mask = eFunctionNameTypeAuto;
4889254721Semaste            m_thread_id = LLDB_INVALID_THREAD_ID;
4890254721Semaste            m_thread_index = UINT32_MAX;
4891254721Semaste            m_thread_name.clear();
4892254721Semaste            m_queue_name.clear();
4893254721Semaste
4894254721Semaste            m_no_inlines = false;
4895254721Semaste            m_sym_ctx_specified = false;
4896254721Semaste            m_thread_specified = false;
4897254721Semaste
4898254721Semaste            m_use_one_liner = false;
4899254721Semaste            m_one_liner.clear();
4900254721Semaste        }
4901254721Semaste
4902254721Semaste
4903254721Semaste        static OptionDefinition g_option_table[];
4904254721Semaste
4905254721Semaste        std::string m_class_name;
4906254721Semaste        std::string m_function_name;
4907254721Semaste        uint32_t    m_line_start;
4908254721Semaste        uint32_t    m_line_end;
4909254721Semaste        std::string m_file_name;
4910254721Semaste        std::string m_module_name;
4911254721Semaste        uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
4912254721Semaste        lldb::tid_t m_thread_id;
4913254721Semaste        uint32_t m_thread_index;
4914254721Semaste        std::string m_thread_name;
4915254721Semaste        std::string m_queue_name;
4916254721Semaste        bool        m_sym_ctx_specified;
4917254721Semaste        bool        m_no_inlines;
4918254721Semaste        bool        m_thread_specified;
4919254721Semaste        // Instance variables to hold the values for one_liner options.
4920254721Semaste        bool m_use_one_liner;
4921254721Semaste        std::string m_one_liner;
4922254721Semaste    };
4923254721Semaste
4924254721Semaste    Options *
4925254721Semaste    GetOptions ()
4926254721Semaste    {
4927254721Semaste        return &m_options;
4928254721Semaste    }
4929254721Semaste
4930254721Semaste    CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
4931254721Semaste        CommandObjectParsed (interpreter,
4932269024Semaste                             "target stop-hook add",
4933254721Semaste                             "Add a hook to be executed when the target stops.",
4934254721Semaste                             "target stop-hook add"),
4935269024Semaste        IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
4936254721Semaste        m_options (interpreter)
4937254721Semaste    {
4938254721Semaste    }
4939254721Semaste
4940254721Semaste    ~CommandObjectTargetStopHookAdd ()
4941254721Semaste    {
4942254721Semaste    }
4943254721Semaste
4944269024Semasteprotected:
4945269024Semaste
4946269024Semaste    virtual void
4947269024Semaste    IOHandlerActivated (IOHandler &io_handler)
4948254721Semaste    {
4949269024Semaste        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4950269024Semaste        if (output_sp)
4951254721Semaste        {
4952269024Semaste            output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
4953269024Semaste            output_sp->Flush();
4954269024Semaste        }
4955269024Semaste    }
4956269024Semaste
4957269024Semaste
4958269024Semaste    virtual void
4959269024Semaste    IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
4960269024Semaste    {
4961269024Semaste        if (m_stop_hook_sp)
4962269024Semaste        {
4963269024Semaste            if (line.empty())
4964254721Semaste            {
4965269024Semaste                StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4966269024Semaste                if (error_sp)
4967254721Semaste                {
4968269024Semaste                    error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
4969269024Semaste                    error_sp->Flush();
4970254721Semaste                }
4971269024Semaste                Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4972269024Semaste                if (target)
4973269024Semaste                    target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4974254721Semaste            }
4975269024Semaste            else
4976254721Semaste            {
4977269024Semaste                m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4978269024Semaste                StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4979269024Semaste                if (output_sp)
4980254721Semaste                {
4981269024Semaste                    output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
4982269024Semaste                    output_sp->Flush();
4983254721Semaste                }
4984254721Semaste            }
4985269024Semaste            m_stop_hook_sp.reset();
4986254721Semaste        }
4987269024Semaste        io_handler.SetIsDone(true);
4988254721Semaste    }
4989269024Semaste
4990254721Semaste    bool
4991254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
4992254721Semaste    {
4993269024Semaste        m_stop_hook_sp.reset();
4994269024Semaste
4995254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4996254721Semaste        if (target)
4997254721Semaste        {
4998269024Semaste            Target::StopHookSP new_hook_sp = target->CreateStopHook();
4999254721Semaste
5000254721Semaste            //  First step, make the specifier.
5001254721Semaste            std::unique_ptr<SymbolContextSpecifier> specifier_ap;
5002254721Semaste            if (m_options.m_sym_ctx_specified)
5003254721Semaste            {
5004254721Semaste                specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
5005254721Semaste
5006254721Semaste                if (!m_options.m_module_name.empty())
5007254721Semaste                {
5008254721Semaste                    specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
5009254721Semaste                }
5010254721Semaste
5011254721Semaste                if (!m_options.m_class_name.empty())
5012254721Semaste                {
5013254721Semaste                    specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
5014254721Semaste                }
5015254721Semaste
5016254721Semaste                if (!m_options.m_file_name.empty())
5017254721Semaste                {
5018254721Semaste                    specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
5019254721Semaste                }
5020254721Semaste
5021254721Semaste                if (m_options.m_line_start != 0)
5022254721Semaste                {
5023254721Semaste                    specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
5024254721Semaste                }
5025254721Semaste
5026254721Semaste                if (m_options.m_line_end != UINT_MAX)
5027254721Semaste                {
5028254721Semaste                    specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5029254721Semaste                }
5030254721Semaste
5031254721Semaste                if (!m_options.m_function_name.empty())
5032254721Semaste                {
5033254721Semaste                    specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
5034254721Semaste                }
5035254721Semaste            }
5036254721Semaste
5037254721Semaste            if (specifier_ap.get())
5038254721Semaste                new_hook_sp->SetSpecifier (specifier_ap.release());
5039254721Semaste
5040254721Semaste            // Next see if any of the thread options have been entered:
5041254721Semaste
5042254721Semaste            if (m_options.m_thread_specified)
5043254721Semaste            {
5044254721Semaste                ThreadSpec *thread_spec = new ThreadSpec();
5045254721Semaste
5046254721Semaste                if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5047254721Semaste                {
5048254721Semaste                    thread_spec->SetTID (m_options.m_thread_id);
5049254721Semaste                }
5050254721Semaste
5051254721Semaste                if (m_options.m_thread_index != UINT32_MAX)
5052254721Semaste                    thread_spec->SetIndex (m_options.m_thread_index);
5053254721Semaste
5054254721Semaste                if (!m_options.m_thread_name.empty())
5055254721Semaste                    thread_spec->SetName (m_options.m_thread_name.c_str());
5056254721Semaste
5057254721Semaste                if (!m_options.m_queue_name.empty())
5058254721Semaste                    thread_spec->SetQueueName (m_options.m_queue_name.c_str());
5059254721Semaste
5060254721Semaste                new_hook_sp->SetThreadSpecifier (thread_spec);
5061254721Semaste
5062254721Semaste            }
5063254721Semaste            if (m_options.m_use_one_liner)
5064254721Semaste            {
5065254721Semaste                // Use one-liner.
5066254721Semaste                new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
5067254721Semaste                result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
5068254721Semaste            }
5069254721Semaste            else
5070254721Semaste            {
5071269024Semaste                m_stop_hook_sp = new_hook_sp;
5072269024Semaste                m_interpreter.GetLLDBCommandsFromIOHandler ("> ",   // Prompt
5073269024Semaste                                                            *this,  // IOHandlerDelegate
5074269024Semaste                                                            true,   // Run IOHandler in async mode
5075269024Semaste                                                            NULL);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
5076269024Semaste
5077254721Semaste            }
5078254721Semaste            result.SetStatus (eReturnStatusSuccessFinishNoResult);
5079254721Semaste        }
5080254721Semaste        else
5081254721Semaste        {
5082254721Semaste            result.AppendError ("invalid target\n");
5083254721Semaste            result.SetStatus (eReturnStatusFailed);
5084254721Semaste        }
5085254721Semaste
5086254721Semaste        return result.Succeeded();
5087254721Semaste    }
5088254721Semasteprivate:
5089254721Semaste    CommandOptions m_options;
5090269024Semaste    Target::StopHookSP m_stop_hook_sp;
5091254721Semaste};
5092254721Semaste
5093254721SemasteOptionDefinition
5094254721SemasteCommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
5095254721Semaste{
5096263363Semaste    { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOneLiner,
5097254721Semaste        "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
5098263363Semaste    { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
5099254721Semaste        "Set the module within which the stop-hook is to be run."},
5100263363Semaste    { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex,
5101254721Semaste        "The stop hook is run only for the thread whose index matches this argument."},
5102263363Semaste    { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadID,
5103254721Semaste        "The stop hook is run only for the thread whose TID matches this argument."},
5104263363Semaste    { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadName,
5105254721Semaste        "The stop hook is run only for the thread whose thread name matches this argument."},
5106263363Semaste    { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, 0, eArgTypeQueueName,
5107254721Semaste        "The stop hook is run only for threads in the queue whose name is given by this argument."},
5108263363Semaste    { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
5109254721Semaste        "Specify the source file within which the stop-hook is to be run." },
5110263363Semaste    { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
5111254721Semaste        "Set the start of the line range for which the stop-hook is to be run."},
5112263363Semaste    { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
5113254721Semaste        "Set the end of the line range for which the stop-hook is to be run."},
5114263363Semaste    { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeClassName,
5115254721Semaste        "Specify the class within which the stop-hook is to be run." },
5116263363Semaste    { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
5117254721Semaste        "Set the function name within which the stop hook will be run." },
5118254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
5119254721Semaste};
5120254721Semaste
5121254721Semaste#pragma mark CommandObjectTargetStopHookDelete
5122254721Semaste
5123254721Semaste//-------------------------------------------------------------------------
5124254721Semaste// CommandObjectTargetStopHookDelete
5125254721Semaste//-------------------------------------------------------------------------
5126254721Semaste
5127254721Semasteclass CommandObjectTargetStopHookDelete : public CommandObjectParsed
5128254721Semaste{
5129254721Semastepublic:
5130254721Semaste
5131254721Semaste    CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
5132254721Semaste        CommandObjectParsed (interpreter,
5133254721Semaste                             "target stop-hook delete",
5134254721Semaste                             "Delete a stop-hook.",
5135254721Semaste                             "target stop-hook delete [<idx>]")
5136254721Semaste    {
5137254721Semaste    }
5138254721Semaste
5139254721Semaste    ~CommandObjectTargetStopHookDelete ()
5140254721Semaste    {
5141254721Semaste    }
5142254721Semaste
5143254721Semasteprotected:
5144254721Semaste    bool
5145254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
5146254721Semaste    {
5147254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5148254721Semaste        if (target)
5149254721Semaste        {
5150254721Semaste            // FIXME: see if we can use the breakpoint id style parser?
5151254721Semaste            size_t num_args = command.GetArgumentCount();
5152254721Semaste            if (num_args == 0)
5153254721Semaste            {
5154254721Semaste                if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
5155254721Semaste                {
5156254721Semaste                    result.SetStatus (eReturnStatusFailed);
5157254721Semaste                    return false;
5158254721Semaste                }
5159254721Semaste                else
5160254721Semaste                {
5161254721Semaste                    target->RemoveAllStopHooks();
5162254721Semaste                }
5163254721Semaste            }
5164254721Semaste            else
5165254721Semaste            {
5166254721Semaste                bool success;
5167254721Semaste                for (size_t i = 0; i < num_args; i++)
5168254721Semaste                {
5169254721Semaste                    lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5170254721Semaste                    if (!success)
5171254721Semaste                    {
5172254721Semaste                        result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5173254721Semaste                        result.SetStatus(eReturnStatusFailed);
5174254721Semaste                        return false;
5175254721Semaste                    }
5176254721Semaste                    success = target->RemoveStopHookByID (user_id);
5177254721Semaste                    if (!success)
5178254721Semaste                    {
5179254721Semaste                        result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5180254721Semaste                        result.SetStatus(eReturnStatusFailed);
5181254721Semaste                        return false;
5182254721Semaste                    }
5183254721Semaste                }
5184254721Semaste            }
5185254721Semaste            result.SetStatus (eReturnStatusSuccessFinishNoResult);
5186254721Semaste        }
5187254721Semaste        else
5188254721Semaste        {
5189254721Semaste            result.AppendError ("invalid target\n");
5190254721Semaste            result.SetStatus (eReturnStatusFailed);
5191254721Semaste        }
5192254721Semaste
5193254721Semaste        return result.Succeeded();
5194254721Semaste    }
5195254721Semaste};
5196254721Semaste#pragma mark CommandObjectTargetStopHookEnableDisable
5197254721Semaste
5198254721Semaste//-------------------------------------------------------------------------
5199254721Semaste// CommandObjectTargetStopHookEnableDisable
5200254721Semaste//-------------------------------------------------------------------------
5201254721Semaste
5202254721Semasteclass CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
5203254721Semaste{
5204254721Semastepublic:
5205254721Semaste
5206254721Semaste    CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
5207254721Semaste        CommandObjectParsed (interpreter,
5208254721Semaste                             name,
5209254721Semaste                             help,
5210254721Semaste                             syntax),
5211254721Semaste        m_enable (enable)
5212254721Semaste    {
5213254721Semaste    }
5214254721Semaste
5215254721Semaste    ~CommandObjectTargetStopHookEnableDisable ()
5216254721Semaste    {
5217254721Semaste    }
5218254721Semaste
5219254721Semasteprotected:
5220254721Semaste    bool
5221254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
5222254721Semaste    {
5223254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5224254721Semaste        if (target)
5225254721Semaste        {
5226254721Semaste            // FIXME: see if we can use the breakpoint id style parser?
5227254721Semaste            size_t num_args = command.GetArgumentCount();
5228254721Semaste            bool success;
5229254721Semaste
5230254721Semaste            if (num_args == 0)
5231254721Semaste            {
5232254721Semaste                target->SetAllStopHooksActiveState (m_enable);
5233254721Semaste            }
5234254721Semaste            else
5235254721Semaste            {
5236254721Semaste                for (size_t i = 0; i < num_args; i++)
5237254721Semaste                {
5238254721Semaste                    lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5239254721Semaste                    if (!success)
5240254721Semaste                    {
5241254721Semaste                        result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5242254721Semaste                        result.SetStatus(eReturnStatusFailed);
5243254721Semaste                        return false;
5244254721Semaste                    }
5245254721Semaste                    success = target->SetStopHookActiveStateByID (user_id, m_enable);
5246254721Semaste                    if (!success)
5247254721Semaste                    {
5248254721Semaste                        result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5249254721Semaste                        result.SetStatus(eReturnStatusFailed);
5250254721Semaste                        return false;
5251254721Semaste                    }
5252254721Semaste                }
5253254721Semaste            }
5254254721Semaste            result.SetStatus (eReturnStatusSuccessFinishNoResult);
5255254721Semaste        }
5256254721Semaste        else
5257254721Semaste        {
5258254721Semaste            result.AppendError ("invalid target\n");
5259254721Semaste            result.SetStatus (eReturnStatusFailed);
5260254721Semaste        }
5261254721Semaste        return result.Succeeded();
5262254721Semaste    }
5263254721Semasteprivate:
5264254721Semaste    bool m_enable;
5265254721Semaste};
5266254721Semaste
5267254721Semaste#pragma mark CommandObjectTargetStopHookList
5268254721Semaste
5269254721Semaste//-------------------------------------------------------------------------
5270254721Semaste// CommandObjectTargetStopHookList
5271254721Semaste//-------------------------------------------------------------------------
5272254721Semaste
5273254721Semasteclass CommandObjectTargetStopHookList : public CommandObjectParsed
5274254721Semaste{
5275254721Semastepublic:
5276254721Semaste
5277254721Semaste    CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
5278254721Semaste        CommandObjectParsed (interpreter,
5279254721Semaste                             "target stop-hook list",
5280254721Semaste                             "List all stop-hooks.",
5281254721Semaste                             "target stop-hook list [<type>]")
5282254721Semaste    {
5283254721Semaste    }
5284254721Semaste
5285254721Semaste    ~CommandObjectTargetStopHookList ()
5286254721Semaste    {
5287254721Semaste    }
5288254721Semaste
5289254721Semasteprotected:
5290254721Semaste    bool
5291254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
5292254721Semaste    {
5293254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5294254721Semaste        if (!target)
5295254721Semaste        {
5296254721Semaste            result.AppendError ("invalid target\n");
5297254721Semaste            result.SetStatus (eReturnStatusFailed);
5298254721Semaste            return result.Succeeded();
5299254721Semaste        }
5300254721Semaste
5301254721Semaste        size_t num_hooks = target->GetNumStopHooks ();
5302254721Semaste        if (num_hooks == 0)
5303254721Semaste        {
5304254721Semaste            result.GetOutputStream().PutCString ("No stop hooks.\n");
5305254721Semaste        }
5306254721Semaste        else
5307254721Semaste        {
5308254721Semaste            for (size_t i = 0; i < num_hooks; i++)
5309254721Semaste            {
5310254721Semaste                Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
5311254721Semaste                if (i > 0)
5312254721Semaste                    result.GetOutputStream().PutCString ("\n");
5313254721Semaste                this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
5314254721Semaste            }
5315254721Semaste        }
5316254721Semaste        result.SetStatus (eReturnStatusSuccessFinishResult);
5317254721Semaste        return result.Succeeded();
5318254721Semaste    }
5319254721Semaste};
5320254721Semaste
5321254721Semaste#pragma mark CommandObjectMultiwordTargetStopHooks
5322254721Semaste//-------------------------------------------------------------------------
5323254721Semaste// CommandObjectMultiwordTargetStopHooks
5324254721Semaste//-------------------------------------------------------------------------
5325254721Semaste
5326254721Semasteclass CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
5327254721Semaste{
5328254721Semastepublic:
5329254721Semaste
5330254721Semaste    CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
5331254721Semaste        CommandObjectMultiword (interpreter,
5332254721Semaste                                "target stop-hook",
5333254721Semaste                                "A set of commands for operating on debugger target stop-hooks.",
5334254721Semaste                                "target stop-hook <subcommand> [<subcommand-options>]")
5335254721Semaste    {
5336254721Semaste        LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
5337254721Semaste        LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
5338254721Semaste        LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5339254721Semaste                                                                                                   false,
5340254721Semaste                                                                                                   "target stop-hook disable [<id>]",
5341254721Semaste                                                                                                   "Disable a stop-hook.",
5342254721Semaste                                                                                                   "target stop-hook disable")));
5343254721Semaste        LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5344254721Semaste                                                                                                   true,
5345254721Semaste                                                                                                   "target stop-hook enable [<id>]",
5346254721Semaste                                                                                                   "Enable a stop-hook.",
5347254721Semaste                                                                                                   "target stop-hook enable")));
5348254721Semaste        LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5349254721Semaste    }
5350254721Semaste
5351254721Semaste    ~CommandObjectMultiwordTargetStopHooks()
5352254721Semaste    {
5353254721Semaste    }
5354254721Semaste};
5355254721Semaste
5356254721Semaste
5357254721Semaste
5358254721Semaste#pragma mark CommandObjectMultiwordTarget
5359254721Semaste
5360254721Semaste//-------------------------------------------------------------------------
5361254721Semaste// CommandObjectMultiwordTarget
5362254721Semaste//-------------------------------------------------------------------------
5363254721Semaste
5364254721SemasteCommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
5365254721Semaste    CommandObjectMultiword (interpreter,
5366254721Semaste                            "target",
5367254721Semaste                            "A set of commands for operating on debugger targets.",
5368254721Semaste                            "target <subcommand> [<subcommand-options>]")
5369254721Semaste{
5370254721Semaste
5371254721Semaste    LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5372254721Semaste    LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5373254721Semaste    LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5374254721Semaste    LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5375254721Semaste    LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5376254721Semaste    LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5377254721Semaste    LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5378254721Semaste    LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5379254721Semaste}
5380254721Semaste
5381254721SemasteCommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5382254721Semaste{
5383254721Semaste}
5384254721Semaste
5385254721Semaste
5386