X-Spam-Check-By: sourceware.org To: cygwin AT cygwin DOT com From: =?ISO-8859-1?Q?Ren=E9_Berber?= Subject: mmap() on 64K aligned address fails Date: Fri, 25 Nov 2005 22:34:26 -0600 Lines: 359 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------030502020207090305080602" User-Agent: Mozilla Thunderbird 1.0.2 (Windows/20050317) OpenPGP: url=ldap://keyserver.pgp.com X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --------------030502020207090305080602 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Hi, I was trying to figure out the often reported failure of mmap seen by runni= ng configure on some packages and, after looking at the answers on the list, I tried a test on a 64k aligned (malloced) address, mmap(... MAP_FIXED ...) f= ails. Attached is the small test file that was compiled with the command at the e= nd of the same file. Any ideas what's wrong? Thanks. --=20 Ren=E9 Berber --------------030502020207090305080602 Content-Type: text/plain; name="mmap_test.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mmap_test.c" /* confdefs.h. */ #define PACKAGE_NAME "package-unused" #define PACKAGE_TARNAME "libstdc++" #define PACKAGE_VERSION "version-unused" #define PACKAGE_STRING "package-unused version-unused" #define PACKAGE_BUGREPORT "" #ifdef __cplusplus extern "C" void exit (int); #endif #define _GLIBCXX_HOSTED 1 #define _GLIBCXX_SJLJ_EXCEPTIONS 1 #define STDC_HEADERS 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_STAT_H 1 #define HAVE_STDLIB_H 1 #define HAVE_STRING_H 1 #define HAVE_MEMORY_H 1 #define HAVE_STRINGS_H 1 #define HAVE_INTTYPES_H 1 #define HAVE_STDINT_H 1 #define HAVE_UNISTD_H 1 #define _GLIBCXX_USE_C99_MATH 1 #define _GLIBCXX_USE_LONG_LONG 1 #define HAVE_GTHR_DEFAULT 1 #define HAVE_IEEEFP_H 1 #define HAVE_ENDIAN_H 1 #define HAVE_MACHINE_ENDIAN_H 1 #define HAVE_MACHINE_PARAM_H 1 #define HAVE_LOCALE_H 1 #define HAVE_FLOAT_H 1 #define HAVE_INTTYPES_H 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_IPC_H 1 #define HAVE_SYS_SEM_H 1 #define HAVE_ISINF 1 #define HAVE_ISNAN 1 #define HAVE_FINITE 1 #define HAVE_COPYSIGN 1 #define HAVE_SINCOS 1 #define HAVE_HYPOT 1 #define HAVE_ACOSF 1 #define HAVE_ASINF 1 #define HAVE_ATANF 1 #define HAVE_COSF 1 #define HAVE_SINF 1 #define HAVE_TANF 1 #define HAVE_COSHF 1 #define HAVE_SINHF 1 #define HAVE_TANHF 1 #define HAVE_CEILF 1 #define HAVE_FLOORF 1 #define HAVE_EXPF 1 #define HAVE_ATAN2F 1 #define HAVE_FABSF 1 #define HAVE_FMODF 1 #define HAVE_FREXPF 1 #define HAVE_HYPOTF 1 #define HAVE_LDEXPF 1 #define HAVE_LOGF 1 #define HAVE_LOG10F 1 #define HAVE_MODFF 1 #define HAVE_POWF 1 #define HAVE_SQRTF 1 #define HAVE_SINCOSF 1 #define HAVE___BUILTIN_ABS 1 #define HAVE___BUILTIN_FABSF 1 #define HAVE___BUILTIN_FABS 1 #define HAVE___BUILTIN_FABSL 1 #define HAVE___BUILTIN_LABS 1 #define HAVE___BUILTIN_SQRTF 1 #define HAVE___BUILTIN_SQRT 1 #define HAVE___BUILTIN_SQRTL 1 #define HAVE___BUILTIN_SINF 1 #define HAVE___BUILTIN_SIN 1 #define HAVE___BUILTIN_SINL 1 #define HAVE___BUILTIN_COSF 1 #define HAVE___BUILTIN_COS 1 #define HAVE___BUILTIN_COSL 1 #define HAVE_LIBM 1 #define HAVE_COPYSIGNF 1 #define HAVE___SIGNBITF 1 #define HAVE_MBSTATE_T 1 #define HAVE_WCHAR_H 1 #define HAVE_WCTYPE_H 1 #define HAVE_WCSLEN 1 #define HAVE_WMEMCHR 1 #define HAVE_WMEMCMP 1 #define HAVE_WMEMCPY 1 #define HAVE_WMEMMOVE 1 #define HAVE_WMEMSET 1 #define HAVE_BTOWC 1 #define HAVE_WCTOB 1 #define HAVE_WPRINTF 1 #define HAVE_MBSINIT 1 #define HAVE_MBRLEN 1 #define HAVE_MBRTOWC 1 #define HAVE_MBSRTOWCS 1 #define HAVE_WCSRTOMBS 1 #define HAVE_WCRTOMB 1 #define HAVE_WCSCPY 1 #define HAVE_WCSNCPY 1 #define HAVE_WCSCAT 1 #define HAVE_WCSNCAT 1 #define HAVE_WCSCMP 1 #define HAVE_WCSCOLL 1 #define HAVE_WCSNCMP 1 #define HAVE_WCSCSPN 1 #define HAVE_WCSSPN 1 #define HAVE_WCSCHR 1 #define HAVE_WCSPBRK 1 #define HAVE_WCSRCHR 1 #define HAVE_WCSSTR 1 #define HAVE_ISWBLANK 1 #define HAVE_NL_LANGINFO 1 #define HAVE_STRTOF 1 #define HAVE_SYS_IOCTL_H 1 #define HAVE_POLL 1 #define HAVE_S_ISREG 1 #define HAVE_SYS_UIO_H 1 #define HAVE_WRITEV 1 #define HAVE_INT64_T 1 #define HAVE_LC_MESSAGES 1 #define HAVE_SIGSETJMP 1 #define HAVE_STDLIB_H 1 #define HAVE_UNISTD_H 1 #define HAVE_GETPAGESIZE 1 /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif /* malloc might have been renamed as rpl_malloc. */ #undef malloc /* Thanks to Mike Haertel and Jim Avera for this test. Here is a matrix of mmap possibilities: mmap private not fixed mmap private fixed at somewhere currently unmapped mmap private fixed at somewhere already mapped mmap shared not fixed mmap shared fixed at somewhere currently unmapped mmap shared fixed at somewhere already mapped For private mappings, we should verify that changes cannot be read() back from the file, nor mmap's back from the file at a different address. (There have been systems where private was not correctly implemented like the infamous i386 svr4.0, and systems where the VM page cache was not coherent with the file system buffer cache like early versions of FreeBSD and possibly contemporary NetBSD.) For shared mappings, we should conversely verify that changes get propagated back to all the places they're supposed to be. Grep wants private fixed already mapped. The main things grep needs to know about mmap are: * does it exist and is it safe to write into the mmap'd area * how to use it (BSD variants) */ #include #include #if !STDC_HEADERS && !HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ #if !HAVE_GETPAGESIZE /* Assume that all systems that can run configure have sys/param.h. */ # if !HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # if HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ int main () { char *data, *data2, *data3; int i, pagesize; int fd; pagesize = getpagesize (); printf("pagesize is %d\n", pagesize); /* First, make a file with some known garbage in it. */ data = (char *) malloc (pagesize); if (!data) { printf("malloc failed\n"); exit (1); } for (i = 0; i < pagesize; ++i) *(data + i) = rand (); umask (0); fd = creat ("conftest.mmap", 0600); if (fd < 0) { printf("creat failed\n"); exit (1); } if (write (fd, data, pagesize) != pagesize) { printf("write failed\n"); exit (1); } close (fd); /* Next, try to mmap the file at a fixed address which already has something else allocated at it. If we can, also make sure that we see the same garbage. */ fd = open ("conftest.mmap", O_RDWR); if (fd < 0) { printf("open failed\n"); exit (1); } #if !defined(__CYGWIN32__) data2 = (char *) malloc (2 * pagesize); if (!data2) { printf("second malloc failed\n"); exit (1); } data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1); #else data2 = (char *) malloc (16 * pagesize); if (!data2) { printf("second malloc failed\n"); exit (1); } printf("data2 before is %p\n", data2); data2 += (16*pagesize - ((long) data2 & (16*pagesize - 1))) & (16*pagesize - 1); printf("data2 after is %p\n", data2); #endif if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) { printf("mmap failed\n"); exit (1); } for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) { printf("pages are not equal\n"); exit (1); } /* Finally, make sure that changes to the mapped area do not percolate back to the file as seen by read(). (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = (char *) malloc (pagesize); if (!data3) { printf("third malloc failed\n"); exit (1); } if (read (fd, data3, pagesize) != pagesize) { printf("read failed\n"); exit (1); } for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) { printf("file changed\n"); exit (1); } close (fd); printf("OK\n"); exit (0); } /* * Local variables: * compile: gcc -o mmap_test -O2 mmap_test.c -lm * end: */ --------------030502020207090305080602 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --------------030502020207090305080602--