From 70969ef10270d3be63498be123ef98ac5dcf2f57 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <peter@pcc.me.uk>
Date: Fri, 3 Jun 2011 20:40:44 +0000
Subject: [PATCH] Implement ProcessLinux::Do{Allocate,Deallocate}Memory using
 inferior mmap/munmap calls

llvm-svn: 132585
---
 .../Plugins/Process/Linux/ProcessLinux.cpp    | 39 +++++++++++++++----
 .../Plugins/Process/Linux/ProcessLinux.h      |  7 ++--
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp
index f915888ef186..c4ce8eeb0b38 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp
@@ -13,12 +13,14 @@
 // C++ Includes
 // Other libraries and framework includes
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/State.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/Target.h"
 
 #include "ProcessLinux.h"
+#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
 #include "ProcessMonitor.h"
 #include "LinuxThread.h"
 
@@ -345,19 +347,40 @@ addr_t
 ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
                                Error &error)
 {
-    return 0;
-}
+    addr_t allocated_addr = LLDB_INVALID_ADDRESS;
 
-addr_t
-ProcessLinux::AllocateMemory(size_t size, uint32_t permissions, Error &error)
-{
-    return 0;
+    unsigned prot = 0;
+    if (permissions & lldb::ePermissionsReadable)
+        prot |= eMmapProtRead;
+    if (permissions & lldb::ePermissionsWritable)
+        prot |= eMmapProtWrite;
+    if (permissions & lldb::ePermissionsExecutable)
+        prot |= eMmapProtExec;
+
+    if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
+                         eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
+        m_addr_to_mmap_size[allocated_addr] = size;
+        error.Clear();
+    } else {
+        allocated_addr = LLDB_INVALID_ADDRESS;
+        error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
+    }
+
+    return allocated_addr;
 }
 
 Error
-ProcessLinux::DoDeallocateMemory(lldb::addr_t ptr)
+ProcessLinux::DoDeallocateMemory(lldb::addr_t addr)
 {
-    return Error(1, eErrorTypeGeneric);
+    Error error;
+    MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
+    if (pos != m_addr_to_mmap_size.end() &&
+        InferiorCallMunmap(this, addr, pos->second))
+        m_addr_to_mmap_size.erase (pos);
+    else
+        error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+
+    return error;
 }
 
 size_t
diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.h b/lldb/source/Plugins/Process/Linux/ProcessLinux.h
index 762f817c3350..418ea69c0332 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.h
@@ -114,10 +114,6 @@ public:
     DoAllocateMemory(size_t size, uint32_t permissions,
                      lldb_private::Error &error);
 
-    lldb::addr_t
-    AllocateMemory(size_t size, uint32_t permissions,
-                   lldb_private::Error &error);
-
     virtual lldb_private::Error
     DoDeallocateMemory(lldb::addr_t ptr);
 
@@ -220,6 +216,9 @@ private:
 
     /// Returns true if the process is stopped.
     bool IsStopped();
+
+    typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+    MMapMap m_addr_to_mmap_size;
 };
 
 #endif  // liblldb_MacOSXProcess_H_