Expand the ABI prepare trivial function call to allow 6 simple args.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@131334 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index f8eb8de..5e685e0 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -45,6 +45,8 @@
     m_supports_vCont_s (eLazyBoolCalculate),
     m_supports_vCont_S (eLazyBoolCalculate),
     m_qHostInfo_is_valid (eLazyBoolCalculate),
+    m_supports__m (eLazyBoolCalculate),
+    m_supports__M (eLazyBoolCalculate),
     m_supports_qProcessInfoPID (true),
     m_supports_qfProcessInfo (true),
     m_supports_qUserName (true),
@@ -130,6 +132,9 @@
     m_supports_vCont_s = eLazyBoolCalculate;
     m_supports_vCont_S = eLazyBoolCalculate;
     m_qHostInfo_is_valid = eLazyBoolCalculate;
+    m_supports__m = eLazyBoolCalculate;
+    m_supports__M = eLazyBoolCalculate;
+
     m_supports_qProcessInfoPID = true;
     m_supports_qfProcessInfo = true;
     m_supports_qUserName = true;
@@ -1016,17 +1021,23 @@
 addr_t
 GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
 {
-    char packet[64];
-    const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
-                                       permissions & lldb::ePermissionsReadable ? "r" : "",
-                                       permissions & lldb::ePermissionsWritable ? "w" : "",
-                                       permissions & lldb::ePermissionsExecutable ? "x" : "");
-    assert (packet_len < sizeof(packet));
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+    if (m_supports__M != eLazyBoolNo)
     {
-        if (!response.IsErrorResponse())
-            return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+        m_supports__M = eLazyBoolYes;
+        char packet[64];
+        const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
+                                           permissions & lldb::ePermissionsReadable ? "r" : "",
+                                           permissions & lldb::ePermissionsWritable ? "w" : "",
+                                           permissions & lldb::ePermissionsExecutable ? "x" : "");
+        assert (packet_len < sizeof(packet));
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+        {
+            if (response.IsUnsupportedResponse())
+                m_supports__M = eLazyBoolNo;
+            else if (!response.IsErrorResponse())
+                return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+        }
     }
     return LLDB_INVALID_ADDRESS;
 }
@@ -1034,14 +1045,20 @@
 bool
 GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
 {
-    char packet[64];
-    const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
-    assert (packet_len < sizeof(packet));
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+    if (m_supports__m != eLazyBoolNo)
     {
-        if (response.IsOKResponse())
-            return true;
+        m_supports__m = eLazyBoolYes;
+        char packet[64];
+        const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
+        assert (packet_len < sizeof(packet));
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+        {
+            if (response.IsOKResponse())
+                return true;
+            else if (response.IsUnsupportedResponse())
+                m_supports__m = eLazyBoolNo;
+        }
     }
     return false;
 }
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index d8f317a..e1d17be 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -305,6 +305,18 @@
     bool
     SetCurrentThreadForRun (int tid);
 
+    lldb_private::LazyBool
+    SupportsAllocateMemory () const
+    {
+        return m_supports__M;
+    }
+
+    lldb_private::LazyBool
+    SupportsDeallocateMemory () const
+    {
+        return m_supports__m;
+    }
+
 protected:
 
     //------------------------------------------------------------------
@@ -319,6 +331,9 @@
     lldb_private::LazyBool m_supports_vCont_s;
     lldb_private::LazyBool m_supports_vCont_S;
     lldb_private::LazyBool m_qHostInfo_is_valid;
+    lldb_private::LazyBool m_supports__m;
+    lldb_private::LazyBool m_supports__M;
+
     bool
         m_supports_qProcessInfoPID:1,
         m_supports_qfProcessInfo:1,
@@ -330,6 +345,7 @@
         m_supports_z2:1,
         m_supports_z3:1,
         m_supports_z4:1;
+    
 
     lldb::tid_t m_curr_tid;         // Current gdb remote protocol thread index for all other operations
     lldb::tid_t m_curr_tid_run;     // Current gdb remote protocol thread index for continue, step, etc
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index cba830e..14f3100 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -11,8 +11,9 @@
 #include <errno.h>
 #include <spawn.h>
 #include <stdlib.h>
-#include <sys/types.h>
+#include <sys/mman.h>       // for mmap
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <time.h>
 
 // C++ Includes
@@ -38,6 +39,7 @@
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/TargetList.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
 #include "lldb/Utility/PseudoTerminal.h"
 
 // Project includes
@@ -1541,7 +1543,93 @@
 lldb::addr_t
 ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
 {
-    addr_t allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
+    addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+    
+    LazyBool supported = m_gdb_comm.SupportsAllocateMemory();
+    switch (supported)
+    {
+        case eLazyBoolCalculate:
+        case eLazyBoolYes:
+            allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
+            if (allocated_addr != LLDB_INVALID_ADDRESS || supported == eLazyBoolYes)
+                return allocated_addr;
+
+        case eLazyBoolNo:
+            // Call mmap() to create executable memory in the inferior..
+            {
+                Thread *thread = GetThreadList().GetSelectedThread().get();
+                if (thread == NULL)
+                    thread = GetThreadList().GetThreadAtIndex(0).get();
+
+                const bool append = true;
+                const bool include_symbols = true;
+                SymbolContextList sc_list;
+                const uint32_t count = m_target.GetImages().FindFunctions (ConstString ("mmap"), 
+                                                                           eFunctionNameTypeFull,
+                                                                           include_symbols, 
+                                                                           append, 
+                                                                           sc_list);
+                if (count > 0)
+                {
+                    SymbolContext sc;
+                    if (sc_list.GetContextAtIndex(0, sc))
+                    {
+                        const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
+                        const bool use_inline_block_range = false;
+                        const bool stop_other_threads = true;
+                        const bool discard_on_error = true;
+                        const bool try_all_threads = true;
+                        const uint32_t single_thread_timeout_usec = 500000;
+                        addr_t arg1_addr = 0;
+                        addr_t arg2_len = size;
+                        addr_t arg3_prot = PROT_NONE;
+                        addr_t arg4_flags = MAP_ANON;
+                        addr_t arg5_fd = -1;
+                        addr_t arg6_offset = 0;
+                        if (permissions & lldb::ePermissionsReadable)
+                            arg3_prot |= PROT_READ;
+                        if (permissions & lldb::ePermissionsWritable)
+                            arg3_prot |= PROT_WRITE;
+                        if (permissions & lldb::ePermissionsExecutable)
+                            arg3_prot |= PROT_EXEC;
+
+                        AddressRange mmap_range;
+                        if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
+                        {
+                            lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
+                                                                                         mmap_range.GetBaseAddress(),
+                                                                                         stop_other_threads,
+                                                                                         discard_on_error,
+                                                                                         &arg1_addr,
+                                                                                         &arg2_len,
+                                                                                         &arg3_prot,
+                                                                                         &arg4_flags,
+                                                                                         &arg5_fd,
+                                                                                         &arg6_offset));
+                            if (call_plan_sp)
+                            {
+                                StreamFile error_strm;
+                                StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+                                if (frame)
+                                {
+                                    ExecutionContext exe_ctx;
+                                    frame->CalculateExecutionContext (exe_ctx);
+                                    ExecutionResults results = RunThreadPlan (exe_ctx,
+                                                                              call_plan_sp,        
+                                                                              stop_other_threads,
+                                                                              try_all_threads,
+                                                                              discard_on_error,
+                                                                              single_thread_timeout_usec,
+                                                                              error_strm);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+    }
+    
     if (allocated_addr == LLDB_INVALID_ADDRESS)
         error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %u", size, permissions);
     else