[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