[MPlayer-dev-eng] [PATCH] Windows DLL support for OS X/Intel (cleaned version)

Nicolas Plourde nicolas.plourde at gmail.com
Sun Nov 19 19:37:37 CET 2006


On 12-Oct-06, at 1:11 PM, Reimar Döffinger wrote:

> Hello,
> On Wed, Oct 11, 2006 at 07:18:09PM -0400, Nicolas Plourde wrote:
>> Any objection before I commit those patch? One is to fix compilation
>> on intel osx and the other one add support for win32 dll on intel  
>> osx.
>
> Yes, at least the loader patch should be split.
> The mmap_anon part seems fine to me, but IMHO it should use
> MAP_ANONYMOUS instead of MAP_ANON (and define MAP_ANONYMOUS as  
> MAP_ANON
> if only the later is available), and default to anonymous mmap for all
> systems that provide it, since /dev/zero even currently causes problem
> when e.g. /dev is mounted noexec or /dev/zero not writable (there is a
> bugzilla entry about that).
> And a .s can't use C macros, it must at least be renamed to .S.
> Didn't have a real look at the mp3lib patch, but I do not like  
> disabling
> the MMX stuff, it just hides the problems.
> Since there is again an active upstream it might be a good idea to
> coordinate patches with them, too.
>
> Greetings,
> Reimar Döffinger
> _______________________________________________
> MPlayer-dev-eng mailing list
> MPlayer-dev-eng at mplayerhq.hu
> http://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng

Index: configure
===================================================================
--- configure	(revision 21055)
+++ configure	(working copy)
@@ -4046,7 +4046,7 @@
echocheck "OpenGL"
#Note: this test is run even with --enable-gl since we autodetect  
$_ld_gl
-if (test "$_x11" = yes || win32) && test "$_gl" != no ; then
+if (test "$_x11" = yes || win32 && test "$_macosx" = no) && test  
"$_gl" != no ; then
    cat > $TMPC << EOF
#include <GL/gl.h>
int main(void) { return 0; }
Index: osdep/mmap_anon.c
===================================================================
--- osdep/mmap_anon.c	(revision 0)
+++ osdep/mmap_anon.c	(revision 0)
@@ -0,0 +1,54 @@
+/*
+ * mmap_anon.c: provide a compatible anonymous space mapping function
+ */
+
+#include <sys/mman.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef MAP_ANON
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+#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.
+ */
+void *mmap_anon(void *addr, size_t len, int prot, int flags, off_t  
offset, int *zerofd)
+{
+    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 __APPLE__
+    /* 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 /* __APPLE__ */
+
+    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 <sys/types.h>
+
+void *mmap_anon(void *, size_t, int, int, off_t, int *);
+
+#endif /* _OSDEP_MMAP_ANON_H_ */
Index: osdep/Makefile
===================================================================
--- osdep/Makefile	(revision 21070)
+++ 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 21055)
+++ loader/ldt_keeper.c	(working copy)
@@ -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>
@@ -104,6 +105,7 @@
/* i got this value from wine sources, it's the first free LDT entry */
#if defined(__FreeBSD__) && defined(LDT_AUTO_ALLOC)
#define       TEB_SEL_IDX     LDT_AUTO_ALLOC
+#define       USE_LDT_AA
#endif
#ifndef       TEB_SEL_IDX
@@ -200,8 +202,9 @@
	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, 0,
+	          &ldt_fs->fd);
+
      if (ldt_fs->fs_seg == (void*)-1)
      {
	perror("ERROR: Couldn't allocate memory for fs segment");
@@ -234,7 +237,7 @@
          unsigned long d[2];
          LDT_EntryToBytes( d, &array );
-#if defined(__FreeBSD__) && defined(LDT_AUTO_ALLOC)
+#ifdef USE_LDT_AA
          ret = i386_set_ldt(LDT_AUTO_ALLOC, (union descriptor *)d, 1);
          array.entry_number = ret;
          fs_ldt = ret;
@@ -286,6 +289,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 21055)
+++ loader/ext.c	(working copy)
@@ -26,6 +26,8 @@
#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 +235,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 +249,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, offset_low, &fd );
      }
-    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,13 +351,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)
      {
@@ -391,8 +366,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, 0,  
&hFile);
+    else
+        answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0);
+
+    if(anon && hFile != -1)
          close(hFile);
      if(answer!=(LPVOID)-1)
      {
@@ -418,7 +397,7 @@
	    fm->name=NULL;
	fm->mapping_size=len;
-	if(anon)
+	if(anon && hFile != -1)
	    close(hFile);
	return (HANDLE)answer;
      }
@@ -471,12 +450,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 +486,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, 0, &fd);
//    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

====
Nicolas Plourde <nicolas.plourde at gmail.com>






More information about the MPlayer-dev-eng mailing list