Don't reference the Linux-specific variables preloader_start and preloader_end in the shared code.
Signed-off-by: Ken Thomases ken@codeweavers.com --- v2: Avoid a platform #ifdef in the shared code Set up infrastructure for eventual implementation of overlap check on Mac
loader/preloader.c | 19 ++++++++++++------- loader/preloader.h | 1 + loader/preloader_mac.c | 5 +++++ 3 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/loader/preloader.c b/loader/preloader.c index 3b1f5ad..9f2fbc3 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -1049,6 +1049,17 @@ static int is_in_preload_range( const struct wld_auxv *av, int type ) return 0; }
+int preloader_overlaps_range( const void *start, const void *end ) +{ + if ((char *)end > preloader_start && (char *)start <= preloader_end) + { + wld_printf( "WINEPRELOADRESERVE range %p-%p overlaps preloader %p-%p\n", + start, end, preloader_start, preloader_end ); + return 1; + } + return 0; +} + /* set the process name if supported */ static void set_process_name( int argc, char *argv[] ) { @@ -1316,14 +1327,8 @@ void preload_reserve( const char *str, struct wine_preload_info *preload_info, s else if (result) goto error; /* single value '0' is allowed */
/* sanity checks */ - if (end <= start) start = end = NULL; - else if ((char *)end > preloader_start && - (char *)start <= preloader_end) - { - wld_printf( "WINEPRELOADRESERVE range %p-%p overlaps preloader %p-%p\n", - start, end, preloader_start, preloader_end ); + if (end <= start || preloader_overlaps_range(start, end)) start = end = NULL; - }
/* check for overlap with low memory areas */ for (i = 0; preload_info[i].size; i++) diff --git a/loader/preloader.h b/loader/preloader.h index 2c2262e..b944a09 100644 --- a/loader/preloader.h +++ b/loader/preloader.h @@ -51,6 +51,7 @@ extern __attribute__((format(printf,1,2))) void wld_printf(const char *fmt, ... extern __attribute__((noreturn,format(printf,1,2))) void fatal_error(const char *fmt, ... );
extern void preload_reserve( const char *str, struct wine_preload_info *preload_info, size_t page_mask ); +extern int preloader_overlaps_range( const void *start, const void *end );
/* remove a range from the preload list */ static inline void remove_preload_range( int i, struct wine_preload_info *preload_info ) diff --git a/loader/preloader_mac.c b/loader/preloader_mac.c index d008270..5e9f9fc 100644 --- a/loader/preloader_mac.c +++ b/loader/preloader_mac.c @@ -374,6 +374,11 @@ static int map_region( struct wine_preload_info *info ) return 0; }
+int preloader_overlaps_range( const void *start, const void *end ) +{ + return 0; +} + static inline void get_dyld_func( const char *name, void **func ) { _dyld_func_lookup( name, func );
Signed-off-by: Ken Thomases ken@codeweavers.com --- loader/preloader_mac.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-)
diff --git a/loader/preloader_mac.c b/loader/preloader_mac.c index 5e9f9fc..294efc9 100644 --- a/loader/preloader_mac.c +++ b/loader/preloader_mac.c @@ -47,6 +47,7 @@ #ifdef HAVE_MACH_O_LOADER_H #include <mach/thread_status.h> #include <mach-o/loader.h> +#include <mach-o/ldsyms.h> #endif
#include "preloader.h" @@ -97,6 +98,8 @@ void __stack_chk_fail(void) { return; } static const size_t page_size = 0x1000; static const size_t page_mask = 0xfff; #define target_mach_header mach_header +#define target_segment_command segment_command +#define TARGET_LC_SEGMENT LC_SEGMENT #define target_thread_state_t i386_thread_state_t #ifdef __DARWIN_UNIX03 #define target_thread_ip(x) (x)->__eip @@ -183,6 +186,8 @@ __ASM_GLOBAL_FUNC( start, static const size_t page_size = 0x1000; static const size_t page_mask = 0xfff; #define target_mach_header mach_header_64 +#define target_segment_command segment_command_64 +#define TARGET_LC_SEGMENT LC_SEGMENT_64 #define target_thread_state_t x86_thread_state64_t #ifdef __DARWIN_UNIX03 #define target_thread_ip(x) (x)->__rip @@ -376,6 +381,31 @@ static int map_region( struct wine_preload_info *info )
int preloader_overlaps_range( const void *start, const void *end ) { + intptr_t slide = p_dyld_get_image_slide(&_mh_execute_header); + struct load_command *cmd = (struct load_command*)(&_mh_execute_header + 1); + int i; + + for (i = 0; i < _mh_execute_header.ncmds; ++i) + { + if (cmd->cmd == TARGET_LC_SEGMENT) + { + struct target_segment_command *seg = (struct target_segment_command*)cmd; + const void *seg_start = (const void*)(seg->vmaddr + slide); + const void *seg_end = (const char*)seg_start + seg->vmsize; + + if (end > seg_start && start <= seg_end) + { + char segname[sizeof(seg->segname) + 1]; + memcpy(segname, seg->segname, sizeof(seg->segname)); + segname[sizeof(segname) - 1] = 0; + wld_printf( "WINEPRELOADRESERVE range %p-%p overlaps preloader %s segment %p-%p\n", + start, end, segname, seg_start, seg_end ); + return 1; + } + } + cmd = (struct load_command*)((char*)cmd + cmd->cmdsize); + } + return 0; }
@@ -413,6 +443,11 @@ void *wld_start( void *stack, int *is_unix_thread ) p++; }
+ LOAD_POSIX_DYLD_FUNC( dlopen ); + LOAD_POSIX_DYLD_FUNC( dlsym ); + LOAD_POSIX_DYLD_FUNC( dladdr ); + LOAD_MACHO_DYLD_FUNC( _dyld_get_image_slide ); + /* reserve memory that Wine needs */ if (reserve) preload_reserve( reserve, preload_info, page_mask ); for (i = 0; preload_info[i].size; i++) @@ -427,11 +462,6 @@ void *wld_start( void *stack, int *is_unix_thread ) if (!map_region( &builtin_dlls )) builtin_dlls.size = 0;
- LOAD_POSIX_DYLD_FUNC( dlopen ); - LOAD_POSIX_DYLD_FUNC( dlsym ); - LOAD_POSIX_DYLD_FUNC( dladdr ); - LOAD_MACHO_DYLD_FUNC( _dyld_get_image_slide ); - /* load the main binary */ if (!(mod = pdlopen( argv[1], RTLD_NOW ))) fatal_error( "%s: could not load binary\n", argv[1] );
The shared code in preloader.c didn't have declarations for wld_exit() or wld_write().
Signed-off-by: Ken Thomases ken@codeweavers.com --- loader/preloader.c | 8 ++------ loader/preloader.h | 2 ++ loader/preloader_mac.c | 2 -- 3 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/loader/preloader.c b/loader/preloader.c index 9f2fbc3..5bfadf2 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -243,7 +243,7 @@ __ASM_GLOBAL_FUNC(_start,
#define SYSCALL_RET(ret) (((ret) < 0 && (ret) > -4096) ? -1 : (ret))
-static inline __attribute__((noreturn)) void wld_exit( int code ) +void wld_exit( int code ) { for (;;) /* avoid warning */ __asm__ __volatile__( "pushl %%ebx; movl %1,%%ebx; int $0x80; popl %%ebx" @@ -276,7 +276,7 @@ static inline ssize_t wld_read( int fd, void *buffer, size_t len ) return SYSCALL_RET(ret); }
-static inline ssize_t wld_write( int fd, const void *buffer, size_t len ) +ssize_t wld_write( int fd, const void *buffer, size_t len ) { int ret; __asm__ __volatile__( "pushl %%ebx; movl %2,%%ebx; int $0x80; popl %%ebx" @@ -392,13 +392,11 @@ __ASM_GLOBAL_FUNC(_start, "syscall\n\t" \ "ret" )
-void wld_exit( int code ) __attribute__((noreturn)); SYSCALL_NOERR( wld_exit, 60 /* SYS_exit */ );
ssize_t wld_read( int fd, void *buffer, size_t len ); SYSCALL_FUNC( wld_read, 0 /* SYS_read */ );
-ssize_t wld_write( int fd, const void *buffer, size_t len ); SYSCALL_FUNC( wld_write, 1 /* SYS_write */ );
int wld_open( const char *name, int flags ); @@ -493,13 +491,11 @@ __ASM_GLOBAL_FUNC(_start, "ldp x8, x9, [SP], #16\n\t" \ "ret" )
-void wld_exit( int code ) __attribute__((noreturn)); SYSCALL_NOERR( wld_exit, 93 /* SYS_exit */ );
ssize_t wld_read( int fd, void *buffer, size_t len ); SYSCALL_FUNC( wld_read, 63 /* SYS_read */ );
-ssize_t wld_write( int fd, const void *buffer, size_t len ); SYSCALL_FUNC( wld_write, 64 /* SYS_write */ );
int wld_openat( int dirfd, const char *name, int flags ); diff --git a/loader/preloader.h b/loader/preloader.h index b944a09..d89c7e4 100644 --- a/loader/preloader.h +++ b/loader/preloader.h @@ -46,6 +46,8 @@ static inline void *wld_memset( void *dest, int val, size_t len ) return dest; }
+extern __attribute__((noreturn)) void wld_exit( int code ); +extern ssize_t wld_write( int fd, const void *buffer, size_t len ); extern int wld_vsprintf(char *buffer, const char *fmt, va_list args ); extern __attribute__((format(printf,1,2))) void wld_printf(const char *fmt, ... ); extern __attribute__((noreturn,format(printf,1,2))) void fatal_error(const char *fmt, ... ); diff --git a/loader/preloader_mac.c b/loader/preloader_mac.c index 294efc9..61a8dbd 100644 --- a/loader/preloader_mac.c +++ b/loader/preloader_mac.c @@ -267,10 +267,8 @@ __ASM_GLOBAL_FUNC( start, #error preloader not implemented for this CPU #endif
-void wld_exit( int code ) __attribute__((noreturn)); SYSCALL_NOERR( wld_exit, 1 /* SYS_exit */ );
-ssize_t wld_write( int fd, const void *buffer, size_t len ); SYSCALL_FUNC( wld_write, 4 /* SYS_write */ );
void *wld_mmap( void *start, size_t len, int prot, int flags, int fd, off_t offset );