Modularised the libc low-level memory management stuff (mmap, etc).


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3891 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index dc84701..26a769f 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -49,6 +49,7 @@
 	pub_core_libcbase.h	\
 	pub_core_libcassert.h	\
 	pub_core_libcfile.h	\
+	pub_core_libcmman.h	\
 	pub_core_libcprint.h	\
 	pub_core_libcsignal.h	\
 	pub_core_main.h		\
@@ -97,6 +98,7 @@
 	m_libcbase.c \
 	m_libcassert.c \
 	m_libcfile.c \
+	m_libcmman.c \
 	m_libcprint.c \
 	m_libcsignal.c \
 	m_main.c \
diff --git a/coregrind/core.h b/coregrind/core.h
index 36afbdf..b1a90b0 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -126,16 +126,6 @@
 extern Int VG_(fcntl) ( Int fd, Int cmd, Int arg );
 extern Int VG_(poll)( struct vki_pollfd *, UInt nfds, Int timeout);
 
-/* system/mman.h */
-extern void* VG_(mmap)       ( void* start, SizeT length, UInt prot, UInt flags,
-                               UInt sf_flags, UInt fd, OffT offset );
-extern SysRes VG_(mmap_native)( void* start, SizeT length, UInt prot, UInt flags,
-                                              UInt fd, OffT offset );
-extern Int VG_(munmap)       ( void* start, SizeT length );
-extern Int VG_(mprotect)       ( void *start, SizeT length, UInt prot );
-extern Int VG_(mprotect_native)( void *start, SizeT length, UInt prot );
-
-
 /* Environment manipulations */
 extern Char **VG_(env_setenv)   ( Char ***envp, const Char* varname,
                                   const Char *val );
diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c
index 76f35f6..de54b62 100644
--- a/coregrind/m_aspacemgr/aspacemgr.c
+++ b/coregrind/m_aspacemgr/aspacemgr.c
@@ -35,6 +35,7 @@
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcfile.h"      // For VG_(fstat)()
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
@@ -1471,7 +1472,7 @@
 {
    static Addr shadow_alloc = 0;
    Addr try_here;
-   Int r;
+   SysRes r;
 
    if (0) show_segments("shadow_alloc(before)");
 
@@ -1509,7 +1510,7 @@
    r = VG_(mprotect_native)( (void*)try_here, 
                              size,  VKI_PROT_READ|VKI_PROT_WRITE );
 
-   if (r != 0)
+   if (r.isError)
       goto failed;
 
    shadow_alloc += size;
diff --git a/coregrind/m_debuginfo/symtab.c b/coregrind/m_debuginfo/symtab.c
index a9ace24..d47313c 100644
--- a/coregrind/m_debuginfo/symtab.c
+++ b/coregrind/m_debuginfo/symtab.c
@@ -35,6 +35,7 @@
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcfile.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
diff --git a/coregrind/m_debuginfo/symtypes.c b/coregrind/m_debuginfo/symtypes.c
index 48e7a09..5e3b625 100644
--- a/coregrind/m_debuginfo/symtypes.c
+++ b/coregrind/m_debuginfo/symtypes.c
@@ -33,6 +33,7 @@
 #include "pub_core_debuglog.h"    /* VG_(debugLog_vprintf) */
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcsignal.h"
 #include "pub_core_mallocfree.h"
diff --git a/coregrind/m_libcmman.c b/coregrind/m_libcmman.c
new file mode 100644
index 0000000..c8536a8
--- /dev/null
+++ b/coregrind/m_libcmman.c
@@ -0,0 +1,170 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Memory management libc stuff.                   m_libcmman.c ---*/
+/*--------------------------------------------------------------------*/
+ 
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward 
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "core.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcmman.h"
+#include "pub_core_libcprint.h"
+#include "vki_unistd.h"
+
+SysRes VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
+                        UInt fd, OffT offset)
+{
+   SysRes res;
+#  if defined(VGP_x86_linux)
+   { 
+      UWord args[6];
+      args[0] = (UWord)start;
+      args[1] = length;
+      args[2] = prot;
+      args[3] = flags;
+      args[4] = fd;
+      args[5] = offset;
+      res = VG_(do_syscall1)(__NR_mmap, (UWord)args );
+   }
+#  elif defined(VGP_amd64_linux)
+   res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, 
+                         prot, flags, fd, offset);
+#  else
+#    error Unknown platform
+#  endif
+   return res;
+}
+
+/* Returns -1 on failure. */
+void* VG_(mmap)( void* start, SizeT length,
+                 UInt prot, UInt flags, UInt sf_flags, UInt fd, OffT offset)
+{
+   SysRes res;
+
+   if (!(flags & VKI_MAP_FIXED)) {
+      start = (void *)VG_(find_map_space)((Addr)start, length, !!(flags & VKI_MAP_CLIENT));
+
+      flags |= VKI_MAP_FIXED;
+   }
+   if (start == 0)
+      return (void *)-1;
+
+   res = VG_(mmap_native)(start, length, prot, 
+                          flags & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
+                          fd, offset);
+
+   // Check it ended up in the right place.
+   if (!res.isError) {
+      if (flags & VKI_MAP_CLIENT) {
+         vg_assert(VG_(client_base) <= res.val 
+                   && res.val+length <= VG_(client_end));
+      } else {
+         vg_assert(VG_(valgrind_base) <= res.val 
+                   && res.val+length-1 <= VG_(valgrind_last));
+      }
+
+      sf_flags |= SF_MMAP;
+      if (  flags & VKI_MAP_FIXED)      sf_flags |= SF_FIXED;
+      if (  flags & VKI_MAP_SHARED)     sf_flags |= SF_SHARED;
+      if (!(flags & VKI_MAP_ANONYMOUS)) sf_flags |= SF_FILE;
+      if (!(flags & VKI_MAP_CLIENT))    sf_flags |= SF_VALGRIND;
+      if (  flags & VKI_MAP_NOSYMS)     sf_flags |= SF_NOSYMS;
+
+      VG_(map_fd_segment)(res.val, length, prot, sf_flags, fd, offset, NULL);
+   }
+
+   return res.isError ? (void*)-1 : (void*)res.val;
+}
+
+static SysRes munmap_native(void *start, SizeT length)
+{
+   return VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
+}
+
+/* Returns -1 on failure. */
+Int VG_(munmap)( void* start, SizeT length )
+{
+   SysRes res = munmap_native(start, length);
+   if (!res.isError) {
+      VG_(unmap_range)((Addr)start, length);
+      return 0;
+   } else {
+      return -1;
+   }
+}
+
+SysRes VG_(mprotect_native)( void *start, SizeT length, UInt prot )
+{
+   return VG_(do_syscall3)(__NR_mprotect, (UWord)start, length, prot );
+}
+
+Int VG_(mprotect)( void *start, SizeT length, UInt prot )
+{
+   SysRes res = VG_(mprotect_native)(start, length, prot);
+   if (!res.isError) {
+      VG_(mprotect_range)((Addr)start, length, prot);
+      return 0;
+   } else {
+      return -1;
+   }
+}
+
+void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who )
+{
+   static SizeT tot_alloc = 0;
+   void* p;
+   p = VG_(mmap)(0, nBytes,
+                 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
+                 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 0, -1, 0);
+
+   if (p != ((void*)(-1))) {
+      vg_assert((void*)VG_(valgrind_base) <= p && p <= (void*)VG_(valgrind_last));
+      tot_alloc += nBytes;
+      if (0)
+         VG_(printf)(
+            "get_memory_from_mmap: %llu tot, %llu req = %p .. %p, caller %s\n",
+            (ULong)tot_alloc, (ULong)nBytes, p, ((char*)p) + nBytes - 1, who );
+      return p;
+   }
+
+   VG_(printf)("\n");
+   VG_(printf)("VG_(get_memory_from_mmap): %s's request for %llu bytes failed.\n",
+               who, (ULong)nBytes);
+   VG_(printf)("VG_(get_memory_from_mmap): %llu bytes already allocated.\n", 
+               (ULong)tot_alloc);
+   VG_(printf)("\n");
+   VG_(printf)("Sorry.  You could try using a tool that uses less memory;\n");
+   VG_(printf)("eg. addrcheck instead of memcheck.\n");
+   VG_(printf)("\n");
+   VG_(exit)(1);
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
+
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 918f1ec..e7d10ed 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -39,6 +39,7 @@
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcfile.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcsignal.h"
 #include "pub_core_main.h"
diff --git a/coregrind/m_mallocfree.c b/coregrind/m_mallocfree.c
index b09d092..3e74e3d 100644
--- a/coregrind/m_mallocfree.c
+++ b/coregrind/m_mallocfree.c
@@ -34,6 +34,7 @@
 #include "pub_core_aspacemgr.h"
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c
index c20d472..eba5ddd 100644
--- a/coregrind/m_signals.c
+++ b/coregrind/m_signals.c
@@ -85,6 +85,7 @@
 #include "pub_core_errormgr.h"
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcsignal.h"
 #include "pub_core_main.h"
diff --git a/coregrind/m_syscalls/syscalls-amd64-linux.c b/coregrind/m_syscalls/syscalls-amd64-linux.c
index 2462d42..3ddfb8d 100644
--- a/coregrind/m_syscalls/syscalls-amd64-linux.c
+++ b/coregrind/m_syscalls/syscalls-amd64-linux.c
@@ -35,6 +35,7 @@
 #include "pub_core_options.h"
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcsignal.h"
 #include "pub_core_sigframe.h"
diff --git a/coregrind/m_syscalls/syscalls-generic.c b/coregrind/m_syscalls/syscalls-generic.c
index 3999a3c..caa6ddc 100644
--- a/coregrind/m_syscalls/syscalls-generic.c
+++ b/coregrind/m_syscalls/syscalls-generic.c
@@ -34,6 +34,7 @@
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcfile.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcsignal.h"
 #include "pub_core_main.h"
diff --git a/coregrind/m_syscalls/syscalls-x86-linux.c b/coregrind/m_syscalls/syscalls-x86-linux.c
index 9f04e7c..9806c89 100644
--- a/coregrind/m_syscalls/syscalls-x86-linux.c
+++ b/coregrind/m_syscalls/syscalls-x86-linux.c
@@ -40,6 +40,7 @@
 #include "pub_core_options.h"
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcsignal.h"
 #include "pub_core_mallocfree.h"
diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c
index a3f4dc0..8ef0f9f 100644
--- a/coregrind/m_transtab.c
+++ b/coregrind/m_transtab.c
@@ -33,6 +33,7 @@
 #include "pub_core_debuginfo.h"
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
+#include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_options.h"
 #include "pub_core_tooliface.h"
diff --git a/coregrind/pub_core_libcmman.h b/coregrind/pub_core_libcmman.h
new file mode 100644
index 0000000..8815a2a
--- /dev/null
+++ b/coregrind/pub_core_libcmman.h
@@ -0,0 +1,54 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Memory management libc stuff.            pub_core_libcmman.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_CORE_LIBCMMAN_H
+#define __PUB_CORE_LIBCMMAN_H
+
+//--------------------------------------------------------------------
+// PURPOSE: This module contains libc code related to low-level
+// memory management, ie. mmap and friends.
+//--------------------------------------------------------------------
+
+#include "pub_tool_libcmman.h"
+
+extern void* VG_(mmap)   ( void* start, SizeT length, UInt prot, UInt flags,
+                           UInt sf_flags, UInt fd, OffT offset );
+extern Int VG_(munmap)   ( void* start, SizeT length );
+extern Int VG_(mprotect) ( void *start, SizeT length, UInt prot );
+
+extern SysRes VG_(mmap_native)     ( void* start, SizeT length, UInt prot,
+                                     UInt flags, UInt fd, OffT offset );
+extern SysRes VG_(mprotect_native) ( void *start, SizeT length, UInt prot );
+
+#endif   // __PUB_CORE_LIBCMMAN_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c
index a6d1fde..967b865 100644
--- a/coregrind/vg_mylibc.c
+++ b/coregrind/vg_mylibc.c
@@ -86,103 +86,9 @@
 
 
 /* ---------------------------------------------------------------------
-   mmap/munmap, exit, fcntl
+   exit, fcntl
    ------------------------------------------------------------------ */
 
-SysRes VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
-                        UInt fd, OffT offset)
-{
-   SysRes res;
-#  if defined(VGP_x86_linux)
-   { 
-      UWord args[6];
-      args[0] = (UWord)start;
-      args[1] = length;
-      args[2] = prot;
-      args[3] = flags;
-      args[4] = fd;
-      args[5] = offset;
-      res = VG_(do_syscall1)(__NR_mmap, (UWord)args );
-   }
-#  elif defined(VGP_amd64_linux)
-   res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, 
-                         prot, flags, fd, offset);
-#  else
-#    error Unknown platform
-#  endif
-   return res;
-}
-
-/* Returns -1 on failure. */
-void* VG_(mmap)( void* start, SizeT length,
-                 UInt prot, UInt flags, UInt sf_flags, UInt fd, OffT offset)
-{
-   SysRes res;
-
-   if (!(flags & VKI_MAP_FIXED)) {
-      start = (void *)VG_(find_map_space)((Addr)start, length, !!(flags & VKI_MAP_CLIENT));
-
-      flags |= VKI_MAP_FIXED;
-   }
-   if (start == 0)
-      return (void *)-1;
-
-   res = VG_(mmap_native)(start, length, prot, 
-                          flags & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
-                          fd, offset);
-
-   // Check it ended up in the right place.
-   if (!res.isError) {
-      if (flags & VKI_MAP_CLIENT) {
-         vg_assert(VG_(client_base) <= res.val 
-                   && res.val+length <= VG_(client_end));
-      } else {
-         vg_assert(VG_(valgrind_base) <= res.val 
-                   && res.val+length-1 <= VG_(valgrind_last));
-      }
-
-      sf_flags |= SF_MMAP;
-      if (  flags & VKI_MAP_FIXED)      sf_flags |= SF_FIXED;
-      if (  flags & VKI_MAP_SHARED)     sf_flags |= SF_SHARED;
-      if (!(flags & VKI_MAP_ANONYMOUS)) sf_flags |= SF_FILE;
-      if (!(flags & VKI_MAP_CLIENT))    sf_flags |= SF_VALGRIND;
-      if (  flags & VKI_MAP_NOSYMS)     sf_flags |= SF_NOSYMS;
-
-      VG_(map_fd_segment)(res.val, length, prot, sf_flags, fd, offset, NULL);
-   }
-
-   return res.isError ? (void*)-1 : (void*)res.val;
-}
-
-static Int munmap_native(void *start, SizeT length)
-{
-   SysRes res = VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
-   return res.isError ? -1 : 0;
-}
-
-/* Returns -1 on failure. */
-Int VG_(munmap)( void* start, SizeT length )
-{
-   Int res = munmap_native(start, length);
-   if (0 == res)
-      VG_(unmap_range)((Addr)start, length);
-   return res;
-}
-
-Int VG_(mprotect_native)( void *start, SizeT length, UInt prot )
-{
-   SysRes res = VG_(do_syscall3)(__NR_mprotect, (UWord)start, length, prot );
-   return res.isError ? -1 : 0;
-}
-
-Int VG_(mprotect)( void *start, SizeT length, UInt prot )
-{
-   Int res = VG_(mprotect_native)(start, length, prot);
-   if (0 == res)
-      VG_(mprotect_range)((Addr)start, length, prot);
-   return res;
-}
-
 /* Pull down the entire world */
 void VG_(exit)( Int status )
 {
@@ -524,40 +430,6 @@
 }
 
 /* ---------------------------------------------------------------------
-   Primitive support for bagging memory via mmap.
-   ------------------------------------------------------------------ */
-
-void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who )
-{
-   static SizeT tot_alloc = 0;
-   void* p;
-   p = VG_(mmap)(0, nBytes,
-                 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
-                 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 0, -1, 0);
-
-   if (p != ((void*)(-1))) {
-      vg_assert((void*)VG_(valgrind_base) <= p && p <= (void*)VG_(valgrind_last));
-      tot_alloc += nBytes;
-      if (0)
-         VG_(printf)(
-            "get_memory_from_mmap: %llu tot, %llu req = %p .. %p, caller %s\n",
-            (ULong)tot_alloc, (ULong)nBytes, p, ((char*)p) + nBytes - 1, who );
-      return p;
-   }
-
-   VG_(printf)("\n");
-   VG_(printf)("VG_(get_memory_from_mmap): %s's request for %llu bytes failed.\n",
-               who, (ULong)nBytes);
-   VG_(printf)("VG_(get_memory_from_mmap): %llu bytes already allocated.\n", 
-               (ULong)tot_alloc);
-   VG_(printf)("\n");
-   VG_(printf)("Sorry.  You could try using a tool that uses less memory;\n");
-   VG_(printf)("eg. addrcheck instead of memcheck.\n");
-   VG_(printf)("\n");
-   VG_(exit)(1);
-}
-
-/* ---------------------------------------------------------------------
    Misc stuff looking for a proper home
    ------------------------------------------------------------------ */
 
diff --git a/include/Makefile.am b/include/Makefile.am
index 9e9ea70..1a2c734 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -12,6 +12,7 @@
 	pub_tool_libcbase.h 		\
 	pub_tool_libcassert.h 		\
 	pub_tool_libcfile.h 		\
+	pub_tool_libcmman.h 		\
 	pub_tool_libcprint.h 		\
 	pub_tool_libcsignal.h 		\
 	pub_tool_mallocfree.h 		\
diff --git a/include/pub_tool_libcmman.h b/include/pub_tool_libcmman.h
new file mode 100644
index 0000000..75d6c67
--- /dev/null
+++ b/include/pub_tool_libcmman.h
@@ -0,0 +1,41 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Memory management libc stuff.            pub_tool_libcmman.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_TOOL_LIBCMMAN_H
+#define __PUB_TOOL_LIBCMMAN_H
+
+/* Get memory by anonymous mmap. */
+extern void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who );
+
+#endif   // __PUB_TOOL_LIBCMMAN_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
diff --git a/include/tool.h b/include/tool.h
index 7fd9c75..60fa413 100644
--- a/include/tool.h
+++ b/include/tool.h
@@ -137,9 +137,6 @@
 extern Int  VG_(setpgid) ( Int pid, Int pgrp );
 
 /* ------------------------------------------------------------------ */
-/* Get memory by anonymous mmap. */
-extern void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who );
-
 /* Register an interest in apparently internal faults; used code which
    wanders around dangerous memory (ie, leakcheck).  The catcher is
    not expected to return. */
diff --git a/massif/ms_main.c b/massif/ms_main.c
index 0e37aa7..57201a0 100644
--- a/massif/ms_main.c
+++ b/massif/ms_main.c
@@ -40,6 +40,7 @@
 #include "pub_tool_libcbase.h"
 #include "pub_tool_libcassert.h"
 #include "pub_tool_libcfile.h"
+#include "pub_tool_libcmman.h"
 #include "pub_tool_libcprint.h"
 #include "pub_tool_mallocfree.h"
 #include "pub_tool_options.h"