Discover support of 'p' packet.

Some stubs only support g/G packets for registers.
This change makes sure that we check if remote stub supports 'p' packet before using it.

llvm-svn: 189576
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 3f702be..05f2d9b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -55,6 +55,7 @@
     m_supports_vCont_C (eLazyBoolCalculate),
     m_supports_vCont_s (eLazyBoolCalculate),
     m_supports_vCont_S (eLazyBoolCalculate),
+    m_supports_p (eLazyBoolCalculate),
     m_qHostInfo_is_valid (eLazyBoolCalculate),
     m_qProcessInfo_is_valid (eLazyBoolCalculate),
     m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
@@ -200,6 +201,7 @@
     m_supports_vCont_C = eLazyBoolCalculate;
     m_supports_vCont_s = eLazyBoolCalculate;
     m_supports_vCont_S = eLazyBoolCalculate;
+    m_supports_p = eLazyBoolCalculate;
     m_qHostInfo_is_valid = eLazyBoolCalculate;
     m_qProcessInfo_is_valid = eLazyBoolCalculate;
     m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
@@ -295,6 +297,24 @@
     return false;
 }
 
+// Check if the target supports 'p' packet. It sends out a 'p'
+// packet and checks the response. A normal packet will tell us
+// that support is available.
+bool
+GDBRemoteCommunicationClient::GetpPacketSupported ()
+{
+    if (m_supports_p == eLazyBoolCalculate)
+    {
+        StringExtractorGDBRemote response;
+        m_supports_p = eLazyBoolNo;
+        if (SendPacketAndWaitForResponse("p0", response, false))
+        {
+            if (response.IsNormalResponse())
+                m_supports_p = eLazyBoolYes;
+        }
+    }
+    return m_supports_p;
+}
 
 size_t
 GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index c8809cb..fc317be 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -228,6 +228,9 @@
     GetVContSupported (char flavor);
 
     bool
+    GetpPacketSupported ();
+
+    bool
     GetVAttachOrWaitSupported ();
     
     bool
@@ -431,6 +434,7 @@
     lldb_private::LazyBool m_watchpoints_trigger_after_instruction;
     lldb_private::LazyBool m_attach_or_wait_reply;
     lldb_private::LazyBool m_prepare_for_reg_writing_reply;
+    lldb_private::LazyBool m_supports_p;
     
     bool
         m_supports_qProcessInfoPID:1,
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 38fb84d..b405f03 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -164,7 +164,6 @@
 ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame)
 {
     lldb::RegisterContextSP reg_ctx_sp;
-    const bool read_all_registers_at_once = false;
     uint32_t concrete_frame_idx = 0;
     
     if (frame)
@@ -177,6 +176,8 @@
         if (process_sp)
         {
             ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
+            // read_all_registers_at_once will be true if 'p' packet is not supported.
+            bool read_all_registers_at_once = !gdb_process->GetGDBRemote().GetpPacketSupported ();
             reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
         }
     }