Added the ability to detect which vCont packets (using the "vCont?") packet
are supported by the remote GDB target. We can also now deal with the lack of
vCont support and send packets that the remote GDB stub can use. We also error
out of the continue if LLDB tries to do something too complex when vCont isn't
supported.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@125433 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 6442e21..9ebb143 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -34,8 +34,15 @@
//----------------------------------------------------------------------
GDBRemoteCommunication::GDBRemoteCommunication() :
Communication("gdb-remote.packets"),
- m_send_acks (true),
- m_thread_suffix_supported (false),
+ 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_rx_packet_listener ("gdbremote.rx_packet"),
m_sequence_mutex (Mutex::eMutexTypeRecursive),
m_public_is_running (false),
@@ -79,7 +86,7 @@
int checksum = 0;
// We only need to compute the checksum if we are sending acks
- if (m_send_acks)
+ if (GetSendAcks ())
{
for (size_t i = 0; i < payload_length; ++i)
checksum += payload[i];
@@ -109,6 +116,112 @@
return Write (&nack_char, 1, status, NULL) == 1;
}
+bool
+GDBRemoteCommunication::GetSendAcks ()
+{
+ if (m_supports_not_sending_acks == eLazyBoolCalculate)
+ {
+ StringExtractorGDBRemote response;
+ m_supports_not_sending_acks = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
+ {
+ if (response.IsOKPacket())
+ m_supports_not_sending_acks = eLazyBoolYes;
+ }
+ }
+ return m_supports_not_sending_acks != eLazyBoolYes;
+}
+
+void
+GDBRemoteCommunication::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_arch.Clear();
+ m_os.Clear();
+ m_vendor.Clear();
+ m_byte_order = lldb::endian::InlHostByteOrder();
+ m_pointer_byte_size = 0;
+}
+
+
+bool
+GDBRemoteCommunication::GetThreadSuffixSupported ()
+{
+ if (m_supports_thread_suffix == eLazyBoolCalculate)
+ {
+ StringExtractorGDBRemote response;
+ m_supports_thread_suffix = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false))
+ {
+ if (response.IsOKPacket())
+ m_supports_thread_suffix = eLazyBoolYes;
+ }
+ }
+ return m_supports_thread_suffix;
+}
+bool
+GDBRemoteCommunication::GetVContSupported (char flavor)
+{
+ if (m_supports_vCont_c == eLazyBoolCalculate)
+ {
+ StringExtractorGDBRemote response;
+ m_supports_vCont_c = eLazyBoolNo;
+ m_supports_vCont_C = eLazyBoolNo;
+ m_supports_vCont_s = eLazyBoolNo;
+ m_supports_vCont_S = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("vCont?", response, 1, false))
+ {
+ const char *response_cstr = response.GetStringRef().c_str();
+ if (::strstr (response_cstr, ";c"))
+ m_supports_vCont_c = eLazyBoolYes;
+
+ if (::strstr (response_cstr, ";C"))
+ m_supports_vCont_C = eLazyBoolYes;
+
+ if (::strstr (response_cstr, ";s"))
+ m_supports_vCont_s = eLazyBoolYes;
+
+ if (::strstr (response_cstr, ";S"))
+ m_supports_vCont_S = eLazyBoolYes;
+
+ if (m_supports_vCont_c == eLazyBoolYes &&
+ m_supports_vCont_C == eLazyBoolYes &&
+ m_supports_vCont_s == eLazyBoolYes &&
+ m_supports_vCont_S == eLazyBoolYes)
+ {
+ m_supports_vCont_all = eLazyBoolYes;
+ }
+
+ if (m_supports_vCont_c == eLazyBoolYes ||
+ m_supports_vCont_C == eLazyBoolYes ||
+ m_supports_vCont_s == eLazyBoolYes ||
+ m_supports_vCont_S == eLazyBoolYes)
+ {
+ m_supports_vCont_any = eLazyBoolYes;
+ }
+ }
+ }
+
+ switch (flavor)
+ {
+ case 'a': return m_supports_vCont_any;
+ case 'A': return m_supports_vCont_all;
+ case 'c': return m_supports_vCont_c;
+ case 'C': return m_supports_vCont_C;
+ case 's': return m_supports_vCont_s;
+ case 'S': return m_supports_vCont_S;
+ default: break;
+ }
+ return false;
+}
+
+
size_t
GDBRemoteCommunication::SendPacketAndWaitForResponse
(
@@ -451,7 +564,7 @@
size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
if (bytes_written == packet.GetSize())
{
- if (m_send_acks)
+ if (GetSendAcks ())
{
if (GetAck (1) != '+')
return 0;
@@ -643,7 +756,7 @@
if (success)
response_str.assign (packet_data + 1, packet_size - 4);
- if (m_send_acks)
+ if (GetSendAcks ())
{
char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
@@ -829,66 +942,66 @@
}
bool
-GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds)
+GDBRemoteCommunication::GetHostInfo ()
{
- m_arch.Clear();
- m_os.Clear();
- m_vendor.Clear();
- m_byte_order = lldb::endian::InlHostByteOrder();
- m_pointer_byte_size = 0;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false))
+ if (m_supports_qHostInfo == eLazyBoolCalculate)
{
- if (response.IsUnsupportedPacket())
- return false;
+ m_supports_qHostInfo = eLazyBoolNo;
-
- std::string name;
- std::string value;
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
-
- while (response.GetNameColonValue(name, value))
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false))
{
- if (name.compare("cputype") == 0)
- {
- // 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("ostype") == 0)
- {
- // exception data in big endian hex
- m_os.SetCString(value.c_str());
- }
- else if (name.compare("vendor") == 0)
- {
- m_vendor.SetCString(value.c_str());
- }
- else if (name.compare("endian") == 0)
- {
- if (value.compare("little") == 0)
- m_byte_order = eByteOrderLittle;
- else if (value.compare("big") == 0)
- m_byte_order = eByteOrderBig;
- else if (value.compare("pdp") == 0)
- m_byte_order = eByteOrderPDP;
- }
- else if (name.compare("ptrsize") == 0)
- {
- m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
- }
- }
+ if (response.IsUnsupportedPacket())
+ return false;
+
+ m_supports_qHostInfo = eLazyBoolYes;
+
+ std::string name;
+ std::string value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
- if (cpu != LLDB_INVALID_CPUTYPE)
- m_arch.SetMachOArch (cpu, sub);
+ while (response.GetNameColonValue(name, value))
+ {
+ if (name.compare("cputype") == 0)
+ {
+ // 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("ostype") == 0)
+ {
+ // exception data in big endian hex
+ m_os.SetCString(value.c_str());
+ }
+ else if (name.compare("vendor") == 0)
+ {
+ m_vendor.SetCString(value.c_str());
+ }
+ else if (name.compare("endian") == 0)
+ {
+ if (value.compare("little") == 0)
+ m_byte_order = eByteOrderLittle;
+ else if (value.compare("big") == 0)
+ m_byte_order = eByteOrderBig;
+ else if (value.compare("pdp") == 0)
+ m_byte_order = eByteOrderPDP;
+ }
+ else if (name.compare("ptrsize") == 0)
+ {
+ m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+ }
+ }
+
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ m_arch.SetMachOArch (cpu, sub);
+ }
}
- return HostInfoIsValid();
+ return m_supports_qHostInfo == eLazyBoolYes;
}
int
@@ -918,7 +1031,7 @@
GDBRemoteCommunication::GetHostArchitecture ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_arch;
}
@@ -926,7 +1039,7 @@
GDBRemoteCommunication::GetOSString ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_os;
}
@@ -934,7 +1047,7 @@
GDBRemoteCommunication::GetVendorString()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_vendor;
}
@@ -942,7 +1055,7 @@
GDBRemoteCommunication::GetByteOrder ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_byte_order;
}
@@ -950,7 +1063,7 @@
GDBRemoteCommunication::GetAddressByteSize ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_pointer_byte_size;
}