<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
This commit is contained in:
parent
38860baad0
commit
1d19a2f253
|
@ -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_
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -94,7 +94,7 @@ OperatingSystemDarwinKernel::CreateInstance (Process *process, bool force)
|
|||
const char *
|
||||
OperatingSystemDarwinKernel::GetPluginNameStatic()
|
||||
{
|
||||
return "darwin-kernel";
|
||||
return "macosx-kernel";
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue