Tools using shadow memory can't handle the first 64KB being mapped, because
they rely on this area being unmapped for their quick sanity check.  This
commit make Valgrind refuse to mmap() this area.  Added a regtest for it.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2085 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index a3d48c4..5437d50 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -3204,6 +3204,14 @@
    SYSCALL_TRACK( pre_mem_read_asciiz, tid, "mkdir(pathname)", arg1 );
 }
 
+void check_mmap_start(ThreadState* tst, Addr start, Int flags)
+{
+   /* Refuse to mmap the first 64KB of memory, so that the cheap sanity test 
+      for tools using shadow memory works. */
+   if (start < 65536 && (flags & VKI_MAP_FIXED))
+      tst->m_eax = -VKI_EINVAL;
+}
+
 PRE(mmap2)
 {
    /* My impression is that this is exactly like __NR_mmap 
@@ -3214,6 +3222,8 @@
    */
    MAYBE_PRINTF("mmap2 ( %p, %d, %d, %d, %d, %d )\n",
 		arg1, arg2, arg3, arg4, arg5, arg6 );
+
+   check_mmap_start(tst, arg1, arg4);
 }
 
 POST(mmap2)
@@ -3240,6 +3250,8 @@
    a6 = arg_block[5];
    MAYBE_PRINTF("mmap ( %p, %d, %d, %d, %d, %d )\n",
 		a1, a2, a3, a4, a5, a6 );
+
+   check_mmap_start(tst, a1, a4);
 }
 
 POST(mmap)
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index fb8b8a1..b94f2c1 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -62,7 +62,8 @@
 	metadata.stderr.exp metadata.stdout.exp metadata.vgtest \
 	threadederrno.stderr.exp threadederrno.stdout.exp \
 	threadederrno.vgtest \
-	writev.stderr.exp writev.vgtest
+	writev.stderr.exp writev.vgtest \
+	zeropage.stderr.exp zeropage.vgtest
 
 check_PROGRAMS = \
 	badaddrvalue badfree badjump badloop badrw brk buflen_check \
@@ -73,7 +74,7 @@
 	overlap pushfpopf \
 	realloc1 realloc2 realloc3 sigaltstack signal2 supp1 supp2 suppfree \
 	trivialleak tronical weirdioctl	\
-	mismatches new_override metadata threadederrno writev
+	mismatches new_override metadata threadederrno writev zeropage
 
 AM_CPPFLAGS = -I$(top_srcdir)/include
 AM_CFLAGS   = $(WERROR) -Winline -Wall -Wshadow -g 
@@ -125,6 +126,7 @@
 threadederrno_SOURCES	= threadederrno.c
 threadederrno_LDADD	= -lpthread
 writev_SOURCES		= writev.c
+zeropage_SOURCES	= zeropage.c
 
 # C++ ones
 mismatches_SOURCES	= mismatches.cpp
diff --git a/memcheck/tests/zeropage.c b/memcheck/tests/zeropage.c
new file mode 100644
index 0000000..9892e34
--- /dev/null
+++ b/memcheck/tests/zeropage.c
@@ -0,0 +1,38 @@
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* The quick sanity check of Memcheck (and other skins with shadow memory)
+   relies on the first 64KB of memory never being used.  So our mmap()
+   refuses to touch this area.  This program tests for that. */
+
+int main(void)
+{
+   /* mmap(0x0, ... FIXED) should fail */
+   int* m = mmap(0x0, 1000000, PROT_READ|PROT_WRITE, 
+                 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+   if (m != (int*)-1)
+      printf("succeeded?!\n");
+
+   /* mmap(0x1000, ... FIXED) should fail */
+        m = mmap((void*)0x1000, 1000000, PROT_READ|PROT_WRITE, 
+                 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+   if (m != (int*)-1)
+      printf("succeeded?!\n");
+
+   /* mmap(0xa000, ... FIXED) should fail */
+        m = mmap((void*)0xa000, 1000000, PROT_READ|PROT_WRITE, 
+                 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+   if (m != (int*)-1)
+      printf("succeeded?!\n");
+
+   /* mmap(0x10000, ... FIXED) should fail */
+        m = mmap((void*)0x10000, 1000000, PROT_READ|PROT_WRITE, 
+                 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+   if (m == (int*)-1)
+      printf("failed?!\n");
+
+   return 0;
+}
diff --git a/memcheck/tests/zeropage.stderr.exp b/memcheck/tests/zeropage.stderr.exp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/memcheck/tests/zeropage.stderr.exp
diff --git a/memcheck/tests/zeropage.vgtest b/memcheck/tests/zeropage.vgtest
new file mode 100644
index 0000000..89038e4
--- /dev/null
+++ b/memcheck/tests/zeropage.vgtest
@@ -0,0 +1,2 @@
+prog: zeropage
+vgopts: -q