http://sourceware.org/bugzilla/show_bug.cgi?id=13406
Bug #: 13406 Summary: version script: please allow anonymous tag to be combined with other tags Product: binutils Version: 2.21 Status: NEW Severity: enhancement Priority: P2 Component: binutils AssignedTo: unassig...@sourceware.org ReportedBy: lio...@mamane.lu Classification: Unclassified Created attachment 6054 --> http://sourceware.org/bugzilla/attachment.cgi?id=6054 patch to allow anonymous version tag combined with non-anonymous version tag In a version script, currently one is not allowed to use an anonymous version tag along with another tag. I'm not sure why that is, http://cygwin.com/ml/binutils/2001-12/msg00182.html says "per Ulrich's request". I would like that to be allowed. My use case is within LibreOffice, which is structured as an executable that (lazily, as the need my arise) dlopen()s various libraries, which themselves lazily dlopen() the libraries they need, ... These libraries use version link scripts along the lines of: UDK_3_0_0 { global: _ZTI*; _ZTS*; # weak RTTI symbols for C++ exceptions component_writeInfo; component_getFactory; local: *; }; In particular, they hide (not export) all symbols by default. This plays out badly with an optimisation within libstdc++, which is that when an empty std::string is created, it does not get memory allocated from the heap, but the internal data pointer points to a unique static address allocated by the linker via a unique symbol (_S_empty_rep_storage). The std::string destructor special-cases that address to avoid calling heap deallocation on it. The situation is that a library using such a version script (an internal library of LibreOffice, mysqlc.uno.so; that is the "native" driver to MySQL for LibreOffice) ldopen()s a library that does *not* use such a version script (a library that is external to LibreOffice, libmysqlcppconn.so; that is the official C++ API to MySQL: http://www.mysql.com/downloads/connector/cpp/). The core of the problem is that because of the "local: *;" in the version script of mysqlc.uno.so, mysqlc.uno.so and libmysqlcppconn.so have a *different* _S_empty_rep_storage symbol; the linker does *not* merge them. So when code in mysqlc.uno.so calls a function in libmysqlcppconn.so, gets an empty std::string and that std::string goes out of scope: 1) The empty std::string is constructed within libmysqlcppconn.so, so its internal data pointer points to libmysqlcppconn's _S_empty_rep_storage. 2) That std::string is destructed in mysqlc.uno.so, so (code equivalent to) this is executed within mysqlc.uno.so: if (the_string.pData != &_S_empty_rep_storage) free(the_string.pData) As it is compared to the address of mysqlc.uno's _S_empty_rep_storage, the test evaluates to false, and heap deallocation is called on libmysqlcppconn.so's _S_empty_rep_storage, which was not heap allocated, and all hell breaks loose ;-) In particular, in libstdc++ debug mode (compile with -D_GLIBCXX_DEBUG), this immediately aborts the whole program. To avoid that, I would like to add to mysqlc.uno.so's version link script: { global: _ZNSs4_Rep20_S_empty_rep_storageE; }; Patch is attached. Tested, works for me, solves the described problem within LibreOffice. This would also solve bug 12548 as a side-effect :) -- Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils