Index: Makefile =================================================================== --- Makefile (revision 21118) +++ Makefile (working copy) @@ -106,7 +106,7 @@ libaf \ ifeq ($(WIN32DLL),yes) -COMMON_LIBS += loader/libloader.a loader/dshow/libDS_Filter.a loader/dmo/libDMO_Filter.a +COMMON_LIBS += loader/libloader.a loader/dshow/libDS_Filter.a loader/dmo/libDMO_Filter.a osdep/libosdep.a PARTS += loader loader/dshow loader/dmo endif ifeq ($(MP3LIB),yes) Index: osdep/mmap_anon.c =================================================================== --- osdep/mmap_anon.c (revision 0) +++ osdep/mmap_anon.c (revision 0) @@ -0,0 +1,67 @@ + /** + * \file mmap_anon.c + * \brief Provide a compatible anonymous space mapping function + */ + +#include +#include +#include +#include + +#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) +#define MAP_ANONYMOUS MAP_ANON +#endif + +/* + * mmap() anonymous space, depending on the system's mmap() style. On systems + * that use the /dev/zero mapping idiom, zerofd will be set to the file descriptor + * of the opened /dev/zero. + */ + + /** + * \brief mmap() anonymous space, depending on the system's mmap() style. On systems + * that use the /dev/zero mapping idiom, zerofd will be set to the file descriptor + * of the opened /dev/zero. + * + * \param addr address to map at. + * \param len number of bytes from addr to be mapped. + * \param prot protections (region accessibility). + * \param flags specifies the type of the mapped object. + * \param offset start mapping at byte offset. + * \param zerofd + * \return a pointer to the mapped region upon successful completion, -1 otherwise. + */ +void *mmap_anon(void *addr, size_t len, int prot, int flags, int *zerofd, off_t offset) +{ + int fd; + void *result; + + /* From loader/ext.c: + * "Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap" + * Therefore we preserve the same behavior on all platforms, ie. no + * shared mappings of anon space (if the concepts are supported). */ +#if defined(MAP_SHARED) && defined(MAP_PRIVATE) + flags = (flags & ~MAP_SHARED) | MAP_PRIVATE; +#endif /* defined(MAP_SHARED) && defined(MAP_PRIVATE) */ + +#ifdef MAP_ANONYMOUS + /* BSD-style anonymous mapping */ + fd = -1; + result = mmap(addr, len, prot, flags | MAP_ANONYMOUS, -1, offset); +#else + /* SysV-style anonymous mapping */ + fd = open("/dev/zero", O_RDWR); + if(fd < 0){ + perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: "); + return NULL; + } + + result = mmap(addr, len, prot, flags, fd, offset); +#endif /* MAP_ANONYMOUS */ + + if (zerofd) + *zerofd = fd; + + return result; +} + Index: osdep/mmap_anon.h =================================================================== --- osdep/mmap_anon.h (revision 0) +++ osdep/mmap_anon.h (revision 0) @@ -0,0 +1,8 @@ +#ifndef _OSDEP_MMAP_ANON_H_ +#define _OSDEP_MMAP_ANON_H_ + +#include + +void *mmap_anon(void *, size_t, int, int, int *, off_t); + +#endif /* _OSDEP_MMAP_ANON_H_ */ Index: osdep/Makefile =================================================================== --- osdep/Makefile (revision 21118) +++ osdep/Makefile (working copy) @@ -12,6 +12,7 @@ fseeko.c \ swab.c \ setenv.c \ + mmap_anon.c \ # timer.c \ getch = getch2.c Index: loader/ldt_keeper.c =================================================================== --- loader/ldt_keeper.c (revision 21118) +++ loader/ldt_keeper.c (working copy) @@ -28,6 +28,7 @@ #include #include #include +#include "osdep/mmap_anon.h" #ifdef __linux__ #include #include @@ -200,8 +201,8 @@ return NULL; } fs_seg= - ldt_fs->fs_seg = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, - ldt_fs->fd, 0); + ldt_fs->fs_seg = mmap_anon(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, + &ldt_fs->fd, 0); if (ldt_fs->fs_seg == (void*)-1) { perror("ERROR: Couldn't allocate memory for fs segment"); @@ -286,6 +287,7 @@ free(ldt_fs->prev_struct); munmap((char*)ldt_fs->fs_seg, getpagesize()); ldt_fs->fs_seg = 0; + if (ldt_fs->fd != -1) close(ldt_fs->fd); free(ldt_fs); } Index: loader/ext.c =================================================================== --- loader/ext.c (revision 21118) +++ loader/ext.c (working copy) @@ -26,6 +26,7 @@ #include #include +#include "osdep/mmap_anon.h" #include "wine/windef.h" #include "wine/winbase.h" #include "wine/debugtools.h" @@ -233,7 +234,6 @@ //#define MAP_PRIVATE //#define MAP_SHARED -#undef MAP_ANON LPVOID FILE_dommap( int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, @@ -248,37 +248,16 @@ if (unix_handle == -1) { -#ifdef MAP_ANON -// printf("Anonymous\n"); - flags |= MAP_ANON; -#else - static int fdzero = -1; - - if (fdzero == -1) - { - if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1) - { - perror( "Cannot open /dev/zero for READ. Check permissions! error: " ); - exit(1); - } - } - fd = fdzero; -#endif /* MAP_ANON */ - /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */ -#ifdef MAP_SHARED - flags &= ~MAP_SHARED; -#endif -#ifdef MAP_PRIVATE - flags |= MAP_PRIVATE; -#endif + ret = mmap_anon( start, size_low, prot, flags, &fd, offset_low ); } - else fd = unix_handle; -// printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot); -// if ((ret = mmap( start, size_low, prot, -// flags, fd, offset_low )) != (LPVOID)-1) - if ((ret = mmap( start, size_low, prot, - MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1) + else { + fd = unix_handle; + ret = mmap( start, size_low, prot, flags, fd, offset_low ); + } + + if (ret != (LPVOID)-1) + { // printf("address %08x\n", *(int*)ret); // printf("%x\n", ret); return ret; @@ -371,14 +350,8 @@ int anon=0; int mmap_access=0; if(hFile<0) - { - anon=1; - hFile=open("/dev/zero", O_RDWR); - if(hFile<0){ - perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " ); - return 0; - } - } + anon=1; + if(!anon) { len=lseek(hFile, 0, SEEK_END); @@ -391,8 +364,12 @@ else mmap_access |=PROT_READ|PROT_WRITE; - answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0); if(anon) + answer=mmap_anon(NULL, len, mmap_access, MAP_PRIVATE, &hFile, 0); + else + answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0); + + if(hFile != -1) close(hFile); if(answer!=(LPVOID)-1) { @@ -418,7 +395,7 @@ fm->name=NULL; fm->mapping_size=len; - if(anon) + if(hFile != -1) close(hFile); return (HANDLE)answer; } @@ -471,12 +448,6 @@ if ((type&(MEM_RESERVE|MEM_COMMIT)) == 0) return NULL; - fd=open("/dev/zero", O_RDWR); - if(fd<0){ - perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " ); - return NULL; - } - if (type&MEM_RESERVE && (unsigned)address&0xffff) { size += (unsigned)address&0xffff; address = (unsigned)address&~0xffff; @@ -513,23 +484,23 @@ && ((unsigned)address+size<=(unsigned)str->address+str->mapping_size) && (type & MEM_COMMIT)) { - close(fd); return address; //returning previously reserved memory } //printf(" VirtualAlloc(...) does not commit or not entirely within reserved, and\n"); } /*printf(" VirtualAlloc(...) (0x%08X, %u) overlaps with (0x%08X, %u, state=%d)\n", (unsigned)address, size, (unsigned)str->address, str->mapping_size, str->state);*/ - close(fd); return NULL; } } - answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE, fd, 0); + answer=mmap_anon(address, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE, &fd, 0); // answer=FILE_dommap(-1, address, 0, size, 0, 0, // PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); - close(fd); + if (fd != -1) + close(fd); + if (answer != (void *)-1 && address && answer != address) { /* It is dangerous to try mmap() with MAP_FIXED since it does not always detect conflicts or non-allocation and chaos ensues after