summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-02-12 06:28:37 +0000
committerGreg Clayton <gclayton@apple.com>2011-02-12 06:28:37 +0000
commit71fc2a33b576839d7653c8ff13dd686efe54d9db (patch)
tree25384bde96fa85c18c0e7531455a0faebe16e1f9 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
parentba6ead4bc08363cba1ecf353f5c60c23cecbd443 (diff)
downloadbcm5719-llvm-71fc2a33b576839d7653c8ff13dd686efe54d9db.tar.gz
bcm5719-llvm-71fc2a33b576839d7653c8ff13dd686efe54d9db.zip
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. llvm-svn: 125433
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp237
1 files changed, 175 insertions, 62 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 6442e21b224..9ebb143a150 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -34,8 +34,15 @@ using namespace lldb_private;
//----------------------------------------------------------------------
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 @@ GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_
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 @@ GDBRemoteCommunication::SendNack ()
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 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le
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 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response,
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 @@ GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uin
}
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)
+ 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;
+
+ while (response.GetNameColonValue(name, value))
{
- m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+ 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);
}
-
- if (cpu != LLDB_INVALID_CPUTYPE)
- m_arch.SetMachOArch (cpu, sub);
}
- return HostInfoIsValid();
+ return m_supports_qHostInfo == eLazyBoolYes;
}
int
@@ -918,7 +1031,7 @@ const lldb_private::ArchSpec &
GDBRemoteCommunication::GetHostArchitecture ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_arch;
}
@@ -926,7 +1039,7 @@ const lldb_private::ConstString &
GDBRemoteCommunication::GetOSString ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_os;
}
@@ -934,7 +1047,7 @@ const lldb_private::ConstString &
GDBRemoteCommunication::GetVendorString()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_vendor;
}
@@ -942,7 +1055,7 @@ lldb::ByteOrder
GDBRemoteCommunication::GetByteOrder ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_byte_order;
}
@@ -950,7 +1063,7 @@ uint32_t
GDBRemoteCommunication::GetAddressByteSize ()
{
if (!HostInfoIsValid ())
- GetHostInfo (1);
+ GetHostInfo ();
return m_pointer_byte_size;
}
OpenPOWER on IntegriCloud