aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--loader/ext.c73
-rw-r--r--loader/ldt_keeper.c6
-rw-r--r--osdep/Makefile1
-rw-r--r--osdep/mmap_anon.c67
-rw-r--r--osdep/mmap_anon.h8
6 files changed, 104 insertions, 54 deletions
diff --git a/Makefile b/Makefile
index fe377f5cfc..9a58b4f3b6 100644
--- a/Makefile
+++ b/Makefile
@@ -62,7 +62,6 @@ COMMON_LIBS = libmpcodecs/libmpcodecs.a \
stream/stream.a \
libswscale/libswscale.a \
libvo/libosd.a \
- osdep/libosdep.a \
LIBS_MPLAYER = libvo/libvo.a \
libao2/libao2.a \
@@ -158,6 +157,8 @@ ifeq ($(TARGET_WIN32),yes)
OBJS_MPLAYER += osdep/mplayer-rc.o
endif
+COMMON_LIBS += osdep/libosdep.a
+
COMMON_LDFLAGS += $(EXTRA_LIB)\
$(EXTRALIBS) \
diff --git a/loader/ext.c b/loader/ext.c
index 4121da29bf..65de0e9afa 100644
--- a/loader/ext.c
+++ b/loader/ext.c
@@ -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 @@ LPSTR HEAP_strdupWtoA(HANDLE heap, DWORD flags, LPCWSTR string)
//#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 @@ LPVOID FILE_dommap( int unix_handle, LPVOID start,
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);
@@ -371,14 +350,8 @@ HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr,
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 @@ HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr,
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 @@ HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr,
fm->name=NULL;
fm->mapping_size=len;
- if(anon)
+ if(hFile != -1)
close(hFile);
return (HANDLE)answer;
}
@@ -471,12 +448,6 @@ LPVOID WINAPI VirtualAlloc(LPVOID address, DWORD size, DWORD type, DWORD protec
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 @@ LPVOID WINAPI VirtualAlloc(LPVOID address, DWORD size, DWORD type, DWORD protec
&& ((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
diff --git a/loader/ldt_keeper.c b/loader/ldt_keeper.c
index 6b28776501..bf61f617cf 100644
--- a/loader/ldt_keeper.c
+++ b/loader/ldt_keeper.c
@@ -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 @@ ldt_fs_t* Setup_LDT_Keeper(void)
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 @@ void Restore_LDT_Keeper(ldt_fs_t* ldt_fs)
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);
}
diff --git a/osdep/Makefile b/osdep/Makefile
index a5ee59201e..abd38716b1 100644
--- a/osdep/Makefile
+++ b/osdep/Makefile
@@ -12,6 +12,7 @@ SRCS= shmem.c \
fseeko.c \
swab.c \
setenv.c \
+ mmap_anon.c \
# timer.c \
getch = getch2.c
diff --git a/osdep/mmap_anon.c b/osdep/mmap_anon.c
new file mode 100644
index 0000000000..b6d0b7cf35
--- /dev/null
+++ b/osdep/mmap_anon.c
@@ -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;
+}
+
diff --git a/osdep/mmap_anon.h b/osdep/mmap_anon.h
new file mode 100644
index 0000000000..edb909bdc0
--- /dev/null
+++ b/osdep/mmap_anon.h
@@ -0,0 +1,8 @@
+#ifndef _OSDEP_MMAP_ANON_H_
+#define _OSDEP_MMAP_ANON_H_
+
+#include <sys/types.h>
+
+void *mmap_anon(void *, size_t, int, int, int *, off_t);
+
+#endif /* _OSDEP_MMAP_ANON_H_ */