From 998255bfe841a4191d458a56aae0267f673b1a72 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Sat, 13 Oct 2012 02:07:45 +0000 Subject: [PATCH] I added the ability for a process plug-in to implement custom commands. All the lldb_private::Process plug-in has to do is override: virtual CommandObject * GetPluginCommandObject(); This object returned should be a multi-word command that vends LLDB commands. There is a sample implementation in ProcessGDBRemote that is hollowed out. It is intended to be used for sending a custom packet, though the body of the command execute function has yet to be implemented! llvm-svn: 165861 --- lldb/include/lldb/Interpreter/CommandInterpreter.h | 7 - lldb/include/lldb/Interpreter/CommandObject.h | 25 +++ .../lldb/Interpreter/CommandObjectCrossref.h | 2 +- .../lldb/Interpreter/CommandObjectMultiword.h | 106 +++++++++- lldb/include/lldb/Target/Process.h | 20 ++ lldb/source/Commands/CommandObjectCommands.cpp | 3 +- lldb/source/Commands/CommandObjectHelp.cpp | 5 +- lldb/source/Commands/CommandObjectMultiword.cpp | 229 +++++++++++++++++++++ lldb/source/Commands/CommandObjectProcess.cpp | 35 +++- lldb/source/Commands/CommandObjectSyntax.cpp | 8 +- lldb/source/Interpreter/CommandInterpreter.cpp | 42 +--- lldb/source/Interpreter/CommandObject.cpp | 16 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 58 +++++- .../Plugins/Process/gdb-remote/ProcessGDBRemote.h | 5 +- 14 files changed, 491 insertions(+), 70 deletions(-) diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h index 6d8a4fc..0fbff9a 100644 --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -412,13 +412,6 @@ public: FindCommandsForApropos (const char *word, StringList &commands_found, StringList &commands_help); - - void - AproposAllSubCommands (CommandObject *cmd_obj, - const char *prefix, - const char *search_word, - StringList &commands_found, - StringList &commands_help); bool GetBatchCommandMode () { return m_batch_command_mode; } diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h index eb99d99..ccc2424 100644 --- a/lldb/include/lldb/Interpreter/CommandObject.h +++ b/lldb/include/lldb/Interpreter/CommandObject.h @@ -144,6 +144,31 @@ public: virtual bool IsMultiwordObject () { return false; } + virtual lldb::CommandObjectSP + GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL) + { + return lldb::CommandObjectSP(); + } + + virtual CommandObject * + GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL) + { + return NULL; + } + + virtual void + AproposAllSubCommands (const char *prefix, + const char *search_word, + StringList &commands_found, + StringList &commands_help) + { + } + + virtual void + GenerateHelpText (CommandReturnObject &result) + { + } + // this is needed in order to allow the SBCommand class to // transparently try and load subcommands - it will fail on // anything but a multiword command, but it avoids us doing diff --git a/lldb/include/lldb/Interpreter/CommandObjectCrossref.h b/lldb/include/lldb/Interpreter/CommandObjectCrossref.h index 839f223..0115cff 100644 --- a/lldb/include/lldb/Interpreter/CommandObjectCrossref.h +++ b/lldb/include/lldb/Interpreter/CommandObjectCrossref.h @@ -34,7 +34,7 @@ public: virtual ~CommandObjectCrossref (); - void + virtual void GenerateHelpText (CommandReturnObject &result); virtual bool diff --git a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h index 3d9b273..c139044 100644 --- a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -46,15 +46,21 @@ public: LoadSubCommand (const char *cmd_name, const lldb::CommandObjectSP& command_obj); - void + virtual void GenerateHelpText (CommandReturnObject &result); - lldb::CommandObjectSP + virtual lldb::CommandObjectSP GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL); - CommandObject * + virtual CommandObject * GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL); + virtual void + AproposAllSubCommands (const char *prefix, + const char *search_word, + StringList &commands_found, + StringList &commands_help); + virtual bool WantsRawCommandString() { return false; }; @@ -88,6 +94,100 @@ protected: bool m_can_be_removed; }; + +class CommandObjectProxy : public CommandObject +{ +public: + CommandObjectProxy (CommandInterpreter &interpreter, + const char *name, + const char *help = NULL, + const char *syntax = NULL, + uint32_t flags = 0); + + virtual + ~CommandObjectProxy (); + + // Subclasses must provide a command object that will be transparently + // used for this object. + virtual CommandObject * + GetProxyCommandObject() = 0; + + virtual const char * + GetHelpLong (); + + virtual void + AddObject (const char *obj_name); + + virtual bool + IsCrossRefObject (); + + virtual bool + IsRemovable() const; + + virtual bool + IsMultiwordObject (); + + virtual lldb::CommandObjectSP + GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL); + + virtual CommandObject * + GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL); + + virtual void + AproposAllSubCommands (const char *prefix, + const char *search_word, + StringList &commands_found, + StringList &commands_help); + + virtual bool + LoadSubCommand (const char *cmd_name, + const lldb::CommandObjectSP& command_obj); + + virtual bool + WantsRawCommandString(); + + virtual bool + WantsCompletion(); + + virtual Options * + GetOptions (); + + + virtual int + HandleCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + + virtual int + HandleArgumentCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + + virtual const char * + GetRepeatCommand (Args ¤t_command_args, + uint32_t index); + + virtual bool + Execute (const char *args_string, + CommandReturnObject &result); + +protected: + + // These two want to iterate over the subcommand dictionary. + friend class CommandInterpreter; + friend class CommandObjectSyntax; + +}; + } // namespace lldb_private #endif // liblldb_CommandObjectMultiword_h_ diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 7921ca8..e043190 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1579,6 +1579,26 @@ public: } //------------------------------------------------------------------ + /// Return a multi-word command object that can be used to expose + /// plug-in specific commands. + /// + /// This object will be used to resolve plug-in commands and can be + /// triggered by a call to: + /// + /// (lldb) process commmand + /// + /// @return + /// A CommandObject which can be one of the concrete subclasses + /// of CommandObject like CommandObjectRaw, CommandObjectParsed, + /// or CommandObjectMultiword. + //------------------------------------------------------------------ + virtual CommandObject * + GetPluginCommandObject() + { + return NULL; + } + + //------------------------------------------------------------------ /// Launch a new process. /// /// Launch a new process by spawning a new process using the diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 364c6f5..4c41d31 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -599,8 +599,7 @@ protected: { const std::string sub_command = args.GetArgumentAtIndex(0); assert (sub_command.length() != 0); - subcommand_obj_sp = - (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str())); + subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str()); if (subcommand_obj_sp.get()) { sub_cmd_obj = subcommand_obj_sp.get(); diff --git a/lldb/source/Commands/CommandObjectHelp.cpp b/lldb/source/Commands/CommandObjectHelp.cpp index 5dfb105b..3879005 100644 --- a/lldb/source/Commands/CommandObjectHelp.cpp +++ b/lldb/source/Commands/CommandObjectHelp.cpp @@ -103,8 +103,7 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result) else { CommandObject *found_cmd; - found_cmd = ((CommandObjectMultiword *) sub_cmd_obj)->GetSubcommandObject(sub_command.c_str(), - &matches); + found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches); if (found_cmd == NULL) all_okay = false; else if (matches.GetSize() > 1) @@ -189,7 +188,7 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result) } else m_interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1); - ((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (result); + sub_cmd_obj->GenerateHelpText (result); } else { diff --git a/lldb/source/Commands/CommandObjectMultiword.cpp b/lldb/source/Commands/CommandObjectMultiword.cpp index e11d37b..9fcd40f 100644 --- a/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/lldb/source/Commands/CommandObjectMultiword.cpp @@ -307,3 +307,232 @@ CommandObjectMultiword::GetRepeatCommand (Args ¤t_command_args, uint32_t i return sub_command_object->GetRepeatCommand(current_command_args, index); } + +void +CommandObjectMultiword::AproposAllSubCommands (const char *prefix, + const char *search_word, + StringList &commands_found, + StringList &commands_help) +{ + CommandObject::CommandMap::const_iterator pos; + + for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) + { + const char * command_name = pos->first.c_str(); + CommandObject *sub_cmd_obj = pos->second.get(); + StreamString complete_command_name; + + complete_command_name.Printf ("%s %s", prefix, command_name); + + if (sub_cmd_obj->HelpTextContainsWord (search_word)) + { + commands_found.AppendString (complete_command_name.GetData()); + commands_help.AppendString (sub_cmd_obj->GetHelp()); + } + + if (sub_cmd_obj->IsMultiwordObject()) + sub_cmd_obj->AproposAllSubCommands (complete_command_name.GetData(), + search_word, + commands_found, + commands_help); + } +} + + + +CommandObjectProxy::CommandObjectProxy (CommandInterpreter &interpreter, + const char *name, + const char *help, + const char *syntax, + uint32_t flags) : + CommandObject (interpreter, name, help, syntax, flags) +{ +} + +CommandObjectProxy::~CommandObjectProxy () +{ +} + +const char * +CommandObjectProxy::GetHelpLong () +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->GetHelpLong(); + return NULL; +} + +void +CommandObjectProxy::AddObject (const char *obj_name) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->AddObject (obj_name); +} + +bool +CommandObjectProxy::IsCrossRefObject () +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->IsCrossRefObject(); + return false; +} + +bool +CommandObjectProxy::IsRemovable() const +{ + const CommandObject *proxy_command = const_cast(this)->GetProxyCommandObject(); + if (proxy_command) + return proxy_command->IsRemovable(); + return false; +} + +bool +CommandObjectProxy::IsMultiwordObject () +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->IsMultiwordObject(); + return false; +} + +lldb::CommandObjectSP +CommandObjectProxy::GetSubcommandSP (const char *sub_cmd, StringList *matches) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->GetSubcommandSP(sub_cmd, matches); + return lldb::CommandObjectSP(); +} + +CommandObject * +CommandObjectProxy::GetSubcommandObject (const char *sub_cmd, StringList *matches) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->GetSubcommandObject(sub_cmd, matches); + return NULL; +} + +void +CommandObjectProxy::AproposAllSubCommands (const char *prefix, + const char *search_word, + StringList &commands_found, + StringList &commands_help) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->AproposAllSubCommands (prefix, + search_word, + commands_found, + commands_help); +} + +bool +CommandObjectProxy::LoadSubCommand (const char *cmd_name, + const lldb::CommandObjectSP& command_sp) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->LoadSubCommand (cmd_name, command_sp); + return false; +} + +bool +CommandObjectProxy::WantsRawCommandString() +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->WantsRawCommandString(); + return false; +} + +bool +CommandObjectProxy::WantsCompletion() +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->WantsCompletion(); + return false; +} + + +Options * +CommandObjectProxy::GetOptions () +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->GetOptions (); + return NULL; +} + + +int +CommandObjectProxy::HandleCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->HandleCompletion (input, + cursor_index, + cursor_char_position, + match_start_point, + max_return_elements, + word_complete, + matches); + matches.Clear(); + return 0; +} +int +CommandObjectProxy::HandleArgumentCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->HandleArgumentCompletion (input, + cursor_index, + cursor_char_position, + opt_element_vector, + match_start_point, + max_return_elements, + word_complete, + matches); + matches.Clear(); + return 0; +} + +const char * +CommandObjectProxy::GetRepeatCommand (Args ¤t_command_args, + uint32_t index) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->GetRepeatCommand (current_command_args, index); + return NULL; +} + +bool +CommandObjectProxy::Execute (const char *args_string, + CommandReturnObject &result) +{ + CommandObject *proxy_command = GetProxyCommandObject(); + if (proxy_command) + return proxy_command->Execute (args_string, result); + result.AppendError ("command is not implemented"); + result.SetStatus (eReturnStatusFailed); + return false; +} + + diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 5653e7a..41e216e 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -1071,7 +1071,6 @@ protected: CommandOptions m_options; }; - OptionDefinition CommandObjectProcessConnect::CommandOptions::g_option_table[] = { @@ -1080,6 +1079,39 @@ CommandObjectProcessConnect::CommandOptions::g_option_table[] = }; //------------------------------------------------------------------------- +// CommandObjectProcessPlugin +//------------------------------------------------------------------------- +#pragma mark CommandObjectProcessPlugin + +class CommandObjectProcessPlugin : public CommandObjectProxy +{ +public: + + CommandObjectProcessPlugin (CommandInterpreter &interpreter) : + CommandObjectProxy (interpreter, + "process plugin", + "Send a custom command to the current process plug-in.", + "process plugin ", + 0) + { + } + + ~CommandObjectProcessPlugin () + { + } + + virtual CommandObject * + GetProxyCommandObject() + { + Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + if (process) + return process->GetPluginCommandObject(); + return NULL; + } +}; + + +//------------------------------------------------------------------------- // CommandObjectProcessLoad //------------------------------------------------------------------------- #pragma mark CommandObjectProcessLoad @@ -1794,6 +1826,7 @@ CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); + LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter))); } CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () diff --git a/lldb/source/Commands/CommandObjectSyntax.cpp b/lldb/source/Commands/CommandObjectSyntax.cpp index d96542e..64308aa 100644 --- a/lldb/source/Commands/CommandObjectSyntax.cpp +++ b/lldb/source/Commands/CommandObjectSyntax.cpp @@ -66,14 +66,12 @@ CommandObjectSyntax::DoExecute (Args& command, CommandReturnObject &result) for (int i = 1; i < argc; ++i) { std::string sub_command = command.GetArgumentAtIndex (i); - if (! cmd_obj->IsMultiwordObject()) + if (!cmd_obj->IsMultiwordObject()) all_okay = false; else { - pos = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.find (sub_command); - if (pos != ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.end()) - cmd_obj = pos->second.get(); - else + cmd_obj = cmd_obj->GetSubcommandObject(sub_command.c_str()); + if (!cmd_obj) all_okay = false; } } diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 56a9d1b..453004d 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -763,8 +763,7 @@ CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliase { if (cmd_obj_sp->IsMultiwordObject()) { - cmd_obj_sp = ((CommandObjectMultiword *) cmd_obj_sp.get())->GetSubcommandSP - (cmd_words.GetArgumentAtIndex (j)); + cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j)); if (cmd_obj_sp.get() == NULL) // The sub-command name was invalid. Fail and return the empty 'ret_val'. return ret_val; @@ -1049,8 +1048,7 @@ CommandInterpreter::GetCommandObjectForCommand (std::string &command_string) else if (cmd_obj->IsMultiwordObject ()) { // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object. - CommandObject *sub_cmd_obj = - ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (cmd_word.c_str()); + CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str()); if (sub_cmd_obj) cmd_obj = sub_cmd_obj; else // cmd_word was not a valid sub-command word, so we are donee @@ -1547,7 +1545,7 @@ CommandInterpreter::HandleCommand (const char *command_line, { if (cmd_obj->IsMultiwordObject ()) { - CommandObject *sub_cmd_obj = ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (next_word.c_str()); + CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str()); if (sub_cmd_obj) { actual_cmd_name_len += next_word.length() + 1; @@ -2722,35 +2720,6 @@ CommandInterpreter::OutputHelpText (Stream &strm, } void -CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word, - StringList &commands_found, StringList &commands_help) -{ - CommandObject::CommandMap::const_iterator pos; - CommandObject::CommandMap sub_cmd_dict = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict; - CommandObject *sub_cmd_obj; - - for (pos = sub_cmd_dict.begin(); pos != sub_cmd_dict.end(); ++pos) - { - const char * command_name = pos->first.c_str(); - sub_cmd_obj = pos->second.get(); - StreamString complete_command_name; - - complete_command_name.Printf ("%s %s", prefix, command_name); - - if (sub_cmd_obj->HelpTextContainsWord (search_word)) - { - commands_found.AppendString (complete_command_name.GetData()); - commands_help.AppendString (sub_cmd_obj->GetHelp()); - } - - if (sub_cmd_obj->IsMultiwordObject()) - AproposAllSubCommands (sub_cmd_obj, complete_command_name.GetData(), search_word, commands_found, - commands_help); - } - -} - -void CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found, StringList &commands_help) { @@ -2768,7 +2737,10 @@ CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList } if (cmd_obj->IsMultiwordObject()) - AproposAllSubCommands (cmd_obj, command_name, search_word, commands_found, commands_help); + cmd_obj->AproposAllSubCommands (command_name, + search_word, + commands_found, + commands_help); } } diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp index 11e90f2..8d8520d 100644 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -377,23 +377,19 @@ CommandObject::HandleCompletion bool CommandObject::HelpTextContainsWord (const char *search_word) { - const char *short_help; - const char *long_help; - const char *syntax_help; std::string options_usage_help; - bool found_word = false; - short_help = GetHelp(); - long_help = GetHelpLong(); - syntax_help = GetSyntax(); + const char *short_help = GetHelp(); + const char *long_help = GetHelpLong(); + const char *syntax_help = GetSyntax(); - if (strcasestr (short_help, search_word)) + if (short_help && strcasestr (short_help, search_word)) found_word = true; - else if (strcasestr (long_help, search_word)) + else if (long_help && strcasestr (long_help, search_word)) found_word = true; - else if (strcasestr (syntax_help, search_word)) + else if (syntax_help && strcasestr (syntax_help, search_word)) found_word = true; if (!found_word diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 215e885..a0658ab 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -196,7 +196,8 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_waiting_for_attach (false), m_destroy_tried_resuming (false), m_dyld_plugin_name(), - m_kernel_load_addr (LLDB_INVALID_ADDRESS) + m_kernel_load_addr (LLDB_INVALID_ADDRESS), + m_command_sp () { m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); @@ -3013,3 +3014,58 @@ ProcessGDBRemote::GetDynamicLoader () return m_dyld_ap.get(); } +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" + +class CommandObjectProcessGDBRemotePacket : public CommandObjectParsed +{ +private: + +public: + CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "process plugin packet", + "Send a custom packet through the GDB remote protocol and print the answer.", + NULL) + { + } + + ~CommandObjectProcessGDBRemotePacket () + { + } + + bool + DoExecute (Args& command, CommandReturnObject &result) + { + printf ("CommandObjectProcessGDBRemotePacket::DoExecute() called!!!\n"); + return true; + } +}; + + +class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword +{ +public: + CommandObjectMultiwordProcessGDBRemote (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "process plugin", + "A set of commands for operating on a ProcessGDBRemote process.", + "process plugin []") + { + LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket (interpreter))); + } + + ~CommandObjectMultiwordProcessGDBRemote () + { + } +}; + + + +CommandObject * +ProcessGDBRemote::GetPluginCommandObject() +{ + if (!m_command_sp) + m_command_sp.reset (new CommandObjectMultiwordProcessGDBRemote (GetTarget().GetDebugger().GetCommandInterpreter())); + return m_command_sp.get(); +} diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 82f840d..5c642d44 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -71,8 +71,8 @@ public: CanDebug (lldb_private::Target &target, bool plugin_specified_by_name); -// virtual uint32_t -// ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector &pids); + virtual lldb_private::CommandObject * + GetPluginCommandObject(); //------------------------------------------------------------------ // Creating a new process, or attaching to an existing one @@ -331,6 +331,7 @@ protected: bool m_destroy_tried_resuming; std::string m_dyld_plugin_name; lldb::addr_t m_kernel_load_addr; + lldb::CommandObjectSP m_command_sp; bool StartAsyncThread (); -- 2.7.4