From 8c7a3134ddf1f43a283fafc1d96b76cc2327540c Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Mon, 28 Jul 2008 22:57:43 +0000 Subject: [PATCH] Lay foundations for new printf() function family implementation. --- winsup/mingw/ChangeLog | 30 ++++++- winsup/mingw/Makefile.in | 39 +++++++-- winsup/mingw/configure | 166 +++++++++++++++++++++++++++++++++++++- winsup/mingw/configure.in | 2 + winsup/mingw/ofmt_stub.s | 40 +++++++++ 5 files changed, 268 insertions(+), 9 deletions(-) create mode 100644 winsup/mingw/ofmt_stub.s diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog index 710e217c9..57369a3c0 100644 --- a/winsup/mingw/ChangeLog +++ b/winsup/mingw/ChangeLog @@ -1,12 +1,36 @@ +2008-07-28 Keith Marshall + + Lay foundations for new printf() function family implementation. + + * ofmt_stub.s: New file; implement forward compatibility stub for... + (_get_output_format): ...this MSVCR80.DLL and later function. + + * Makefile.in (SRCDIST_FILES): Add ofmt_stub.s. + (NM, OBJCOPY): New macros; define them with AC_SUBSTed values. + (sym_prefix, NM_LOOKUP, MINGW_REPL_FUNCS): New macros; define them. + (lib%.a): Include ofmt_stub.o when import library does not already + advertise availability of the _get_output_format() function; + Add alias stubs for MINGW_REPL_FUNCS, such that... + (__msvcrt_printf): ...is an alias for Microsoft's printf(). + (__msvcrt_fprintf): ...is an alias for Microsoft's fprintf(). + (__msvcrt_sprintf): ...is an alias for Microsoft's sprintf(). + (__msvcrt_vprintf): ...is an alias for Microsoft's vprintf(). + (__msvcrt_vfprintf): ...is an alias for Microsoft's vfprintf(). + (__msvcrt_vsprintf): ...is an alias for Microsoft's vsprintf(). + (clean): Add msvcr*.def. + + * configure.in (NM, OBJCOPY): Use AC_CHECK_TOOL to specify them. + * configure: Regenerated. + 2008-07-06 Gregory McGarry - * include/ctype.h (_imp____mb_cur_max): Correct spelling. + * include/ctype.h (_imp____mb_cur_max): Correct spelling. (_imp____mb_cur_max_dll): Likewise. 2008-07-04 Danny Smith - * include/stdio.h (swprintf, vswprintf): Guard with #ifndef __STRICT_ANSI__ - * include/wchar.h (swprintf, vswprintf): Likewise. + * include/stdio.h (swprintf, vswprintf): Guard with #ifndef __STRICT_ANSI__ + * include/wchar.h (swprintf, vswprintf): Likewise. 2008-07-01 Keith Marshall diff --git a/winsup/mingw/Makefile.in b/winsup/mingw/Makefile.in index 84ea03e21..c9ced3cf6 100644 --- a/winsup/mingw/Makefile.in +++ b/winsup/mingw/Makefile.in @@ -136,6 +136,8 @@ DLLTOOL_FLAGS = --as $(AS_FOR_TARGET) DLLWRAP = @DLLWRAP@ DLLWRAP_FOR_TARGET = $(DLLWRAP) DLLWRAP_FLAGS = --dlltool $(DLLTOOL) --as $(AS) --driver-name $(CC) +OBJCOPY = @OBJCOPY@ +NM = @NM@ TAR = tar TARFLAGS = z @@ -205,7 +207,7 @@ SRCDIST_FILES = CRT_noglob.c CRTfmode.c CRTglob.c CRTinit.c ChangeLog \ Makefile.in README TODO config.guess config.sub configure configure.in \ aclocal.m4 crt1.c crtdll.def crtmt.c crtst.c dllcrt1.c dllmain.c \ gccmain.c init.c install-sh jamfile main.c mkinstalldirs \ -moldname.def.in msvcrt.def.in \ +moldname.def.in msvcrt.def.in ofmt_stub.s \ mthr.c mthr_init.c mthr_stub.c readme.txt \ isascii.c iscsym.c iscsymf.c toascii.c \ strcasecmp.c strncasecmp.c wcscmpi.c \ @@ -334,7 +336,7 @@ test_headers: clean: -rm -f *.o *.a *~ core a.out mingwthrd.def mingwthrd.base mingwthrd.exp -rm -f $(THREAD_DLL_NAME) mingwthrd_dummy.exe - -rm -f moldname-*.def + -rm -f msvcr*.def moldname-*.def @$(MAKE) subdirs DO=$@ $(FLAGS_TO_PASS) distclean: clean @@ -469,7 +471,7 @@ subdirs: $(SUBDIRS) force: # -# Dependancies +# Dependencies # libcrtdll.a: crtdll.def libmsvcrt.a: msvcrt.def @@ -501,8 +503,35 @@ config.status: configure .SUFFIXES: .y $(SUFFIXES) .cc .def .a -lib%.a:%.def - $(DLLTOOL) --as=$(AS) -k --dllname $*.dll --output-lib lib$*.a --def $< +sym_prefix = __msvcrt + +NM_LOOKUP = $(NM) $@ | sed -n \ + -e '/:$$/h;/^[0-7][0-7]* *T */{s///;H;g;s/\n//p' \ + -e '}' | sed -n 's/:_'"$$key"'$$//p' + +MINGW_REPL_FUNCS = printf fprintf sprintf vprintf vfprintf vsprintf + +lib%.a: %.def + $(DLLTOOL) --as=$(AS) -k --dllname $*.dll --output-lib $@ --def $< + for key in $(MINGW_REPL_FUNCS); do \ + src=`$(NM_LOOKUP)`; \ + if test -n "$$src"; then \ + dst=`echo "$$src" | sed 's/0/4/'`; repl="$$repl $$dst"; \ + tmpfiles="$$tmpfiles $$src $$dst"; \ + $(AR) x $@ $$src; \ + $(OBJCOPY) --redefine-sym _$$key=_$(sym_prefix)_$$key \ + --redefine-sym __imp__$$key=__imp__$(sym_prefix)_$$key \ + $$src $$dst; \ + fi; done; \ + test `key=_get_output_format; $(NM_LOOKUP)` || \ + repl="$$repl ofmt_stub.o"; \ + test -n "$$repl" && $(AR) rcs $@ $$repl; \ + $(RM) $$tmpfiles + +libmsvcrt.a libmsvcrtd.a: ofmt_stub.o +libmsvcr70.a libmsvcr70d.a: ofmt_stub.o +libmsvcr71.a libmsvcr71d.a: ofmt_stub.o +libcrtdll.a libcrtdlld.a: ofmt_stub.o .c.o: $(CC) -c $(ALL_CFLAGS) $< -o $@ diff --git a/winsup/mingw/configure b/winsup/mingw/configure index c67eca256..7d15f8707 100755 --- a/winsup/mingw/configure +++ b/winsup/mingw/configure @@ -273,7 +273,7 @@ PACKAGE_BUGREPORT='' ac_unique_file="include/_mingw.h" ac_subdirs_all="$ac_subdirs_all profile mingwex" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT with_cross_host all_dlls_host install_dlls_host AR ac_ct_AR AS ac_ct_AS RANLIB ac_ct_RANLIB LD ac_ct_LD DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP WINDRES ac_ct_WINDRES subdirs THREAD_DLL MKINSTALLDIRS MNO_CYGWIN LIBM_A LIBGMON_A HEADER_SUBDIR W32API_INCLUDE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA mingw_manpage_transform LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT with_cross_host all_dlls_host install_dlls_host AR ac_ct_AR AS ac_ct_AS RANLIB ac_ct_RANLIB LD ac_ct_LD NM ac_ct_NM OBJCOPY ac_ct_OBJCOPY DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP WINDRES ac_ct_WINDRES subdirs THREAD_DLL MKINSTALLDIRS MNO_CYGWIN LIBM_A LIBGMON_A HEADER_SUBDIR W32API_INCLUDE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA mingw_manpage_transform LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -2679,6 +2679,166 @@ else LD="$ac_cv_prog_LD" fi +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NM="nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_NM" && ac_cv_prog_ac_ct_NM="nm" +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + echo "$as_me:$LINENO: result: $ac_ct_NM" >&5 +echo "${ECHO_T}$ac_ct_NM" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + NM=$ac_ct_NM +else + NM="$ac_cv_prog_NM" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +OBJCOPY=$ac_cv_prog_OBJCOPY +if test -n "$OBJCOPY"; then + echo "$as_me:$LINENO: result: $OBJCOPY" >&5 +echo "${ECHO_T}$OBJCOPY" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_OBJCOPY"; then + ac_ct_OBJCOPY=$OBJCOPY + # Extract the first word of "objcopy", so it can be a program name with args. +set dummy objcopy; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_OBJCOPY"; then + ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJCOPY="objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_OBJCOPY" && ac_cv_prog_ac_ct_OBJCOPY="objcopy" +fi +fi +ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY +if test -n "$ac_ct_OBJCOPY"; then + echo "$as_me:$LINENO: result: $ac_ct_OBJCOPY" >&5 +echo "${ECHO_T}$ac_ct_OBJCOPY" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + OBJCOPY=$ac_ct_OBJCOPY +else + OBJCOPY="$ac_cv_prog_OBJCOPY" +fi + if test -n "$ac_tool_prefix"; then # 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 @@ -3718,6 +3878,10 @@ s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@LD@,$LD,;t t s,@ac_ct_LD@,$ac_ct_LD,;t t +s,@NM@,$NM,;t t +s,@ac_ct_NM@,$ac_ct_NM,;t t +s,@OBJCOPY@,$OBJCOPY,;t t +s,@ac_ct_OBJCOPY@,$ac_ct_OBJCOPY,;t t s,@DLLTOOL@,$DLLTOOL,;t t s,@ac_ct_DLLTOOL@,$ac_ct_DLLTOOL,;t t s,@DLLWRAP@,$DLLWRAP,;t t diff --git a/winsup/mingw/configure.in b/winsup/mingw/configure.in index 4d11d3584..775149b7e 100644 --- a/winsup/mingw/configure.in +++ b/winsup/mingw/configure.in @@ -36,6 +36,8 @@ AC_CHECK_TOOL([AR], [ar], [ar]) AC_CHECK_TOOL([AS], [as], [as]) AC_CHECK_TOOL([RANLIB], [ranlib], [ranlib]) AC_CHECK_TOOL([LD], [ld], [ld]) +AC_CHECK_TOOL([NM], [nm], [nm]) +AC_CHECK_TOOL([OBJCOPY], [objcopy], [objcopy]) AC_CHECK_TOOL([DLLTOOL], [dlltool], [dlltool]) AC_CHECK_TOOL([DLLWRAP], [dlltool], [dlltool]) AC_CHECK_TOOL([WINDRES], [windres], [windres]) diff --git a/winsup/mingw/ofmt_stub.s b/winsup/mingw/ofmt_stub.s new file mode 100644 index 000000000..388dcb45d --- /dev/null +++ b/winsup/mingw/ofmt_stub.s @@ -0,0 +1,40 @@ +/* ofmt_stub.s + * + * $Id$ + * + * A trivial stub, to replace the _get_output_format() function. + * + * _pformat() requires this function, which is provided by MSVCRT runtimes + * from msvcr80.dll onwards; add this stub to the import libraries for earlier + * versions of MSVCRT, (those which do not already advertise availability of + * any exported _get_output_format() function); this will permit _pformat() + * to transparently interoperate with all supported versions of MSVCRT. + * (Likewise for CRTDLL). + * + * Written by Keith Marshall + * Contributed to the MinGW Project, and hereby assigned to the public domain. + * + * This is free software. It is provided AS IS, in the hope that it may be + * useful. There is NO WARRANTY OF ANY KIND, not even an implied warranty of + * merchantability, nor of fitness for any particular purpose. + * + */ + .text + .p2align 1,,4 + +.globl __get_output_format + .def __get_output_format; .scl 2; .type 32; .endef + +__get_output_format: +/* + * int _get_output_format( void ); + * + * Implementation is trivial: we immediately return zero, thus matching the + * default behaviour of Microsoft's own implementation, in the absence of any + * preceding call to _set_output_format(); (if we are using this stub, then + * that entire API is unsupported, so no such prior call is possible). + */ + xorl %eax, %eax + ret + +/* $RCSfile$Revision$: end of file */ -- 2.43.5