diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | 237 |
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; } |