I wrote:
So, CL_REQUIRE can't call the global ctors directly, because it doesn't know what the symbol name is. Only CL_PROVIDE and CL_PROVIDE_END do know that. But, it doesn't appear to be possible to introduce another layer of indirection in CL_PROVIDE like the attached patch tries to. It leads to an infinite loop in the global ctors. Right now, I've run out of ideas.
Well, it turns out that the infinite recursion was due to the braindead way I implemented that other layer of indirection. A plain C function should do the trick. The attached patch seems to work over here using prerelease GCC 4.3.0-20071130. I would appreciate it if people give it a try and report how it worx 4 them. Cheers -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> Index: ChangeLog =================================================================== RCS file: /home/cvs/cln/ChangeLog,v retrieving revision 1.194 diff -u -r1.194 ChangeLog --- ChangeLog 18 Dec 2007 23:01:19 -0000 1.194 +++ ChangeLog 6 Jan 2008 01:53:04 -0000 @@ -1,3 +1,16 @@ +2008-01-06 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + Richard B. Kreckel <kreckel@ginac.de> + + Cater to the fact that g++ 4.3 will use a different naming for + the global constructor suffix in shared and static objects. + * m4/c++-constructors.m4 (CL_GLOBAL_CONSTRUCTORS): Add test for + the global constructor suffix, define CL_GLOBAL_CONSTRUCTOR_SUFFIX_PIC + and CL_GLOBAL_CONSTRUCTOR_SUFFIX_NOPIC appropriately. + * include/cln/config.h.in: Provide templates to be filled in by + configure. + * include/cln/modules.h (CL_PROVIDE, CL_REQUIRE): Use + CL_GLOBAL_CONSTRUCTOR_SUFFIX_PIC, CL_GLOBAL_CONSTRUCTOR_SUFFIX_NOPIC. + 2007-12-19 Richard B. Kreckel <kreckel@ginac.de> * m4/general.m4 (CL_CANONICAL_HOST_CPU): Force host_cpu=rs6000 for Index: m4/c++-constructors.m4 =================================================================== RCS file: /home/cvs/cln/m4/c++-constructors.m4,v retrieving revision 1.1 diff -u -r1.1 c++-constructors.m4 --- m4/c++-constructors.m4 29 Aug 2005 13:18:40 -0000 1.1 +++ m4/c++-constructors.m4 6 Jan 2008 01:53:04 -0000 @@ -95,6 +95,40 @@ if test "$cl_cv_cplusplus_ctorexport" = yes; then AC_DEFINE(CL_NEED_GLOBALIZE_CTORDTOR) fi +AC_CACHE_CHECK([for the global constructor function suffix in shared objects], +cl_cv_cplusplus_ctorsuffix_pic, [ +cat > conftest.cc << EOF +extern "C" void func () {} +static struct S { + inline S () {} +} S; +EOF +AC_TRY_COMMAND(${CXX-g++} $CXXFLAGS ${lt_prog_compiler_pic_CXX-"-fPIC"} -S conftest.cc) >/dev/null 2>&1 +if grep "${cl_cv_cplusplus_ctorprefix}conftest\.cc" conftest.s >/dev/null; then + cl_cv_cplusplus_ctorsuffix_pic='#module ".cc"' +else + cl_cv_cplusplus_ctorsuffix_pic='"cl_module__" #module "__firstglobalfun"' +fi +rm -f conftest* +]) +AC_DEFINE_UNQUOTED([CL_GLOBAL_CONSTRUCTOR_SUFFIX_PIC(module)], [$cl_cv_cplusplus_ctorsuffix_pic]) +AC_CACHE_CHECK([for the global constructor function suffix in static objects], +cl_cv_cplusplus_ctorsuffix_nopic, [ +cat > conftest.cc << EOF +extern "C" void func () {} +static struct S { + inline S () {} +} S; +EOF +AC_TRY_COMMAND(${CXX-g++} $CXXFLAGS -S conftest.cc) >/dev/null 2>&1 +if grep "${cl_cv_cplusplus_ctorprefix}conftest\.cc" conftest.s >/dev/null; then + cl_cv_cplusplus_ctorsuffix_nopic='#module ".cc"' +else + cl_cv_cplusplus_ctorsuffix_nopic='"cl_module__" #module "__firstglobalfun"' +fi +rm -f conftest* +]) +AC_DEFINE_UNQUOTED([CL_GLOBAL_CONSTRUCTOR_SUFFIX_NOPIC(module)], [$cl_cv_cplusplus_ctorsuffix_nopic]) fi fi ]) Index: include/cln/config.h.in =================================================================== RCS file: /home/cvs/cln/include/cln/config.h.in,v retrieving revision 1.10 diff -u -r1.10 config.h.in --- include/cln/config.h.in 13 Jun 2006 18:31:18 -0000 1.10 +++ include/cln/config.h.in 6 Jan 2008 01:53:04 -0000 @@ -141,6 +141,13 @@ /* Define if a module's global constructor function and global destructor function need to be exported in order to be accessible from other modules. */ #undef CL_NEED_GLOBALIZE_CTORDTOR +/* Define as the suffix of the name of a module's global constructor function */ +#ifndef CL_GLOBAL_CONSTRUCTOR_SUFFIX_PIC +#undef CL_GLOBAL_CONSTRUCTOR_SUFFIX_PIC +#endif +#ifndef CL_GLOBAL_CONSTRUCTOR_SUFFIX_NOPIC +#undef CL_GLOBAL_CONSTRUCTOR_SUFFIX_NOPIC +#endif /* CL_CHAR_UNSIGNED */ #ifndef __CHAR_UNSIGNED__ Index: include/cln/modules.h =================================================================== RCS file: /home/cvs/cln/include/cln/modules.h,v retrieving revision 1.20 diff -u -r1.20 modules.h --- include/cln/modules.h 18 Sep 2007 21:56:18 -0000 1.20 +++ include/cln/modules.h 6 Jan 2008 01:53:04 -0000 @@ -3,6 +3,9 @@ #ifndef _CL_MODULES_H #define _CL_MODULES_H +// global constructor/destructor naming. +#include "cln/config.h" + // The order of initialization of different compilation units is not // specified in C++. AIX 4 has a linker which apparently does order // the modules according to dependencies, so that low-level modules @@ -56,6 +59,12 @@ // OK, stop reading here, because it's getting obscene. +#if defined(PIC) + #define CL_GLOBAL_CONSTRUCTOR_SUFFIX CL_GLOBAL_CONSTRUCTOR_SUFFIX_PIC +#else + #define CL_GLOBAL_CONSTRUCTOR_SUFFIX CL_GLOBAL_CONSTRUCTOR_SUFFIX_NOPIC +#endif + #if defined(__GNUC__) && defined(__OPTIMIZE__) && !(defined(__hppa__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 8)) && !defined(NO_PROVIDE_REQUIRE) #ifdef ASM_UNDERSCORE #define ASM_UNDERSCORE_PREFIX "_" @@ -227,11 +236,15 @@ // Thus we need to hack the constructors only. #define CL_PROVIDE(module) \ extern "C" void cl_module__##module##__firstglobalfun () {} \ + extern "C" void cl_module__##module##__docallctors() \ + __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \ + CL_GLOBAL_CONSTRUCTOR_SUFFIX(module)); \ + extern "C" void cl_module__##module##__globalctors () \ + { cl_module__##module##__docallctors(); } \ extern "C" void cl_module__##module##__ctorend (void); \ - CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend) \ CL_GLOBALIZE_CTORDTOR_LABEL( \ ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \ - "cl_module__" #module "__firstglobalfun") \ + CL_GLOBAL_CONSTRUCTOR_SUFFIX(module)) \ static int cl_module__##module##__counter; \ struct cl_module__##module##__controller { \ inline cl_module__##module##__controller () \ @@ -248,8 +261,7 @@ static cl_module__##module##__destroyer cl_module__##module##__dtordummy; #define CL_REQUIRE(module) \ extern "C" void cl_module__##module##__ctor (void) \ - __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \ - "cl_module__" #module "__firstglobalfun"); \ + __asm__ ("cl_module__" #module "__globalctors"); \ struct _CL_REQUIRE_CLASSNAME(module,__LINE__) { \ inline _CL_REQUIRE_CLASSNAME(module,__LINE__) () \ { cl_module__##module##__ctor (); } \