C++ runtime version patch for testing

2013-01-27 Thread David Chisnall
Hi All,

Here is a patch that, I believe, should fix the symbol version mismatches 
between the runtime and the STL implementation.  I have run the exception tests 
from libcxxrt with this patch applied and:

- libsupc++  libstdc++
- libcxxrt  libstdc++
- libcxxrt  libc++

All tests pass for me now.  Please let me know if there are any problems with 
this, otherwise I'll aim to commit it today or tomorrow with a 1-week MFC.

David

Index: gnu/lib/libsupc++/Version.map
===
--- gnu/lib/libsupc++/Version.map   (revision 245840)
+++ gnu/lib/libsupc++/Version.map   (working copy)
@@ -142,6 +142,28 @@
 _ZdaPvRKSt9nothrow_t;
 _ZdlPv;
 _ZdlPvRKSt9nothrow_t;
+extern C++ {
+  std::set_new_handler*;
+  std::set_terminate*;
+  std::set_unexpected*;
+  std::bad_alloc*;
+
+  std::bad_alloc*;
+  std::bad_cast*;
+  std::exception*;
+
+  typeinfo for std::bad_alloc;
+  typeinfo for std::bad_cast;
+  typeinfo for std::exception;
+
+  typeinfo name for std::bad_alloc;
+  typeinfo name for std::bad_cast;
+  typeinfo name for std::exception;
+
+  vtable for std::bad_alloc;
+  vtable for std::bad_cast;
+  vtable for std::exception;
+};
 };
 
 CXXABI_1.3.1 {
Index: lib/libcxxrt/Version.map
===
--- lib/libcxxrt/Version.map(revision 245840)
+++ lib/libcxxrt/Version.map(working copy)
@@ -209,18 +209,7 @@
 
 std::type_info::type_info(std::type_info const);
 std::type_info::type_info(std::type_info const);
-std::type_info::~type_info();
-std::type_info::~type_info();
-std::type_info::~type_info();
 std::type_info::operator=(std::type_info const);
-std::unexpected();
-std::get_terminate();
-std::set_terminate(void (*)());
-std::get_unexpected();
-std::set_unexpected(void (*)());
-std::set_new_handler(void (*)());
-std::uncaught_exception();
-std::terminate();
 
 
 # Extensions
@@ -243,70 +232,25 @@
 CXXRT_1.0 {
 
 extern C++ {
-std::bad_cast::what() const;
-std::bad_typeid::what() const;
-std::bad_alloc::what() const;
-std::exception::what() const;
 std::type_info::name() const;
 std::type_info::before(std::type_info const) const;
 std::type_info::operator==(std::type_info const) const;
 std::type_info::operator!=(std::type_info const) const;
-std::bad_typeid::bad_typeid(std::bad_typeid const);
-std::bad_typeid::bad_typeid();
-std::bad_typeid::bad_typeid(std::bad_typeid const);
-std::bad_typeid::bad_typeid();
-std::bad_typeid::~bad_typeid();
-std::bad_typeid::~bad_typeid();
-std::bad_typeid::~bad_typeid();
-std::bad_typeid::operator=(std::bad_typeid const);
 std::bad_cast::bad_cast(std::bad_cast const);
 std::bad_cast::bad_cast();
 std::bad_cast::bad_cast(std::bad_cast const);
 std::bad_cast::bad_cast();
-std::bad_cast::~bad_cast();
-std::bad_cast::~bad_cast();
-std::bad_cast::~bad_cast();
 std::bad_cast::operator=(std::bad_cast const);
-std::bad_alloc::bad_alloc(std::bad_alloc const);
-std::bad_alloc::bad_alloc();
-std::bad_alloc::bad_alloc(std::bad_alloc const);
-std::bad_alloc::bad_alloc();
-std::bad_alloc::~bad_alloc();
-std::bad_alloc::~bad_alloc();
-std::bad_alloc::~bad_alloc();
-std::bad_alloc::operator=(std::bad_alloc const);
 std::exception::exception(std::exception const);
 std::exception::exception();
 std::exception::exception(std::exception const);
 std::exception::exception();
-std::exception::~exception();
-std::exception::~exception();
-std::exception::~exception();
 std::exception::operator=(std::exception const);
 
 
-vtable for std::bad_typeid;
-vtable for std::bad_cast;
-vtable for std::bad_alloc;
-vtable for std::exception;
-vtable for std::type_info;
-typeinfo for std::bad_typeid;
-typeinfo for std::bad_cast;
-typeinfo for std::bad_alloc;
-typeinfo for std::exception;
-typeinfo for std::type_info;
-typeinfo name for std::bad_typeid;
-typeinfo name for std::bad_cast;
-typeinfo name for std::bad_alloc;
-typeinfo name for std::exception;
-typeinfo name for std::type_info;
 
-std::type_info::__is_function_p() const;
-std::type_info::__do_upcast(__cxxabiv1::__class_type_info const*, 
void**) const;
-std::type_info::__is_pointer_p() const;
 
 
-
 };
 __cxa_allocate_dependent_exception;
 __cxa_current_primary_exception;
@@ -317,6 +261,15 @@
 
 } CXXABI_1.3.1;
 
+
+GLIBCXX_3.4.9 {
+extern C++ {
+

Re: C++ runtime version patch for testing

2013-01-27 Thread David Chisnall
On 27 Jan 2013, at 15:03, Konstantin Belousov wrote:

 On Sun, Jan 27, 2013 at 01:28:44PM +, David Chisnall wrote:
 +  std::set_new_handler*;
 What are the symbols you assigning the version there ? I cannot find
 anything in the libstdc++.so export list which would match the line.

std::set_new_handler(void (*)())

# objdump -T /usr/lib/libsupc++.so  | c++filt | grep new_h
9010 __float128DF .text 000e  GLIBCXX_3.4 
std::set_new_handler(void (*)())

 +  std::set_terminate*;
 +  std::set_unexpected*;
 +  std::bad_alloc*;
 +
 +  std::bad_alloc*;
 std::bad_alloc seems to be duplicated.

Thanks, removed.

 Besides that, pristine libstdc++.so exports 'std::bad_alloc::what() const'
 at the GLIBCXX_3.4.9 namespace. You did this for the *::what()' from
 libcxxrt but not for the libsupc++.

Ooops.  I wrote a script that checked for version mismatches, but for some 
reason I missed this one.  Running it again, it shows two mismatches, both 
fixed in the new version of the diff.


 +  std::bad_cast*;
 +  std::exception*;
 +
 +  typeinfo for std::bad_alloc;
 +  typeinfo for std::bad_cast;
 +  typeinfo for std::exception;
 +
 +  typeinfo name for std::bad_alloc;
 +  typeinfo name for std::bad_cast;
 +  typeinfo name for std::exception;
 +
 +  vtable for std::bad_alloc;
 +  vtable for std::bad_cast;
 +  vtable for std::exception;
 +};
 };
 
 CXXABI_1.3.1 {
 Index: lib/libcxxrt/Version.map
 ===
 --- lib/libcxxrt/Version.map (revision 245840)
 +++ lib/libcxxrt/Version.map (working copy)
 @@ -209,18 +209,7 @@
 
 std::type_info::type_info(std::type_info const);
 std::type_info::type_info(std::type_info const);
 -std::type_info::~type_info();
 -std::type_info::~type_info();
 -std::type_info::~type_info();
 std::type_info::operator=(std::type_info const);
 [omitted]
 
 Do applications record the dependency on the libcxxrt directly,
 using the DT_NEEDED tag ?

I don't believe so, they get it indirectly via libc++ or libstdc++.  How can I 
check?

David

Index: gnu/lib/libsupc++/Version.map
===
--- gnu/lib/libsupc++/Version.map   (revision 245840)
+++ gnu/lib/libsupc++/Version.map   (working copy)
@@ -130,6 +130,13 @@
 *;
 };
 
+GLIBCXX_3.4.9 {
+extern C++ {
+std::bad_alloc::what() const;
+std::bad_cast::what() const;
+};
+};
+
 GLIBCXX_3.4 {
 # operator new and new[]
 _Znai[jm];
@@ -142,6 +149,27 @@
 _ZdaPvRKSt9nothrow_t;
 _ZdlPv;
 _ZdlPvRKSt9nothrow_t;
+extern C++ {
+  std::set_new_handler*;
+  std::set_terminate*;
+  std::set_unexpected*;
+
+  std::bad_alloc*;
+  std::bad_cast*;
+  std::exception*;
+
+  typeinfo for std::bad_alloc;
+  typeinfo for std::bad_cast;
+  typeinfo for std::exception;
+
+  typeinfo name for std::bad_alloc;
+  typeinfo name for std::bad_cast;
+  typeinfo name for std::exception;
+
+  vtable for std::bad_alloc;
+  vtable for std::bad_cast;
+  vtable for std::exception;
+};
 };
 
 CXXABI_1.3.1 {
Index: lib/libcxxrt/Version.map
===
--- lib/libcxxrt/Version.map(revision 245840)
+++ lib/libcxxrt/Version.map(working copy)
@@ -209,18 +209,7 @@
 
 std::type_info::type_info(std::type_info const);
 std::type_info::type_info(std::type_info const);
-std::type_info::~type_info();
-std::type_info::~type_info();
-std::type_info::~type_info();
 std::type_info::operator=(std::type_info const);
-std::unexpected();
-std::get_terminate();
-std::set_terminate(void (*)());
-std::get_unexpected();
-std::set_unexpected(void (*)());
-std::set_new_handler(void (*)());
-std::uncaught_exception();
-std::terminate();
 
 
 # Extensions
@@ -243,70 +232,25 @@
 CXXRT_1.0 {
 
 extern C++ {
-std::bad_cast::what() const;
-std::bad_typeid::what() const;
-std::bad_alloc::what() const;
-std::exception::what() const;
 std::type_info::name() const;
 std::type_info::before(std::type_info const) const;
 std::type_info::operator==(std::type_info const) const;
 std::type_info::operator!=(std::type_info const) const;
-std::bad_typeid::bad_typeid(std::bad_typeid const);
-std::bad_typeid::bad_typeid();
-std::bad_typeid::bad_typeid(std::bad_typeid const);
-std::bad_typeid::bad_typeid();
-std::bad_typeid::~bad_typeid();
-std::bad_typeid::~bad_typeid();
-std::bad_typeid::~bad_typeid();
-std::bad_typeid::operator=(std::bad_typeid const);
 std::bad_cast::bad_cast(std::bad_cast const);
 std::bad_cast::bad_cast();
 

Re: C++ runtime version patch for testing

2013-01-27 Thread Konstantin Belousov
On Sun, Jan 27, 2013 at 06:15:51PM +0200, Konstantin Belousov wrote:
 On Sun, Jan 27, 2013 at 04:01:48PM +, David Chisnall wrote:
  On 27 Jan 2013, at 15:52, Konstantin Belousov wrote:
  
   On Sun, Jan 27, 2013 at 03:17:51PM +, David Chisnall wrote:
   
   Apparently c++filt from 2.23.1 binutils has bug, c++filt is
   not able to demangle the set_new_handler.
  
  I'm using the one from head, which may be the elftoolchain project one?  It 
  seems to be missing a man page...
  
 In head, the c++ demangler is coming from either binutils or gcc copy
 of libiberty. I did not looked which one is selected.
 
   You need to add 'std::bad_typeid::what() const' to 3.4.9 as well, it
   seems.
  
  Added
  
   Do readelf -d some binary and look for the needed tags. If libcxxrt
   is not passed on the linker command line and not recorded as needed
   in the libc++/libstdc++, it should be fine.
  
   0x0001 (NEEDED) Shared library: [libcxxrt.so.1]
  
  This is with something compiled with -stdlib=libc++. It seems the
  (NEEDED) is there even if I compile with clang -lc++, instead of
  clang++, so the linker is adding it via the indirect dependency? Or
  does it show up because libc++ has that line too?
 
 Until recently, the default behaviour of the ELF linker was to record
 all second order needed libraries (i.e. libraries needed by a library
 specified on the linker command line) in the final link result. This is
 controllable with --copy-dt-needed-entries linker flag and recently
 the default were flipped to --no-copy.
 
 
   Your changes to libcxxrt obviously break the ABI, removing the symbols
   from the version namespace, but my hope is that namespace for libcxxrt
   is actually not part of the _system_ ABI. Thus the question.
  
  I'm okay with breaking the libcxxrt ABI at this point. libc++ is
  not part of the standard install, and is there for testing in 9.1.
  libcxxrt isn't linked against anything unless you use libc++ (or
  libstdc++ and a line in libmap.conf) so nothing non-experimental
  should use it. For 9.2, I'd like to have an ABI that we can support
  long term.
 
 You might be okay with ABI breakage, but the project is not.
 Having ABI breakage on the stable branch is very unfortunate both
 from the technical and PR points of view. You should consider using
 .gnu.warning. section or some other mechanism to explicitely warn
 about using libcxxrt begin unsupported, or better, remove it from
 the stable branch.

I noted one more thing to verify. Shouldn't the GLIBCXX_3.4.9 version
inherit from the GLIBCXX_3.4, both for libsupc++ and libcxxrt ? I cannot
verify the stock libstdc++ right now, but I suspect that namespace is
inherited, and this must be fixed before the commit, if true.


pgpKQhR7iEfFy.pgp
Description: PGP signature