diff --git a/.gitignore b/.gitignore index 4f084d3fa2f..73e315257dc 100644 --- a/.gitignore +++ b/.gitignore @@ -203,14 +203,8 @@ libs/wpp/ppl.yy.c libs/wpp/ppy.tab.c libs/wpp/ppy.tab.h loader/wine -loader/wine-freebsd -loader/wine-freebsd-installed -loader/wine-glibc -loader/wine-glibc-installed +loader/wine-installed loader/wine-preloader -loader/wine-preloader-installed -loader/wine-pthread -loader/wine-pthread-installed loader/wine.de.man loader/wine.fr.man loader/wine.man diff --git a/configure b/configure index e32cb692faa..c254f1086da 100755 --- a/configure +++ b/configure @@ -655,7 +655,6 @@ LDAPLIBS LIBPOLL LIBDL EXTRA_BINARIES -MAIN_BINARY SOCKETLIBS CRTLIBS LDPATH @@ -17995,19 +17994,11 @@ case $host_os in ;; esac -MAIN_BINARY="wine-pthread" - case $host_cpu in +case $host_cpu in *i[3456789]86*) case $host_os in linux* | k*bsd*-gnu) - MAIN_BINARY="wine-glibc" - - EXTRA_BINARIES="wine-pthread wine-preloader" - ;; - freebsd*) - MAIN_BINARY="wine-freebsd" - - EXTRA_BINARIES="wine-pthread" + EXTRA_BINARIES="wine-preloader" ;; esac ;; diff --git a/configure.ac b/configure.ac index 274d60abc6e..b1c3c125f60 100644 --- a/configure.ac +++ b/configure.ac @@ -1431,16 +1431,11 @@ case $host_os in ;; esac -AC_SUBST(MAIN_BINARY,"wine-pthread") dnl Default value case $host_cpu in *i[[3456789]]86*) case $host_os in linux* | k*bsd*-gnu) - AC_SUBST(MAIN_BINARY,"wine-glibc") - AC_SUBST(EXTRA_BINARIES,"wine-pthread wine-preloader") ;; - freebsd*) - AC_SUBST(MAIN_BINARY,"wine-freebsd") - AC_SUBST(EXTRA_BINARIES,"wine-pthread") ;; + AC_SUBST(EXTRA_BINARIES,"wine-preloader") ;; esac ;; esac diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index c0e27fcb530..fea63a87986 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1242,6 +1242,7 @@ static char **build_envp( const WCHAR *envW ) { if (*p == '=') continue; /* skip drive curdirs, this crashes some unix apps */ if (!strncmp( p, "WINEPRELOADRESERVE=", sizeof("WINEPRELOADRESERVE=")-1 )) continue; + if (!strncmp( p, "WINELOADERNOEXEC=", sizeof("WINELOADERNOEXEC=")-1 )) continue; if (!strncmp( p, "WINESERVERSOCKET=", sizeof("WINESERVERSOCKET=")-1 )) continue; if (is_special_env_var( p )) /* prefix it with "WINE" */ { diff --git a/loader/Makefile.in b/loader/Makefile.in index 23bf99e8c9c..1c882c62766 100644 --- a/loader/Makefile.in +++ b/loader/Makefile.in @@ -5,28 +5,18 @@ VPATH = @srcdir@ MODULE = wine C_SRCS = \ - freebsd.c \ - glibc.c \ main.c \ preloader.c \ pthread.c -PTHREAD_OBJS = pthread.o main.o +MAIN_OBJS = pthread.o main.o -MAIN_BINARY = @MAIN_BINARY@ EXTRA_BINARIES = @EXTRA_BINARIES@ -WINE_BINARIES = $(MAIN_BINARY) $(EXTRA_BINARIES) PROGRAMS = \ wine \ - wine-freebsd \ - wine-freebsd-installed \ - wine-glibc \ - wine-glibc-installed \ - wine-preloader \ - wine-preloader-installed \ - wine-pthread \ - wine-pthread-installed + wine-installed \ + wine-preloader MANPAGES = \ wine.man \ @@ -39,50 +29,31 @@ INSTALLDIRS = \ $(DESTDIR)$(mandir)/de.UTF-8/man$(prog_manext) \ $(DESTDIR)$(mandir)/fr.UTF-8/man$(prog_manext) -all: $(WINE_BINARIES) $(WINE_BINARIES:%=%-installed) $(MODULE) $(MANPAGES) +all: wine wine-installed $(EXTRA_BINARIES) $(MANPAGES) @MAKE_RULES@ LIBPTHREAD = @LIBPTHREAD@ LDEXECFLAGS = @LDEXECFLAGS@ -wine-freebsd: freebsd.o Makefile.in - $(CC) -o $@ freebsd.o $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_LOCAL) - -wine-freebsd-installed: freebsd.o Makefile.in - $(CC) -o $@ freebsd.o $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_INSTALL) - -wine-glibc: glibc.o Makefile.in - $(CC) -o $@ glibc.o $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_LOCAL) - -wine-glibc-installed: glibc.o Makefile.in - $(CC) -o $@ glibc.o $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_INSTALL) - -wine-preloader wine-preloader-installed: preloader.o Makefile.in +wine-preloader: preloader.o Makefile.in $(CC) -o $@ -static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7c000000 preloader.o $(LIBPORT) $(LDFLAGS) -wine-pthread: $(PTHREAD_OBJS) Makefile.in - $(CC) -o $@ $(LDEXECFLAGS) $(PTHREAD_OBJS) $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_LOCAL) +wine: $(MAIN_OBJS) Makefile.in + $(CC) -o $@ $(LDEXECFLAGS) $(MAIN_OBJS) $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_LOCAL) -wine-pthread-installed: $(PTHREAD_OBJS) Makefile.in - $(CC) -o $@ $(LDEXECFLAGS) $(PTHREAD_OBJS) $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_INSTALL) +wine-installed: $(MAIN_OBJS) Makefile.in + $(CC) -o $@ $(LDEXECFLAGS) $(MAIN_OBJS) $(LIBWINE) $(LIBPORT) $(LIBPTHREAD) $(EXTRALIBS) $(LDFLAGS) $(LDRPATH_INSTALL) -$(MODULE): $(MAIN_BINARY) - $(RM) $(MODULE) && $(LN_S) $(MAIN_BINARY) $(MODULE) - -install install-lib:: $(WINE_BINARIES:%=%-installed) $(MANPAGES) $(INSTALLDIRS) - for f in $(WINE_BINARIES); do \ - if [ "$(MAIN_BINARY)" = "$$f" ]; \ - then $(INSTALL_PROGRAM) $$f-installed $(DESTDIR)$(bindir)/$(MODULE); \ - else $(INSTALL_PROGRAM) $$f-installed $(DESTDIR)$(bindir)/$$f; \ - fi; \ - done +install install-lib:: wine-installed $(EXTRA_BINARIES) $(MANPAGES) $(INSTALLDIRS) + $(INSTALL_PROGRAM) wine-installed $(DESTDIR)$(bindir)/$(MODULE) + for f in $(EXTRA_BINARIES); do $(INSTALL_PROGRAM) $$f $(DESTDIR)$(bindir)/$$f; done $(INSTALL_DATA) wine.man $(DESTDIR)$(mandir)/man$(prog_manext)/wine.$(prog_manext) $(INSTALL_DATA) wine.de.man $(DESTDIR)$(mandir)/de.UTF-8/man$(prog_manext)/wine.$(prog_manext) $(INSTALL_DATA) wine.fr.man $(DESTDIR)$(mandir)/fr.UTF-8/man$(prog_manext)/wine.$(prog_manext) uninstall:: - -cd $(DESTDIR)$(bindir) && $(RM) $(WINE_BINARIES) $(MODULE) + -cd $(DESTDIR)$(bindir) && $(RM) $(EXTRA_BINARIES) $(MODULE) $(RM) $(DESTDIR)$(mandir)/man$(prog_manext)/wine.$(prog_manext) $(RM) $(DESTDIR)$(mandir)/de.UTF-8/man$(prog_manext)/wine.$(prog_manext) $(RM) $(DESTDIR)$(mandir)/fr.UTF-8/man$(prog_manext)/wine.$(prog_manext) diff --git a/loader/freebsd.c b/loader/freebsd.c deleted file mode 100644 index 0d0eb5767cb..00000000000 --- a/loader/freebsd.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * FreeBSD loader - * - * Copyright 2007 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#ifdef HAVE_SYS_RESOURCE_H -# include -#endif - -#include "wine/library.h" - -/* build a new full path from the specified path and name */ -static const char *build_new_path( const char *path, const char *name ) -{ - const char *p; - char *ret; - - if (!(p = strrchr( path, '/' ))) return name; - p++; - ret = malloc( (p - path) + strlen(name) + 1 ); - memcpy( ret, path, p - path ); - strcpy( ret + (p - path), name ); - return ret; -} - -/********************************************************************** - * main - */ -int main( int argc, char *argv[] ) -{ - const char *new_argv0 = build_new_path( argv[0], "wine-pthread" ); - struct rlimit rl; - rl.rlim_cur = 0x02000000; - rl.rlim_max = 0x02000000; - setrlimit( RLIMIT_DATA, &rl ); - wine_init_argv0_path( new_argv0 ); - wine_exec_wine_binary( NULL, argv, NULL ); - fprintf( stderr, "wine: could not exec %s\n", new_argv0 ); - exit(1); -} diff --git a/loader/glibc.c b/loader/glibc.c deleted file mode 100644 index 1a1829680b6..00000000000 --- a/loader/glibc.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * glibc threading support - * - * Copyright 2003 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#ifdef HAVE_SYS_RESOURCE_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_PTHREAD_H -# include -#endif - -#include "wine/library.h" - -/* malloc wrapper */ -static void *xmalloc( size_t size ) -{ - void *res; - - if (!size) size = 1; - if (!(res = malloc( size ))) - { - fprintf( stderr, "wine: virtual memory exhausted\n" ); - exit(1); - } - return res; -} - -/* separate thread to check for NPTL and TLS features */ -static void *needs_pthread( void *arg ) -{ - pid_t tid = gettid(); - /* check for NPTL */ - if (tid != -1 && tid != getpid()) return (void *)1; - /* check for TLS glibc */ - if (wine_get_gs() != 0) return (void *)1; - /* check for exported epoll_create to detect new glibc versions without TLS */ - if (wine_dlsym( RTLD_DEFAULT, "epoll_create", NULL, 0 )) - fprintf( stderr, - "wine: glibc >= 2.3 without NPTL or TLS is not a supported combination.\n" - " Please upgrade to a glibc with NPTL support.\n" ); - else - fprintf( stderr, - "wine: Your C library is too old. You need at least glibc 2.3 with NPTL support.\n" ); - return 0; -} - -/* check if we support the glibc threading model */ -static void check_threading(void) -{ - pthread_t id; - void *ret; - - pthread_create( &id, NULL, needs_pthread, NULL ); - pthread_join( id, &ret ); - if (!ret) exit(1); -} - -/* build a new full path from the specified path and name */ -static const char *build_new_path( const char *path, const char *name ) -{ - const char *p; - char *ret; - - if (!(p = strrchr( path, '/' ))) return name; - p++; - ret = xmalloc( (p - path) + strlen(name) + 1 ); - memcpy( ret, path, p - path ); - strcpy( ret + (p - path), name ); - return ret; -} - -static void check_vmsplit( void *stack ) -{ - if (stack < (void *)0x80000000) - { - /* if the stack is below 0x80000000, assume we can safely try a munmap there */ - if (munmap( (void *)0x80000000, 1 ) == -1 && errno == EINVAL) - fprintf( stderr, - "Warning: memory above 0x80000000 doesn't seem to be accessible.\n" - "Wine requires a 3G/1G user/kernel memory split to work properly.\n" ); - } -} - -static void set_max_limit( int limit ) -{ - struct rlimit rlimit; - - if (!getrlimit( limit, &rlimit )) - { - rlimit.rlim_cur = rlimit.rlim_max; - setrlimit( limit, &rlimit ); - } -} - - -/********************************************************************** - * main - */ -int main( int argc, char *argv[] ) -{ - const char *loader = getenv( "WINELOADER" ); - const char *new_argv0 = build_new_path( argv[0], "wine-pthread" ); - - wine_init_argv0_path( new_argv0 ); - - /* set the address space limit before starting the preloader */ - set_max_limit( RLIMIT_AS ); - - if (loader) - { - /* update WINELOADER with the new name */ - const char *new_name = build_new_path( loader, "wine-pthread" ); - char *new_loader = xmalloc( sizeof("WINELOADER=") + strlen(new_name) ); - strcpy( new_loader, "WINELOADER=" ); - strcat( new_loader, new_name ); - putenv( new_loader ); - loader = new_name; - } - - check_threading(); - check_vmsplit( &argc ); - wine_exec_wine_binary( NULL, argv, loader ); - fprintf( stderr, "wine: could not exec wine-pthread\n" ); - exit(1); -} diff --git a/loader/main.c b/loader/main.c index 314398debc8..4c2cb504c49 100644 --- a/loader/main.c +++ b/loader/main.c @@ -21,10 +21,20 @@ #include "config.h" #include "wine/port.h" +#include #include #include #ifdef HAVE_SYS_MMAN_H -#include +# include +#endif +#ifdef HAVE_SYS_RESOURCE_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include #endif #include "wine/library.h" @@ -91,6 +101,93 @@ static void check_command_line( int argc, char *argv[] ) } +#if defined(__linux__) && defined(__i386__) + +/* separate thread to check for NPTL and TLS features */ +static void *needs_pthread( void *arg ) +{ + pid_t tid = gettid(); + /* check for NPTL */ + if (tid != -1 && tid != getpid()) return (void *)1; + /* check for TLS glibc */ + if (wine_get_gs() != 0) return (void *)1; + /* check for exported epoll_create to detect new glibc versions without TLS */ + if (wine_dlsym( RTLD_DEFAULT, "epoll_create", NULL, 0 )) + fprintf( stderr, + "wine: glibc >= 2.3 without NPTL or TLS is not a supported combination.\n" + " Please upgrade to a glibc with NPTL support.\n" ); + else + fprintf( stderr, + "wine: Your C library is too old. You need at least glibc 2.3 with NPTL support.\n" ); + return 0; +} + +/* check if we support the glibc threading model */ +static void check_threading(void) +{ + pthread_t id; + void *ret; + + pthread_create( &id, NULL, needs_pthread, NULL ); + pthread_join( id, &ret ); + if (!ret) exit(1); +} + +static void check_vmsplit( void *stack ) +{ + if (stack < (void *)0x80000000) + { + /* if the stack is below 0x80000000, assume we can safely try a munmap there */ + if (munmap( (void *)0x80000000, 1 ) == -1 && errno == EINVAL) + fprintf( stderr, + "Warning: memory above 0x80000000 doesn't seem to be accessible.\n" + "Wine requires a 3G/1G user/kernel memory split to work properly.\n" ); + } +} + +static void set_max_limit( int limit ) +{ + struct rlimit rlimit; + + if (!getrlimit( limit, &rlimit )) + { + rlimit.rlim_cur = rlimit.rlim_max; + setrlimit( limit, &rlimit ); + } +} + +static int pre_exec(void) +{ + int temp; + + check_threading(); + check_vmsplit( &temp ); + set_max_limit( RLIMIT_AS ); + return 1; +} + +#elif defined(__FreeBSD__) && defined(__i386__) + +static int pre_exec(void) +{ + struct rlimit rl; + + rl.rlim_cur = 0x02000000; + rl.rlim_max = 0x02000000; + setrlimit( RLIMIT_DATA, &rl ); + return 1; +} + +#else + +static int pre_exec(void) +{ + return 0; /* no exec needed */ +} + +#endif + + /********************************************************************** * main */ @@ -99,7 +196,21 @@ int main( int argc, char *argv[] ) char error[1024]; int i; - check_command_line( argc, argv ); + if (!getenv( "WINELOADERNOEXEC" )) /* first time around */ + { + static char noexec[] = "WINELOADERNOEXEC=1"; + + putenv( noexec ); + check_command_line( argc, argv ); + if (pre_exec()) + { + wine_init_argv0_path( argv[0] ); + wine_exec_wine_binary( NULL, argv, getenv( "WINELOADER" )); + fprintf( stderr, "wine: could not exec the wine loader\n" ); + exit(1); + } + } + if (wine_main_preload_info) { for (i = 0; wine_main_preload_info[i].size; i++)