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.cpp15
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp561
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h23
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp237
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h29
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp18
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp44
8 files changed, 745 insertions, 185 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 7a9694647f4..3b8d6056063 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -30,7 +30,7 @@ using namespace lldb_private;
//----------------------------------------------------------------------
GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name) :
Communication(comm_name),
- m_packet_timeout (1),
+ m_packet_timeout (60),
m_rx_packet_listener (listener_name),
m_sequence_mutex (Mutex::eMutexTypeRecursive),
m_public_is_running (false),
@@ -57,7 +57,6 @@ GDBRemoteCommunication::~GDBRemoteCommunication()
}
}
-
char
GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
{
@@ -80,7 +79,7 @@ GDBRemoteCommunication::SendAck ()
log->Printf ("send packet: +");
ConnectionStatus status = eConnectionStatusSuccess;
char ack_char = '+';
- return Write (&ack_char, 1, status, NULL) == 1;
+ return Write (&ack_char, 1, status, NULL);
}
size_t
@@ -91,7 +90,15 @@ GDBRemoteCommunication::SendNack ()
log->Printf ("send packet: -");
ConnectionStatus status = eConnectionStatusSuccess;
char nack_char = '-';
- return Write (&nack_char, 1, status, NULL) == 1;
+ return Write (&nack_char, 1, status, NULL);
+}
+
+size_t
+GDBRemoteCommunication::SendPacket (lldb_private::StreamString &payload)
+{
+ Mutex::Locker locker(m_sequence_mutex);
+ const std::string &p (payload.GetString());
+ return SendPacketNoLock (p.c_str(), p.size());
}
size_t
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index e8129ce919f..f53d036a518 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -49,6 +49,9 @@ public:
SendPacket (const char *payload,
size_t payload_length);
+ size_t
+ SendPacket (lldb_private::StreamString &response);
+
// Wait for a packet within 'nsec' seconds
size_t
WaitForPacket (StringExtractorGDBRemote &response,
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index f8a0600fb81..d640d5b1d86 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -38,13 +38,17 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
m_supports_not_sending_acks (eLazyBoolCalculate),
m_supports_thread_suffix (eLazyBoolCalculate),
- m_supports_qHostInfo (eLazyBoolCalculate),
m_supports_vCont_all (eLazyBoolCalculate),
m_supports_vCont_any (eLazyBoolCalculate),
m_supports_vCont_c (eLazyBoolCalculate),
m_supports_vCont_C (eLazyBoolCalculate),
m_supports_vCont_s (eLazyBoolCalculate),
m_supports_vCont_S (eLazyBoolCalculate),
+ m_qHostInfo_is_valid (eLazyBoolCalculate),
+ m_supports_qProcessInfoPID (true),
+ m_supports_qfProcessInfo (true),
+ m_supports_qUserName (true),
+ m_supports_qGroupName (true),
m_async_mutex (Mutex::eMutexTypeRecursive),
m_async_packet_predicate (false),
m_async_packet (),
@@ -113,11 +117,15 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings()
{
m_supports_not_sending_acks = eLazyBoolCalculate;
m_supports_thread_suffix = eLazyBoolCalculate;
- m_supports_qHostInfo = eLazyBoolCalculate;
m_supports_vCont_c = eLazyBoolCalculate;
m_supports_vCont_C = eLazyBoolCalculate;
m_supports_vCont_s = eLazyBoolCalculate;
m_supports_vCont_S = eLazyBoolCalculate;
+ m_qHostInfo_is_valid = eLazyBoolCalculate;
+ m_supports_qProcessInfoPID = true;
+ m_supports_qfProcessInfo = true;
+ m_supports_qUserName = true;
+ m_supports_qGroupName = true;
m_host_arch.Clear();
}
@@ -759,107 +767,159 @@ GDBRemoteCommunicationClient::GetSystemArchitecture ()
bool
GDBRemoteCommunicationClient::GetHostInfo ()
{
- if (m_supports_qHostInfo == eLazyBoolCalculate)
+ if (m_qHostInfo_is_valid == eLazyBoolCalculate)
{
- m_supports_qHostInfo = eLazyBoolNo;
-
+ m_qHostInfo_is_valid = eLazyBoolNo;
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
{
if (response.IsUnsupportedResponse())
+ {
return false;
-
- m_supports_qHostInfo = eLazyBoolYes;
-
- std::string name;
- std::string value;
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
- 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))
+ }
+ else if (response.IsNormalResponse())
{
- if (name.compare("cputype") == 0)
+ std::string name;
+ std::string value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ 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;
+ uint32_t num_keys_decoded = 0;
+ while (response.GetNameColonValue(name, value))
{
- // exception type in big endian hex
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
- }
- else if (name.compare("cpusubtype") == 0)
- {
- // exception count in big endian hex
- sub = Args::StringToUInt32 (value.c_str(), 0, 0);
- }
- else if (name.compare("arch") == 0)
- {
- 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);
- }
- else if (name.compare("vendor") == 0)
- {
- vendor_name.swap(value);
- }
- else if (name.compare("endian") == 0)
- {
- if (value.compare("little") == 0)
- byte_order = eByteOrderLittle;
- else if (value.compare("big") == 0)
- byte_order = eByteOrderBig;
- else if (value.compare("pdp") == 0)
- byte_order = eByteOrderPDP;
- }
- else if (name.compare("ptrsize") == 0)
- {
- 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 (name.compare("cputype") == 0)
+ {
+ // exception type in big endian hex
+ cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ ++num_keys_decoded;
+ }
+ else if (name.compare("cpusubtype") == 0)
+ {
+ // exception count in big endian hex
+ sub = Args::StringToUInt32 (value.c_str(), 0, 0);
+ if (sub != 0)
+ ++num_keys_decoded;
+ }
+ else if (name.compare("arch") == 0)
+ {
+ arch_name.swap (value);
+ ++num_keys_decoded;
+ }
+ 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);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("os_build") == 0)
+ {
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (m_os_build);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("hostname") == 0)
+ {
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (m_hostname);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("os_kernel") == 0)
+ {
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (m_os_kernel);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("ostype") == 0)
+ {
+ os_name.swap (value);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("vendor") == 0)
+ {
+ vendor_name.swap(value);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("endian") == 0)
+ {
+ ++num_keys_decoded;
+ if (value.compare("little") == 0)
+ byte_order = eByteOrderLittle;
+ else if (value.compare("big") == 0)
+ byte_order = eByteOrderBig;
+ else if (value.compare("pdp") == 0)
+ byte_order = eByteOrderPDP;
+ else
+ --num_keys_decoded;
+ }
+ else if (name.compare("ptrsize") == 0)
+ {
+ pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+ if (pointer_byte_size != 0)
+ ++num_keys_decoded;
+ }
+ 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 (m_os_version_major != UINT32_MAX)
+ ++num_keys_decoded;
+ }
}
- }
-
- if (triple.empty())
- {
- if (arch_name.empty())
+
+ if (num_keys_decoded > 0)
+ m_qHostInfo_is_valid = eLazyBoolYes;
+
+ if (triple.empty())
{
- if (cpu != LLDB_INVALID_CPUTYPE)
+ if (arch_name.empty())
{
- m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ {
+ m_host_arch.SetArchitecture (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
+ {
+ 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());
@@ -868,27 +928,11 @@ 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)
{
@@ -898,24 +942,11 @@ GDBRemoteCommunicationClient::GetHostInfo ()
{
assert (byte_order == m_host_arch.GetByteOrder());
}
-
- }
+ }
}
- else
- {
- 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;
+ return m_qHostInfo_is_valid == eLazyBoolYes;
}
int
@@ -927,10 +958,10 @@ GDBRemoteCommunicationClient::SendAttach
{
if (pid != LLDB_INVALID_PROCESS_ID)
{
- StreamString packet;
- packet.Printf("vAttach;%x", pid);
-
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ char packet[64];
+ const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid);
+ assert (packet_len < sizeof(packet));
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
{
if (response.IsErrorResponse())
return response.GetError();
@@ -943,7 +974,7 @@ GDBRemoteCommunicationClient::SendAttach
const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetHostArchitecture ()
{
- if (m_supports_qHostInfo == eLazyBoolCalculate)
+ if (m_qHostInfo_is_valid == eLazyBoolCalculate)
GetHostInfo ();
return m_host_arch;
}
@@ -952,12 +983,13 @@ addr_t
GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
{
char packet[64];
- ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
- permissions & lldb::ePermissionsReadable ? "r" : "",
- permissions & lldb::ePermissionsWritable ? "w" : "",
- permissions & lldb::ePermissionsExecutable ? "x" : "");
+ const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
+ permissions & lldb::ePermissionsReadable ? "r" : "",
+ permissions & lldb::ePermissionsWritable ? "w" : "",
+ permissions & lldb::ePermissionsExecutable ? "x" : "");
+ assert (packet_len < sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
{
if (!response.IsErrorResponse())
return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
@@ -969,9 +1001,10 @@ bool
GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
{
char packet[64];
- snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
+ const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
+ assert (packet_len < sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
{
if (response.IsOKResponse())
return true;
@@ -1070,11 +1103,11 @@ GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
int
GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
{
- StreamString packet;
- packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
-
+ char packet[32];
+ const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
+ assert (packet_len < sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
{
if (response.IsOKResponse())
return 0;
@@ -1084,3 +1117,251 @@ GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
}
return -1;
}
+
+bool
+GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInfo &process_info)
+{
+ if (response.IsNormalResponse())
+ {
+ std::string name;
+ std::string value;
+ StringExtractor extractor;
+
+ while (response.GetNameColonValue(name, value))
+ {
+ if (name.compare("pid") == 0)
+ {
+ process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
+ }
+ else if (name.compare("ppid") == 0)
+ {
+ process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
+ }
+ else if (name.compare("uid") == 0)
+ {
+ process_info.SetRealUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ }
+ else if (name.compare("euid") == 0)
+ {
+ process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ }
+ else if (name.compare("gid") == 0)
+ {
+ process_info.SetRealGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ }
+ else if (name.compare("egid") == 0)
+ {
+ process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ }
+ 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 (value);
+ process_info.GetArchitecture ().SetTriple (value.c_str());
+ }
+ else if (name.compare("name") == 0)
+ {
+ StringExtractor extractor;
+ // The the process name from ASCII hex bytes since we can't
+ // control the characters in a process name
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString (value);
+ process_info.SwapName (value);
+ }
+ }
+
+ if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ }
+ return false;
+}
+
+bool
+GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+{
+ process_info.Clear();
+
+ if (m_supports_qProcessInfoPID)
+ {
+ char packet[32];
+ const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%i", pid);
+ assert (packet_len < sizeof(packet));
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ {
+ if (response.IsUnsupportedResponse())
+ {
+ m_supports_qProcessInfoPID = false;
+ return false;
+ }
+
+ return DecodeProcessInfoResponse (response, process_info);
+ }
+ }
+ return false;
+}
+
+uint32_t
+GDBRemoteCommunicationClient::FindProcesses (const ProcessInfoMatch &match_info,
+ ProcessInfoList &process_infos)
+{
+ process_infos.Clear();
+
+ if (m_supports_qfProcessInfo)
+ {
+ StreamString packet;
+ packet.PutCString ("qfProcessInfo");
+ if (!match_info.MatchAllProcesses())
+ {
+ packet.PutChar (':');
+ const char *name = match_info.GetProcessInfo().GetName();
+ bool has_name_match = false;
+ if (name && name[0])
+ {
+ has_name_match = true;
+ NameMatchType name_match_type = match_info.GetNameMatchType();
+ switch (name_match_type)
+ {
+ case eNameMatchIgnore:
+ has_name_match = false;
+ break;
+
+ case eNameMatchEquals:
+ packet.PutCString ("name_match:equals;");
+ break;
+
+ case eNameMatchContains:
+ packet.PutCString ("name_match:contains;");
+ break;
+
+ case eNameMatchStartsWith:
+ packet.PutCString ("name_match:starts_with;");
+ break;
+
+ case eNameMatchEndsWith:
+ packet.PutCString ("name_match:ends_with;");
+ break;
+
+ case eNameMatchRegularExpression:
+ packet.PutCString ("name_match:regex;");
+ break;
+ }
+ if (has_name_match)
+ {
+ packet.PutCString ("name:");
+ packet.PutBytesAsRawHex8(name, ::strlen(name));
+ packet.PutChar (';');
+ }
+ }
+
+ if (match_info.GetProcessInfo().ProcessIDIsValid())
+ packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
+ if (match_info.GetProcessInfo().ParentProcessIDIsValid())
+ packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
+ if (match_info.GetProcessInfo().RealUserIDIsValid())
+ packet.Printf("uid:%u;",match_info.GetProcessInfo().GetRealUserID());
+ if (match_info.GetProcessInfo().RealGroupIDIsValid())
+ packet.Printf("gid:%u;",match_info.GetProcessInfo().GetRealGroupID());
+ if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
+ packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
+ if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
+ packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
+ if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
+ packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
+ if (match_info.GetProcessInfo().GetArchitecture().IsValid())
+ {
+ const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
+ const llvm::Triple &triple = match_arch.GetTriple();
+ packet.PutCString("triple:");
+ packet.PutCStringAsRawHex8(triple.getTriple().c_str());
+ packet.PutChar (';');
+ }
+ }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsUnsupportedResponse())
+ {
+ m_supports_qfProcessInfo = false;
+ return 0;
+ }
+
+ do
+ {
+ ProcessInfo process_info;
+ if (!DecodeProcessInfoResponse (response, process_info))
+ break;
+ process_infos.Append(process_info);
+ response.GetStringRef().clear();
+ response.SetFilePos(0);
+ } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
+ }
+ }
+ return process_infos.GetSize();
+
+}
+
+bool
+GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
+{
+ if (m_supports_qUserName)
+ {
+ char packet[32];
+ const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
+ assert (packet_len < sizeof(packet));
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ {
+ if (response.IsUnsupportedResponse())
+ {
+ m_supports_qUserName = false;
+ return false;
+ }
+
+ if (response.IsNormalResponse())
+ {
+ // Make sure we parsed the right number of characters. The response is
+ // the hex encoded user name and should make up the entire packet.
+ // If there are any non-hex ASCII bytes, the length won't match below..
+ if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
+ return true;
+ }
+ }
+ }
+ return false;
+
+}
+
+bool
+GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
+{
+ if (m_supports_qGroupName)
+ {
+ char packet[32];
+ const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
+ assert (packet_len < sizeof(packet));
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ {
+ if (response.IsUnsupportedResponse())
+ {
+ m_supports_qGroupName = false;
+ return false;
+ }
+
+ if (response.IsNormalResponse())
+ {
+ // Make sure we parsed the right number of characters. The response is
+ // the hex encoded group name and should make up the entire packet.
+ // If there are any non-hex ASCII bytes, the length won't match below..
+ if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
+ return true;
+ }
+ }
+ }
+ return false;
+
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 39ddb622218..d28c8275bd4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -213,6 +213,20 @@ public:
GetSupportsThreadSuffix ();
bool
+ GetProcessInfo (lldb::pid_t pid,
+ lldb_private::ProcessInfo &process_info);
+
+ uint32_t
+ FindProcesses (const lldb_private::ProcessInfoMatch &process_match_info,
+ lldb_private::ProcessInfoList &process_infos);
+
+ bool
+ GetUserName (uint32_t uid, std::string &name);
+
+ bool
+ GetGroupName (uint32_t gid, std::string &name);
+
+ bool
HasFullVContSupport ()
{
return GetVContSupported ('A');
@@ -239,13 +253,17 @@ protected:
//------------------------------------------------------------------
lldb_private::LazyBool m_supports_not_sending_acks;
lldb_private::LazyBool m_supports_thread_suffix;
- lldb_private::LazyBool m_supports_qHostInfo;
lldb_private::LazyBool m_supports_vCont_all;
lldb_private::LazyBool m_supports_vCont_any;
lldb_private::LazyBool m_supports_vCont_c;
lldb_private::LazyBool m_supports_vCont_C;
lldb_private::LazyBool m_supports_vCont_s;
lldb_private::LazyBool m_supports_vCont_S;
+ lldb_private::LazyBool m_qHostInfo_is_valid;
+ bool m_supports_qProcessInfoPID;
+ bool m_supports_qfProcessInfo;
+ bool m_supports_qUserName;
+ bool m_supports_qGroupName;
// If we need to send a packet while the target is running, the m_async_XXX
// member variables take care of making this happen.
@@ -263,6 +281,9 @@ protected:
std::string m_os_kernel;
std::string m_hostname;
+ bool
+ DecodeProcessInfoResponse (StringExtractorGDBRemote &response,
+ lldb_private::ProcessInfo &process_info);
private:
//------------------------------------------------------------------
// For GDBRemoteCommunicationClient only
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index faee6776a83..ea6842b999a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -97,13 +97,28 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout
break;
case StringExtractorGDBRemote::eServerPacketType_unimplemented:
- return SendUnimplementedResponse () > 0;
+ return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0;
case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
- return Handle_qHostInfo ();
-
+ return Handle_qHostInfo (packet);
+
+ case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
+ return Handle_qProcessInfoPID (packet);
+
+ case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
+ return Handle_qfProcessInfo (packet);
+
+ case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
+ return Handle_qsProcessInfo (packet);
+
+ case StringExtractorGDBRemote::eServerPacketType_qUserName:
+ return Handle_qUserName (packet);
+
+ case StringExtractorGDBRemote::eServerPacketType_qGroupName:
+ return Handle_qGroupName (packet);
+
case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
- return Handle_QStartNoAckMode ();
+ return Handle_QStartNoAckMode (packet);
}
return true;
}
@@ -119,12 +134,23 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout
}
size_t
-GDBRemoteCommunicationServer::SendUnimplementedResponse ()
+GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
{
+ // TODO: Log the packet we aren't handling...
return SendPacket ("");
}
size_t
+GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
+{
+ char packet[16];
+ int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
+ assert (packet_len < sizeof(packet));
+ return SendPacket (packet, packet_len);
+}
+
+
+size_t
GDBRemoteCommunicationServer::SendOKResponse ()
{
return SendPacket ("OK");
@@ -139,7 +165,7 @@ GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
}
bool
-GDBRemoteCommunicationServer::Handle_qHostInfo ()
+GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet)
{
StreamString response;
@@ -204,13 +230,208 @@ GDBRemoteCommunicationServer::Handle_qHostInfo ()
response.PutChar(';');
}
- return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0;
+ return SendPacket (response) > 0;
+}
+
+static void
+CreateProcessInfoResponse (const ProcessInfo &proc_info, StreamString &response)
+{
+ response.Printf ("pid:%i;ppid:%i;uid:%i;gid:%i;euid:%i;egid:%i;",
+ proc_info.GetProcessID(),
+ proc_info.GetParentProcessID(),
+ proc_info.GetRealUserID(),
+ proc_info.GetRealGroupID(),
+ proc_info.GetEffectiveUserID(),
+ proc_info.GetEffectiveGroupID());
+ response.PutCString ("name:");
+ response.PutCStringAsRawHex8(proc_info.GetName());
+ response.PutChar(';');
+ const ArchSpec &proc_arch = proc_info.GetArchitecture();
+ if (proc_arch.IsValid())
+ {
+ const llvm::Triple &proc_triple = proc_arch.GetTriple();
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
+ response.PutChar(';');
+ }
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
+{
+ // Packet format: "qProcessInfoPID:%i" where %i is the pid
+ packet.SetFilePos(strlen ("qProcessInfoPID:"));
+ lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ {
+ ProcessInfo proc_info;
+ if (Host::GetProcessInfo(pid, proc_info))
+ {
+ StreamString response;
+ CreateProcessInfoResponse (proc_info, response);
+ return SendPacket (response);
+ }
+ }
+ return SendErrorResponse (1);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
+{
+ m_proc_infos_index = 0;
+ m_proc_infos.Clear();
+
+ ProcessInfoMatch match_info;
+ packet.SetFilePos(strlen ("qfProcessInfo"));
+ if (packet.GetChar() == ':')
+ {
+
+ std::string key;
+ std::string value;
+ while (packet.GetNameColonValue(key, value))
+ {
+ bool success = true;
+ if (key.compare("name") == 0)
+ {
+ StringExtractor extractor;
+ extractor.GetStringRef().swap(value);
+ extractor.GetHexByteString (value);
+ match_info.GetProcessInfo().SetName (value.c_str());
+ }
+ else if (key.compare("name_match") == 0)
+ {
+ if (value.compare("equals") == 0)
+ {
+ match_info.SetNameMatchType (eNameMatchEquals);
+ }
+ else if (value.compare("starts_with") == 0)
+ {
+ match_info.SetNameMatchType (eNameMatchStartsWith);
+ }
+ else if (value.compare("ends_with") == 0)
+ {
+ match_info.SetNameMatchType (eNameMatchEndsWith);
+ }
+ else if (value.compare("contains") == 0)
+ {
+ match_info.SetNameMatchType (eNameMatchContains);
+ }
+ else if (value.compare("regex") == 0)
+ {
+ match_info.SetNameMatchType (eNameMatchRegularExpression);
+ }
+ else
+ {
+ success = false;
+ }
+ }
+ else if (key.compare("pid") == 0)
+ {
+ match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
+ }
+ else if (key.compare("parent_pid") == 0)
+ {
+ match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
+ }
+ else if (key.compare("uid") == 0)
+ {
+ match_info.GetProcessInfo().SetRealUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ }
+ else if (key.compare("gid") == 0)
+ {
+ match_info.GetProcessInfo().SetRealGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ }
+ else if (key.compare("euid") == 0)
+ {
+ match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ }
+ else if (key.compare("egid") == 0)
+ {
+ match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ }
+ else if (key.compare("all_users") == 0)
+ {
+ match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
+ }
+ else if (key.compare("triple") == 0)
+ {
+ match_info.GetProcessInfo().GetArchitecture().SetTriple(value.c_str());
+ }
+ else
+ {
+ success = false;
+ }
+
+ if (!success)
+ return SendErrorResponse (2);
+ }
+ }
+
+ if (Host::FindProcesses (match_info, m_proc_infos))
+ {
+ // We found something, return the first item by calling the get
+ // subsequent process info packet handler...
+ return Handle_qsProcessInfo (packet);
+ }
+ return SendErrorResponse (3);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
+{
+ if (m_proc_infos_index < m_proc_infos.GetSize())
+ {
+ StreamString response;
+ CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
+ ++m_proc_infos_index;
+ return SendPacket (response);
+ }
+ return SendErrorResponse (4);
+}
+
+bool
+GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet)
+{
+ // Packet format: "qUserName:%i" where %i is the uid
+ packet.SetFilePos(strlen ("qUserName:"));
+ uint32_t uid = packet.GetU32 (UINT32_MAX);
+ if (uid != UINT32_MAX)
+ {
+ std::string name;
+ if (Host::GetUserName (uid, name))
+ {
+ StreamString response;
+ response.PutCStringAsRawHex8 (name.c_str());
+ return SendPacket (response);
+ }
+ }
+ return SendErrorResponse (5);
+
}
+bool
+GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet)
+{
+ // Packet format: "qGroupName:%i" where %i is the gid
+ packet.SetFilePos(strlen ("qGroupName:"));
+ uint32_t gid = packet.GetU32 (UINT32_MAX);
+ if (gid != UINT32_MAX)
+ {
+ std::string name;
+ if (Host::GetGroupName (gid, name))
+ {
+ StreamString response;
+ response.PutCStringAsRawHex8 (name.c_str());
+ return SendPacket (response);
+ }
+ }
+ return SendErrorResponse (6);
+}
bool
-GDBRemoteCommunicationServer::Handle_QStartNoAckMode ()
+GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
{
+ // Send response first before changing m_send_acks to we ack this packet
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 66ddc77bc95..22fb7be4e9f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -14,9 +14,12 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Target/Process.h"
+
#include "GDBRemoteCommunication.h"
class ProcessGDBRemote;
+class StringExtractorGDBRemote;
class GDBRemoteCommunicationServer : public GDBRemoteCommunication
{
@@ -52,18 +55,38 @@ public:
protected:
lldb::thread_t m_async_thread;
+ lldb_private::ProcessInfoList m_proc_infos;
+ uint32_t m_proc_infos_index;
+
+ size_t
+ SendUnimplementedResponse (const char *packet);
size_t
- SendUnimplementedResponse ();
+ SendErrorResponse (uint8_t error);
size_t
SendOKResponse ();
bool
- Handle_qHostInfo ();
+ Handle_qHostInfo (StringExtractorGDBRemote &packet);
+
+ bool
+ Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
+
+ bool
+ Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
+
+ bool
+ Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
+
+ bool
+ Handle_qUserName (StringExtractorGDBRemote &packet);
+
+ bool
+ Handle_qGroupName (StringExtractorGDBRemote &packet);
bool
- Handle_QStartNoAckMode ();
+ Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
private:
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 556fa511b3a..0a1f87279f8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -495,15 +495,15 @@ GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters()
{ "sp", "r13", 4, 52, eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, 13 }},
{ "lr", "r14", 4, 56, eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, 14 }},
{ "pc", "r15", 4, 60, eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, 15 }},
- { NULL, NULL, 12, 64, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 16 }},
- { NULL, NULL, 12, 76, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 17 }},
- { NULL, NULL, 12, 88, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 18 }},
- { NULL, NULL, 12, 100, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 19 }},
- { NULL, NULL, 12, 112, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 20 }},
- { NULL, NULL, 12, 124, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 21 }},
- { NULL, NULL, 12, 136, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 22 }},
- { NULL, NULL, 12, 148, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 23 }},
- { NULL, NULL, 12, 160, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 24 }},
+// { NULL, NULL, 12, 64, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 16 }},
+// { NULL, NULL, 12, 76, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 17 }},
+// { NULL, NULL, 12, 88, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 18 }},
+// { NULL, NULL, 12, 100, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 19 }},
+// { NULL, NULL, 12, 112, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 20 }},
+// { NULL, NULL, 12, 124, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 21 }},
+// { NULL, NULL, 12, 136, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 22 }},
+// { NULL, NULL, 12, 148, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 23 }},
+// { NULL, NULL, 12, 160, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 24 }},
{ "cpsr", "psr", 4, 172, eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 25 }},
{ "s0", NULL, 4, 176, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 26 }},
{ "s1", NULL, 4, 180, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 27 }},
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 987f24637d2..a2b17e56892 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -312,6 +312,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
else
{
response_type = StringExtractorGDBRemote::eError;
+ break;
}
}
@@ -377,6 +378,7 @@ ProcessGDBRemote::DoConnectRemote (const char *remote_url)
{
// We have a valid process
SetID (pid);
+ UpdateThreadListIfNeeded ();
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, false))
{
@@ -601,23 +603,28 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
return error;
}
- if (m_gdb_comm.StartReadThread(&error))
+ // We always seem to be able to open a connection to a local port
+ // so we need to make sure we can then send data to it. If we can't
+ // then we aren't actually connected to anything, so try and do the
+ // handshake with the remote GDB server and make sure that goes
+ // alright.
+ if (!m_gdb_comm.HandshakeWithServer (NULL))
{
- // Send an initial ack
- m_gdb_comm.SendAck();
-
- if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
- m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
- this,
- m_debugserver_pid,
- false);
-
- m_gdb_comm.ResetDiscoverableSettings();
- m_gdb_comm.GetSendAcks ();
- m_gdb_comm.GetThreadSuffixSupported ();
- m_gdb_comm.GetHostInfo ();
- m_gdb_comm.GetVContSupported ('c');
+ m_gdb_comm.Disconnect();
+ if (error.Success())
+ error.SetErrorString("not connected to remote gdb server");
+ return error;
}
+ if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
+ this,
+ m_debugserver_pid,
+ false);
+ m_gdb_comm.ResetDiscoverableSettings();
+ m_gdb_comm.QueryNoAckModeSupported ();
+ m_gdb_comm.GetThreadSuffixSupported ();
+ m_gdb_comm.GetHostInfo ();
+ m_gdb_comm.GetVContSupported ('c');
return error;
}
@@ -633,9 +640,6 @@ ProcessGDBRemote::DidLaunchOrAttach ()
BuildDynamicRegisterInfo (false);
-
- StreamString strm;
-
// See if the GDB server supports the qHostInfo information
const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
@@ -2364,13 +2368,13 @@ ProcessGDBRemote::GetDispatchQueueNameForThread
{
static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
const Symbol *dispatch_queue_offsets_symbol = NULL;
- ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false)));
+ ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false), NULL, NULL));
if (module_sp)
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
if (dispatch_queue_offsets_symbol == NULL)
{
- module_sp = GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false));
+ module_sp = GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false), NULL, NULL);
if (module_sp)
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
}
OpenPOWER on IntegriCloud