[PATCH 1/2] libwine: Export our own wrapper around the mmap() syscall on Mac OS X.
Charles Davis
cdavis at mymail.mines.edu
Wed May 12 14:30:29 CDT 2010
From: Charles Davis <cdavis at mines.edu>
This allows us to use unaligned file offsets on Mac OS X.
---
include/wine/library.h | 2 +
libs/wine/mmap.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/include/wine/library.h b/include/wine/library.h
index 242bb69..2fcc6d4 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -76,6 +76,8 @@ 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 );
+extern void *wine_mmap( void *start, size_t size, int prot, int flags, int fd,
+ off_t off );
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..6cac2c7 100644
--- a/libs/wine/mmap.c
+++ b/libs/wine/mmap.c
@@ -63,6 +63,85 @@ 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.
+ */
+#ifdef __APPLE__
+# ifdef __i386__
+extern int *__error(void);
+__ASM_GLOBAL_FUNC( wine_mmap,
+ "movl $197,%eax\n\t" /* SYS_mmap */
+ "int $0x80\n\t"
+ "jae 1f\n\t"
+ "calll 2f\n" /* PIC reference to errno */
+ "2:\tpopl %edx\n\t"
+ "movl L_errno__non_lazy_ptr-2b(%edx),%edx\n\t"
+ "movl %eax,(%edx)\n\t"
+ ".section __IMPORT,__pointers,non_lazy_symbol_pointers\n"
+ "L_errno__non_lazy_ptr:\n\t"
+ ".indirect_symbol _errno\n\t"
+ ".long 0\n\t"
+ ".text\n\t"
+ "movl %esp,%edx\n\t"
+ "andl $0xFFFFFFF0,%esp\n\t"
+ "subl $16,%esp\n\t"
+ "movl %edx,4(%esp)\n\t"
+ "movl %eax,(%esp)\n\t"
+ "calll 2f\n" /* PIC call to cthread_set_errno_self() */
+ "2:\tpopl %edx\n\t"
+ "movl L_cthread_set_errno_self__non_lazy_ptr-2b(%edx),%edx\n\t"
+ "calll *%edx\n\t"
+ ".section __IMPORT,__pointers,non_lazy_symbol_pointers\n"
+ "L_cthread_set_errno_self__non_lazy_ptr:\n\t"
+ ".indirect_symbol _cthread_set_errno_self\n\t"
+ ".long 0\n\t"
+ ".text\n\t"
+ "movl 4(%esp),%esp\n\t"
+ "stc\n\t"
+ "sbbl %edx,%edx\n\t"
+ "sbbl %eax,%eax\n\t"
+ "1:\tret\n\t" )
+# elif defined __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" )
+}
+# 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
+#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 +253,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 +292,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 +311,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