Mercurial > mplayer.hg
changeset 21187:d9cedf7b8069
added mmap_anon to osdep lib. Used in loader for now
author | nplourde |
---|---|
date | Sat, 25 Nov 2006 01:22:20 +0000 |
parents | d3b66895640c |
children | 4906844e35c8 |
files | Makefile loader/ext.c loader/ldt_keeper.c osdep/Makefile osdep/mmap_anon.c osdep/mmap_anon.h |
diffstat | 6 files changed, 104 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sat Nov 25 00:50:43 2006 +0000 +++ b/Makefile Sat Nov 25 01:22:20 2006 +0000 @@ -62,7 +62,6 @@ stream/stream.a \ libswscale/libswscale.a \ libvo/libosd.a \ - osdep/libosdep.a \ LIBS_MPLAYER = libvo/libvo.a \ libao2/libao2.a \ @@ -158,6 +157,8 @@ OBJS_MPLAYER += osdep/mplayer-rc.o endif +COMMON_LIBS += osdep/libosdep.a + COMMON_LDFLAGS += $(EXTRA_LIB)\ $(EXTRALIBS) \
--- a/loader/ext.c Sat Nov 25 00:50:43 2006 +0000 +++ b/loader/ext.c Sat Nov 25 01:22:20 2006 +0000 @@ -26,6 +26,7 @@ #include <stdarg.h> #include <ctype.h> +#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,36 +248,15 @@ if (unix_handle == -1) { -#ifdef MAP_ANON -// printf("Anonymous\n"); - flags |= MAP_ANON; -#else - static int fdzero = -1; + ret = mmap_anon( start, size_low, prot, flags, &fd, offset_low ); + } + else + { + fd = unix_handle; + ret = mmap( start, size_low, prot, flags, fd, offset_low ); + } - 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 - } - 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) + if (ret != (LPVOID)-1) { // printf("address %08x\n", *(int*)ret); // printf("%x\n", 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
--- a/loader/ldt_keeper.c Sat Nov 25 00:50:43 2006 +0000 +++ b/loader/ldt_keeper.c Sat Nov 25 01:22:20 2006 +0000 @@ -28,6 +28,7 @@ #include <sys/types.h> #include <stdio.h> #include <unistd.h> +#include "osdep/mmap_anon.h" #ifdef __linux__ #include <asm/unistd.h> #include <asm/ldt.h> @@ -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); }
--- a/osdep/Makefile Sat Nov 25 00:50:43 2006 +0000 +++ b/osdep/Makefile Sat Nov 25 01:22:20 2006 +0000 @@ -12,6 +12,7 @@ fseeko.c \ swab.c \ setenv.c \ + mmap_anon.c \ # timer.c \ getch = getch2.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osdep/mmap_anon.c Sat Nov 25 01:22:20 2006 +0000 @@ -0,0 +1,67 @@ + /** + * \file mmap_anon.c + * \brief Provide a compatible anonymous space mapping function + */ + +#include <sys/mman.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> + +#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; +} +