[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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [patch] dynamic linking for GCC v2/3 and Sun C++ ABI,
Mumit Khan <=