From 03904accc0ac27177867f6f4a28b080bb604011f Mon Sep 17 00:00:00 2001 From: Steve Pucci Date: Tue, 4 Mar 2014 23:18:46 +0000 Subject: [PATCH] Add ProcessGDBRemote::GetAuxvData() and fix multiple-packet concatenation for binary data. ProcessGDBRemote::GetAuxvData obtains the auxv from a remote gdbserver (via a binary-data packet), and returns the data as a DataBufferSP. The patch includes a small fix to GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses() to support binary file format packet returns (by not assuming each binary packet is a null-terminated string when concatenating them). llvm-svn: 202907 --- .../GDBRemoteCommunicationClient.cpp | 24 ++++++++++++++----- .../gdb-remote/GDBRemoteCommunicationClient.h | 4 ++++ .../Process/gdb-remote/ProcessGDBRemote.cpp | 13 ++++++++++ .../Process/gdb-remote/ProcessGDBRemote.h | 3 +++ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 9853de1476eb..9b9de22808ca 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -66,6 +66,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : m_prepare_for_reg_writing_reply (eLazyBoolCalculate), m_supports_p (eLazyBoolCalculate), m_supports_QSaveRegisterState (eLazyBoolCalculate), + m_supports_qXfer_auxv_read (eLazyBoolCalculate), m_supports_qXfer_libraries_read (eLazyBoolCalculate), m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate), m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate), @@ -187,6 +188,16 @@ GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported () return (m_supports_qXfer_libraries_read == eLazyBoolYes); } +bool +GDBRemoteCommunicationClient::GetQXferAuxvReadSupported () +{ + if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) + { + GetRemoteQSupported(); + } + return (m_supports_qXfer_auxv_read == eLazyBoolYes); +} + uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() { @@ -294,6 +305,7 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings() m_supports_memory_region_info = eLazyBoolCalculate; m_prepare_for_reg_writing_reply = eLazyBoolCalculate; m_attach_or_wait_reply = eLazyBoolCalculate; + m_supports_qXfer_auxv_read = eLazyBoolCalculate; m_supports_qXfer_libraries_read = eLazyBoolCalculate; m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate; m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate; @@ -320,8 +332,9 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported () { // Clear out any capabilities we expect to see in the qSupported response - m_supports_qXfer_libraries_svr4_read = eLazyBoolNo; + m_supports_qXfer_auxv_read = eLazyBoolNo; m_supports_qXfer_libraries_read = eLazyBoolNo; + m_supports_qXfer_libraries_svr4_read = eLazyBoolNo; m_supports_augmented_libraries_svr4_read = eLazyBoolNo; m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if not, we assume no limit @@ -331,6 +344,8 @@ GDBRemoteCommunicationClient::GetRemoteQSupported () /*send_async=*/false) == PacketResult::Success) { const char *response_cstr = response.GetStringRef().c_str(); + if (::strstr (response_cstr, "qXfer:auxv:read+")) + m_supports_qXfer_auxv_read = eLazyBoolYes; if (::strstr (response_cstr, "qXfer:libraries-svr4:read+")) m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; if (::strstr (response_cstr, "augmented-libraries-svr4-read")) @@ -502,11 +517,8 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses { return PacketResult::ErrorReplyInvalid; } - // Skip past m or l - const char *s = this_string.c_str() + 1; - - // Concatenate the result so far - response_string += s; + // Concatenate the result so far (skipping 'm' or 'l') + response_string.append(this_string, 1, std::string::npos); if (first_char == 'l') // We're done return PacketResult::Success; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index a1e982b3ec4e..4e404b6ab44a 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -383,6 +383,9 @@ public: bool SetCurrentThreadForRun (uint64_t tid); + bool + GetQXferAuxvReadSupported (); + bool GetQXferLibrariesReadSupported (); @@ -525,6 +528,7 @@ protected: lldb_private::LazyBool m_prepare_for_reg_writing_reply; lldb_private::LazyBool m_supports_p; lldb_private::LazyBool m_supports_QSaveRegisterState; + lldb_private::LazyBool m_supports_qXfer_auxv_read; lldb_private::LazyBool m_supports_qXfer_libraries_read; lldb_private::LazyBool m_supports_qXfer_libraries_svr4_read; lldb_private::LazyBool m_supports_augmented_libraries_svr4_read; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 800bd2570610..604906e2a850 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -3060,6 +3060,19 @@ ProcessGDBRemote::GetDynamicLoader () return m_dyld_ap.get(); } +const DataBufferSP +ProcessGDBRemote::GetAuxvData() +{ + DataBufferSP buf; + if (m_gdb_comm.GetQXferAuxvReadSupported()) + { + std::string response_string; + if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::", response_string) == GDBRemoteCommunication::PacketResult::Success) + buf.reset(new DataBufferHeap(response_string.c_str(), response_string.length())); + } + return buf; +} + class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed { diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 9331775bb896..1d4a23509e65 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -299,6 +299,9 @@ protected: bool ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array); + virtual const lldb::DataBufferSP + GetAuxvData(); + //------------------------------------------------------------------ /// Broadcaster event bits definitions. //------------------------------------------------------------------