diff --git a/configure b/configure index eaece4d34d6..622f81a71e4 100755 --- a/configure +++ b/configure @@ -2117,8 +2117,55 @@ else echo "$ac_t""no" 1>&6 fi +echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "configure:2122: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + echo $ac_n "checking for XF86DGAQueryExtension in -lXxf86dga""... $ac_c" 1>&6 -echo "configure:2122: checking for XF86DGAQueryExtension in -lXxf86dga" >&5 +echo "configure:2169: checking for XF86DGAQueryExtension in -lXxf86dga" >&5 ac_lib_var=`echo Xxf86dga'_'XF86DGAQueryExtension | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2126,7 +2173,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXxf86dga $X_LIBS -lXext -lX11 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2165,17 +2212,17 @@ for ac_hdr in sys/soundcard.h machine/soundcard.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2169: checking for $ac_hdr" >&5 +echo "configure:2216: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2179: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2226: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -2203,12 +2250,12 @@ done echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6 -echo "configure:2207: checking "for Open Sound System"" >&5 +echo "configure:2254: checking "for Open Sound System"" >&5 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2279: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_opensoundsystem="yes" else @@ -2252,12 +2299,12 @@ fi echo $ac_n "checking "for union semun"""... $ac_c" 1>&6 -echo "configure:2256: checking "for union semun"" >&5 +echo "configure:2303: checking "for union semun"" >&5 if eval "test \"`echo '$''{'ac_cv_c_union_semun'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2265,7 +2312,7 @@ int main() { union semun foo ; return 0; } EOF -if { (eval echo configure:2269: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2316: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_union_semun="yes" else @@ -2293,7 +2340,7 @@ if test "x${GCC}" = "xyes" then CFLAGS="$CFLAGS -Wall" echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6 -echo "configure:2297: checking "for gcc strength-reduce bug"" >&5 +echo "configure:2344: checking "for gcc strength-reduce bug"" >&5 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2301,7 +2348,7 @@ else ac_cv_c_gcc_strength_bug="yes" else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_gcc_strength_bug="no" else @@ -2335,7 +2382,7 @@ fi echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6 -echo "configure:2339: checking "whether external symbols need an underscore prefix"" >&5 +echo "configure:2386: checking "whether external symbols need an underscore prefix"" >&5 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2347,14 +2394,14 @@ _ac_test: .long 0 EOF cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_extern_prefix="yes" else @@ -2378,7 +2425,7 @@ fi echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6 -echo "configure:2382: checking "whether assembler accepts .string"" >&5 +echo "configure:2429: checking "whether assembler accepts .string"" >&5 if eval "test \"`echo '$''{'ac_cv_c_asm_string'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2388,14 +2435,14 @@ cat > conftest_asm.s < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2446: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_asm_string="yes" else @@ -2422,21 +2469,21 @@ DLLFLAGS="" if test "$LIB_TARGET" = "libwine.so.1.0" then echo $ac_n "checking "whether we can build a dll"""... $ac_c" 1>&6 -echo "configure:2426: checking "whether we can build a dll"" >&5 +echo "configure:2473: checking "whether we can build a dll"" >&5 if eval "test \"`echo '$''{'ac_cv_c_dll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_dll="yes" else @@ -2462,7 +2509,7 @@ fi echo $ac_n "checking "for reentrant libc"""... $ac_c" 1>&6 -echo "configure:2466: checking "for reentrant libc"" >&5 +echo "configure:2513: checking "for reentrant libc"" >&5 if eval "test \"`echo '$''{'wine_cv_libc_reentrant'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2470,14 +2517,14 @@ else wine_cv_libc_reentrant=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then wine_cv_libc_reentrant=yes else @@ -2502,7 +2549,7 @@ fi echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6 -echo "configure:2506: checking "for reentrant X libraries"" >&5 +echo "configure:2553: checking "for reentrant X libraries"" >&5 if eval "test \"`echo '$''{'wine_cv_x_reentrant'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2547,12 +2594,12 @@ fi for ac_func in clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2551: checking for $ac_func" >&5 +echo "configure:2598: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2599,21 +2646,21 @@ else fi done -for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h +for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2607: checking for $ac_hdr" >&5 +echo "configure:2654: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2617: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2664: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -2640,12 +2687,12 @@ fi done echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 -echo "configure:2644: checking whether stat file-mode macros are broken" >&5 +echo "configure:2691: checking whether stat file-mode macros are broken" >&5 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2696,12 +2743,12 @@ EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:2700: checking for working const" >&5 +echo "configure:2747: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2801: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -2771,12 +2818,12 @@ EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:2775: checking for ANSI C header files" >&5 +echo "configure:2822: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2784,7 +2831,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2788: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2835: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -2801,7 +2848,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -2819,7 +2866,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -2840,7 +2887,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -2851,7 +2898,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:2855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then : else @@ -2875,12 +2922,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:2879: checking for size_t" >&5 +echo "configure:2926: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2908,7 +2955,7 @@ EOF fi echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:2912: checking size of long long" >&5 +echo "configure:2959: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2916,7 +2963,7 @@ else ac_cv_sizeof_long_long=0 else cat > conftest.$ac_ext < main() @@ -2927,7 +2974,7 @@ main() exit(0); } EOF -if { (eval echo configure:2931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else @@ -2950,7 +2997,7 @@ EOF if test $ac_cv_func_sendmsg = no; then echo $ac_n "checking for sendmsg in -lsocket""... $ac_c" 1>&6 -echo "configure:2954: checking for sendmsg in -lsocket" >&5 +echo "configure:3001: checking for sendmsg in -lsocket" >&5 ac_lib_var=`echo socket'_'sendmsg | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2958,7 +3005,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3020: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3002,12 +3049,12 @@ fi if test "$ac_cv_header_sys_vfs_h" = "yes" then echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6 -echo "configure:3006: checking "whether sys/vfs.h defines statfs"" >&5 +echo "configure:3053: checking "whether sys/vfs.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3024,7 +3071,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3028: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3075: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_vfs_has_statfs=yes else @@ -3051,12 +3098,12 @@ fi if test "$ac_cv_header_sys_statfs_h" = "yes" then echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6 -echo "configure:3055: checking "whether sys/statfs.h defines statfs"" >&5 +echo "configure:3102: checking "whether sys/statfs.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3071,7 +3118,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3075: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3122: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_statfs_has_statfs=yes else @@ -3098,12 +3145,12 @@ fi if test "$ac_cv_header_sys_mount_h" = "yes" then echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6 -echo "configure:3102: checking "whether sys/mount.h defines statfs"" >&5 +echo "configure:3149: checking "whether sys/mount.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3118,7 +3165,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3122: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3169: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_mount_has_statfs=yes else @@ -3144,7 +3191,7 @@ fi echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6 -echo "configure:3148: checking "for statfs.f_bfree"" >&5 +echo "configure:3195: checking "for statfs.f_bfree"" >&5 if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3153,7 +3200,7 @@ else wine_cv_statfs_bfree=no else cat > conftest.$ac_ext < @@ -3180,7 +3227,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3184: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3231: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_statfs_bfree=yes else @@ -3204,7 +3251,7 @@ EOF fi echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6 -echo "configure:3208: checking "for statfs.f_bavail"" >&5 +echo "configure:3255: checking "for statfs.f_bavail"" >&5 if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3213,7 +3260,7 @@ else wine_cv_statfs_bavail=no else cat > conftest.$ac_ext < @@ -3240,7 +3287,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3244: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3291: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_statfs_bavail=yes else @@ -3265,7 +3312,7 @@ fi echo $ac_n "checking "for working sigaltstack"""... $ac_c" 1>&6 -echo "configure:3269: checking "for working sigaltstack"" >&5 +echo "configure:3316: checking "for working sigaltstack"" >&5 if eval "test \"`echo '$''{'ac_cv_c_working_sigaltstack'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3274,7 +3321,7 @@ else else cat > conftest.$ac_ext < @@ -3312,7 +3359,7 @@ else } EOF -if { (eval echo configure:3316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_working_sigaltstack="yes" else @@ -3339,12 +3386,12 @@ fi echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6 -echo "configure:3343: checking "for msg_accrights in struct msghdr"" >&5 +echo "configure:3390: checking "for msg_accrights in struct msghdr"" >&5 if eval "test \"`echo '$''{'ac_cv_c_msg_accrights'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3352,7 +3399,7 @@ int main() { struct msghdr hdr; hdr.msg_accrights=0 ; return 0; } EOF -if { (eval echo configure:3356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_msg_accrights="yes" else diff --git a/configure.in b/configure.in index 0e0a190837b..c55b17762d2 100644 --- a/configure.in +++ b/configure.in @@ -81,6 +81,8 @@ dnl Check for -lw for Solaris AC_CHECK_LIB(w,iswalnum) dnl Check for -lxpg4 for FreeBSD AC_CHECK_LIB(xpg4,setrunelocale) +dnl Check for -ldl +AC_CHECK_LIB(dl,dlopen) dnl Check for XFree86 DGA extension AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,AC_DEFINE(HAVE_LIBXXF86DGA) X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga",,$X_LIBS -lXext -lX11) @@ -260,7 +262,7 @@ fi dnl **** Check for functions and header files **** AC_CHECK_FUNCS(clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf) -AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h) +AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h) AC_HEADER_STAT() AC_C_CONST() AC_TYPE_SIZE_T() diff --git a/include/config.h.in b/include/config.h.in index 0fb133bc085..76e8c00e62c 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -105,6 +105,9 @@ /* Define if you have the waitpid function. */ #undef HAVE_WAITPID +/* Define if you have the header file. */ +#undef HAVE_DLFCN_H + /* Define if you have the header file. */ #undef HAVE_FLOAT_H @@ -156,6 +159,9 @@ /* Define if you have the header file. */ #undef HAVE_WCTYPE_H +/* Define if you have the dl library (-ldl). */ +#undef HAVE_LIBDL + /* Define if you have the i386 library (-li386). */ #undef HAVE_LIBI386 diff --git a/include/module.h b/include/module.h index 96ca217eb8d..dd06e33832c 100644 --- a/include/module.h +++ b/include/module.h @@ -114,7 +114,7 @@ typedef struct _wine_modref MODULE32_TYPE type; union { PE_MODREF pe; - /* ELF_MODREF elf; */ + ELF_MODREF elf; } binfmt; HMODULE32 module; @@ -145,6 +145,7 @@ extern HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs ); extern FARPROC16 MODULE_GetWndProcEntry16( const char *name ); extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hmodule, LPCSTR name ); extern SEGPTR WINAPI HasGPHandler( SEGPTR address ); +HMODULE32 MODULE_LoadLibraryEx32A(LPCSTR libname,struct _PDB32*process,HFILE32 hfile,DWORD flags); /* loader/ne/module.c */ extern NE_MODULE *NE_GetPtr( HMODULE16 hModule ); diff --git a/include/pe_image.h b/include/pe_image.h index cb1d0ddbc4c..bace33f6464 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -52,4 +52,27 @@ extern LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY,LPC typedef DWORD (CALLBACK*DLLENTRYPROC32)(HMODULE32,DWORD,LPVOID); +typedef struct { + WORD popl WINE_PACKED; /* 0x8f 0x05 */ + DWORD addr_popped WINE_PACKED;/* ... */ + BYTE pushl1 WINE_PACKED; /* 0x68 */ + DWORD newret WINE_PACKED; /* ... */ + BYTE pushl2 WINE_PACKED; /* 0x68 */ + DWORD origfun WINE_PACKED; /* original function */ + BYTE ret1 WINE_PACKED; /* 0xc3 */ + WORD addesp WINE_PACKED; /* 0x83 0xc4 */ + BYTE nrofargs WINE_PACKED; /* nr of arguments to add esp, */ + BYTE pushl3 WINE_PACKED; /* 0x68 */ + DWORD oldret WINE_PACKED; /* Filled out from popl above */ + BYTE ret2 WINE_PACKED; /* 0xc3 */ +} ELF_STDCALL_STUB; + +typedef struct { + void* dlhandle; + ELF_STDCALL_STUB *stubs; +} ELF_MODREF; + +extern HMODULE32 ELF_LoadLibraryEx32A(LPCSTR,struct _PDB32*,HFILE32,DWORD); +extern FARPROC32 ELF_FindExportedFunction(struct _PDB32 *process,struct _wine_modref *wm, LPCSTR funcName); + #endif /* __WINE_PE_IMAGE_H */ diff --git a/include/peexe.h b/include/peexe.h index 9d1a60d7c08..e0239fbbfb5 100644 --- a/include/peexe.h +++ b/include/peexe.h @@ -130,6 +130,7 @@ typedef struct _IMAGE_OPTIONAL_HEADER #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 #define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 /* Subsystem Values */ diff --git a/loader/Makefile.in b/loader/Makefile.in index 7f0ae305c82..e405eeb979a 100644 --- a/loader/Makefile.in +++ b/loader/Makefile.in @@ -6,6 +6,7 @@ VPATH = @srcdir@ MODULE = loader C_SRCS = \ + elf.c \ libres.c \ main.c \ module.c \ diff --git a/loader/elf.c b/loader/elf.c new file mode 100644 index 00000000000..5c5c9b4e25a --- /dev/null +++ b/loader/elf.c @@ -0,0 +1,242 @@ +/* + * UNIX dynamic loader + * + * Currently only supports stuff using the dl* API. + * + * Copyright 1998 Marcus Meissner + * + * FIXME: Small reentrancy problem. + * IDEA(s): could be used to split up shell32,comctl32... + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "windows.h" +#include "snoop.h" +#include "process.h" +#include "peexe.h" +#include "heap.h" +#include "pe_image.h" +#include "module.h" +#include "debug.h" + +#if defined(HAVE_LIBDL) && defined(HAVE_DLFCN_H) + +#define UNIX_DLL_ENDING "so" + +#define STUBSIZE 4095 + +#include + +HMODULE32 +ELF_LoadLibraryEx32A(LPCSTR libname,PDB32 *process,HANDLE32 hf,DWORD flags) { + WINE_MODREF *wm; + char *modname,*s,*t,*x; + LPVOID *dlhandle; + LPIMAGE_DOS_HEADER dh; + LPIMAGE_NT_HEADERS nth; + LPIMAGE_SECTION_HEADER sh; + HMODULE32 hmod; + + t = HeapAlloc(process->heap,HEAP_ZERO_MEMORY,strlen(libname)+strlen("lib.so")+1); + *t = '\0'; + /* copy path to tempvar ... */ + s=strrchr(libname,'/'); + if (!s) + s=strrchr(libname,'\\'); + if (s) { + strncpy(t,libname,s-libname+1); + t[libname-s+1]= '\0'; + } else + s = (LPSTR)libname; + modname = s; + /* append "lib" foo ".so" */ + strcat(t,"lib"); + x = t+strlen(t); + strcat(t,s); + s = strchr(x,'.'); + while (s) { + if (!strcasecmp(s,".dll")) { + strcpy(s+1,UNIX_DLL_ENDING); + break; + } + s=strchr(s+1,'.'); + } + + /* FIXME: make UNIX filename from DOS fn? */ + + /* ... and open it */ + dlhandle = dlopen(t,RTLD_NOW); + if (!dlhandle) { + HeapFree(process->heap,0,t); + return 0; + } + wm=(WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(*wm)); + wm->type = MODULE32_ELF; + wm->binfmt.elf.dlhandle = dlhandle; + + /* FIXME: hmm, order? */ + wm->next = process->modref_list; + process->modref_list = wm; + + wm->modname = HEAP_strdupA(process->heap,0,modname); + wm->longname = HEAP_strdupA(process->heap,0,t); + + hmod = (HMODULE32)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)+100); + dh = (LPIMAGE_DOS_HEADER)hmod; + dh->e_magic = IMAGE_DOS_SIGNATURE; + dh->e_lfanew = sizeof(IMAGE_DOS_HEADER); + nth = PE_HEADER(hmod); + nth->Signature = IMAGE_NT_SIGNATURE; + nth->FileHeader.Machine = IMAGE_FILE_MACHINE_I386; + nth->FileHeader.NumberOfSections = 1; + nth->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); + nth->FileHeader.Characteristics = + IMAGE_FILE_RELOCS_STRIPPED|IMAGE_FILE_LINE_NUMS_STRIPPED| + IMAGE_FILE_LOCAL_SYMS_STRIPPED|IMAGE_FILE_32BIT_MACHINE| + IMAGE_FILE_DLL|IMAGE_FILE_DEBUG_STRIPPED; + nth->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; + nth->OptionalHeader.SizeOfCode = 0; + nth->OptionalHeader.SizeOfInitializedData = 0; + nth->OptionalHeader.SizeOfUninitializedData = 0; + nth->OptionalHeader.AddressOfEntryPoint = 0; + nth->OptionalHeader.BaseOfCode = 0; + nth->OptionalHeader.MajorOperatingSystemVersion = 4; + nth->OptionalHeader.MajorImageVersion = 4; + nth->OptionalHeader.SizeOfImage = 0; + nth->OptionalHeader.SizeOfHeaders = 0; + nth->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_NATIVE; + nth->OptionalHeader.DllCharacteristics = 0; + nth->OptionalHeader.NumberOfRvaAndSizes = 0; + + /* allocate one code section that crosses the whole process range + * (we could find out from internal tables ... hmm ) + */ + sh=(LPIMAGE_SECTION_HEADER)(nth+1); + strcpy(sh->Name,".text"); + sh->Misc.VirtualSize = 0x7fffffff; + sh->VirtualAddress = 0x42; /* so snoop can use it ... */ + sh->SizeOfRawData = 0x7fffffff; + sh->PointerToRawData = 0; + sh->Characteristics = IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ; + wm->module = hmod; + SNOOP_RegisterDLL(hmod,libname,STUBSIZE/sizeof(ELF_STDCALL_STUB)); + return hmod; +} + +FARPROC32 +ELF_FindExportedFunction( PDB32 *process,WINE_MODREF *wm, LPCSTR funcName) { + LPVOID fun; + int i,nrofargs = 0; + ELF_STDCALL_STUB *stub; + + assert(wm->type == MODULE32_ELF); + if (!HIWORD(funcName)) { + ERR(win32,"Can't import from UNIX dynamic libs by ordinal, sorry.\n"); + return (FARPROC32)0; + } + fun = dlsym(wm->binfmt.elf.dlhandle,funcName); + /* we sometimes have an excess '_' at the beginning of the name */ + if (!fun && (funcName[0]=='_')) { + funcName++ ; + fun = dlsym(wm->binfmt.elf.dlhandle,funcName); + } + if (!fun) { + /* Function@nrofargs usually marks a stdcall function + * with nrofargs bytes that are popped at the end + */ + if (strchr(funcName,'@')) { + LPSTR t,fn = HEAP_strdupA(process->heap,0,funcName); + + t = strchr(fn,'@'); + *t = '\0'; + nrofargs = 0; + sscanf(t+1,"%d",&nrofargs); + fun = dlsym(wm->binfmt.elf.dlhandle,fn); + HeapFree(process->heap,0,fn); + } + } + /* We sometimes have Win32 dlls implemented using stdcall but UNIX + * dlls using cdecl. If we find out the number of args the function + * uses, we remove them from the stack using two small stubs. + */ + if (!wm->binfmt.elf.stubs) { + /* one page should suffice */ + wm->binfmt.elf.stubs = VirtualAlloc(NULL,STUBSIZE,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); + memset(wm->binfmt.elf.stubs,0,STUBSIZE); + } + stub = wm->binfmt.elf.stubs; + for (i=0;iorigfun) + break; + if (stub->origfun == (DWORD)fun) + break; + stub++; + } + if (i==STUBSIZE/sizeof(ELF_STDCALL_STUB)) { + ERR(win32,"please report, that there are not enough slots for stdcall stubs in the ELF loader.\n"); + assert(iorigfun) + stub->origfun=(DWORD)fun; /* just a marker */ + + if (fun && nrofargs) { /* we don't need it for 0 args */ + /* Selfmodifying entry/return stub for stdcall -> cdecl + * conversion. + * - Pop returnaddress directly into our return code + * popl + * - Replace it by pointer to start of our returncode + * push $newret + * - And call the original function + * jmp $orgfun + * - Remove the arguments no longer needed + * newret: add esp, + * - Push the original returnvalue on the stack + * pushl + * - And return to it. + * ret + */ + + /* FIXME: The function stub is not reentrant. */ + + ((LPBYTE)&(stub->popl))[0] = 0x8f; + ((LPBYTE)&(stub->popl))[1] = 0x05; + stub->addr_popped = (DWORD)&(stub->oldret); + stub->pushl1 = 0x68; + stub->newret = (DWORD)&(stub->addesp); + stub->pushl2 = 0x68; + stub->origfun = (DWORD)fun; + stub->ret1 = 0xc3; + ((LPBYTE)&(stub->addesp))[0]=0x83; + ((LPBYTE)&(stub->addesp))[1]=0xc4; + stub->nrofargs = nrofargs; + stub->pushl3 = 0x68; + /* filled out by entrycode */ + stub->oldret = 0xdeadbeef; + stub->ret2 = 0xc3; + fun=(FARPROC32)stub; + } + if (!fun) { + FIXME(win32,"function %s not found: %s\n",funcName,dlerror()); + return fun; + } + fun = SNOOP_GetProcAddress32(wm->module,funcName,stub-wm->binfmt.elf.stubs,fun); + return (FARPROC32)fun; +} +#else + +HMODULE32 +ELF_LoadLibraryEx32A(LPCSTR libname,PDB32 *process,HANDLE32 hf,DWORD flags) { + return 0; +} +FARPROC32 +ELF_FindExportedFunction( PDB32 *process,WINE_MODREF *wm, LPCSTR funcName) { + return (FARPROC32)0; +} + +#endif diff --git a/loader/module.c b/loader/module.c index 1a4764aa75c..172c817d14e 100644 --- a/loader/module.c +++ b/loader/module.c @@ -686,20 +686,29 @@ HMODULE32 WINAPI LoadLibraryEx32W16( LPCSTR libname, HANDLE16 hf, * LoadLibraryEx32A (KERNEL32) */ HMODULE32 WINAPI LoadLibraryEx32A(LPCSTR libname,HFILE32 hfile,DWORD flags) +{ + return MODULE_LoadLibraryEx32A(libname,PROCESS_Current(),hfile,flags); +} + +HMODULE32 MODULE_LoadLibraryEx32A(LPCSTR libname,PDB32*process,HFILE32 hfile,DWORD flags) { HMODULE32 hmod; - hmod = PE_LoadLibraryEx32A(libname,PROCESS_Current(),hfile,flags); + hmod = ELF_LoadLibraryEx32A(libname,process,hfile,flags); + if (hmod) + return hmod; /* already initialized for ELF */ + + hmod = PE_LoadLibraryEx32A(libname,process,hfile,flags); if (hmod < 32) { char buffer[256]; strcpy( buffer, libname ); strcat( buffer, ".dll" ); - hmod = PE_LoadLibraryEx32A(buffer,PROCESS_Current(),hfile,flags); + hmod = PE_LoadLibraryEx32A(buffer,process,hfile,flags); } /* initialize all DLLs, which haven't been initialized yet. */ if (hmod >= 32) - PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, NULL); + PE_InitializeDLLs( process, DLL_PROCESS_ATTACH, NULL); return hmod; } @@ -1018,6 +1027,8 @@ FARPROC32 MODULE_GetProcAddress32( { case MODULE32_PE: return PE_FindExportedFunction( process, wm, function); + case MODULE32_ELF: + return ELF_FindExportedFunction( process, wm, function); default: ERR(module,"wine_modref type %d not handled.\n",wm->type); return (FARPROC32)0; diff --git a/loader/pe_image.c b/loader/pe_image.c index 942e5a36708..5c282f4b7c7 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -253,7 +253,7 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm) char *name = (char *) RVA(pe_imp->Name); /* don't use MODULE_Load, Win32 creates new task differently */ - hImpModule = PE_LoadLibraryEx32A( name, process, 0, 0 ); + hImpModule = MODULE_LoadLibraryEx32A( name, process, 0, 0 ); if (!hImpModule) { char *p,buffer[2000]; @@ -262,7 +262,7 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm) if (!(p = strrchr (buffer, '\\'))) p = buffer; strcpy (p + 1, name); - hImpModule = PE_LoadLibraryEx32A( buffer, process, 0, 0 ); + hImpModule = MODULE_LoadLibraryEx32A( buffer, process, 0, 0 ); } if (!hImpModule) { ERR (module, "Module %s not found\n", name);