diff options
author | Greg Clayton <gclayton@apple.com> | 2012-10-19 22:22:57 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-10-19 22:22:57 +0000 |
commit | 1d19a2f25313d7f46bf725b1c8c29a586b490901 (patch) | |
tree | c38c953a9b6f764587eb7e411f86352ac6a35220 | |
parent | 38860baad039595fc33e3036cc934c8f8fe8bdb3 (diff) | |
download | bcm5719-llvm-1d19a2f25313d7f46bf725b1c8c29a586b490901.tar.gz bcm5719-llvm-1d19a2f25313d7f46bf725b1c8c29a586b490901.zip |
<rdar://problem/12491387>
Added commands to the KDP plug-in that allow sending raw commands through the KDP protocol. You specify a command byte and a payload as ASCII hex bytes, and the packet is created with a valid header/sequenceID/length and sent. The command responds with a raw ASCII hex string that contains all bytes in the reply including the header.
An example of sending a read register packet for the GPR on x86_64:
(lldb) process plugin packet send --command 0x07 --payload 0100000004000000
llvm-svn: 166346
9 files changed, 403 insertions, 7 deletions
diff --git a/lldb/include/lldb/Interpreter/OptionGroupString.h b/lldb/include/lldb/Interpreter/OptionGroupString.h new file mode 100644 index 00000000000..9389f0d1864 --- /dev/null +++ b/lldb/include/lldb/Interpreter/OptionGroupString.h @@ -0,0 +1,82 @@ +//===-- OptionGroupString.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_OptionGroupString_h_ +#define liblldb_OptionGroupString_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/Options.h" +#include "lldb/Interpreter/OptionValueString.h" + +namespace lldb_private { + //------------------------------------------------------------------------- + // OptionGroupString + //------------------------------------------------------------------------- + + class OptionGroupString : public OptionGroup + { + public: + + OptionGroupString (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + const char *default_value); + + virtual + ~OptionGroupString (); + + + virtual uint32_t + GetNumDefinitions () + { + return 1; + } + + virtual const OptionDefinition* + GetDefinitions () + { + return &m_option_definition; + } + + virtual Error + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_value); + + virtual void + OptionParsingStarting (CommandInterpreter &interpreter); + + OptionValueString & + GetOptionValue () + { + return m_value; + } + + const OptionValueString & + GetOptionValue () const + { + return m_value; + } + + protected: + OptionValueString m_value; + OptionDefinition m_option_definition; + + }; + +} // namespace lldb_private + +#endif // liblldb_OptionGroupString_h_ diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 80469723c3e..1fa2dbbde93 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -88,6 +88,8 @@ 2628A4D513D4977900F5487A /* ThreadKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2628A4D313D4977900F5487A /* ThreadKDP.cpp */; }; 262CFC7711A4510000946C6C /* debugserver in Resources */ = {isa = PBXBuildFile; fileRef = 26CE05A0115C31E50022F371 /* debugserver */; }; 262D24E613FB8710002D1960 /* RegisterContextMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262D24E413FB8710002D1960 /* RegisterContextMemory.cpp */; }; + 262ED0051631FA2800879631 /* OptionGroupString.h in Headers */ = {isa = PBXBuildFile; fileRef = 262ED0041631FA2800879631 /* OptionGroupString.h */; }; + 262ED0081631FA3A00879631 /* OptionGroupString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262ED0071631FA3A00879631 /* OptionGroupString.cpp */; }; 26368A3C126B697600E8659F /* darwin-debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26368A3B126B697600E8659F /* darwin-debug.cpp */; }; 26368AF7126B960500E8659F /* darwin-debug in Resources */ = {isa = PBXBuildFile; fileRef = 26579F68126A25920007C5CB /* darwin-debug */; }; 263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263E949D13661AE400E7D1CE /* UnwindAssembly-x86.cpp */; }; @@ -889,6 +891,8 @@ 2628A4D413D4977900F5487A /* ThreadKDP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadKDP.h; sourceTree = "<group>"; }; 262D24E413FB8710002D1960 /* RegisterContextMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextMemory.cpp; path = Utility/RegisterContextMemory.cpp; sourceTree = "<group>"; }; 262D24E513FB8710002D1960 /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = "<group>"; }; + 262ED0041631FA2800879631 /* OptionGroupString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptionGroupString.h; path = include/lldb/Interpreter/OptionGroupString.h; sourceTree = "<group>"; }; + 262ED0071631FA3A00879631 /* OptionGroupString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupString.cpp; path = source/Interpreter/OptionGroupString.cpp; sourceTree = "<group>"; }; 263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 263664941140A4C10075843B /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Debugger.h; path = include/lldb/Core/Debugger.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 26368A3B126B697600E8659F /* darwin-debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "darwin-debug.cpp"; path = "tools/darwin-debug/darwin-debug.cpp"; sourceTree = "<group>"; }; @@ -2934,6 +2938,8 @@ 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */, 26D5E161135BB040006EA0A7 /* OptionGroupPlatform.h */, 26D5E162135BB054006EA0A7 /* OptionGroupPlatform.cpp */, + 262ED0041631FA2800879631 /* OptionGroupString.h */, + 262ED0071631FA3A00879631 /* OptionGroupString.cpp */, 2686536E1370AE5A00D186A3 /* OptionGroupUInt64.h */, 2686536F1370AE7200D186A3 /* OptionGroupUInt64.cpp */, 260E07C3136FA68900CF21D3 /* OptionGroupUUID.h */, @@ -3429,6 +3435,7 @@ 2698699D15E6CBD0002415FF /* OperatingSystemPython.h in Headers */, 260D9B2715EC369500960137 /* ModuleSpec.h in Headers */, 947A1D651616476B0017C8D1 /* CommandObjectPlugin.h in Headers */, + 262ED0051631FA2800879631 /* OptionGroupString.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4153,6 +4160,7 @@ 2698699B15E6CBD0002415FF /* OperatingSystemPython.cpp in Sources */, 94CDEB9D15F0258500DD2A7A /* CXXFormatterFunctions.cpp in Sources */, 947A1D641616476B0017C8D1 /* CommandObjectPlugin.cpp in Sources */, + 262ED0081631FA3A00879631 /* OptionGroupString.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/Interpreter/OptionGroupString.cpp b/lldb/source/Interpreter/OptionGroupString.cpp new file mode 100644 index 00000000000..7440fd4973b --- /dev/null +++ b/lldb/source/Interpreter/OptionGroupString.cpp @@ -0,0 +1,58 @@ +//===-- OptionGroupString.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Interpreter/OptionGroupString.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +using namespace lldb; +using namespace lldb_private; + +OptionGroupString::OptionGroupString (uint32_t usage_mask, + bool required, + const char *long_option, + char short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + const char *default_value) : + m_value (default_value, default_value) +{ + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.option_has_arg = required_argument; + m_option_definition.enum_values = NULL; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; +} + +OptionGroupString::~OptionGroupString () +{ +} + +Error +OptionGroupString::SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) +{ + Error error (m_value.SetValueFromCString (option_arg)); + return error; +} + +void +OptionGroupString::OptionParsingStarting (CommandInterpreter &interpreter) +{ + m_value.Clear(); +} diff --git a/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp b/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp index a8cd1567791..93e69336c7f 100644 --- a/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp +++ b/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp @@ -94,7 +94,7 @@ OperatingSystemDarwinKernel::CreateInstance (Process *process, bool force) const char * OperatingSystemDarwinKernel::GetPluginNameStatic() { - return "darwin-kernel"; + return "macosx-kernel"; } const char * diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index 04d0f7b0c2a..df5e535fe1d 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -84,7 +84,7 @@ typedef struct { #endif void -CommunicationKDP::MakeRequestPacketHeader (CommandType request_type, +CommunicationKDP::MakeRequestPacketHeader (CommandType request_type, PacketStreamType &request_packet, uint16_t request_length) { @@ -656,6 +656,10 @@ CommunicationKDP::SendRequestReadMemory (lldb::addr_t addr, else error.SetErrorString ("kdp read memory failed"); } + else + { + error.SetErrorString ("failed to send packet"); + } return 0; } @@ -691,9 +695,48 @@ CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr, return src_len; } } + else + { + error.SetErrorString ("failed to send packet"); + } return 0; } +bool +CommunicationKDP::SendRawRequest (uint8_t command_byte, + const void *src, // Raw packet payload bytes + uint32_t src_len, // Raw packet payload length + DataExtractor &reply_packet, + Error &error) +{ + PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); + // Size is header + address size + uint32_t length + const uint32_t command_length = 8 + src_len; + const CommandType command = (CommandType)command_byte; + const uint32_t request_sequence_id = m_request_sequence_id; + MakeRequestPacketHeader (command, request_packet, command_length); + request_packet.PutRawBytes(src, src_len); + + if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) + { + uint32_t offset = 8; + uint32_t kdp_error = reply_packet.GetU32 (&offset); + if (kdp_error) + error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error); + else + { + error.Clear(); + return true; + } + } + else + { + error.SetErrorString ("failed to send packet"); + } + return false; +} + + const char * CommunicationKDP::GetCommandAsCString (uint8_t command) { @@ -1120,6 +1163,10 @@ CommunicationKDP::SendRequestReadRegisters (uint32_t cpu, else error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor); } + else + { + error.SetErrorString ("failed to send packet"); + } return 0; } @@ -1148,6 +1195,10 @@ CommunicationKDP::SendRequestWriteRegisters (uint32_t cpu, return src_len; error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error); } + else + { + error.SetErrorString ("failed to send packet"); + } return 0; } diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h index c46d409be47..1d2df321857 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h @@ -171,6 +171,13 @@ public: uint32_t src_len, lldb_private::Error &error); + bool + SendRawRequest (uint8_t command_byte, + const void *src, + uint32_t src_len, + lldb_private::DataExtractor &reply, + lldb_private::Error &error); + uint32_t SendRequestReadRegisters (uint32_t cpu, uint32_t flavor, diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index ac09a551931..d7de4138b4e 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -22,6 +22,12 @@ #include "lldb/Core/UUID.h" #include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionGroupString.h" +#include "lldb/Interpreter/OptionGroupUInt64.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" @@ -32,6 +38,7 @@ #include "ProcessKDPLog.h" #include "ThreadKDP.h" #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" +#include "Utility/StringExtractor.h" using namespace lldb; using namespace lldb_private; @@ -108,7 +115,8 @@ ProcessKDP::ProcessKDP(Target& target, Listener &listener) : m_async_thread (LLDB_INVALID_HOST_THREAD), m_destroy_in_process (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"); @@ -829,3 +837,183 @@ ProcessKDP::AsyncThread (void *arg) } +class CommandObjectProcessKDPPacketSend : public CommandObjectParsed +{ +private: + + OptionGroupOptions m_option_group; + OptionGroupUInt64 m_command_byte; + OptionGroupString m_packet_data; + + virtual Options * + GetOptions () + { + return &m_option_group; + } + + +public: + CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "process plugin packet send", + "Send a custom packet through the KDP protocol by specifying the command byte and the packet payload data. A packet will be sent with a correct header and payload, and the raw result bytes will be displayed as a string value. ", + NULL), + m_option_group (interpreter), + m_command_byte(LLDB_OPT_SET_1, true , "command", 'c', 0, eArgTypeNone, "Specify the command byte to use when sending the KDP request packet.", 0), + m_packet_data (LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone, "Specify packet payload bytes as a hex ASCII string with no spaces or hex prefixes.", NULL) + { + m_option_group.Append (&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append (&m_packet_data , LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Finalize(); + } + + ~CommandObjectProcessKDPPacketSend () + { + } + + bool + DoExecute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + if (argc == 0) + { + if (!m_command_byte.GetOptionValue().OptionWasSet()) + { + result.AppendError ("the --command option must be set to a valid command byte"); + result.SetStatus (eReturnStatusFailed); + } + else + { + const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0); + if (command_byte > 0 && command_byte <= UINT8_MAX) + { + ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr(); + if (process) + { + const StateType state = process->GetState(); + + if (StateIsStoppedState (state, true)) + { + std::vector<uint8_t> payload_bytes; + const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue(); + if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) + { + StringExtractor extractor(ascii_hex_bytes_cstr); + const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size(); + if (ascii_hex_bytes_cstr_len & 1) + { + result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr); + result.SetStatus (eReturnStatusFailed); + return false; + } + payload_bytes.resize(ascii_hex_bytes_cstr_len/2); + if (extractor.GetHexBytes(&payload_bytes[0], payload_bytes.size(), '\xdd') != payload_bytes.size()) + { + result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + Error error; + DataExtractor reply; + process->GetCommunication().SendRawRequest (command_byte, + payload_bytes.empty() ? NULL : payload_bytes.data(), + payload_bytes.size(), + reply, + error); + + if (error.Success()) + { + // Copy the binary bytes into a hex ASCII string for the result + StreamString packet; + packet.PutBytesAsRawHex8(reply.GetDataStart(), + reply.GetByteSize(), + lldb::endian::InlHostByteOrder(), + lldb::endian::InlHostByteOrder()); + result.AppendMessage(packet.GetString().c_str()); + result.SetStatus (eReturnStatusSuccessFinishResult); + return true; + } + else + { + const char *error_cstr = error.AsCString(); + if (error_cstr && error_cstr[0]) + result.AppendError (error_cstr); + else + result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state)); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("invalid process"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendErrorWithFormat ("invalid command byte 0x%llx, valid values are 1 - 255", command_byte); + result.SetStatus (eReturnStatusFailed); + } + } + } + else + { + result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str()); + result.SetStatus (eReturnStatusFailed); + } + return false; + } +}; + +class CommandObjectProcessKDPPacket : public CommandObjectMultiword +{ +private: + +public: + CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "process plugin packet", + "Commands that deal with KDP remote packets.", + NULL) + { + LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessKDPPacketSend (interpreter))); + } + + ~CommandObjectProcessKDPPacket () + { + } +}; + +class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword +{ +public: + CommandObjectMultiwordProcessKDP (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "process plugin", + "A set of commands for operating on a ProcessKDP process.", + "process plugin <subcommand> [<subcommand-options>]") + { + LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket (interpreter))); + } + + ~CommandObjectMultiwordProcessKDP () + { + } +}; + +CommandObject * +ProcessKDP::GetPluginCommandObject() +{ + if (!m_command_sp) + m_command_sp.reset (new CommandObjectMultiwordProcessKDP (GetTarget().GetDebugger().GetCommandInterpreter())); + return m_command_sp.get(); +} + diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h index 5fb1027d116..9b24b4f5e78 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h @@ -70,8 +70,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<lldb::pid_t> &pids); + virtual lldb_private::CommandObject * + GetPluginCommandObject(); //------------------------------------------------------------------ // Creating a new process, or attaching to an existing one @@ -260,6 +260,8 @@ protected: bool m_destroy_in_process; std::string m_dyld_plugin_name; lldb::addr_t m_kernel_load_addr; + lldb::CommandObjectSP m_command_sp; + bool StartAsyncThread (); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 09278719081..1b3ebc7bcce 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -41,6 +41,8 @@ #include "lldb/Host/Symbols.h" #include "lldb/Host/TimeValue.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" @@ -3016,8 +3018,6 @@ ProcessGDBRemote::GetDynamicLoader () return m_dyld_ap.get(); } -#include "lldb/Interpreter/CommandObject.h" -#include "lldb/Interpreter/CommandObjectMultiword.h" class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed { |