diff --git a/configure b/configure index 4c8b85bab95..1f619667210 100755 --- a/configure +++ b/configure @@ -12360,57 +12360,7 @@ echo "${ECHO_T}$ac_cv_c_dll_zdefs" >&6 then LDDLL="$LDDLL,-z,defs" fi - echo "$as_me:$LINENO: checking whether we can relocate the executable to 0x3c000000" >&5 -echo $ECHO_N "checking whether we can relocate the executable to 0x3c000000... $ECHO_C" >&6 -if test "${ac_cv_ld_reloc_exec+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wl,--section-start,.interp=0x3c000100" - if test "$cross_compiling" = yes; then - ac_cv_ld_reloc_exec="no" -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - int main() { return (sbrk(32*1024*1024) == (void *)-1); } -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_ld_reloc_exec="yes" -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_ld_reloc_exec="no" -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - CFLAGS="$saved_CFLAGS" -fi -echo "$as_me:$LINENO: result: $ac_cv_ld_reloc_exec" >&5 -echo "${ECHO_T}$ac_cv_ld_reloc_exec" >&6 - if test "$ac_cv_ld_reloc_exec" = "yes" - then - LDEXECFLAGS="-Wl,--section-start,.interp=0x3c000100" - - fi echo "$as_me:$LINENO: checking whether the linker accepts --export-dynamic" >&5 echo $ECHO_N "checking whether the linker accepts --export-dynamic... $ECHO_C" >&6 if test "${ac_cv_c_export_dynamic+set}" = set; then @@ -12460,8 +12410,65 @@ echo "$as_me:$LINENO: result: $ac_cv_c_export_dynamic" >&5 echo "${ECHO_T}$ac_cv_c_export_dynamic" >&6 if test "$ac_cv_c_export_dynamic" = "yes" then - LDEXECFLAGS="$LDEXECFLAGS -Wl,--export-dynamic" + LDEXECFLAGS="-Wl,--export-dynamic" + fi + + case $host_cpu in + *i[3456789]86*) + echo "$as_me:$LINENO: checking whether we can relocate the executable to 0x00110000" >&5 +echo $ECHO_N "checking whether we can relocate the executable to 0x00110000... $ECHO_C" >&6 +if test "${ac_cv_ld_reloc_exec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wl,--section-start,.interp=0x00110400" + if test "$cross_compiling" = yes; then + ac_cv_ld_reloc_exec="no" +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + int main() { return (sbrk(32*1024*1024) == (void *)-1); } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_ld_reloc_exec="yes" +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_ld_reloc_exec="no" +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + CFLAGS="$saved_CFLAGS" +fi +echo "$as_me:$LINENO: result: $ac_cv_ld_reloc_exec" >&5 +echo "${ECHO_T}$ac_cv_ld_reloc_exec" >&6 + if test "$ac_cv_ld_reloc_exec" = "yes" + then + LDEXECFLAGS="$LDEXECFLAGS -Wl,--section-start,.interp=0x00110400" + fi + ;; + esac + else echo "$as_me:$LINENO: checking whether we can build a UnixWare (Solaris) dll" >&5 echo $ECHO_N "checking whether we can build a UnixWare (Solaris) dll... $ECHO_C" >&6 diff --git a/configure.ac b/configure.ac index dc79d057d95..99e06818d1a 100644 --- a/configure.ac +++ b/configure.ac @@ -882,26 +882,31 @@ case $host_os in then LDDLL="$LDDLL,-z,defs" fi - AC_CACHE_CHECK([whether we can relocate the executable to 0x3c000000], ac_cv_ld_reloc_exec, - [saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wl,--section-start,.interp=0x3c000100" - AC_TRY_RUN([#include - int main() { return (sbrk(32*1024*1024) == (void *)-1); }], - ac_cv_ld_reloc_exec="yes", - ac_cv_ld_reloc_exec="no", - ac_cv_ld_reloc_exec="no") - CFLAGS="$saved_CFLAGS"]) - if test "$ac_cv_ld_reloc_exec" = "yes" - then - AC_SUBST(LDEXECFLAGS,["-Wl,--section-start,.interp=0x3c000100"]) - fi + AC_CACHE_CHECK([whether the linker accepts --export-dynamic], ac_cv_c_export_dynamic, [WINE_TRY_CFLAGS([-fPIC -Wl,--export-dynamic], ac_cv_c_export_dynamic="yes",ac_cv_c_export_dynamic="no")]) if test "$ac_cv_c_export_dynamic" = "yes" then - LDEXECFLAGS="$LDEXECFLAGS -Wl,--export-dynamic" + AC_SUBST(LDEXECFLAGS,["-Wl,--export-dynamic"]) fi + + case $host_cpu in + *i[[3456789]]86*) + AC_CACHE_CHECK([whether we can relocate the executable to 0x00110000], ac_cv_ld_reloc_exec, + [saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wl,--section-start,.interp=0x00110400" + AC_TRY_RUN([#include + int main() { return (sbrk(32*1024*1024) == (void *)-1); }], + ac_cv_ld_reloc_exec="yes", ac_cv_ld_reloc_exec="no", ac_cv_ld_reloc_exec="no") + CFLAGS="$saved_CFLAGS"]) + if test "$ac_cv_ld_reloc_exec" = "yes" + then + LDEXECFLAGS="$LDEXECFLAGS -Wl,--section-start,.interp=0x00110400" + fi + ;; + esac + else AC_CACHE_CHECK(whether we can build a UnixWare (Solaris) dll, ac_cv_c_dll_unixware, [WINE_TRY_CFLAGS([-fPIC -Wl,-G,-h,conftest.so.1.0,-B,symbolic], diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 4a56da5511b..06a124a2ca3 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -879,6 +879,8 @@ void __wine_kernel_init(void) } found: + wine_free_pe_load_area(); /* the main binary is loaded, we don't need this anymore */ + /* build command line */ set_library_wargv( __wine_main_argv ); if (!build_command_line( __wine_main_wargv )) goto error; diff --git a/include/wine/library.h b/include/wine/library.h index 9967404bada..9f03f393e11 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -52,6 +52,7 @@ extern int __wine_main_argc; extern char **__wine_main_argv; extern WCHAR **__wine_main_wargv; extern char **__wine_main_environ; +extern void wine_init( int argc, char *argv[], char *error, int error_size ); /* debugging */ @@ -69,6 +70,8 @@ extern int wine_dbg_parse_options( const char *str ); extern void DECLSPEC_NORETURN wine_switch_to_stack( void (*func)(void *), void *arg, void *stack ); extern void *wine_anon_mmap( void *start, size_t size, int prot, int flags ); +extern void wine_set_pe_load_area( void *base, size_t size ); +extern void wine_free_pe_load_area(void); /* LDT management */ diff --git a/libs/wine/port.c b/libs/wine/port.c index 19332fd305d..3027cb3e461 100644 --- a/libs/wine/port.c +++ b/libs/wine/port.c @@ -144,6 +144,36 @@ __ASM_GLOBAL_FUNC( wine_switch_to_stack, #endif +static char *pe_area; +static size_t pe_area_size; + +/*********************************************************************** + * wine_set_pe_load_area + * + * Define the reserved area to use for loading the main PE binary. + */ +void wine_set_pe_load_area( void *base, size_t size ) +{ + unsigned int page_mask = getpagesize() - 1; + char *end = (char *)base + size; + + pe_area = (char *)(((unsigned long)base + page_mask) & ~page_mask); + pe_area_size = (end - pe_area) & ~page_mask; +} + + +/*********************************************************************** + * wine_free_pe_load_area + * + * Free the reserved area to use for loading the main PE binary. + */ +void wine_free_pe_load_area(void) +{ + if (pe_area) munmap( pe_area, pe_area_size ); + pe_area = NULL; +} + + #if (defined(__svr4__) || defined(__NetBSD__)) && !defined(MAP_TRYFIXED) /*********************************************************************** * try_mmap_fixed @@ -257,14 +287,24 @@ void *wine_anon_mmap( void *start, size_t size, int prot, int flags ) flags |= MAP_PRIVATE; #endif -#ifdef MAP_TRYFIXED - /* If available, this will attempt a fixed mapping in-kernel */ - flags |= MAP_TRYFIXED; -#elif defined(__svr4__) || defined(__NetBSD__) - if ( try_mmap_fixed( start, size, prot, flags, fdzero, 0 ) ) - return start; -#endif + if (pe_area && start && + (char *)start >= pe_area && + (char *)start + size <= pe_area + pe_area_size) + { + wine_free_pe_load_area(); + flags |= MAP_FIXED; + } + if (!(flags & MAP_FIXED)) + { +#ifdef MAP_TRYFIXED + /* If available, this will attempt a fixed mapping in-kernel */ + flags |= MAP_TRYFIXED; +#elif defined(__svr4__) || defined(__NetBSD__) + if ( try_mmap_fixed( start, size, prot, flags, fdzero, 0 ) ) + return start; +#endif + } return mmap( start, size, prot, flags, fdzero, 0 ); #else return (void *)-1; diff --git a/loader/Makefile.in b/loader/Makefile.in index d4999ba36a7..356da179227 100644 --- a/loader/Makefile.in +++ b/loader/Makefile.in @@ -10,8 +10,8 @@ C_SRCS = \ main.c \ pthread.c -KTHREAD_OBJS = main.o kthread.o -PTHREAD_OBJS = main.o pthread.o +KTHREAD_OBJS = kthread.o main.o +PTHREAD_OBJS = pthread.o main.o WINE_BINARIES = @WINE_BINARIES@ MAIN_BINARY = @MAIN_BINARY@ diff --git a/loader/main.c b/loader/main.c index 638e2aeada5..07e0d0f3500 100644 --- a/loader/main.c +++ b/loader/main.c @@ -20,8 +20,7 @@ #include #include - -extern void wine_init( int argc, char *argv[], char *error, int error_size ); +#include "wine/library.h" /********************************************************************** * main @@ -30,6 +29,11 @@ int main( int argc, char *argv[] ) { char error[1024]; +#ifdef __i386__ + static char pe_load[256*1024*1024] __attribute__((aligned(4096))); + wine_set_pe_load_area( pe_load, sizeof(pe_load) ); +#endif + wine_init( argc, argv, error, sizeof(error) ); fprintf( stderr, "wine: failed to initialize: %s\n", error ); exit(1);