summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/mmap.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-03-25 20:39:26 +0000
committerCorinna Vinschen <corinna@vinschen.de>2011-03-25 20:39:26 +0000
commit57abff16c3282c1d16550d438eeaa4765c915dbd (patch)
tree1fae9b9510caa5e13eafe627e0783097fe8db2ad /winsup/cygwin/mmap.cc
parentd6ab646ff6f8cb71d50f4a56242eb89ec240aaf0 (diff)
downloadcygnal-57abff16c3282c1d16550d438eeaa4765c915dbd.tar.gz
cygnal-57abff16c3282c1d16550d438eeaa4765c915dbd.tar.bz2
cygnal-57abff16c3282c1d16550d438eeaa4765c915dbd.zip
* mmap.cc (mmap64): Add a cheat to let a certain autoconf test succeed
on 64 bit systems. Explain why.
Diffstat (limited to 'winsup/cygwin/mmap.cc')
-rw-r--r--winsup/cygwin/mmap.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 91c2d7bc7..8522b6d6d 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -801,6 +801,50 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
/* mmap /dev/zero is like MAP_ANONYMOUS. */
if (fh->get_device () == FH_ZERO)
flags |= MAP_ANONYMOUS;
+
+ /* The autoconf mmap test maps a file of size 1 byte. It then tests
+ every byte of the entire mapped page of 64K for 0-bytes since that's
+ what POSIX requires. The problem is, we can't create that mapping on
+ 64 bit systems. The file mapping will be only a single page, 4K, and
+ since 64 bit systems don't support the AT_ROUND_TO_PAGE flag, the
+ remainder of the 64K slot will result in a SEGV when accessed.
+
+ So, what we do here is cheating for the sake of the autoconf test
+ on 64 bit systems. The justification is that there's very likely
+ no application actually utilizing the map beyond EOF, and we know that
+ all bytes beyond EOF are set to 0 anyway. If this test doesn't work
+ on 64 bit systems, it will result in not using mmap at all in a
+ package. But we want that mmap is treated as usable by autoconf,
+ regardless whether the autoconf test runs on a 32 bit or a 64 bit
+ system.
+
+ Ok, so we know exactly what autoconf is doing. The file is called
+ "conftest.txt", it has a size of 1 byte, the mapping size is the
+ pagesize, the requested protection is PROT_READ | PROT_WRITE, the
+ mapping is MAP_SHARED, the offset is 0.
+
+ If all these requirements are given, we just return an anonymous map.
+ This will help to get over the autoconf test even on 64 bit systems.
+ The tests are ordered for speed. */
+ if (wincap.is_wow64 ())
+ {
+ UNICODE_STRING fname;
+ IO_STATUS_BLOCK io;
+ FILE_STANDARD_INFORMATION fsi;
+
+ if (len == pagesize
+ && prot == (PROT_READ | PROT_WRITE)
+ && flags == MAP_SHARED
+ && off == 0
+ && (RtlSplitUnicodePath (fh->pc.get_nt_native_path (), NULL,
+ &fname),
+ wcscmp (fname.Buffer, L"conftest.txt") == 0)
+ && NT_SUCCESS (NtQueryInformationFile (fh->get_handle (), &io,
+ &fsi, sizeof fsi,
+ FileStandardInformation))
+ && fsi.EndOfFile.QuadPart == 1LL)
+ flags |= MAP_ANONYMOUS;
+ }
}
if (anonymous (flags) || fd == -1)