summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp9
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h13
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp201
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h35
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp98
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h16
6 files changed, 321 insertions, 51 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 707fe46c26f..15ab58975cc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -32,7 +32,8 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char
m_rx_packet_listener (listener_name),
m_sequence_mutex (Mutex::eMutexTypeRecursive),
m_public_is_running (false),
- m_private_is_running (false)
+ m_private_is_running (false),
+ m_send_acks (true)
{
m_rx_packet_listener.StartListeningForEvents(this,
Communication::eBroadcastBitPacketAvailable |
@@ -127,7 +128,10 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le
if (GetSendAcks ())
{
if (GetAck () != '+')
+ {
+ printf("get ack failed...");
return 0;
+ }
}
}
else
@@ -238,9 +242,10 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &packet, c
}
}
}
- else if (Communication::eBroadcastBitReadThreadDidExit)
+ else if (event_type | Communication::eBroadcastBitReadThreadDidExit)
{
// Our read thread exited on us so just fall through and return zero...
+ Disconnect();
}
}
return 0;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 858f67c6534..e8129ce919f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -88,15 +88,18 @@ public:
return m_public_is_running.GetValue();
}
+ bool
+ GetSendAcks ()
+ {
+ return m_send_acks;
+ }
+
//------------------------------------------------------------------
// Client and server must implement these pure virtual functions
//------------------------------------------------------------------
virtual bool
GetThreadSuffixSupported () = 0;
- virtual bool
- GetSendAcks () = 0;
-
//------------------------------------------------------------------
// Set the global packet timeout.
//
@@ -135,6 +138,10 @@ protected:
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
lldb_private::Predicate<bool> m_public_is_running;
lldb_private::Predicate<bool> m_private_is_running;
+ bool m_send_acks;
+
+
+
private:
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 7700ab2b7f5..e158e5c6237 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -50,7 +50,10 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
m_async_packet (),
m_async_response (),
m_async_signal (-1),
- m_host_arch()
+ m_host_arch(),
+ m_os_version_major (UINT32_MAX),
+ m_os_version_minor (UINT32_MAX),
+ m_os_version_update (UINT32_MAX)
{
m_rx_packet_listener.StartListeningForEvents(this,
Communication::eBroadcastBitPacketAvailable |
@@ -73,19 +76,36 @@ GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
}
bool
-GDBRemoteCommunicationClient::GetSendAcks ()
+GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
+{
+ // Start the read thread after we send the handshake ack since if we
+ // fail to send the handshake ack, there is no reason to continue...
+ if (SendAck())
+ return StartReadThread (error_ptr);
+
+ if (error_ptr)
+ error_ptr->SetErrorString("failed to send the handshake ack");
+ return false;
+}
+
+void
+GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
{
if (m_supports_not_sending_acks == eLazyBoolCalculate)
{
- StringExtractorGDBRemote response;
+ m_send_acks = true;
m_supports_not_sending_acks = eLazyBoolNo;
+
+ StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
{
if (response.IsOKResponse())
+ {
+ m_send_acks = false;
m_supports_not_sending_acks = eLazyBoolYes;
+ }
}
}
- return m_supports_not_sending_acks != eLazyBoolYes;
}
void
@@ -664,6 +684,79 @@ GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_valu
}
bool
+GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
+ uint32_t &minor,
+ uint32_t &update)
+{
+ if (GetHostInfo ())
+ {
+ if (m_os_version_major != UINT32_MAX)
+ {
+ major = m_os_version_major;
+ minor = m_os_version_minor;
+ update = m_os_version_update;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
+{
+ if (GetHostInfo ())
+ {
+ if (!m_os_build.empty())
+ {
+ s = m_os_build;
+ return true;
+ }
+ }
+ s.clear();
+ return false;
+}
+
+
+bool
+GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
+{
+ if (GetHostInfo ())
+ {
+ if (!m_os_kernel.empty())
+ {
+ s = m_os_kernel;
+ return true;
+ }
+ }
+ s.clear();
+ return false;
+}
+
+bool
+GDBRemoteCommunicationClient::GetHostname (std::string &s)
+{
+ if (GetHostInfo ())
+ {
+ if (!m_hostname.empty())
+ {
+ s = m_hostname;
+ return true;
+ }
+ }
+ s.clear();
+ return false;
+}
+
+ArchSpec
+GDBRemoteCommunicationClient::GetSystemArchitecture ()
+{
+ if (GetHostInfo ())
+ return m_host_arch;
+ return ArchSpec();
+}
+
+
+bool
GDBRemoteCommunicationClient::GetHostInfo ()
{
if (m_supports_qHostInfo == eLazyBoolCalculate)
@@ -685,7 +778,9 @@ GDBRemoteCommunicationClient::GetHostInfo ()
std::string arch_name;
std::string os_name;
std::string vendor_name;
+ std::string triple;
uint32_t pointer_byte_size = 0;
+ StringExtractor extractor;
ByteOrder byte_order = eByteOrderInvalid;
while (response.GetNameColonValue(name, value))
{
@@ -703,6 +798,31 @@ GDBRemoteCommunicationClient::GetHostInfo ()
{
arch_name.swap (value);
}
+ else if (name.compare("triple") == 0)
+ {
+ // The triple comes as ASCII hex bytes since it contains '-' chars
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (triple);
+ }
+ else if (name.compare("os_build") == 0)
+ {
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (m_os_build);
+ }
+ else if (name.compare("hostname") == 0)
+ {
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (m_hostname);
+ }
+ else if (name.compare("os_kernel") == 0)
+ {
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (m_os_kernel);
+ }
else if (name.compare("ostype") == 0)
{
os_name.swap (value);
@@ -724,13 +844,52 @@ GDBRemoteCommunicationClient::GetHostInfo ()
{
pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
}
+ else if (name.compare("os_version") == 0)
+ {
+ Args::StringToVersion (value.c_str(),
+ m_os_version_major,
+ m_os_version_minor,
+ m_os_version_update);
+ }
}
- if (arch_name.empty())
+ if (triple.empty())
{
- if (cpu != LLDB_INVALID_CPUTYPE)
+ if (arch_name.empty())
+ {
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ {
+ m_host_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
+ if (pointer_byte_size)
+ {
+ assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid)
+ {
+ assert (byte_order == m_host_arch.GetByteOrder());
+ }
+ if (!vendor_name.empty())
+ m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
+ if (!os_name.empty())
+ m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
+
+ }
+ }
+ else
{
- m_host_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
+ std::string triple;
+ triple += arch_name;
+ triple += '-';
+ if (vendor_name.empty())
+ triple += "unknown";
+ else
+ triple += vendor_name;
+ triple += '-';
+ if (os_name.empty())
+ triple += "unknown";
+ else
+ triple += os_name;
+ m_host_arch.SetTriple (triple.c_str());
if (pointer_byte_size)
{
assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
@@ -739,29 +898,21 @@ GDBRemoteCommunicationClient::GetHostInfo ()
{
assert (byte_order == m_host_arch.GetByteOrder());
}
- if (!vendor_name.empty())
- m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
- if (!os_name.empty())
- m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
-
+
}
}
else
{
- std::string triple;
- triple += arch_name;
- triple += '-';
- if (vendor_name.empty())
- triple += "unknown";
- else
- triple += vendor_name;
- triple += '-';
- if (os_name.empty())
- triple += "unknown";
- else
- triple += os_name;
m_host_arch.SetTriple (triple.c_str());
- }
+ if (pointer_byte_size)
+ {
+ assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid)
+ {
+ assert (byte_order == m_host_arch.GetByteOrder());
+ }
+ }
}
}
return m_supports_qHostInfo == eLazyBoolYes;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index bcf23f2c589..410d80de316 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -29,6 +29,13 @@ public:
virtual
~GDBRemoteCommunicationClient();
+ //------------------------------------------------------------------
+ // After connecting, send the handshake to the server to make sure
+ // we are communicating with it.
+ //------------------------------------------------------------------
+ bool
+ HandshakeWithServer (lldb_private::Error *error_ptr);
+
size_t
SendPacketAndWaitForResponse (const char *send_payload,
StringExtractorGDBRemote &response,
@@ -49,8 +56,8 @@ public:
virtual bool
GetThreadSuffixSupported ();
- virtual bool
- GetSendAcks ();
+ void
+ QueryNoAckModeSupported ();
bool
SendAsyncSignal (int signo);
@@ -186,6 +193,23 @@ public:
GetHostInfo ();
bool
+ GetOSVersion (uint32_t &major,
+ uint32_t &minor,
+ uint32_t &update);
+
+ bool
+ GetOSBuildString (std::string &s);
+
+ bool
+ GetOSKernelDescription (std::string &s);
+
+ lldb_private::ArchSpec
+ GetSystemArchitecture ();
+
+ bool
+ GetHostname (std::string &s);
+
+ bool
GetSupportsThreadSuffix ();
bool
@@ -232,7 +256,12 @@ protected:
int m_async_signal; // We were asked to deliver a signal to the inferior process.
lldb_private::ArchSpec m_host_arch;
- uint32_t m_cpusubtype;
+ uint32_t m_os_version_major;
+ uint32_t m_os_version_minor;
+ uint32_t m_os_version_update;
+ std::string m_os_build;
+ std::string m_os_kernel;
+ std::string m_hostname;
private:
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 18d6087e8b5..faee6776a83 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -35,8 +35,7 @@ using namespace lldb_private;
//----------------------------------------------------------------------
GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() :
GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"),
- m_async_thread (LLDB_INVALID_HOST_THREAD),
- m_send_acks (true)
+ m_async_thread (LLDB_INVALID_HOST_THREAD)
{
}
@@ -73,6 +72,7 @@ GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
//
bool
GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_ptr,
+ Error &error,
bool &interrupt,
bool &quit)
{
@@ -87,10 +87,12 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout
break;
case StringExtractorGDBRemote::eServerPacketType_invalid:
+ error.SetErrorString("invalid packet");
quit = true;
break;
case StringExtractorGDBRemote::eServerPacketType_interrupt:
+ error.SetErrorString("interrupt received");
interrupt = true;
break;
@@ -99,9 +101,20 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout
case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
return Handle_qHostInfo ();
+
+ case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
+ return Handle_QStartNoAckMode ();
}
return true;
}
+ else
+ {
+ if (!IsConnected())
+ error.SetErrorString("lost connection");
+ else
+ error.SetErrorString("timeout");
+ }
+
return false;
}
@@ -111,6 +124,19 @@ GDBRemoteCommunicationServer::SendUnimplementedResponse ()
return SendPacket ("");
}
+size_t
+GDBRemoteCommunicationServer::SendOKResponse ()
+{
+ return SendPacket ("OK");
+}
+
+bool
+GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
+{
+ if (StartReadThread(error_ptr))
+ return GetAck();
+ return false;
+}
bool
GDBRemoteCommunicationServer::Handle_qHostInfo ()
@@ -120,17 +146,18 @@ GDBRemoteCommunicationServer::Handle_qHostInfo ()
// $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
ArchSpec host_arch (Host::GetArchitecture ());
-
const llvm::Triple &host_triple = host_arch.GetTriple();
- const llvm::StringRef arch_name (host_triple.getArchName());
- const llvm::StringRef vendor_name (host_triple.getOSName());
- const llvm::StringRef os_name (host_triple.getVendorName());
- response.Printf ("arch:%.*s;ostype:%.*s;vendor:%.*s;ptrsize:%u",
- (int)arch_name.size(), arch_name.data(),
- (int)os_name.size(), os_name.data(),
- (int)vendor_name.size(), vendor_name.data(),
- host_arch.GetAddressByteSize());
-
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
+ response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
+
+ uint32_t cpu = host_arch.GetMachOCPUType();
+ uint32_t sub = host_arch.GetMachOCPUSubType();
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ response.Printf ("cputype:%u;", cpu);
+ if (sub != LLDB_INVALID_CPUTYPE)
+ response.Printf ("cpusubtype:%u;", sub);
+
switch (lldb::endian::InlHostByteOrder())
{
case eByteOrderBig: response.PutCString ("endian:big;"); break;
@@ -139,5 +166,52 @@ GDBRemoteCommunicationServer::Handle_qHostInfo ()
default: response.PutCString ("endian:unknown;"); break;
}
+ uint32_t major = UINT32_MAX;
+ uint32_t minor = UINT32_MAX;
+ uint32_t update = UINT32_MAX;
+ if (Host::GetOSVersion (major, minor, update))
+ {
+ if (major != UINT32_MAX)
+ {
+ response.Printf("os_version:%u", major);
+ if (minor != UINT32_MAX)
+ {
+ response.Printf(".%u", minor);
+ if (update != UINT32_MAX)
+ response.Printf(".%u", update);
+ }
+ response.PutChar(';');
+ }
+ }
+
+ std::string s;
+ if (Host::GetOSBuildString (s))
+ {
+ response.PutCString ("os_build:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
+ if (Host::GetOSKernelDescription (s))
+ {
+ response.PutCString ("os_kernel:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
+ if (Host::GetHostname (s))
+ {
+ response.PutCString ("hostname:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
+
return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0;
}
+
+
+bool
+GDBRemoteCommunicationServer::Handle_QStartNoAckMode ()
+{
+ SendOKResponse ();
+ m_send_acks = false;
+ return true;
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 4e0b24ddea0..66ddc77bc95 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -35,6 +35,7 @@ public:
bool
GetPacketAndSendResponse (const lldb_private::TimeValue* timeout_ptr,
+ lldb_private::Error &error,
bool &interrupt,
bool &quit);
@@ -44,23 +45,26 @@ public:
return true;
}
- virtual bool
- GetSendAcks ()
- {
- return m_send_acks;
- }
+ // After connecting, do a little handshake with the client to make sure
+ // we are at least communicating
+ bool
+ HandshakeWithClient (lldb_private::Error *error_ptr);
protected:
lldb::thread_t m_async_thread;
- bool m_send_acks;
size_t
SendUnimplementedResponse ();
+ size_t
+ SendOKResponse ();
bool
Handle_qHostInfo ();
+ bool
+ Handle_QStartNoAckMode ();
+
private:
//------------------------------------------------------------------
// For GDBRemoteCommunicationServer only
OpenPOWER on IntegriCloud