[PATCH 1/2] libwine: Export our own wrapper around the mmap() syscall on 64-bit Mac OS X, and use the old wrapper on 32-bit Mac OS. (try 2)

Charles Davis cdavis at mymail.mines.edu
Thu May 13 03:09:57 CDT 2010


From: Charles Davis <cdavis at mines.edu>

This allows us to use unaligned file offsets on Mac OS.

This version simply uses the old wrapper instead of adding our own on 32-bit
Mac OS. As a side effect, this also works for PowerPC Macs (as if anybody
cares about that).
---
 include/wine/library.h |    7 +++++++
 libs/wine/mmap.c       |   48 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/include/wine/library.h b/include/wine/library.h
index 242bb69..963c5d8 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -76,6 +76,13 @@ extern int wine_call_on_stack( int (*func)(void *), void *arg, void *stack );
 /* memory mappings */
 
 extern void *wine_anon_mmap( void *start, size_t size, int prot, int flags );
+#if defined(__APPLE__) && !defined(__x86_64__)
+extern void *wine_mmap( void *start, size_t size, int prot, int flags, int fd,
+                        off_t off ) __asm("_mmap");
+#else
+extern void *wine_mmap( void *start, size_t size, int prot, int flags, int fd,
+                        off_t off );
+#endif
 extern void wine_mmap_add_reserved_area( void *addr, size_t size );
 extern void wine_mmap_remove_reserved_area( void *addr, size_t size, int unmap );
 extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
diff --git a/libs/wine/mmap.c b/libs/wine/mmap.c
index b400189..289703a 100644
--- a/libs/wine/mmap.c
+++ b/libs/wine/mmap.c
@@ -63,6 +63,48 @@ static const unsigned int granularity_mask = 0xffff;  /* reserved areas have 64k
 #define MAP_ANON 0
 #endif
 
+/*
+ * In Mac OS 10.5, the mmap() function was changed to match UNIX '03 (as
+ * Linux does). In particular, this means that unaligned file offsets fail
+ * with EINVAL. However, that check is done at the library level, not the
+ * kernel level. This is done to maintain backwards compatibility with old
+ * programs that expect unaligned offsets to succeed.
+ * Because the syscall itself still supports unaligned file offsets, instead
+ * of calling the wrapper in libc, we define our own function to make the
+ * syscall directly on 64-bit Mac OS.
+ * For 32-bit Mac OS, the old wrapper is still exported from libc, so we
+ * just remap wine_mmap to mmap.
+ */
+#ifdef __APPLE__
+# ifdef __x86_64__
+extern int *__error(void);
+__ASM_GLOBAL_FUNC( wine_mmap,
+                   "movq %rcx,%r10\n\t"
+                   "movl $0x020000c5,%eax\n\t"  /* SYS_mmap (decorated) */
+                   "syscall\n\t"
+                   "jae 1f\n\t"
+                   "movq _errno at GOTPCREL(%rip),%r11\n\t"
+                   "movq %rax,(%r11)\n\t"
+                   "movq %rsp,%rdx\n\t"
+                   "andq $~16,%rsp\n\t"
+                   "subq $16,%rsp\n\t"
+                   "movq %rdx,(%rsp)\n\t"
+                   "movq %rax,%rdi\n\t"
+                   "callq _cthread_set_errno_self\n\t"
+                   "movq (%rsp),%rsp\n\t"
+                   "stc\n\t"
+                   "sbbq %rdx,%rdx\n\t"
+                   "sbbq %rax,%rax\n\t"
+                   "1:\tret\n\t" )
+}
+# endif
+#else
+void *wine_mmap( void *addr, size_t len, int prot, int flags, int fd, off_t off )
+{
+    return mmap( addr, len, prot, flags, fd, off );
+}
+#endif
+
 static inline int get_fdzero(void)
 {
     static int fd = -1;
@@ -174,7 +216,7 @@ static int try_mmap_fixed (void *addr, size_t len, int prot, int flags,
 
     if (!vm_allocate(mach_task_self(),&result,len,0))
     {
-        if (mmap( (void *)result, len, prot, flags | MAP_FIXED, fildes, off ) != MAP_FAILED)
+        if (wine_mmap( (void *)result, len, prot, flags | MAP_FIXED, fildes, off ) != MAP_FAILED)
             return 1;
         vm_deallocate(mach_task_self(),result,len);
     }
@@ -213,7 +255,7 @@ void *wine_anon_mmap( void *start, size_t size, int prot, int flags )
             return start;
 #endif
     }
-    return mmap( start, size, prot, flags, get_fdzero(), 0 );
+    return wine_mmap( start, size, prot, flags, get_fdzero(), 0 );
 }
 
 
@@ -232,7 +274,7 @@ static inline int mmap_reserve( void *addr, size_t size )
 #elif defined(__APPLE__)
     return try_mmap_fixed( addr, size, PROT_NONE, flags, get_fdzero(), 0 );
 #endif
-    ptr = mmap( addr, size, PROT_NONE, flags, get_fdzero(), 0 );
+    ptr = wine_mmap( addr, size, PROT_NONE, flags, get_fdzero(), 0 );
     if (ptr != addr && ptr != (void *)-1)  munmap( ptr, size );
     return (ptr == addr);
 }
-- 
1.7.1




More information about the wine-patches mailing list