Create a huge array in bss to reserve the memory area we need for PE
binaries, to prevent exec shield from mapping system libraries there.

diff --git a/configure b/configure
index 4c8b85b..1f61966 100755
--- a/configure
+++ b/configure
@@ -12360,57 +12360,7 @@
         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 <unistd.h>
-                       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 "${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 <unistd.h>
+                           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 dc79d05..99e0681 100644
--- a/configure.ac
+++ b/configure.ac
@@ -882,26 +882,31 @@
         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 <unistd.h>
-                       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 <unistd.h>
+                           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 4a56da5..06a124a 100644
--- a/dlls/kernel/process.c
+++ b/dlls/kernel/process.c
@@ -879,6 +879,8 @@
     }
 
  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 9967404..9f03f39 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -52,6 +52,7 @@
 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 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 19332fd..3027cb3 100644
--- a/libs/wine/port.c
+++ b/libs/wine/port.c
@@ -144,6 +144,36 @@
 #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 @@
     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 d4999ba..356da17 100644
--- a/loader/Makefile.in
+++ b/loader/Makefile.in
@@ -10,8 +10,8 @@
 	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 638e2ae..07e0d0f 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -20,8 +20,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-
-extern void wine_init( int argc, char *argv[], char *error, int error_size );
+#include "wine/library.h"
 
 /**********************************************************************
  *           main
@@ -30,6 +29,11 @@
 {
     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);