From eb8061bf350faa0074e04a9746f1284cf7604360 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Mon, 9 Nov 1998 21:51:51 +0000 Subject: [PATCH] * pe-dll.c: New file; direct support for PE DLLs * deffile.h: New file; direct support for PE DLLs * deffilep.y: New file; direct support for PE DLLs * emultempl/pe.em: add direct support for PE DLLs * configure.tgt: allow target-specific extra files * configure.in: allow target-specific extra files * ldlang.c (lang_add_assignment): return the assignment so that one can change the value later based on the object files (pe-dll DEF files do this) * ldint.texinfo: add section for emulation walkthrough --- ld/.Sanitize | 3 + ld/ChangeLog | 12 + ld/Makefile.in | 26 +- ld/configure | 582 ++++++++++++++++----------- ld/configure.in | 15 +- ld/configure.tgt | 5 +- ld/deffile.h | 111 +++++ ld/deffilep.y | 978 +++++++++++++++++++++++++++++++++++++++++++++ ld/emultempl/pe.em | 213 +++++++++- ld/pe-dll.c | 928 ++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 2625 insertions(+), 248 deletions(-) create mode 100644 ld/deffile.h create mode 100644 ld/deffilep.y create mode 100644 ld/pe-dll.c diff --git a/ld/.Sanitize b/ld/.Sanitize index 5798f8bad4c..12d848616df 100644 --- a/ld/.Sanitize +++ b/ld/.Sanitize @@ -56,6 +56,8 @@ configure.bat configure.host configure.in configure.tgt +deffile.h +deffilep.y dep-in.sed emulparams emultempl @@ -98,6 +100,7 @@ mpw-idtmips.c mpw-make.sed mri.c mri.h +pe-dll.c po scripttempl stamp-h.in diff --git a/ld/ChangeLog b/ld/ChangeLog index c9fe297b7bd..196a313fe9c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +Mon Nov 9 16:41:30 1998 DJ Delorie + + * pe-dll.c: New file; direct support for PE DLLs + * deffile.h: New file; direct support for PE DLLs + * deffilep.y: New file; direct support for PE DLLs + * emultempl/pe.em: add direct support for PE DLLs + * configure.tgt: allow target-specific extra files + * configure.in: allow target-specific extra files + * ldlang.c (lang_add_assignment): return the assignment so + that one can change the value later (pe-dll DEF files do this) + * ldint.texinfo: add section for emulation walkthrough + Wed Nov 4 16:39:18 1998 Nick Clifton * Makefile.am: Add support for FR30 target. diff --git a/ld/Makefile.in b/ld/Makefile.in index 4017ffb0c9f..3a8884ba289 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -86,7 +86,7 @@ SUBDIRS = po tooldir = $(exec_prefix)/$(target_alias) -YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi` +YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L$(srcdir)/../bison/ ; else echo bison -y ; fi` YFLAGS = -d LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi` @@ -97,6 +97,7 @@ scriptdir = $(tooldir)/lib EMUL = @EMUL@ EMULATION_OFILES = @EMULATION_OFILES@ +EMUL_EXTRA_OFILES = @EMUL_EXTRA_OFILES@ # Search path to override the default search path for -lfoo libraries. # If LIB_PATH is empty, the ones in the script (if any) are left alone. @@ -232,6 +233,8 @@ ALL_EMULATIONS = \ ei386nbsd.o \ ei386nw.o \ ei386pe.o \ + pe-dll.o \ + deffilep.o \ elnk960.o \ em68k4knbsd.o \ em68kaout.o \ @@ -286,18 +289,18 @@ ALL_64_EMULATIONS = \ CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \ ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \ - mri.c ldcref.c + mri.c ldcref.c pe-dll.c HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \ ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \ - ldwrite.h mri.h + ldwrite.h mri.h deffile.h -GENERATED_CFILES = ldgram.c ldlex.c -GENERATED_HFILES = ldgram.h ldemul-list.h +GENERATED_CFILES = ldgram.c ldlex.c deffilep.c +GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h OFILES = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o \ ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o \ - ldfile.o ldcref.o ${EMULATION_OFILES} + ldfile.o ldcref.o ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES} STAGESTUFF = *.o ldscripts/* e*.c @@ -314,8 +317,8 @@ GEN_DEPENDS = $(srcdir)/genscripts.sh $(srcdir)/emultempl/stringify.sed ld_new_SOURCES = ldgram.y ldlex.l lexsup.c ldlang.c mri.c ldctor.c ldmain.c \ ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c -ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLDEPS) -ld_new_LDADD = $(EMULATION_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS) +ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLDEPS) +ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS) # This is the real libbfd.a created by libtool. TESTBFDLIB = @TESTBFDLIB@ @@ -1431,6 +1434,11 @@ ldcref.o: ldcref.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ $(INCDIR)/libiberty.h ld.h ldmain.h ldmisc.h ldexp.h \ ldlang.h +pe-dll.o: pe-dll.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \ + ldmisc.h ldgram.h ldmain.h $(INCDIR)/coff/internal.h \ + ../bfd/libcoff.h deffile.h ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ ld.h ldexp.h ldver.h ldlang.h ldemul.h ldfile.h ldmisc.h \ @@ -1438,6 +1446,8 @@ ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ ldlex.o: ldlex.c ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \ ld.h ldgram.h ldmisc.h ldexp.h ldlang.h ldfile.h ldlex.h \ ldmain.h +deffilep.o: deffilep.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + ../bfd/bfd.h ld.h deffile.h # IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/ld/configure b/ld/configure index e4fa8c5d2c4..f7bd1691153 100755 --- a/ld/configure +++ b/ld/configure @@ -1,7 +1,7 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.12.1 +# Generated automatically using autoconf version 2.12.2 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -354,7 +354,7 @@ EOF verbose=yes ;; -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.12.1" + echo "configure generated by autoconf version 2.12.2" exit 0 ;; -with-* | --with-*) @@ -524,9 +524,11 @@ ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross +ac_exeext= +ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then @@ -588,7 +590,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:592: checking host system type" >&5 +echo "configure:594: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -609,7 +611,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:613: checking target system type" >&5 +echo "configure:615: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -627,7 +629,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:631: checking build system type" >&5 +echo "configure:633: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -662,12 +664,12 @@ test "$host_alias" != "$target_alias" && # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:666: checking for a BSD compatible install" >&5 +echo "configure:668: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in @@ -716,7 +718,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:720: checking whether build environment is sane" >&5 +echo "configure:722: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -773,7 +775,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:777: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:779: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -802,7 +804,7 @@ fi PACKAGE=ld -VERSION=2.9.1 +VERSION=2.9.4 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } @@ -819,7 +821,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 -echo "configure:823: checking for working aclocal" >&5 +echo "configure:825: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -832,7 +834,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:836: checking for working autoconf" >&5 +echo "configure:838: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -845,7 +847,7 @@ else fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:849: checking for working automake" >&5 +echo "configure:851: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -858,7 +860,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:862: checking for working autoheader" >&5 +echo "configure:864: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -871,7 +873,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:875: checking for working makeinfo" >&5 +echo "configure:877: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -934,14 +936,14 @@ fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:938: checking for $ac_word" >&5 +echo "configure:940: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -963,14 +965,14 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:967: checking for $ac_word" >&5 +echo "configure:969: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -992,14 +994,14 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:996: checking for $ac_word" >&5 +echo "configure:998: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. @@ -1036,25 +1038,58 @@ else echo "$ac_t""no" 1>&6 fi + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1048: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1044: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1079: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1093: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1074,12 +1109,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1078: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1113: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1083: checking whether we are using GNU C" >&5 +echo "configure:1118: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1088,7 +1123,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1092: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1127: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1099,11 +1134,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes - ac_test_CFLAGS="${CFLAGS+set}" - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1107: checking whether ${CC-cc} accepts -g" >&5 +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1146: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1118,16 +1157,20 @@ rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 - if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" - elif test $ac_cv_prog_cc_g = yes; then +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then CFLAGS="-g -O2" else - CFLAGS="-O2" + CFLAGS="-g" fi else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi fi # Check whether --with-gnu-ld or --without-gnu-ld was given. @@ -1143,7 +1186,7 @@ ac_prog=ld if test "$ac_cv_prog_gcc" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 -echo "configure:1147: checking for ld used by GCC" >&5 +echo "configure:1190: checking for ld used by GCC" >&5 ac_prog=`($CC -print-prog-name=ld) 2>&5` case "$ac_prog" in # Accept absolute paths. @@ -1161,10 +1204,10 @@ echo "configure:1147: checking for ld used by GCC" >&5 esac elif test "$with_gnu_ld" = yes; then echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:1165: checking for GNU ld" >&5 +echo "configure:1208: checking for GNU ld" >&5 else echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:1168: checking for non-GNU ld" >&5 +echo "configure:1211: checking for non-GNU ld" >&5 fi if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1200,7 +1243,7 @@ fi test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:1204: checking if the linker ($LD) is GNU ld" >&5 +echo "configure:1247: checking if the linker ($LD) is GNU ld" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1216,7 +1259,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 -echo "configure:1220: checking for BSD-compatible nm" >&5 +echo "configure:1263: checking for BSD-compatible nm" >&5 if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1250,7 +1293,7 @@ echo "$ac_t""$NM" 1>&6 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1254: checking whether ln -s works" >&5 +echo "configure:1297: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1292,8 +1335,8 @@ test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" case "$host" in *-*-irix6*) # Find out which ABI we are using. - echo '#line 1296 "configure"' > conftest.$ac_ext - if { (eval echo configure:1297: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + echo '#line 1339 "configure"' > conftest.$ac_ext + if { (eval echo configure:1340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then case "`/usr/bin/file conftest.o`" in *32-bit*) LD="${LD-ld} -32" @@ -1318,14 +1361,14 @@ case "$host" in # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1322: checking for $ac_word" >&5 +echo "configure:1365: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1349,14 +1392,14 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1353: checking for $ac_word" >&5 +echo "configure:1396: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1383,14 +1426,14 @@ fi # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1387: checking for $ac_word" >&5 +echo "configure:1430: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1414,14 +1457,14 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1418: checking for $ac_word" >&5 +echo "configure:1461: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1497,14 +1540,14 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1501: checking for $ac_word" >&5 +echo "configure:1544: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1526,14 +1569,14 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1530: checking for $ac_word" >&5 +echo "configure:1573: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. @@ -1570,25 +1613,58 @@ else echo "$ac_t""no" 1>&6 fi + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1623: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1578: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1654: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1608,12 +1684,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1612: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1617: checking whether we are using GNU C" >&5 +echo "configure:1693: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1622,7 +1698,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1633,11 +1709,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes - ac_test_CFLAGS="${CFLAGS+set}" - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1641: checking whether ${CC-cc} accepts -g" >&5 +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1721: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1652,16 +1732,20 @@ rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 - if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" - elif test $ac_cv_prog_cc_g = yes; then +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then CFLAGS="-g -O2" else - CFLAGS="-O2" + CFLAGS="-g" fi else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi fi @@ -1670,7 +1754,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' ALL_LINGUAS= echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1674: checking how to run the C preprocessor" >&5 +echo "configure:1758: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1685,14 +1769,14 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1695: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1779: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -1702,14 +1786,31 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1796: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1712: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1813: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -1721,6 +1822,8 @@ else fi rm -f conftest* fi +rm -f conftest* +fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi @@ -1731,7 +1834,7 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 -echo "configure:1735: checking for POSIXized ISC" >&5 +echo "configure:1838: checking for POSIXized ISC" >&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then @@ -1752,12 +1855,12 @@ else fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1756: checking for ANSI C header files" >&5 +echo "configure:1859: 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 @@ -1765,8 +1868,8 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1769: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1872: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes @@ -1782,7 +1885,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 @@ -1800,7 +1903,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 @@ -1821,7 +1924,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1832,7 +1935,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1939: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1856,12 +1959,12 @@ EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:1860: checking for working const" >&5 +echo "configure:1963: 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:2017: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -1931,21 +2034,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:1935: checking for inline" >&5 +echo "configure:2038: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2052: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -1971,12 +2074,12 @@ EOF esac echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:1975: checking for off_t" >&5 +echo "configure:2078: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2004,12 +2107,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:2008: checking for size_t" >&5 +echo "configure:2111: 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 @@ -2039,19 +2142,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:2043: checking for working alloca.h" >&5 +echo "configure:2146: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:2055: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -2072,25 +2175,30 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:2076: checking for alloca" >&5 +echo "configure:2179: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < +# ifdef _MSC_VER +# include +# define alloca _alloca # else -# ifdef _AIX - #pragma alloca +# if HAVE_ALLOCA_H +# include # else -# ifndef alloca /* predefined by HP cc +Olibcalls */ +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); +# endif # endif # endif # endif @@ -2100,7 +2208,7 @@ int main() { char *p = (char *) alloca(1); ; return 0; } EOF -if { (eval echo configure:2104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2212: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -2125,19 +2233,19 @@ if test $ac_cv_func_alloca_works = no; then # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. - ALLOCA=alloca.o + ALLOCA=alloca.${ac_objext} cat >> confdefs.h <<\EOF #define C_ALLOCA 1 EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:2136: checking whether alloca needs Cray hooks" >&5 +echo "configure:2244: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2166: checking for $ac_func" >&5 +echo "configure:2274: 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:2302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2217,7 +2325,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:2221: checking stack direction for C alloca" >&5 +echo "configure:2329: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2225,7 +2333,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -2269,18 +2377,18 @@ for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2273: checking for $ac_hdr" >&5 +echo "configure:2381: 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:2283: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:2391: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -2308,12 +2416,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2312: checking for $ac_func" >&5 +echo "configure:2420: 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:2448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2361,7 +2469,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:2365: checking for working mmap" >&5 +echo "configure:2473: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2369,7 +2477,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -2537,18 +2645,18 @@ unistd.h values.h sys/param.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2541: checking for $ac_hdr" >&5 +echo "configure:2649: 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:2551: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:2659: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -2577,12 +2685,12 @@ done __argz_count __argz_stringify __argz_next do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2581: checking for $ac_func" >&5 +echo "configure:2689: 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:2717: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2634,12 +2742,12 @@ done for ac_func in stpcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2638: checking for $ac_func" >&5 +echo "configure:2746: 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:2774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2696,19 +2804,19 @@ EOF if test $ac_cv_header_locale_h = yes; then echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 -echo "configure:2700: checking for LC_MESSAGES" >&5 +echo "configure:2808: checking for LC_MESSAGES" >&5 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return LC_MESSAGES ; return 0; } EOF -if { (eval echo configure:2712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2820: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* am_cv_val_LC_MESSAGES=yes else @@ -2729,7 +2837,7 @@ EOF fi fi echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 -echo "configure:2733: checking whether NLS is requested" >&5 +echo "configure:2841: checking whether NLS is requested" >&5 # Check whether --enable-nls or --disable-nls was given. if test "${enable_nls+set}" = set; then enableval="$enable_nls" @@ -2749,7 +2857,7 @@ fi EOF echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 -echo "configure:2753: checking whether included gettext is requested" >&5 +echo "configure:2861: checking whether included gettext is requested" >&5 # Check whether --with-included-gettext or --without-included-gettext was given. if test "${with_included_gettext+set}" = set; then withval="$with_included_gettext" @@ -2768,18 +2876,18 @@ fi ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 -echo "configure:2772: checking for libintl.h" >&5 +echo "configure:2880: checking for libintl.h" >&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:2782: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:2890: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -2795,19 +2903,19 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 -echo "configure:2799: checking for gettext in libc" >&5 +echo "configure:2907: checking for gettext in libc" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return (int) gettext ("") ; return 0; } EOF -if { (eval echo configure:2811: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gt_cv_func_gettext_libc=yes else @@ -2823,7 +2931,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 if test "$gt_cv_func_gettext_libc" != "yes"; then echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 -echo "configure:2827: checking for bindtextdomain in -lintl" >&5 +echo "configure:2935: checking for bindtextdomain in -lintl" >&5 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2831,7 +2939,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2858,19 +2966,19 @@ fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 -echo "configure:2862: checking for gettext in libintl" >&5 +echo "configure:2970: checking for gettext in libintl" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+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:2982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gt_cv_func_gettext_libintl=yes else @@ -2898,7 +3006,7 @@ EOF # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2902: checking for $ac_word" >&5 +echo "configure:3010: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2932,12 +3040,12 @@ fi for ac_func in dcgettext do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2936: checking for $ac_func" >&5 +echo "configure:3044: 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:3072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2987,7 +3095,7 @@ done # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2991: checking for $ac_word" >&5 +echo "configure:3099: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2999,7 +3107,7 @@ else ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. ;; *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -3022,7 +3130,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3026: checking for $ac_word" >&5 +echo "configure:3134: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3054,7 +3162,7 @@ else fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* CATOBJEXT=.gmo DATADIRNAME=share @@ -3094,7 +3202,7 @@ fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3098: checking for $ac_word" >&5 +echo "configure:3206: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3128,7 +3236,7 @@ fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3132: checking for $ac_word" >&5 +echo "configure:3240: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3140,7 +3248,7 @@ else ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. ;; *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -3163,7 +3271,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3167: checking for $ac_word" >&5 +echo "configure:3275: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3253,7 +3361,7 @@ fi LINGUAS= else echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 -echo "configure:3257: checking for catalogs to be installed" >&5 +echo "configure:3365: checking for catalogs to be installed" >&5 NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in @@ -3281,18 +3389,18 @@ echo "configure:3257: checking for catalogs to be installed" >&5 if test "$CATOBJEXT" = ".cat"; then ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 -echo "configure:3285: checking for linux/version.h" >&5 +echo "configure:3393: checking for linux/version.h" >&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:3295: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:3403: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -3354,19 +3462,19 @@ fi echo $ac_n "checking for Cygwin32 environment""... $ac_c" 1>&6 -echo "configure:3358: checking for Cygwin32 environment" >&5 +echo "configure:3466: checking for Cygwin32 environment" >&5 if eval "test \"`echo '$''{'am_cv_cygwin32'+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:3478: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* am_cv_cygwin32=yes else @@ -3383,19 +3491,19 @@ echo "$ac_t""$am_cv_cygwin32" 1>&6 CYGWIN32= test "$am_cv_cygwin32" = yes && CYGWIN32=yes echo $ac_n "checking for Mingw32 environment""... $ac_c" 1>&6 -echo "configure:3387: checking for Mingw32 environment" >&5 +echo "configure:3495: checking for Mingw32 environment" >&5 if eval "test \"`echo '$''{'am_cv_mingw32'+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:3507: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* am_cv_mingw32=yes else @@ -3414,7 +3522,7 @@ test "$am_cv_mingw32" = yes && MINGW32=yes echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:3418: checking for executable suffix" >&5 +echo "configure:3526: checking for executable suffix" >&5 if eval "test \"`echo '$''{'am_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3450,14 +3558,14 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3454: checking for $ac_word" >&5 +echo "configure:3562: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -3485,14 +3593,14 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3489: checking for $ac_word" >&5 +echo "configure:3597: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -3517,14 +3625,14 @@ test -n "$LEX" || LEX=""$missing_dir/missing flex"" # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3521: checking for $ac_word" >&5 +echo "configure:3629: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -3550,7 +3658,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:3554: checking for yywrap in -l$ac_lib" >&5 +echo "configure:3662: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3558,7 +3666,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3681: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3592,7 +3700,7 @@ fi fi echo $ac_n "checking lex output file root""... $ac_c" 1>&6 -echo "configure:3596: checking lex output file root" >&5 +echo "configure:3704: checking lex output file root" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3613,7 +3721,7 @@ echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 -echo "configure:3617: checking whether yytext is a pointer" >&5 +echo "configure:3725: checking whether yytext is a pointer" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3625,14 +3733,14 @@ echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS="$LIBS" LIBS="$LIBS $LEXLIB" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_prog_lex_yytext_pointer=yes else @@ -3655,7 +3763,7 @@ fi echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:3659: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:3767: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" @@ -3684,18 +3792,18 @@ for ac_hdr in string.h strings.h stdlib.h unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3688: checking for $ac_hdr" >&5 +echo "configure:3796: 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:3698: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:3806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -3723,12 +3831,12 @@ done for ac_func in sbrk do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3727: checking for $ac_func" >&5 +echo "configure:3835: 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:3863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3780,12 +3888,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:3784: checking for $ac_hdr that defines DIR" >&5 +echo "configure:3892: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -3793,7 +3901,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:3797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3905: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -3818,7 +3926,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:3822: checking for opendir in -ldir" >&5 +echo "configure:3930: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3826,7 +3934,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3859,7 +3967,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:3863: checking for opendir in -lx" >&5 +echo "configure:3971: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3867,7 +3975,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3911,12 +4019,12 @@ EOF esac echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6 -echo "configure:3915: checking whether strstr must be declared" >&5 +echo "configure:4023: checking whether strstr must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3937,7 +4045,7 @@ int main() { char *(*pfn) = (char *(*)) strstr ; return 0; } EOF -if { (eval echo configure:3941: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4049: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_strstr=no else @@ -3959,12 +4067,12 @@ EOF fi echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6 -echo "configure:3963: checking whether free must be declared" >&5 +echo "configure:4071: checking whether free must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3985,7 +4093,7 @@ int main() { char *(*pfn) = (char *(*)) free ; return 0; } EOF -if { (eval echo configure:3989: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4097: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_free=no else @@ -4007,12 +4115,12 @@ EOF fi echo $ac_n "checking whether sbrk must be declared""... $ac_c" 1>&6 -echo "configure:4011: checking whether sbrk must be declared" >&5 +echo "configure:4119: checking whether sbrk must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_sbrk'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -4033,7 +4141,7 @@ int main() { char *(*pfn) = (char *(*)) sbrk ; return 0; } EOF -if { (eval echo configure:4037: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_sbrk=no else @@ -4055,12 +4163,12 @@ EOF fi echo $ac_n "checking whether getenv must be declared""... $ac_c" 1>&6 -echo "configure:4059: checking whether getenv must be declared" >&5 +echo "configure:4167: checking whether getenv must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_getenv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -4081,7 +4189,7 @@ int main() { char *(*pfn) = (char *(*)) getenv ; return 0; } EOF -if { (eval echo configure:4085: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_getenv=no else @@ -4108,6 +4216,7 @@ fi all_targets= EMUL= all_emuls= +all_emul_extras= rm -f tdirs @@ -4141,6 +4250,15 @@ do ;; esac done + + for i in $targ_extra_ofiles; do + case " $all_emul_extras " in + *" ${i} "*) ;; + *) + all_emul_extras="$all_emul_extras ${i}" + ;; + esac + done fi done @@ -4155,11 +4273,14 @@ if test x${all_targets} = xtrue; then else EMULATION_OFILES='$(ALL_EMULATIONS)' fi + EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES)' else EMULATION_OFILES=$all_emuls + EMUL_EXTRA_OFILES=$all_emul_extras fi + if test x${enable_static} = xno; then TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so" else @@ -4257,7 +4378,7 @@ do echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.12.1" + echo "$CONFIG_STATUS generated by autoconf version 2.12.2" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; @@ -4369,6 +4490,7 @@ s%@EMUL@%$EMUL%g /@TDIRS@/r $TDIRS s%@TDIRS@%%g s%@EMULATION_OFILES@%$EMULATION_OFILES%g +s%@EMUL_EXTRA_OFILES@%$EMUL_EXTRA_OFILES%g s%@TESTBFDLIB@%$TESTBFDLIB%g CEOF diff --git a/ld/configure.in b/ld/configure.in index b87943d3c96..290560901df 100644 --- a/ld/configure.in +++ b/ld/configure.in @@ -5,7 +5,7 @@ AC_INIT(ldmain.c) AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(ld, 2.9.1) +AM_INIT_AUTOMAKE(ld, 2.9.4) AM_PROG_LIBTOOL @@ -73,6 +73,7 @@ BFD_NEED_DECLARATION(getenv) all_targets= EMUL= all_emuls= +all_emul_extras= dnl We need to get an arbitrary number of tdir definitions into dnl Makefile. We can't do it using AC_SUBST, because autoconf does @@ -110,6 +111,15 @@ do ;; esac done + + for i in $targ_extra_ofiles; do + case " $all_emul_extras " in + *" ${i} "*) ;; + *) + all_emul_extras="$all_emul_extras ${i}" + ;; + esac + done fi done @@ -127,10 +137,13 @@ if test x${all_targets} = xtrue; then else EMULATION_OFILES='$(ALL_EMULATIONS)' fi + EMUL_EXTRA_OFILES='' else EMULATION_OFILES=$all_emuls + EMUL_EXTRA_OFILES=$all_emul_extras fi AC_SUBST(EMULATION_OFILES) +AC_SUBST(EMUL_EXTRA_OFILES) if test x${enable_static} = xno; then TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so" diff --git a/ld/configure.tgt b/ld/configure.tgt index c9cfea9b327..426641d9ffb 100644 --- a/ld/configure.tgt +++ b/ld/configure.tgt @@ -7,8 +7,10 @@ # following shell variables: # targ_emul name of linker emulation to use # targ_extra_emuls additional linker emulations to provide +# targ_extra_ofiles additional objects needed by the emulation targ_extra_emuls= +targ_extra_ofiles= case "${targ}" in arm-*-pe) targ_emul=armpe ;; @@ -99,7 +101,8 @@ i[3456]86-*-msdos*) targ_emul=i386msdos; targ_extra_emuls=i386aout ;; i[3456]86-*-moss*) targ_emul=i386moss; targ_extra_emuls=i386msdos ;; i[3456]86-*-winnt*) targ_emul=i386pe ;; i[3456]86-*-pe) targ_emul=i386pe ;; -i[3456]86-*-cygwin32*) targ_emul=i386pe ;; +i[3456]86-*-cygwin32*) targ_emul=i386pe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; i[3456]86-*-mingw32*) targ_emul=i386pe ;; # start-sanitize-beos i[3456]86-*-beospe*) targ_emul=i386beos ;; diff --git a/ld/deffile.h b/ld/deffile.h new file mode 100644 index 00000000000..255739db8a9 --- /dev/null +++ b/ld/deffile.h @@ -0,0 +1,111 @@ +/* deffile.h - header for .DEF file parser + Copyright (C) 1998 Free Software Foundation, Inc. + Written by DJ Delorie dj@cygnus.com + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "ansidecl.h" + +/* DEF storage definitions. Note that any ordinal may be zero, and + any pointer may be NULL, if not defined by the DEF file. */ + +typedef struct def_file_section + { + char *name; /* always set */ + char *class; /* may be NULL */ + char flag_read, flag_write, flag_execute, flag_shared; + } +def_file_section; + +typedef struct def_file_export + { + char *name; /* always set */ + char *internal_name; /* always set, may == name */ + int ordinal; /* -1 if not specified */ + char flag_private, flag_constant, flag_noname, flag_data; + } +def_file_export; + +typedef struct def_file_import + { + char *internal_name; /* always set */ + char *module; /* always set */ + char *name; /* may be NULL; either this or ordinal will be set */ + int ordinal; /* may be -1 */ + } +def_file_import; + +typedef struct def_file + { + + /* from the NAME or LIBRARY command */ + char *name; + int is_dll; /* -1 if NAME/LIBRARY not given */ + bfd_vma base_address; /* (bfd_vma)(-1) if unspecified */ + + /* from the DESCRIPTION command */ + char *description; + + /* from the STACK/HEAP command, -1 if unspecified */ + int stack_reserve, stack_commit; + int heap_reserve, heap_commit; + + /* from the SECTION/SEGMENT commands */ + int num_section_defs; + def_file_section *section_defs; + + /* from the EXPORTS commands */ + int num_exports; + def_file_export *exports; + + /* from the IMPORTS commands */ + int num_imports; + def_file_import *imports; + + /* from the VERSION command, -1 if not specified */ + int version_major, version_minor; + } +def_file; + +extern def_file *def_file_empty PARAMS ((void)); + +/* add_to may be NULL. If not, this .def is appended to it */ +extern def_file *def_file_parse PARAMS ((const char *_filename, + def_file * _add_to)); + +extern void def_file_free PARAMS ((def_file * _def)); + +extern def_file_export *def_file_add_export PARAMS ((def_file * _def, + const char *_name, + const char *_internal_name, + int _ordinal)); + +extern def_file_import *def_file_add_import PARAMS ((def_file * _def, + const char *_name, + const char *_from, + int _ordinal, + const char *_imported_name)); + +extern int def_file_add_directive PARAMS ((def_file * _def, + const char *param, + int len)); + +#ifdef DEF_FILE_PRINT +extern void def_file_print PARAMS ((FILE * _file, + def_file * _def)); +#endif diff --git a/ld/deffilep.y b/ld/deffilep.y new file mode 100644 index 00000000000..c0f350b3574 --- /dev/null +++ b/ld/deffilep.y @@ -0,0 +1,978 @@ +%{ /* deffilep.y - parser for .def files */ + +/* Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include +#include +#include "libiberty.h" +#include "bfd.h" +#include "ld.h" +#include "deffile.h" + +#define TRACE 0 + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in ld. Note that these are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +#define yymaxdepth def_maxdepth +#define yyparse def_parse +#define yylex def_lex +#define yyerror def_error +#define yylval def_lval +#define yychar def_char +#define yydebug def_debug +#define yypact def_pact +#define yyr1 def_r1 +#define yyr2 def_r2 +#define yydef def_def +#define yychk def_chk +#define yypgo def_pgo +#define yyact def_act +#define yyexca def_exca +#define yyerrflag def_errflag +#define yynerrs def_nerrs +#define yyps def_ps +#define yypv def_pv +#define yys def_s +#define yy_yys def_yys +#define yystate def_state +#define yytmp def_tmp +#define yyv def_v +#define yy_yyv def_yyv +#define yyval def_val +#define yylloc def_lloc +#define yyreds def_reds /* With YYDEBUG defined */ +#define yytoks def_toks /* With YYDEBUG defined */ +#define yylhs def_yylhs +#define yylen def_yylen +#define yydefred def_yydefred +#define yydgoto def_yydgoto +#define yysindex def_yysindex +#define yyrindex def_yyrindex +#define yygindex def_yygindex +#define yytable def_yytable +#define yycheck def_yycheck + +static int def_lex (); + +static void def_description PARAMS ((const char *)); +static void def_exports PARAMS ((const char *, const char *, int, int)); +static void def_heapsize PARAMS ((int, int)); +static void def_import + PARAMS ((const char *, const char *, const char *, const char *, int)); +static void def_library PARAMS ((const char *, int)); +static void def_name PARAMS ((const char *, int)); +static void def_section PARAMS ((const char *, int)); +static void def_section_alt PARAMS ((const char *, const char *)); +static void def_stacksize PARAMS ((int, int)); +static void def_version PARAMS ((int, int)); +static void def_directive PARAMS ((char *)); +static int def_parse PARAMS ((void)); +static int def_error PARAMS ((const char *)); +static int def_debug; +static int def_lex PARAMS ((void)); + +static int lex_forced_token = 0; +static const char *lex_parse_string = 0; +static const char *lex_parse_string_end = 0; + +%} + +%union { + char *id; + int number; +}; + +%token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA +%token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT, PRIVATE +%token READ WRITE EXECUTE SHARED NONAME DIRECTIVE +%token ID +%token NUMBER +%type opt_base opt_ordinal +%type attr attr_list opt_number exp_opt_list exp_opt +%type opt_name opt_equal_name + +%% + +start: start command + | command + ; + +command: + NAME opt_name opt_base { def_name ($2, $3); } + | LIBRARY opt_name opt_base { def_library ($2, $3); } + | DESCRIPTION ID { def_description ($2);} + | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);} + | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);} + | CODE attr_list { def_section ("CODE", $2);} + | DATA attr_list { def_section ("DATA", $2);} + | SECTIONS seclist + | EXPORTS explist + | IMPORTS implist + | VERSIONK NUMBER { def_version ($2, 0);} + | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);} + | DIRECTIVE ID { def_directive ($2);} + ; + + +explist: + /* EMPTY */ + | expline + | explist expline + ; + +expline: + ID opt_equal_name opt_ordinal exp_opt_list + { def_exports ($1, $2, $3, $4); } + ; +exp_opt_list: + exp_opt exp_opt_list { $$ = $1 | $2; } + | { $$ = 0; } + ; +exp_opt: + NONAME { $$ = 1; } + | CONSTANT { $$ = 2; } + | DATA { $$ = 4; } + | PRIVATE { $$ = 8; } + ; +implist: + implist impline + | impline + ; + +impline: + ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); } + | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); } + | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); } + | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); } + | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); } + | ID '.' ID { def_import ( 0, $1, 0, $3, -1); } +; + +seclist: + seclist secline + | secline + ; + +secline: + ID attr_list { def_section ($1, $2);} + | ID ID { def_section_alt ($1, $2);} + ; + +attr_list: + attr_list opt_comma attr { $$ = $1 | $3; } + | attr { $$ = $1; } + ; + +opt_comma: + ',' + | + ; +opt_number: ',' NUMBER { $$=$2;} + | { $$=-1;} + ; + +attr: + READ { $$ = 1;} + | WRITE { $$ = 2;} + | EXECUTE { $$=4;} + | SHARED { $$=8;} + ; + +opt_name: ID { $$ = $1; } + | { $$ = 0; } + ; + +opt_ordinal: + '@' NUMBER { $$ = $2;} + | { $$ = -1;} + ; + +opt_equal_name: + '=' ID { $$ = $2; } + | { $$ = 0; } + ; + +opt_base: BASE '=' NUMBER { $$ = $3;} + | { $$ = 0;} + ; + + + +%% + +/***************************************************************************** + API + *****************************************************************************/ + +static FILE *the_file; +static const char *def_filename; +static int linenumber; +static def_file *def; +static int max_exports, max_imports, max_sections; +static int saw_newline; + +struct directive + { + struct directive *next; + char *name; + int len; + }; + +static struct directive *directives = 0; + +def_file * +def_file_empty () +{ + def_file *rv = (def_file *) xmalloc (sizeof (def_file)); + memset (rv, 0, sizeof (def_file)); + max_exports = max_imports = max_sections = 0; + rv->is_dll = -1; + rv->base_address = (bfd_vma) (-1); + rv->stack_reserve = rv->stack_commit = -1; + rv->heap_reserve = rv->heap_commit = -1; + rv->version_major = rv->version_minor = -1; + return rv; +} + +def_file * +def_file_parse (filename, add_to) + const char *filename; + def_file *add_to; +{ + struct directive *d; + + the_file = fopen (filename, "r"); + def_filename = filename; + linenumber = 1; + if (!the_file) + { + perror (filename); + return 0; + } + if (add_to) + { + def = add_to; + max_exports = def->num_exports; + max_imports = def->num_imports; + max_sections = def->num_section_defs; + } + else + { + def = def_file_empty (); + } + + saw_newline = 1; + if (def_parse ()) + { + def_file_free (def); + fclose (the_file); + return 0; + } + + fclose (the_file); + + for (d = directives; d; d = d->next) + { +#if TRACE + printf ("Adding directive `%s'\n", d->name); +#endif + def_file_add_directive (def, d->name, d->len); + } + + return def; +} + +void +def_file_free (def) + def_file *def; +{ + int i; + if (!def) + return; + if (def->name) + free (def->name); + if (def->description) + free (def->description); + + if (def->section_defs) + { + for (i = 0; i < def->num_section_defs; i++) + { + if (def->section_defs[i].name) + free (def->section_defs[i].name); + if (def->section_defs[i].class) + free (def->section_defs[i].class); + } + free (def->section_defs); + } + + if (def->exports) + { + for (i = 0; i < def->num_exports; i++) + { + if (def->exports[i].internal_name + && def->exports[i].internal_name != def->exports[i].name) + free (def->exports[i].internal_name); + if (def->exports[i].name) + free (def->exports[i].name); + } + free (def->exports); + } + + if (def->imports) + { + for (i = 0; i < def->num_imports; i++) + { + if (def->imports[i].internal_name + && def->imports[i].internal_name != def->imports[i].name) + free (def->imports[i].internal_name); + if (def->imports[i].name) + free (def->imports[i].name); + if (def->imports[i].module) + free (def->imports[i].module); + } + free (def->imports); + } + + free (def); +} + +#ifdef DEF_FILE_PRINT +void +def_file_print (file, def) + FILE *file; + def_file *def; +{ + int i; + fprintf (file, ">>>> def_file at 0x%08x\n", def); + if (def->name) + fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)"); + if (def->is_dll != -1) + fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no"); + if (def->base_address != (bfd_vma) (-1)) + fprintf (file, " base address: 0x%08x\n", def->base_address); + if (def->description) + fprintf (file, " description: `%s'\n", def->description); + if (def->stack_reserve != -1) + fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve); + if (def->stack_commit != -1) + fprintf (file, " stack commit: 0x%08x\n", def->stack_commit); + if (def->heap_reserve != -1) + fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve); + if (def->heap_commit != -1) + fprintf (file, " heap commit: 0x%08x\n", def->heap_commit); + + if (def->num_section_defs > 0) + { + fprintf (file, " section defs:\n"); + for (i = 0; i < def->num_section_defs; i++) + { + fprintf (file, " name: `%s', class: `%s', flags:", + def->section_defs[i].name, def->section_defs[i].class); + if (def->section_defs[i].flag_read) + fprintf (file, " R"); + if (def->section_defs[i].flag_write) + fprintf (file, " W"); + if (def->section_defs[i].flag_execute) + fprintf (file, " X"); + if (def->section_defs[i].flag_shared) + fprintf (file, " S"); + fprintf (file, "\n"); + } + } + + if (def->num_exports > 0) + { + fprintf (file, " exports:\n"); + for (i = 0; i < def->num_exports; i++) + { + fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:", + def->exports[i].name, def->exports[i].internal_name, + def->exports[i].ordinal); + if (def->exports[i].flag_private) + fprintf (file, " P"); + if (def->exports[i].flag_constant) + fprintf (file, " C"); + if (def->exports[i].flag_noname) + fprintf (file, " N"); + if (def->exports[i].flag_data) + fprintf (file, " D"); + fprintf (file, "\n"); + } + } + + if (def->num_imports > 0) + { + fprintf (file, " imports:\n"); + for (i = 0; i < def->num_imports; i++) + { + fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n", + def->imports[i].internal_name, + def->imports[i].module, + def->imports[i].name, + def->imports[i].ordinal); + } + } + if (def->version_major != -1) + fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor); + fprintf (file, "<<<< def_file at 0x%08x\n", def); +} +#endif + +def_file_export * +def_file_add_export (def, external_name, internal_name, ordinal) + def_file *def; + const char *external_name; + const char *internal_name; + int ordinal; +{ + def_file_export *e; + if (def->num_exports >= max_exports) + { + max_exports = def->num_exports + 50; + if (def->exports) + def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export)); + else + def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export)); + } + e = def->exports + def->num_exports; + memset (e, 0, sizeof (def_file_export)); + if (internal_name && !external_name) + external_name = internal_name; + if (external_name && !internal_name) + internal_name = external_name; + e->name = xstrdup (external_name); + e->internal_name = xstrdup (internal_name); + e->ordinal = ordinal; + def->num_exports++; + return e; +} + +def_file_import * +def_file_add_import (def, name, module, ordinal, internal_name) + def_file *def; + const char *name; + const char *module; + int ordinal; + const char *internal_name; +{ + def_file_import *i; + if (def->num_imports >= max_imports) + { + max_imports = def->num_imports + 50; + if (def->imports) + def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import)); + else + def->imports = (def_file_import *) xmalloc (max_imports * sizeof (def_file_import)); + } + i = def->imports + def->num_imports; + memset (i, 0, sizeof (def_file_import)); + if (name) + i->name = xstrdup (name); + if (module) + i->module = xstrdup (module); + i->ordinal = ordinal; + if (internal_name) + i->internal_name = xstrdup (internal_name); + else + i->internal_name = i->name; + def->num_imports++; + return i; +} + +struct +{ + char *param; + int token; +} +diropts[] = +{ + { "-heap", HEAPSIZE }, + { "-stack", STACKSIZE }, + { "-attr", SECTIONS }, + { "-export", EXPORTS }, + { 0, 0 } +}; + +int +def_file_add_directive (my_def, param, len) + def_file *my_def; + const char *param; + int len; +{ + def_file *save_def = def; + const char *pend = param + len; + const char *tend = param; + unsigned int sh_reserve, sh_commit; + int i, j; + + def = my_def; + + while (param < pend) + { + while (param < pend && isspace (*param)) + param++; + for (tend = param + 1; + tend < pend && !(isspace (tend[-1]) && *tend == '-'); + tend++); + + for (i = 0; diropts[i].param; i++) + { + int len = strlen (diropts[i].param); + if (tend - param >= len + && strncmp (param, diropts[i].param, len) == 0 + && (param[len] == ':' || param[len] == ' ')) + { + lex_parse_string_end = tend; + lex_parse_string = param + len + 1; + lex_forced_token = diropts[i].token; + saw_newline = 0; + def_parse (); + break; + } + } + + if (!diropts[i].param) + { + /* xgettext:c-format */ + einfo (_("Warning: .drectve `%.*s' unrecognized\n"), + tend - param, param); + } + lex_parse_string = 0; + param = tend; + } + + def = save_def; +} + +/***************************************************************************** + Parser Callbacks + *****************************************************************************/ + +static void +def_name (name, base) + const char *name; + int base; +{ + if (def->name) + free (def->name); + def->name = xstrdup (name); + def->base_address = base; + def->is_dll = 0; +} + +static void +def_library (name, base) + const char *name; + int base; +{ + if (def->name) + free (def->name); + def->name = xstrdup (name); + def->base_address = base; + def->is_dll = 1; +} + +static void +def_description (text) + const char *text; +{ + int len = def->description ? strlen (def->description) : 0; + len += strlen (text) + 1; + if (def->description) + { + def->description = (char *) xrealloc (def->description, len); + strcat (def->description, text); + } + else + { + def->description = (char *) xmalloc (len); + strcpy (def->description, text); + } +} + +static void +def_stacksize (reserve, commit) + int reserve; + int commit; +{ + def->stack_reserve = reserve; + def->stack_commit = commit; +} + +static void +def_heapsize (reserve, commit) + int reserve; + int commit; +{ + def->heap_reserve = reserve; + def->heap_commit = commit; +} + +static void +def_section (name, attr) + const char *name; + int attr; +{ + def_file_section *s; + if (def->num_section_defs >= max_sections) + { + max_sections = def->num_section_defs + 50; + if (def->section_defs) + def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import)); + else + def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import)); + } + s = def->section_defs + def->num_section_defs; + memset (s, 0, sizeof (def_file_section)); + s->name = xstrdup (name); + if (attr & 1) + s->flag_read = 1; + if (attr & 2) + s->flag_write = 1; + if (attr & 4) + s->flag_execute = 1; + if (attr & 8) + s->flag_shared = 1; + + def->num_section_defs++; +} + +static void +def_section_alt (name, attr) + const char *name; + const char *attr; +{ + int aval = 0; + for (; *attr; attr++) + { + switch (*attr) + { + case 'R': + case 'r': + aval |= 1; + break; + case 'W': + case 'w': + aval |= 2; + break; + case 'X': + case 'x': + aval |= 4; + break; + case 'S': + case 's': + aval |= 8; + break; + } + } + def_section (name, aval); +} + +static void +def_exports (external_name, internal_name, ordinal, flags) + const char *external_name; + const char *internal_name; + int ordinal; + int flags; +{ + def_file_export *dfe; + + if (!internal_name && external_name) + internal_name = external_name; +#if TRACE + printf ("def_exports, ext=%s int=%s\n", external_name, internal_name); +#endif + + dfe = def_file_add_export (def, external_name, internal_name, ordinal); + if (flags & 1) + dfe->flag_noname = 1; + if (flags & 2) + dfe->flag_constant = 1; + if (flags & 4) + dfe->flag_data = 1; + if (flags & 8) + dfe->flag_private = 1; +} + +static void +def_import (internal_name, module, dllext, name, ordinal) + const char *internal_name; + const char *module; + const char *dllext; + const char *name; + int ordinal; +{ + char *buf = 0; + + if (dllext != NULL) + { + buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2); + sprintf (buf, "%s.%s", module, dllext); + module = buf; + } + + def_file_add_import (def, name, module, ordinal, internal_name); + if (buf) + free (buf); +} + +static void +def_version (major, minor) + int major; + int minor; +{ + def->version_major = major; + def->version_minor = minor; +} + +static void +def_directive (str) + char *str; +{ + struct directive *d = (struct directive *) xmalloc (sizeof (struct directive)); + d->next = directives; + directives = d; + d->name = xstrdup (str); + d->len = strlen (str); +} + +static int +def_error (err) + const char *err; +{ + einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err); + + return 0; +} + + +/***************************************************************************** + Lexical Scanner + *****************************************************************************/ + +#undef TRACE +#define TRACE 0 + +/* Never freed, but always reused as needed, so no real leak */ +static char *buffer = 0; +static int buflen = 0; +static int bufptr = 0; + +static void +put_buf (c) + char c; +{ + if (bufptr == buflen) + { + buflen += 50; /* overly reasonable, eh? */ + if (buffer) + buffer = (char *) xrealloc (buffer, buflen + 1); + else + buffer = (char *) xmalloc (buflen + 1); + } + buffer[bufptr++] = c; + buffer[bufptr] = 0; /* not optimal, but very convenient */ +} + +static struct +{ + char *name; + int token; +} +tokens[] = +{ + { "BASE", BASE }, + { "CODE", CODE }, + { "CONSTANT", CONSTANT }, + { "DATA", DATA }, + { "DESCRIPTION", DESCRIPTION }, + { "DIRECTIVE", DIRECTIVE }, + { "EXECUTE", EXECUTE }, + { "EXPORTS", EXPORTS }, + { "HEAPSIZE", HEAPSIZE }, + { "IMPORTS", IMPORTS }, + { "LIBRARY", LIBRARY }, + { "NAME", NAME }, + { "NONAME", NONAME }, + { "PRIVATE", PRIVATE }, + { "READ", READ }, + { "SECTIONS", SECTIONS }, + { "SEGMENTS", SECTIONS }, + { "SHARED", SHARED }, + { "STACKSIZE", STACKSIZE }, + { "VERSION", VERSIONK }, + { "WRITE", WRITE }, + { 0, 0 } +}; + +static int +def_getc () +{ + int rv; + if (lex_parse_string) + { + if (lex_parse_string >= lex_parse_string_end) + rv = EOF; + else + rv = *lex_parse_string++; + } + else + { + rv = fgetc (the_file); + } + if (rv == '\n') + saw_newline = 1; + return rv; +} + +static int +def_ungetc (c) + int c; +{ + if (lex_parse_string) + lex_parse_string--; + else + return ungetc (c, the_file); +} + +static int +def_lex () +{ + int c, i, q; + + if (lex_forced_token) + { + i = lex_forced_token; + lex_forced_token = 0; +#if TRACE + printf ("lex: forcing token %d\n", i); +#endif + return i; + } + + c = def_getc (); + + /* trim leading whitespace */ + while (c != EOF && (c == ' ' || c == '\t') && saw_newline) + c = def_getc (); + + if (c == EOF) + { +#if TRACE + printf ("lex: EOF\n"); +#endif + return 0; + } + + if (saw_newline && c == ';') + { + do + { + c = def_getc (); + } + while (c != EOF && c != '\n'); + if (c == '\n') + return def_lex (); + return 0; + } + /* must be something else */ + saw_newline = 0; + + if (isdigit (c)) + { + bufptr = 0; + while (c != EOF && isxdigit (c) || (c == 'x')) + { + put_buf (c); + c = def_getc (); + } + if (c != EOF) + def_ungetc (c); + yylval.number = strtoul (buffer, 0, 0); +#if TRACE + printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number); +#endif + return NUMBER; + } + + if (isalpha (c) || strchr ("$:-_?", c)) + { + bufptr = 0; + while (c != EOF && isalnum (c) || strchr ("$:-_?/@", c)) + { + put_buf (c); + c = def_getc (); + } + if (c != EOF) + def_ungetc (c); + for (i = 0; tokens[i].name; i++) + if (strcmp (tokens[i].name, buffer) == 0) + { +#if TRACE + printf ("lex: `%s' is a string token\n", buffer); +#endif + return tokens[i].token; + } +#if TRACE + printf ("lex: `%s' returns ID\n", buffer); +#endif + yylval.id = xstrdup (buffer); + return ID; + } + + if (c == '\'' || c == '"') + { + q = c; + c = def_getc (); + bufptr = 0; + while (c != EOF && c != q) + { + put_buf (c); + c = def_getc (); + } + yylval.id = xstrdup (buffer); +#if TRACE + printf ("lex: `%s' returns ID\n", buffer); +#endif + return ID; + } + + if (c == '=' || c == '.' || c == '@' || c == ',') + { +#if TRACE + printf ("lex: `%c' returns itself\n", c); +#endif + return c; + } + + if (c == '\n') + { + linenumber++; + saw_newline = 1; + } + + /*printf ("lex: 0x%02x ignored\n", c); */ + return def_lex (); +} diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index f4092a690b6..029db8a75c2 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -42,6 +42,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ldfile.h" #include "coff/internal.h" #include "../bfd/libcoff.h" +#include "deffile.h" #define TARGET_IS_${EMULATION_NAME} @@ -60,6 +61,14 @@ static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **)); static struct internal_extra_pe_aouthdr pe; static int dll; static int support_old_code = 0; +def_file *pe_def_file = 0; +static lang_assignment_statement_type *image_base_statement = 0; + +static char *pe_out_def_filename = 0; +int pe_dll_export_everything = 0; +int pe_dll_do_default_excludes = 1; +int pe_dll_kill_ats = 0; +int pe_dll_stdcall_aliases = 0; extern const char *output_filename; @@ -68,6 +77,9 @@ gld_${EMULATION_NAME}_before_parse() { output_filename = "a.exe"; ldfile_output_architecture = bfd_arch_${ARCH}; +#ifdef TARGET_IS_i386pe + config.has_shared = 1; +#endif } /* PE format extra command line options. */ @@ -88,6 +100,11 @@ gld_${EMULATION_NAME}_before_parse() #define OPTION_SUBSYSTEM (OPTION_STACK + 1) #define OPTION_HEAP (OPTION_SUBSYSTEM + 1) #define OPTION_SUPPORT_OLD_CODE (OPTION_HEAP + 1) +#define OPTION_OUT_DEF (OPTION_SUPPORT_OLD_CODE + 1) +#define OPTION_EXPORT_ALL (OPTION_OUT_DEF + 1) +#define OPTION_EXCLUDE_SYMBOLS (OPTION_EXPORT_ALL + 1) +#define OPTION_KILL_ATS (OPTION_EXCLUDE_SYMBOLS + 1) +#define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1) static struct option longopts[] = { @@ -107,6 +124,14 @@ static struct option longopts[] = {"stack", required_argument, NULL, OPTION_STACK}, {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, + /* getopt allows abbreviations, so we do this to stop it from treating -o + as an abbreviation for this option */ + {"output-def", required_argument, NULL, OPTION_OUT_DEF}, + {"output-def", required_argument, NULL, OPTION_OUT_DEF}, + {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL}, + {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS}, + {"kill-at", no_argument, NULL, OPTION_KILL_ATS}, + {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES}, {NULL, no_argument, NULL, 0} }; @@ -366,6 +391,21 @@ gld_${EMULATION_NAME}_parse_args(argc, argv) case OPTION_SUPPORT_OLD_CODE: support_old_code = 1; break; + case OPTION_OUT_DEF: + pe_out_def_filename = xstrdup (optarg); + break; + case OPTION_EXPORT_ALL: + pe_dll_export_everything = 1; + break; + case OPTION_EXCLUDE_SYMBOLS: + pe_dll_add_excludes (optarg); + break; + case OPTION_KILL_ATS: + pe_dll_kill_ats = 1; + break; + case OPTION_STDCALL_ALIASES: + pe_dll_stdcall_aliases = 1; + break; } return 1; } @@ -385,7 +425,7 @@ gld_${EMULATION_NAME}_set_symbols () { if (link_info.relocateable) init[IMAGEBASEOFF].value = 0; - else if (init[DLLOFF].value) + else if (init[DLLOFF].value || link_info.shared) init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE; else init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE; @@ -403,7 +443,8 @@ gld_${EMULATION_NAME}_set_symbols () for (j = 0; init[j].ptr; j++) { long val = init[j].value; - lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val))); + lang_assignment_statement_type *rv; + rv = lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val))); if (init[j].size == sizeof(short)) *(short *)init[j].ptr = val; else if (init[j].size == sizeof(int)) @@ -414,6 +455,8 @@ gld_${EMULATION_NAME}_set_symbols () else if (init[j].size == sizeof(bfd_vma)) *(bfd_vma *)init[j].ptr = val; else abort(); + if (j == IMAGEBASEOFF) + image_base_statement = rv; } /* Restore the pointer. */ stat_ptr = save; @@ -447,6 +490,66 @@ gld_${EMULATION_NAME}_after_parse () ldlang_add_undef (entry_symbol); } +static struct bfd_link_hash_entry *pe_undef_found_sym; + +static boolean +pe_undef_cdecl_match (h, string) + struct bfd_link_hash_entry *h; + PTR string; +{ + int sl = strlen (string); + if (h->type == bfd_link_hash_defined + && strncmp (h->root.string, string, sl) == 0 + && h->root.string[sl] == '@') + { + pe_undef_found_sym = h; + return false; + } + return true; +} + +static void +pe_fixup_stdcalls () +{ + struct bfd_link_hash_entry *undef, *sym; + char *at; + for (undef = link_info.hash->undefs; undef; undef=undef->next) + if (undef->type == bfd_link_hash_undefined) + { + at = strchr (undef->root.string, '@'); + if (at) + { + /* The symbol is a stdcall symbol, so let's look for a cdecl + symbol with the same name and resolve to that */ + char *cname = xstrdup (undef->root.string); + at = strchr (cname, '@'); + *at = 0; + sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1); + if (sym && sym->type == bfd_link_hash_defined) + { + undef->type = bfd_link_hash_defined; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + } + } + else + { + /* The symbol is a cdecl symbol, so we don't look for stdcall + symbols - you should have included the right header */ + pe_undef_found_sym = 0; + bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match, + (PTR) undef->root.string); + sym = pe_undef_found_sym; + if (sym) + { + undef->type = bfd_link_hash_defined; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + } + } + } +} + static void gld_${EMULATION_NAME}_after_open () { @@ -460,6 +563,13 @@ gld_${EMULATION_NAME}_after_open () pe_data (output_bfd)->pe_opthdr = pe; pe_data (output_bfd)->dll = init[DLLOFF].value; + pe_fixup_stdcalls (); + +#ifdef TARGET_IS_i386pe + if (link_info.shared) + pe_dll_build_sections (output_bfd, &link_info); +#endif + #ifdef TARGET_IS_armpe { /* Find a BFD that can hold the interworking stubs. */ @@ -516,6 +626,91 @@ gld_${EMULATION_NAME}_before_allocation() bfd_arm_allocate_interworking_sections (& link_info); #endif /* TARGET_IS_armpe */ } + + +/* This is called when an input file isn't recognized as a BFD. We + check here for .DEF files and pull them in automatically. */ + +static int +saw_option(char *option) +{ + int i; + for (i=0; init[i].ptr; i++) + if (strcmp (init[i].symbol, option) == 0) + return init[i].inited; + return 0; +} + +static boolean +gld_${EMULATION_NAME}_unrecognized_file(entry) + lang_input_statement_type *entry; +{ +#ifdef TARGET_IS_i386pe + const char *ext = entry->filename + strlen (entry->filename) - 4; + + if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0) + { + if (pe_def_file == 0) + pe_def_file = def_file_empty (); + def_file_parse (entry->filename, pe_def_file); + if (pe_def_file) + { + /* def_file_print (stdout, pe_def_file); */ + if (pe_def_file->is_dll == 1) + link_info.shared = 1; + + if (pe_def_file->base_address != (bfd_vma)(-1)) + { + pe.ImageBase = + pe_data (output_bfd)->pe_opthdr.ImageBase = + init[IMAGEBASEOFF].value = pe_def_file->base_address; + init[IMAGEBASEOFF].inited = 1; + if (image_base_statement) + image_base_statement->exp = + exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase)); + } + +#if 0 + /* Not sure if these *should* be set */ + if (pe_def_file->version_major != -1) + { + pe.MajorImageVersion = pe_def_file->version_major; + pe.MinorImageVersion = pe_def_file->version_minor; + } +#endif + if (pe_def_file->stack_reserve != -1 + && ! saw_option ("__size_of_stack_reserve__")) + { + pe.SizeOfStackReserve = pe_def_file->stack_reserve; + if (pe_def_file->stack_commit != -1) + pe.SizeOfStackCommit = pe_def_file->stack_commit; + } + if (pe_def_file->heap_reserve != -1 + && ! saw_option ("__size_of_heap_reserve__")) + { + pe.SizeOfHeapReserve = pe_def_file->heap_reserve; + if (pe_def_file->heap_commit != -1) + pe.SizeOfHeapCommit = pe_def_file->heap_commit; + } + return true; + } + } +#endif + return false; + +} + +static void +gld_${EMULATION_NAME}_finish () +{ +#ifdef TARGET_IS_i386pe + if (link_info.shared) + pe_dll_fill_sections (output_bfd, &link_info); + if (pe_out_def_filename) + pe_dll_generate_def_file (pe_out_def_filename); +#endif +} + /* Place an orphan section. @@ -712,10 +907,12 @@ gld_${EMULATION_NAME}_place_orphan (file, s) lang_list_init (&list); wild_doit (&list, s, hold_use, file); - ASSERT (list.head != NULL && list.head->next == NULL); - - list.head->next = *pl; - *pl = list.head; + if (list.head != NULL) + { + ASSERT (list.head->next == NULL); + list.head->next = *pl; + *pl = list.head; + } } free (hold_section_name); @@ -793,13 +990,13 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", - NULL, /* finish */ + gld_${EMULATION_NAME}_finish, /* finish */ NULL, /* create output section statements */ NULL, /* open dynamic archive */ gld_${EMULATION_NAME}_place_orphan, gld_${EMULATION_NAME}_set_symbols, gld_${EMULATION_NAME}_parse_args, - NULL, /* unrecognised file */ + gld_${EMULATION_NAME}_unrecognized_file, gld_${EMULATION_NAME}_list_options }; EOF diff --git a/ld/pe-dll.c b/ld/pe-dll.c new file mode 100644 index 00000000000..af6e859914c --- /dev/null +++ b/ld/pe-dll.c @@ -0,0 +1,928 @@ +/* Routines to help build PEI-format DLLs (Win32 etc) + Copyright (C) 1998 Free Software Foundation, Inc. + Written by DJ Delorie + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libiberty.h" + +#include "ld.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldwrite.h" +#include "ldmisc.h" +#include "ldgram.h" +#include "ldmain.h" +#include "coff/internal.h" +#include "../bfd/libcoff.h" +#include "deffile.h" + +/************************************************************************ + + This file turns a regular Windows PE image into a DLL. Because of + the complexity of this operation, it has been broken down into a + number of separate modules which are all called by the main function + at the end of this file. This function is not re-entrant and is + normally only called once, so static variables are used to reduce + the number of parameters and return values required. + + See also: ld/emultempl/pe.em + + ************************************************************************/ + +/* from emultempl/pe.em */ + +extern def_file *pe_def_file; +extern int pe_dll_export_everything; +extern int pe_dll_do_default_excludes; +extern int pe_dll_kill_ats; +extern int pe_dll_stdcall_aliases; + +/************************************************************************ + + static variables and types + + ************************************************************************/ + +static bfd_vma image_base; + +static bfd *filler_bfd; +static struct sec *edata_s, *reloc_s; +static unsigned char *edata_d, *reloc_d; +static int edata_sz, reloc_sz; + +/************************************************************************ + + Helper functions for qsort. Relocs must be sorted so that we can write + them out by pages. + + ************************************************************************/ + +static int +reloc_sort (va, vb) + const void *va, *vb; +{ + unsigned long a = *(unsigned long *) va; + unsigned long b = *(unsigned long *) vb; + return a - b; +} + +static int +pe_export_sort (va, vb) + const void *va, *vb; +{ + def_file_export *a = (def_file_export *) va; + def_file_export *b = (def_file_export *) vb; + return strcmp (a->name, b->name); +} + +/************************************************************************ + + Read and process the .DEF file + + ************************************************************************/ + +/* These correspond to the entries in pe_def_file->exports[]. I use + exported_symbol_sections[i] to tag whether or not the symbol was + defined, since we can't export symbols we don't have. */ + +static bfd_vma *exported_symbol_offsets; +static struct sec **exported_symbol_sections; + +static int export_table_size; +static int count_exported; +static int count_exported_byname; +static int count_with_ordinals; +static const char *dll_name; +static int min_ordinal, max_ordinal; +static int *exported_symbols; + +typedef struct exclude_list_struct + { + char *string; + struct exclude_list_struct *next; + } +exclude_list_struct; +static struct exclude_list_struct *excludes = 0; + +void +pe_dll_add_excludes (new_excludes) + const char *new_excludes; +{ + char *local_copy; + char *exclude_string; + + local_copy = xstrdup (new_excludes); + + exclude_string = strtok (local_copy, ",:"); + for (; exclude_string; exclude_string = strtok (NULL, ",:")) + { + struct exclude_list_struct *new_exclude; + + new_exclude = ((struct exclude_list_struct *) + xmalloc (sizeof (struct exclude_list_struct))); + new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 1); + strcpy (new_exclude->string, exclude_string); + new_exclude->next = excludes; + excludes = new_exclude; + } + + free (local_copy); +} + +static int +auto_export (d, n) + def_file *d; + const char *n; +{ + int i; + struct exclude_list_struct *ex; + for (i = 0; i < d->num_exports; i++) + if (strcmp (d->exports[i].name, n) == 0) + return 0; + if (pe_dll_do_default_excludes) + { + if (strcmp (n, "DllMain@12") == 0) + return 0; + if (strcmp (n, "DllEntryPoint@0") == 0) + return 0; + if (strcmp (n, "impure_ptr") == 0) + return 0; + } + for (ex = excludes; ex; ex = ex->next) + if (strcmp (n, ex->string) == 0) + return 0; + return 1; +} + +static void +process_def_file (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + int i, j; + struct bfd_link_hash_entry *blhe; + bfd *b; + struct sec *s; + def_file_export *e; + + if (!pe_def_file) + pe_def_file = def_file_empty (); + + /* First, run around to all the objects looking for the .drectve + sections, and push those into the def file too */ + + for (b = info->input_bfds; b; b = b->link_next) + { + s = bfd_get_section_by_name (b, ".drectve"); + if (s) + { + int size = bfd_get_section_size_before_reloc (s); + char *buf = xmalloc (size); + bfd_get_section_contents (b, s, buf, 0, size); + def_file_add_directive (pe_def_file, buf, size); + free (buf); + } + } + + /* Now, maybe export everything else the default way */ + + if (pe_dll_export_everything) + { + for (b = info->input_bfds; b; b = b->link_next) + { + asymbol **symbols; + int nsyms, symsize; + + symsize = bfd_get_symtab_upper_bound (b); + symbols = (asymbol **) xmalloc (symsize); + nsyms = bfd_canonicalize_symtab (b, symbols); + + for (j = 0; j < nsyms; j++) + { + if ((symbols[j]->flags & (BSF_FUNCTION | BSF_GLOBAL)) + == (BSF_FUNCTION | BSF_GLOBAL)) + { + const char *sn = symbols[j]->name; + if (*sn == '_') + sn++; + if (auto_export (pe_def_file, sn)) + def_file_add_export (pe_def_file, sn, 0, -1); + } + } + } + } + +#undef NE +#define NE pe_def_file->num_exports + e = pe_def_file->exports; /* convenience */ + + /* Canonicalize the export list */ + + if (pe_dll_kill_ats) + { + for (i = 0; i < NE; i++) + { + if (strchr (e[i].name, '@')) + { + /* This will preserve internal_name, which may have been pointing + to the same memory as name, or might not have */ + char *tmp = xstrdup (e[i].name); + *(strchr (tmp, '@')) = 0; + e[i].name = tmp; + } + } + } + + if (pe_dll_stdcall_aliases) + { + for (i = 0; i < NE; i++) + { + if (strchr (e[i].name, '@')) + { + char *tmp = xstrdup (e[i].name); + *(strchr (tmp, '@')) = 0; + if (auto_export (pe_def_file, tmp)) + def_file_add_export (pe_def_file, tmp, e[i].internal_name, -1); + else + free (tmp); + } + } + } + + exported_symbol_offsets = (bfd_vma *) xmalloc (NE * sizeof (bfd_vma)); + exported_symbol_sections = (struct sec **) xmalloc (NE * sizeof (struct sec *)); + + memset (exported_symbol_sections, 0, NE * sizeof (struct sec *)); + max_ordinal = 0; + min_ordinal = 65536; + count_exported = 0; + count_exported_byname = 0; + count_with_ordinals = 0; + + qsort (pe_def_file->exports, NE, sizeof (pe_def_file->exports[0]), pe_export_sort); + for (i = 0, j = 0; i < NE; i++) + { + if (i > 0 && strcmp (e[i].name, e[i - 1].name) == 0) + { + /* This is a duplicate */ + if (e[j - 1].ordinal != -1 + && e[i].ordinal != -1 + && e[j - 1].ordinal != e[i].ordinal) + { + /* xgettext:c-format */ + einfo (_("%XError, duplicate EXPORT with oridinals: %s (%d vs %d)\n"), + e[j - 1].name, e[j - 1].ordinal, e[i].ordinal); + } + else + { + /* xgettext:c-format */ + einfo (_("Warning, duplicate EXPORT: %s\n"), + e[j - 1].name); + } + if (e[i].ordinal) + e[j - 1].ordinal = e[i].ordinal; + e[j - 1].flag_private |= e[i].flag_private; + e[j - 1].flag_constant |= e[i].flag_constant; + e[j - 1].flag_noname |= e[i].flag_noname; + e[j - 1].flag_data |= e[i].flag_data; + } + else + { + if (i != j) + e[j] = e[i]; + j++; + } + } + pe_def_file->num_exports = j; /* == NE */ + + for (i = 0; i < NE; i++) + { + char *name = (char *) xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2); + *name = '_'; + strcpy (name + 1, pe_def_file->exports[i].internal_name); + + blhe = bfd_link_hash_lookup (info->hash, + name, + false, false, true); + + if (blhe && (blhe->type == bfd_link_hash_defined)) + { + count_exported++; + if (!pe_def_file->exports[i].flag_noname) + count_exported_byname++; + exported_symbol_offsets[i] = blhe->u.def.value; + exported_symbol_sections[i] = blhe->u.def.section; + if (pe_def_file->exports[i].ordinal != -1) + { + if (max_ordinal < pe_def_file->exports[i].ordinal) + max_ordinal = pe_def_file->exports[i].ordinal; + if (min_ordinal > pe_def_file->exports[i].ordinal) + min_ordinal = pe_def_file->exports[i].ordinal; + count_with_ordinals++; + } + } + else if (blhe) + { + /* xgettext:c-format */ + einfo (_("%XCannot export %s: symbol wrong type\n"), + pe_def_file->exports[i].internal_name); + } + else + { + /* xgettext:c-format */ + einfo (_("%XCannot export %s: symbol not found\n"), + pe_def_file->exports[i].internal_name); + } + free(name); + } + +#if 0 + /* For now, just export all global functions. Read DEF files later */ + for (i = 0; i < num_input_bfds; i++) + { + for (j = 0; j < symtab[i].nsyms; j++) + { + if ((symtab[i].symbols[j]->flags & (BSF_FUNCTION | BSF_GLOBAL)) + == (BSF_FUNCTION | BSF_GLOBAL)) + symtab[i].exported[j] = 1; + } + } +#endif +} + +/************************************************************************ + + Build the bfd that will contain .edata and .reloc sections + + ************************************************************************/ + +static void +build_filler_bfd () +{ + static lang_input_statement_type *filler_file; + filler_file = lang_add_input_file ("dll stuff", + lang_input_file_is_fake_enum, + NULL); + filler_file->the_bfd = filler_bfd = bfd_create ("dll stuff", output_bfd); + if (filler_bfd == NULL + || !bfd_set_arch_mach (filler_bfd, + bfd_get_arch (output_bfd), + bfd_get_mach (output_bfd))) + { + einfo ("%X%P: can not create BFD %E\n"); + return; + } + + edata_s = bfd_make_section_old_way (filler_bfd, ".edata"); + if (edata_s == NULL + || !bfd_set_section_flags (filler_bfd, edata_s, + (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD + | SEC_KEEP + | SEC_IN_MEMORY))) + { + einfo ("%X%P: can not create .edata section: %E\n"); + return; + } + bfd_set_section_size (filler_bfd, edata_s, edata_sz); + + reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc"); + if (reloc_s == NULL + || !bfd_set_section_flags (filler_bfd, reloc_s, + (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD + | SEC_KEEP + | SEC_IN_MEMORY))) + { + einfo ("%X%P: can not create .reloc section: %E\n"); + return; + } + bfd_set_section_size (filler_bfd, reloc_s, 0); + + ldlang_add_file (filler_file); +} + +/************************************************************************ + + Gather all the exported symbols and build the .edata section + + ************************************************************************/ + +static void +generate_edata (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + int i, j, next_ordinal; + int name_table_size = 0; + const char *dlnp; + + /* First, we need to know how many exported symbols there are, + and what the range of ordinals is. */ + + if (pe_def_file->name) + { + dll_name = pe_def_file->name; + } + else + { + dll_name = abfd->filename; + for (dlnp = dll_name; *dlnp; dlnp++) + { + if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':') + dll_name = dlnp + 1; + } + } + + if (count_with_ordinals && max_ordinal > count_exported) + { + if (min_ordinal > max_ordinal - count_exported + 1) + min_ordinal = max_ordinal - count_exported + 1; + } + else + { + min_ordinal = 1; + max_ordinal = count_exported; + } + export_table_size = max_ordinal - min_ordinal + 1; + + exported_symbols = (int *) xmalloc (export_table_size * sizeof (int)); + for (i = 0; i < export_table_size; i++) + exported_symbols[i] = -1; + + /* Now we need to assign ordinals to those that don't have them */ + for (i = 0; i < NE; i++) + { + if (exported_symbol_sections[i]) + { + if (pe_def_file->exports[i].ordinal != -1) + { + int ei = pe_def_file->exports[i].ordinal - min_ordinal; + int pi = exported_symbols[ei]; + if (pi != -1) + { + /* xgettext:c-format */ + einfo (_("%XError, oridinal used twice: %d (%s vs %s)\n"), + pe_def_file->exports[i].ordinal, + pe_def_file->exports[i].name, + pe_def_file->exports[pi].name); + } + exported_symbols[ei] = i; + } + name_table_size += strlen (pe_def_file->exports[i].name) + 1; + } + } + + next_ordinal = min_ordinal; + for (i = 0; i < NE; i++) + if (exported_symbol_sections[i]) + if (pe_def_file->exports[i].ordinal == -1) + { + while (exported_symbols[next_ordinal - min_ordinal] != -1) + next_ordinal++; + exported_symbols[next_ordinal - min_ordinal] = i; + pe_def_file->exports[i].ordinal = next_ordinal; + } + + /* OK, now we can allocate some memory */ + + edata_sz = (40 /* directory */ + + 4 * export_table_size /* addresses */ + + 4 * count_exported_byname /* name ptrs */ + + 2 * count_exported_byname /* ordinals */ + + name_table_size + strlen (dll_name) + 1); +} + +static void +fill_edata (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + int i; + unsigned char *edirectory; + unsigned long *eaddresses; + unsigned long *enameptrs; + unsigned short *eordinals; + unsigned char *enamestr; + + edata_d = (unsigned char *) xmalloc (edata_sz); + + /* Note use of array pointer math here */ + edirectory = edata_d; + eaddresses = (unsigned long *) (edata_d + 40); + enameptrs = eaddresses + export_table_size; + eordinals = (unsigned short *) (enameptrs + count_exported_byname); + enamestr = (char *) (eordinals + count_exported_byname); + +#define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) + edata_s->output_section->vma - image_base) + + memset (edata_d, 0, 40); + if (pe_def_file->version_major != -1) + { + bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8); + bfd_put_16 (abfd, pe_def_file->version_minor, edata_d + 10); + } + bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12); + strcpy (enamestr, dll_name); + enamestr += strlen (enamestr) + 1; + bfd_put_32 (abfd, min_ordinal, edata_d + 16); + bfd_put_32 (abfd, export_table_size, edata_d + 20); + bfd_put_32 (abfd, count_exported_byname, edata_d + 24); + bfd_put_32 (abfd, ERVA (eaddresses), edata_d + 28); + bfd_put_32 (abfd, ERVA (enameptrs), edata_d + 32); + bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36); + + /* Ok, now for the filling in part */ + for (i = 0; i < export_table_size; i++) + { + int s = exported_symbols[i]; + if (s != -1) + { + struct sec *ssec = exported_symbol_sections[s]; + unsigned long srva = (exported_symbol_offsets[s] + + ssec->output_section->vma + + ssec->output_offset); + + bfd_put_32 (abfd, srva - image_base, (void *) (eaddresses + i)); + if (!pe_def_file->exports[s].flag_noname) + { + char *ename = pe_def_file->exports[s].name; + bfd_put_32 (abfd, ERVA (enamestr), (void *) enameptrs); + strcpy (enamestr, ename[0] == '_' ? ename + 1 : ename); + enamestr += strlen (enamestr) + 1; + bfd_put_16 (abfd, i, (void *) eordinals); + enameptrs++; + } + eordinals++; + } + } +} + +/************************************************************************ + + Gather all the relocations and build the .reloc section + + ************************************************************************/ + +static void +generate_reloc (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + + /* for .reloc stuff */ + bfd_vma *reloc_addresses; + int total_relocs = 0; + int i, j; + unsigned long sec_page = (unsigned long) (-1); + unsigned long page_ptr, page_count; + int bi; + bfd *b; + struct sec *s; + + total_relocs = 0; + for (b = info->input_bfds; b; b = b->link_next) + for (s = b->sections; s; s = s->next) + total_relocs += s->reloc_count; + + reloc_addresses = (unsigned long *) xmalloc (total_relocs * sizeof (unsigned long)); + + total_relocs = 0; + bi = 0; + for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next) + { + arelent **relocs; + int relsize, nrelocs, i; + + for (s = b->sections; s; s = s->next) + { + unsigned long sec_vma = s->output_section->vma + s->output_offset; + asymbol **symbols; + int nsyms, symsize; + + symsize = bfd_get_symtab_upper_bound (b); + symbols = (asymbol **) xmalloc (symsize); + nsyms = bfd_canonicalize_symtab (b, symbols); + + relsize = bfd_get_reloc_upper_bound (b, s); + relocs = (arelent **) xmalloc ((size_t) relsize); + nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols); + + for (i = 0; i < nrelocs; i++) + { + if (!relocs[i]->howto->pc_relative) + { + switch (relocs[i]->howto->bitsize) + { + case 32: + reloc_addresses[total_relocs++] = sec_vma + relocs[i]->address; + break; + default: + /* xgettext:c-format */ + einfo (_("%XError: %d-bit reloc in dll\n"), + relocs[i]->howto->bitsize); + break; + } + } + } + free (relocs); + /* Warning: the allocated symbols are remembered in BFD and reused + later, so don't free them! */ + /* free(symbols); */ + } + } + + /* At this point, we have total_relocs relocation addresses in + reloc_addresses, which are all suitable for the .reloc section. + We must now create the new sections. */ + + qsort (reloc_addresses, total_relocs, sizeof (unsigned long), reloc_sort); + + for (i = 0; i < total_relocs; i++) + { + unsigned long this_page = (reloc_addresses[i] >> 12); + if (this_page != sec_page) + { + reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */ + reloc_sz += 8; + sec_page = this_page; + } + reloc_sz += 2; + } + reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */ + + reloc_d = (unsigned char *) xmalloc (reloc_sz); + + sec_page = (unsigned long) (-1); + reloc_sz = 0; + page_ptr = (unsigned long) (-1); + page_count = 0; + for (i = 0; i < total_relocs; i++) + { + unsigned long rva = reloc_addresses[i] - image_base; + unsigned long this_page = (rva & ~0xfff); + if (this_page != sec_page) + { + while (reloc_sz & 3) + reloc_d[reloc_sz++] = 0; + if (page_ptr != (unsigned long) (-1)) + bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4); + bfd_put_32 (abfd, this_page, reloc_d + reloc_sz); + page_ptr = reloc_sz; + reloc_sz += 8; + sec_page = this_page; + page_count = 0; + } + bfd_put_16 (abfd, (rva & 0xfff) + 0x3000, reloc_d + reloc_sz); + reloc_sz += 2; + page_count++; + } + while (reloc_sz & 3) + reloc_d[reloc_sz++] = 0; + if (page_ptr != (unsigned long) (-1)) + bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4); + while (reloc_sz < reloc_s->_raw_size) + reloc_d[reloc_sz++] = 0; +} + +/************************************************************************ + + Given the exiting def_file structure, print out a .DEF file that + corresponds to it. + + ************************************************************************/ + +static void +quoteput (s, f, needs_quotes) + char *s; + FILE * f; + int needs_quotes; +{ + char *cp; + for (cp = s; *cp; cp++) + if (*cp == '\'' || *cp == '"' || *cp == '\\' || isspace (*cp) || *cp == ',' + || *cp == ';') + needs_quotes = 1; + if (needs_quotes) + { + putc ('"', f); + while (*s) + { + if (*s == '"' || *s == '\\') + putc ('\\', f); + putc (*s, f); + s++; + } + putc ('"', f); + } + else + fputs (s, f); +} + +void +pe_dll_generate_def_file (pe_out_def_filename) + char *pe_out_def_filename; +{ + int i; + FILE *out = fopen (pe_out_def_filename, "w"); + if (out == NULL) + { + /* xgettext:c-format */ + einfo (_("%s: Can't open output def file %s\n"), + program_name, pe_out_def_filename); + } + + if (pe_def_file->name) + { + if (pe_def_file->is_dll) + fprintf (out, "LIBRARY "); + else + fprintf (out, "NAME "); + quoteput (pe_def_file->name, out, 1); + if (pe_def_file->base_address != (bfd_vma) (-1)) + fprintf (out, " BASE=0x%x", pe_def_file->base_address); + fprintf (out, "\n"); + } + + if (pe_def_file->description) + { + fprintf (out, "DESCRIPTION "); + quoteput (pe_def_file->description, out, 1); + fprintf (out, "\n"); + } + + if (pe_def_file->version_minor) + fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major, + pe_def_file->version_minor); + else + fprintf (out, "VERSION %d\n", pe_def_file->version_major); + + if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1) + fprintf (out, "\n"); + + if (pe_def_file->stack_commit != -1) + fprintf (out, "STACKSIZE 0x%x,0x%x\n", + pe_def_file->stack_reserve, pe_def_file->stack_commit); + else if (pe_def_file->stack_reserve != -1) + fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve); + if (pe_def_file->heap_commit != -1) + fprintf (out, "HEAPSIZE 0x%x,0x%x\n", + pe_def_file->heap_reserve, pe_def_file->heap_commit); + else if (pe_def_file->heap_reserve != -1) + fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve); + + if (pe_def_file->num_section_defs > 0) + { + fprintf (out, "\nSECTIONS\n\n"); + for (i = 0; i < pe_def_file->num_section_defs; i++) + { + fprintf (out, " "); + quoteput (pe_def_file->section_defs[i].name, out, 0); + if (pe_def_file->section_defs[i].class) + { + fprintf (out, " CLASS "); + quoteput (pe_def_file->section_defs[i].class, out, 0); + } + if (pe_def_file->section_defs[i].flag_read) + fprintf (out, " READ"); + if (pe_def_file->section_defs[i].flag_write) + fprintf (out, " WRITE"); + if (pe_def_file->section_defs[i].flag_execute) + fprintf (out, " EXECUTE"); + if (pe_def_file->section_defs[i].flag_shared) + fprintf (out, " SHARED"); + fprintf (out, "\n"); + } + } + + if (pe_def_file->num_exports > 0) + { + fprintf (out, "\nEXPORTS\n\n"); + for (i = 0; i < pe_def_file->num_exports; i++) + { + def_file_export *e = pe_def_file->exports + i; + fprintf (out, " "); + quoteput (e->name, out, 0); + if (e->internal_name && strcmp (e->internal_name, e->name)) + { + fprintf (out, " = "); + quoteput (e->internal_name, out, 0); + } + if (e->ordinal != -1) + fprintf (out, " @%d", e->ordinal); + if (e->flag_private) + fprintf (out, " PRIVATE"); + if (e->flag_constant) + fprintf (out, " CONSTANT"); + if (e->flag_noname) + fprintf (out, " NONAME"); + if (e->flag_data) + fprintf (out, " DATA"); + + fprintf (out, "\n"); + } + } + + if (pe_def_file->num_imports > 0) + { + fprintf (out, "\nIMPORTS\n\n"); + for (i = 0; i < pe_def_file->num_imports; i++) + { + def_file_import *im = pe_def_file->imports + i; + fprintf (out, " "); + if (im->internal_name + && (!im->name || strcmp (im->internal_name, im->name))) + { + quoteput (im->internal_name, out, 0); + fprintf (out, " = "); + } + quoteput (im->module, out, 0); + fprintf (out, "."); + if (im->name) + quoteput (im->name, out, 0); + else + fprintf (out, "%d", im->ordinal); + fprintf (out, "\n"); + } + } + + if (fclose (out) == EOF) + { + /* xgettext:c-format */ + einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename); + } +} + +/************************************************************************ + + These are the main functions, called from the emulation. The first + is called after the bfds are read, so we can guess at how much space + we need. The second is called after everything is placed, so we + can put the right values in place. + + ************************************************************************/ + +void +pe_dll_build_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + process_def_file (abfd, info); + + generate_edata (abfd, info); + build_filler_bfd (); +} + +void +pe_dll_fill_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + image_base = pe_data (abfd)->pe_opthdr.ImageBase; + + generate_reloc (abfd, info); + if (reloc_sz > 0) + { + bfd_set_section_size (filler_bfd, reloc_s, reloc_sz); + + /* Resize the sections. */ + lang_size_sections (stat_ptr->head, abs_output_section, + &stat_ptr->head, 0, (bfd_vma) 0, false); + + /* Redo special stuff. */ + ldemul_after_allocation (); + + /* Do the assignments again. */ + lang_do_assignments (stat_ptr->head, + abs_output_section, + (fill_type) 0, (bfd_vma) 0); + } + + fill_edata (abfd, info); + + pe_data (abfd)->dll = 1; + + edata_s->contents = edata_d; + reloc_s->contents = reloc_d; +} -- 2.30.2