octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch] dynamic linking for GCC v2/3 and Sun C++ ABI


From: Mumit Khan
Subject: [patch] dynamic linking for GCC v2/3 and Sun C++ ABI
Date: Thu, 28 Jun 2001 18:09:28 -0500 (CDT)

[ I'm not subscribed to this list, so please copy me if appropriate ]

The following patch adds support for dynamic linking when using GNU v3 
and Sun ABI. JWE's suggestion to use C linkage for dynamically loadable
functions is definitely worth investigating, provided we understand
the caveat -- loaded modules will mysteriously crash if there's a
compiler version mismatch. One solution is to encode the abi version
(eg., gxx_v2, gxx_v3, sun, compaq, etc) in the function name via the
DEFUN_DLD macro. I'll send a patch along if it works.

Note to testers -- you must re-create the autogenerated files after
applying this patch as it changes acconfig.h and aclocal.m4. If you
use the CVS version:

  $ cd <octave_src_toplevel>
  $ ./autogen.sh

or, if you're using snapshots that lack autogen.sh,

  $ autoconf
  $ autoheader

should do the job.

A few odds and ends to note:

- I've added a new macro -- CXX_ABI_VERSION -- that is used only for GNU
C++. If the other C++ vendors start using the new ABI, supposedly a 
standard now, it will of course get used for other compilers as well.

- I've stuck to using deprecated strstream instead of stringstream to
avoid the whole library issue. This will get "fixed" once the all of
Octave moves to using strstream instead.

- The Sun mangling is based on a somewhat educated guess. 

My tree is somewhat modified, so please try and manually work out any
patch conflicts.

Tested on GNU/Linux with gcc-2.95.2 and gcc-3.0, SPARC/Solaris 8 with
Sun Workshop 6 update 1.

ChangeLog/toplevel:

2001-04-28  Mumit Khan  <address@hidden>

        * aclocal.m4 (OCTAVE_CXX_ABI_VERSION): New macro.
        (OCTAVE_CXX_PREPENDS_UNDERSCORE): Add missing return value.
        * configure.in: Use.
        * acconfig.h (CXX_ABI_VERSION): New macro.

ChangeLog/src:

2001-04-28  Mumit Khan  <address@hidden>

        * dynamic-ld.cc ({algorithm,cctype,strstream}): Include.
        (octave_dynamic_loader::mangle_name): Support dynamic linking
        for GNU v3 and Sun C++ ABI.

Index: aclocal.m4
===================================================================
RCS file: /cvs/octave/aclocal.m4,v
retrieving revision 1.55
diff -u -3 -p -r1.55 aclocal.m4
--- aclocal.m4  2001/05/23 06:41:58     1.55
+++ aclocal.m4  2001/06/28 19:10:12
@@ -913,7 +913,7 @@ AC_DEFUN(OCTAVE_CXX_PREPENDS_UNDERSCORE,
     AC_LANG_SAVE
     AC_LANG_CPLUSPLUS
     cat > conftest.$ac_ext <<EOF
-bool FSmy_dld_fcn (void) { }
+bool FSmy_dld_fcn (void) { return false; }
 EOF
     if AC_TRY_EVAL(ac_compile); then
       if test "`${NM-nm} conftest.o | grep _FSmy_dld_fcn`" != ""; then
@@ -990,3 +990,37 @@ AC_DEFUN(OCTAVE_ENABLE_READLINE, [
     ])
   fi
 ])
+dnl
+dnl Determine the C++ compiler ABI version. It sets the macro 
+dnl CXX_ABI_VERSION, the value of which is then used to mangle names for
+dnl dynamic loading. Note that value 0 means it it's indeterminate, and
+dnl we can't assume anything about the ABI. GNU C++ currently uses v2 
+dnl (GCC versions <= 2.95.x) or v3 (GCC versions >= 3.0).
+dnl
+dnl OCTAVE_CXX_ABI_VERSION
+AC_DEFUN(OCTAVE_CXX_ABI_VERSION,
+[AC_MSG_CHECKING([C++ ABI version used by ${CXX-g++}])
+  AC_CACHE_VAL(octave_cv_cxx_abi_version,
+    [octave_cv_cxx_abi_version='0'
+    AC_LANG_SAVE
+    AC_LANG_CPLUSPLUS
+    cat > conftest.$ac_ext <<EOF
+bool FSmy_dld_fcn (void) { return false; }
+EOF
+    if AC_TRY_EVAL(ac_compile); then
+      if test "`${NM-nm} conftest.o | grep FSmy_dld_fcn__Fv`" != ""; then
+        octave_cv_cxx_abi_version=2
+      fi
+      if test "`${NM-nm} conftest.o | grep _Z12FSmy_dld_fcnv`" != ""; then
+        octave_cv_cxx_abi_version=3
+      fi
+    else
+      echo "configure: failed program was:" >&AC_FD_CC
+      cat conftest.$ac_ext >&AC_FD_CC
+    fi
+    AC_LANG_RESTORE
+  ])
+  AC_MSG_RESULT($octave_cv_cxx_abi_version)
+  AC_DEFINE_UNQUOTED(CXX_ABI_VERSION, $octave_cv_cxx_abi_version)
+])
+
Index: configure.in
===================================================================
RCS file: /cvs/octave/configure.in,v
retrieving revision 1.348
diff -u -3 -p -r1.348 configure.in
--- configure.in        2001/05/23 06:41:58     1.348
+++ configure.in        2001/06/28 19:10:12
@@ -185,6 +185,14 @@ changequote([,])dnl
   ;;
 esac
 
+
+# The GNU C++ compiler uses either ABI version 2, default for GCC versions
+# <= 2.95.x, or version 3, default for GCC versions >= 3.0. However, we 
+# can't just assume one or the other since gcc-2.9[6-7] snapshots could 
+# be built to use either ABI.
+
+OCTAVE_CXX_ABI_VERSION
+
 CXX_VERSION=
 if test -n "$gxx_version"; then
   CXX_VERSION="$gxx_version"
Index: acconfig.h
===================================================================
RCS file: /cvs/octave/acconfig.h,v
retrieving revision 1.47
diff -u -3 -p -r1.47 acconfig.h
--- acconfig.h  2001/05/02 06:15:07     1.47
+++ acconfig.h  2001/06/28 19:10:12
@@ -14,6 +14,9 @@
    internal array and matrix classes. */
 #undef BOUNDS_CHECKING
 
+/* Define to the C++ ABI version your compiler uses.  */
+#undef CXX_ABI_VERSION
+
 /* Define if your C++ runtime library is ISO compliant. */
 #undef CXX_ISO_COMPLIANT_LIBRARY

Index: src/dynamic-ld.cc
===================================================================
RCS file: /cvs/octave/src/dynamic-ld.cc,v
retrieving revision 1.64
diff -u -3 -p -r1.64 dynamic-ld.cc
--- src/dynamic-ld.cc   2000/04/04 06:16:23     1.64
+++ src/dynamic-ld.cc   2001/06/28 22:51:11
@@ -24,6 +24,10 @@ Software Foundation, 59 Temple Place - S
 #include <config.h>
 #endif
 
+#include <algorithm>
+#include <strstream>
+#include <cctype>
+
 #include "oct-time.h"
 #include "file-stat.h"
 
@@ -311,13 +315,69 @@ octave_dynamic_loader::remove (const std
 std::string
 octave_dynamic_loader::mangle_name (const std::string& name)
 {
-#if defined (CXX_PREPENDS_UNDERSCORE)
-  std::string retval ("_FS");
-#else
-  std::string retval ("FS");
-#endif
+  std::string retval;
+
+#if defined(__GNUC__)
+
+# if CXX_ABI_VERSION < 2
+#  error Unsupported GNU C++ ABI version. Must be >= 2.
+# elif CXX_ABI_VERSION == 2
+
+#  if defined (CXX_PREPENDS_UNDERSCORE)
+  retval = ("_FS");
+#  else
+  retval = ("FS");
+#  endif
   retval.append (name);
   retval.append ("__FRC12octave_shlib");
+
+# elif CXX_ABI_VERSION == 3
+
+  /* GNU C++ ABI v3 uses _Z followed by the length of the symbol.  We 
+     add 2 to account for "FS".  */
+  std::ostrstream mangled_name;
+  mangled_name << "_Z" << (name.length () + 2) << "FS";
+  mangled_name << name << "RK12octave_shlib" << std::ends;
+  retval = mangled_name.str ();
+  mangled_name.freeze (0);
+
+# else /* CXX_ABI_VERSION */
+#  warning Unsupported GNU C++ ABI version. Supported versions are <= 3.
+# endif /* CXX_ABI_VERSION */
+
+#elif defined(__SUNPRO_CC)
+
+  /* Sun Workshop uses __1c followed by the length of the symbol, encoded
+     in the most bizarre way, almost base-26, but not quite: the least 
+     significant digit goes from 'B' to 'Z', and the rest from 'b' to 'z'.
+     Go figure.  We add 2 to account for "FS".  */
+  
+  std::string::size_type len = name.length () + 2;
+  std::ostrstream ostr;
+  while (len > 25)
+    {
+      int digit = len % 26;
+      len /= 26;
+      ostr << static_cast<char> ('a' + digit);
+    }
+  ostr << static_cast<char> ('a' + len);
+
+  ostr << std::ends;
+  std::string mangled_len = ostr.str ();
+  ostr.freeze (0);
+  mangled_len[0] = std::toupper (mangled_len[0]);
+  std::reverse (mangled_len.begin (), mangled_len.end ());
+
+  std::ostrstream mangled_name;
+  mangled_name << "__1c" << mangled_len << "FS" << 
+    name << "6FrknMoctave_shlib__b_" << std::ends;
+  retval = mangled_name.str ();
+  mangled_name.freeze (0);
+
+#else
+# warning Unsupported C++ ABI version.
+#endif /* __GNUC__ */
+
   return retval;
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]