From dd9d9ac28b56faa0c480877b29e1a74fb856214f Mon Sep 17 00:00:00 2001 From: davek Date: Mon, 30 Nov 2009 23:22:04 +0000 Subject: [PATCH] gcc/ChangeLog: 2009-11-30 Dave Korn * configure.ac (USE_CYGWIN_LIBSTDCXX_WRAPPERS): Define to reflect status of AC_CHECK_FUNC for Cygwin DLL libstdc++ support wrappers. * configure: Regenerate. * config.in: Regenerate. * config/i386/cygwin.h (CXX_WRAP_SPEC_LIST): Define list of --wrap options for Cygwin DLL libstdc++ support wrappers. (CXX_WRAP_SPEC_OPT): Define spec to use wrappers or not by default according to defined value of USE_CYGWIN_LIBSTDCXX_WRAPPERS. (CXX_WRAP_SPEC): Define entire wrapper spec in or out according to whether USE_CYGWIN_LIBSTDCXX_WRAPPERS is even defined or not. (LINK_SPEC): Include CXX_WRAP_SPEC. * gcc/config/i386/winnt.c (wrapper_strcmp): New qsort helper function. (i386_find_on_wrapper_list): Check if a function is found on the list of libstdc++ wrapper options. (i386_pe_file_end): If we are importing a wrapped function, also emit an external declaration for the real version. * config/i386/cygming.opt (muse-libstdc-wrappers): New option for Cygwin targets. Update copyright year. libstdc++-v3/ChangeLog: 2009-11-30 Dave Korn * libstdc++-v3/acinclude.m4 (GLIBCXX_ENABLE_SYMVERS): Don't disable on PE targets. * libstdc++-v3/configure: Regenerate. * libstdc++-v3/configure.host: Add libtool DLL options for Cygwin and MinGW platforms. * libstdc++-v3/include/bits/c++config (_GLIBCXX_VISIBILITY_ATTR): On platforms that don't support visibility, allow them to declare a macro _GLIBCXX_PSEUDO_VISIBILITY that is applied in place of visibility. (_GLIBCXX_PSEUDO_VISIBILITY): Supply empty default if not declared by CPU- or OS-specific headers. * libstdc++-v3/config/os/newlib/os_defines.h (_GLIBCXX_PSEUDO_VISIBILITY_default): New macro for dllimport. (_GLIBCXX_PSEUDO_VISIBILITY_hidden): New empty macro. (_GLIBCXX_PSEUDO_VISIBILITY): Evaluate to one of the above. * libstdc++-v3/config/os/mingw32/os_defines.h (_GLIBCXX_PSEUDO_VISIBILITY_default, _GLIBCXX_PSEUDO_VISIBILITY_hidden, _GLIBCXX_PSEUDO_VISIBILITY): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154853 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 22 ++++++++++ gcc/config.in | 7 +++ gcc/config/i386/cygming.opt | 6 ++- gcc/config/i386/cygwin.h | 32 ++++++++++++++ gcc/config/i386/winnt.c | 67 +++++++++++++++++++++++++++++ gcc/configure | 26 +++++++++++ gcc/configure.ac | 19 ++++++++ libstdc++-v3/ChangeLog | 23 ++++++++++ libstdc++-v3/acinclude.m4 | 2 +- libstdc++-v3/config/os/mingw32/os_defines.h | 9 ++++ libstdc++-v3/config/os/newlib/os_defines.h | 9 ++++ libstdc++-v3/configure | 2 +- libstdc++-v3/configure.host | 2 + libstdc++-v3/include/bits/c++config | 10 ++++- 14 files changed, 232 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ded17f3a0b..ff41ceb7095 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2009-11-30 Dave Korn + + * configure.ac (USE_CYGWIN_LIBSTDCXX_WRAPPERS): Define to reflect + status of AC_CHECK_FUNC for Cygwin DLL libstdc++ support wrappers. + * configure: Regenerate. + * config.in: Regenerate. + + * config/i386/cygwin.h (CXX_WRAP_SPEC_LIST): Define list of --wrap + options for Cygwin DLL libstdc++ support wrappers. + (CXX_WRAP_SPEC_OPT): Define spec to use wrappers or not by default + according to defined value of USE_CYGWIN_LIBSTDCXX_WRAPPERS. + (CXX_WRAP_SPEC): Define entire wrapper spec in or out according to + whether USE_CYGWIN_LIBSTDCXX_WRAPPERS is even defined or not. + (LINK_SPEC): Include CXX_WRAP_SPEC. + * gcc/config/i386/winnt.c (wrapper_strcmp): New qsort helper function. + (i386_find_on_wrapper_list): Check if a function is found on the list + of libstdc++ wrapper options. + (i386_pe_file_end): If we are importing a wrapped function, also emit + an external declaration for the real version. + * config/i386/cygming.opt (muse-libstdc-wrappers): New option for + Cygwin targets. Update copyright year. + 2009-11-30 Steve Ellcey Jakub Jelinek diff --git a/gcc/config.in b/gcc/config.in index fbc9fbb9288..681e4f8bd48 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1634,6 +1634,13 @@ #endif +/* Define if you want to generate code by default that assumes that the Cygwin + DLL exports wrappers to support libstdc++ function replacement. */ +#ifndef USED_FOR_TARGET +#undef USE_CYGWIN_LIBSTDCXX_WRAPPERS +#endif + + /* Define to 1 if the 'long long' (or '__int64') is wider than 'long' but still efficiently supported by the host hardware. */ #ifndef USED_FOR_TARGET diff --git a/gcc/config/i386/cygming.opt b/gcc/config/i386/cygming.opt index e845a0d5827..72dfc3401bb 100644 --- a/gcc/config/i386/cygming.opt +++ b/gcc/config/i386/cygming.opt @@ -1,6 +1,6 @@ ; Cygwin- and MinGW-specific options. -; Copyright (C) 2005, 2007 Free Software Foundation, Inc. +; Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. ; ; This file is part of GCC. ; @@ -49,3 +49,7 @@ Create GUI application mpe-aligned-commons Target Var(use_pe_aligned_common) Init(HAVE_GAS_ALIGNED_COMM) Use the GNU extension to the PE format for aligned common data + +muse-libstdc-wrappers +Target Condition({defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS)}) +Compile code that relies on Cygwin DLL wrappers to support C++ operator new/delete replacement diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h index 8eb21da4948..86eff635ae6 100644 --- a/gcc/config/i386/cygwin.h +++ b/gcc/config/i386/cygwin.h @@ -85,9 +85,41 @@ along with GCC; see the file COPYING3. If not see %{mwindows:-lgdi32 -lcomdlg32} \ -luser32 -lkernel32 -ladvapi32 -lshell32" +/* To implement C++ function replacement we always wrap the cxx + malloc-like operators. See N2800 #17.6.4.6 [replacement.functions] */ +#define CXX_WRAP_SPEC_LIST "%{!static: %{!static-libstdc++: \ + --wrap _Znwj \ + --wrap _Znaj \ + --wrap _ZdlPv \ + --wrap _ZdaPv \ + --wrap _ZnwjRKSt9nothrow_t \ + --wrap _ZnajRKSt9nothrow_t \ + --wrap _ZdlPvRKSt9nothrow_t \ + --wrap _ZdaPvRKSt9nothrow_t \ + }}" + +#if defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS) + +#if USE_CYGWIN_LIBSTDCXX_WRAPPERS +/* Default on, only explict -mno disables. */ +#define CXX_WRAP_SPEC_OPT "!mno-use-libstdc-wrappers" +#else +/* Default off, only explict -m enables. */ +#define CXX_WRAP_SPEC_OPT "muse-libstdc-wrappers" +#endif + +#define CXX_WRAP_SPEC "%{" CXX_WRAP_SPEC_OPT ":" CXX_WRAP_SPEC_LIST "}" + +#else /* !defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS) */ + +#define CXX_WRAP_SPEC "" + +#endif /* ?defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS) */ + #define LINK_SPEC "\ %{mwindows:--subsystem windows} \ %{mconsole:--subsystem console} \ + " CXX_WRAP_SPEC " \ %{shared: %{mdll: %eshared and mdll are not compatible}} \ %{shared: --shared} %{mdll:--dll} \ %{static:-Bstatic} %{!static:-Bdynamic} \ diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index f8dcaa9673a..a6bd1e4f739 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -603,6 +603,64 @@ i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data) export_head = p; } +#ifdef CXX_WRAP_SPEC_LIST + +/* Hash table equality helper function. */ + +static int +wrapper_strcmp (const void *x, const void *y) +{ + return !strcmp ((const char *) x, (const char *) y); +} + +/* Search for a function named TARGET in the list of library wrappers + we are using, returning a pointer to it if found or NULL if not. + This function might be called on quite a few symbols, and we only + have the list of names of wrapped functions available to us as a + spec string, so first time round we lazily initialise a hash table + to make things quicker. */ + +static const char * +i386_find_on_wrapper_list (const char *target) +{ + static char first_time = 1; + static htab_t wrappers; + + if (first_time) + { + /* Beware that this is not a complicated parser, it assumes + that any sequence of non-whitespace beginning with an + underscore is one of the wrapped symbols. For now that's + adequate to distinguish symbols from spec substitutions + and command-line options. */ + static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST; + char *bufptr; + /* Breaks up the char array into separated strings + strings and enter them into the hash table. */ + wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp, + 0, xcalloc, free); + for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr) + { + char *found = NULL; + if (ISSPACE (*bufptr)) + continue; + if (*bufptr == '_') + found = bufptr; + while (*bufptr && !ISSPACE (*bufptr)) + ++bufptr; + if (*bufptr) + *bufptr = 0; + if (found) + *htab_find_slot (wrappers, found, INSERT) = found; + } + first_time = 0; + } + + return (const char *) htab_find (wrappers, target); +} + +#endif /* CXX_WRAP_SPEC_LIST */ + /* This is called at the end of assembly. For each external function which has not been defined, we output a declaration now. We also output the .drectve section. */ @@ -624,6 +682,15 @@ i386_pe_file_end (void) if (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) { +#ifdef CXX_WRAP_SPEC_LIST + /* To ensure the DLL that provides the corresponding real + functions is still loaded at runtime, we must reference + the real function so that an (unused) import is created. */ + const char *realsym = i386_find_on_wrapper_list (p->name); + if (realsym) + i386_pe_declare_function_type (asm_out_file, + concat ("__real_", realsym, NULL), TREE_PUBLIC (decl)); +#endif /* CXX_WRAP_SPEC_LIST */ TREE_ASM_WRITTEN (decl) = 1; i386_pe_declare_function_type (asm_out_file, p->name, TREE_PUBLIC (decl)); diff --git a/gcc/configure b/gcc/configure index f49cdb77f67..abf0b9acf74 100755 --- a/gcc/configure +++ b/gcc/configure @@ -22699,6 +22699,32 @@ fi i[34567]86-*-* | x86_64-*-*) case $target_os in + cygwin*) + # Full C++ conformance when using a shared libstdc++-v3 requires some + # support from the Cygwin DLL, which in more recent versions exports + # wrappers to aid in interposing and redirecting operators new, delete, + # etc., as per n2800 #17.6.4.6 [replacement.functions]. Check if we + # are configuring for a version of Cygwin that exports the wrappers. + if test x$host = x$target; then + ac_fn_c_check_func "$LINENO" "__wrap__Znaj" "ac_cv_func___wrap__Znaj" +if test "x$ac_cv_func___wrap__Znaj" = x""yes; then : + gcc_ac_cygwin_dll_wrappers=yes +else + gcc_ac_cygwin_dll_wrappers=no +fi + + else + # Can't check presence of libc functions during cross-compile, so + # we just have to assume we're building for an up-to-date target. + gcc_ac_cygwin_dll_wrappers=yes + fi + +cat >>confdefs.h <<_ACEOF +#define USE_CYGWIN_LIBSTDCXX_WRAPPERS `if test $gcc_ac_cygwin_dll_wrappers = yes; then echo 1; else echo 0; fi` +_ACEOF + + esac + case $target_os in cygwin* | pe | mingw32*) # Recent binutils allows the three-operand form of ".comm" on PE. This # definition is used unconditionally to initialise the default state of diff --git a/gcc/configure.ac b/gcc/configure.ac index dfc72991c50..f357e1ee5a8 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3000,6 +3000,25 @@ changequote(,)dnl i[34567]86-*-* | x86_64-*-*) changequote([,])dnl case $target_os in + cygwin*) + # Full C++ conformance when using a shared libstdc++-v3 requires some + # support from the Cygwin DLL, which in more recent versions exports + # wrappers to aid in interposing and redirecting operators new, delete, + # etc., as per n2800 #17.6.4.6 [replacement.functions]. Check if we + # are configuring for a version of Cygwin that exports the wrappers. + if test x$host = x$target; then + AC_CHECK_FUNC([__wrap__Znaj],[gcc_ac_cygwin_dll_wrappers=yes],[gcc_ac_cygwin_dll_wrappers=no]) + else + # Can't check presence of libc functions during cross-compile, so + # we just have to assume we're building for an up-to-date target. + gcc_ac_cygwin_dll_wrappers=yes + fi + AC_DEFINE_UNQUOTED(USE_CYGWIN_LIBSTDCXX_WRAPPERS, + [`if test $gcc_ac_cygwin_dll_wrappers = yes; then echo 1; else echo 0; fi`], + [Define if you want to generate code by default that assumes that the + Cygwin DLL exports wrappers to support libstdc++ function replacement.]) + esac + case $target_os in cygwin* | pe | mingw32*) # Recent binutils allows the three-operand form of ".comm" on PE. This # definition is used unconditionally to initialise the default state of diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 5919694834b..e44d6f4e5f3 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,26 @@ +2009-11-30 Dave Korn + + * libstdc++-v3/acinclude.m4 (GLIBCXX_ENABLE_SYMVERS): Don't disable + on PE targets. + * libstdc++-v3/configure: Regenerate. + * libstdc++-v3/configure.host: Add libtool DLL options for Cygwin + and MinGW platforms. + + * libstdc++-v3/include/bits/c++config (_GLIBCXX_VISIBILITY_ATTR): On + platforms that don't support visibility, allow them to declare a macro + _GLIBCXX_PSEUDO_VISIBILITY that is applied in place of visibility. + (_GLIBCXX_PSEUDO_VISIBILITY): Supply empty default if not declared by + CPU- or OS-specific headers. + + * libstdc++-v3/config/os/newlib/os_defines.h + (_GLIBCXX_PSEUDO_VISIBILITY_default): New macro for dllimport. + (_GLIBCXX_PSEUDO_VISIBILITY_hidden): New empty macro. + (_GLIBCXX_PSEUDO_VISIBILITY): Evaluate to one of the above. + * libstdc++-v3/config/os/mingw32/os_defines.h + (_GLIBCXX_PSEUDO_VISIBILITY_default, + _GLIBCXX_PSEUDO_VISIBILITY_hidden, + _GLIBCXX_PSEUDO_VISIBILITY): Likewise. + 2009-11-30 Paolo Carlini * include/tr1_impl/functional: Remove file, copy its contents, diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index aba9a1b2f52..e0c698d75c2 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -2737,7 +2737,7 @@ if test x$enable_symvers = xyes ; then else if test $with_gnu_ld = yes ; then case ${target_os} in - cygwin* | pe | mingw32* | hpux*) + hpux*) enable_symvers=no ;; *) enable_symvers=gnu ;; diff --git a/libstdc++-v3/config/os/mingw32/os_defines.h b/libstdc++-v3/config/os/mingw32/os_defines.h index 7b4e8066457..5435ce9ae84 100644 --- a/libstdc++-v3/config/os/mingw32/os_defines.h +++ b/libstdc++-v3/config/os/mingw32/os_defines.h @@ -45,6 +45,15 @@ #undef NOMINMAX #define NOMINMAX 1 +#if defined (_GLIBCXX_DLL) +#define _GLIBCXX_PSEUDO_VISIBILITY_default __attribute__ ((__dllimport__)) +#else +#define _GLIBCXX_PSEUDO_VISIBILITY_default +#endif +#define _GLIBCXX_PSEUDO_VISIBILITY_hidden + +#define _GLIBCXX_PSEUDO_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY_ ## V + // See libstdc++/20806. #define _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM 1 diff --git a/libstdc++-v3/config/os/newlib/os_defines.h b/libstdc++-v3/config/os/newlib/os_defines.h index fbc886365ff..1ff3d4846cb 100644 --- a/libstdc++-v3/config/os/newlib/os_defines.h +++ b/libstdc++-v3/config/os/newlib/os_defines.h @@ -36,6 +36,15 @@ #ifdef __CYGWIN__ #define _GLIBCXX_GTHREAD_USE_WEAK 0 +#if defined (_GLIBCXX_DLL) +#define _GLIBCXX_PSEUDO_VISIBILITY_default __attribute__ ((__dllimport__)) +#else +#define _GLIBCXX_PSEUDO_VISIBILITY_default +#endif +#define _GLIBCXX_PSEUDO_VISIBILITY_hidden + +#define _GLIBCXX_PSEUDO_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY_ ## V + // See libstdc++/20806. #define _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM 1 #endif diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 75adc589e12..4f5d51783d6 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -58050,7 +58050,7 @@ if test x$enable_symvers = xyes ; then else if test $with_gnu_ld = yes ; then case ${target_os} in - cygwin* | pe | mingw32* | hpux*) + hpux*) enable_symvers=no ;; *) enable_symvers=gnu ;; diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host index de7745a1286..02292b016d0 100644 --- a/libstdc++-v3/configure.host +++ b/libstdc++-v3/configure.host @@ -209,6 +209,7 @@ case "${host_os}" in ;; cygwin*) os_include_dir="os/newlib" + OPT_LDFLAGS="${OPT_LDFLAGS} -no-undefined -bindir \$(bindir)" ;; darwin | darwin[1-7] | darwin[1-7].*) # On Darwin, performance is improved if libstdc++ is single-module. @@ -258,6 +259,7 @@ case "${host_os}" in mingw32*) os_include_dir="os/mingw32" error_constants_dir="os/mingw32" + OPT_LDFLAGS="${OPT_LDFLAGS} -no-undefined -bindir \$(bindir)" ;; netbsd*) os_include_dir="os/bsd/netbsd" diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index f4f1f8b901f..3746696458a 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -42,7 +42,9 @@ #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ (#V))) #else -# define _GLIBCXX_VISIBILITY_ATTR(V) +// If this is not supplied by the OS-specific or CPU-specific +// headers included below, it will be defined to an empty default. +# define _GLIBCXX_VISIBILITY_ATTR(V) _GLIBCXX_PSEUDO_VISIBILITY(V) #endif // Macros for deprecated. @@ -275,6 +277,12 @@ namespace std // Pick up any CPU-specific definitions. #include +// If platform uses neither visibility nor psuedo-visibility, +// specify empty default for namespace annotation macros. +#ifndef _GLIBCXX_PSEUDO_VISIBILITY +#define _GLIBCXX_PSEUDO_VISIBILITY(V) +#endif + // Allow use of "export template." This is currently not a feature // that g++ supports. // #define _GLIBCXX_EXPORT_TEMPLATE 1 -- 2.11.0