Ambiguities in version script

Ian Lance Taylor iant@google.com
Sat Jan 9 19:06:00 GMT 2010


Paolo Carlini <paolo.carlini@oracle.com> writes:

>> Does anybody want to argue that it is a good idea for the version
>> script to work this way?  Or should I send in a patch to change it?
>
> I suspect this issue is due to the sadly 'famous' here oversight a few
> years ago where we started to export some new symbols with an old
> version number, instead of the current one. As you may imagine, the
> users experienced some weird link error messages. Then Jakub helped
> sorting out the issue, for sure he knows better than me the details of
> his fix, I'm afraid some (minor) problems cannot be fixed completely
> at this time without breaking the abi.
>
> So... I would say, if you are fully aware of the specific issue I
> mentioned above, then go ahead with proposing a linker script patch,
> otherwise, if you need technical details first ask Jakub

The way a linker uses a version script is to say "given this symbol
with no version, what version should I use?"  In other words, a
version script assigns a unique version to a symbol.  So it's hard to
understand what it means to list a symbol multiple times in a version
script.


The GNU linker picks the first symbol that it finds.  So this is a
simple patch which produces the same results as the current linker
script:

Index: abi/pre/gnu.ver
===================================================================
--- abi/pre/gnu.ver	(revision 155510)
+++ abi/pre/gnu.ver	(working copy)
@@ -802,7 +802,8 @@ GLIBCXX_3.4.4 {
 GLIBCXX_3.4.5 {
 
     # std::string
-    _ZNKSs11_M_disjunctEPKc;
+    # This symbol has two versions.
+    #_ZNKSs11_M_disjunctEPKc;
     _ZNKSs15_M_check_lengthE[jmy][jmy]PKc;
     _ZNSs4_Rep26_M_set_length_and_sharableE*;
     _ZNSs7_M_copyEPcPKc[jmy];
@@ -810,7 +811,8 @@ GLIBCXX_3.4.5 {
     _ZNSs9_M_assignEPc[jmy]c;
 
     # std::wstring
-    _ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw;
+    # This symbol has two versions.
+    #_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw;
     _ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthE[jmy][jmy]PKc;
     _ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableE*;
     _ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKw[jmy];
@@ -839,7 +841,8 @@ GLIBCXX_3.4.6 {
 
     _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE9showmanycEv;
 
-    _ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv;
+    # This is in GLIBCXX_3.4.
+    #_ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv;
 
     _ZN9__gnu_cxx6__poolILb1EE13_M_initializeEv;
 



But this patch is a little odd, because, at least for the M_disjunct
cases, I am commenting out the current version of the symbol.  That
version is coming from compatibility.cc.  If I comment out the old
listing for the symbol, then the GNU linker drops the hidden
GLIBCXX_3.4 versions of the symbols, even though they are present in
compatibility.cc.  This happens because when the GNU linker finds a
version associated with a symbol, it looks it up in that specific
version in the version script to see whether it should be global or
local.  GLIBCXX_3.4 has a wildcard match for all symbols to force them
to be local.

Needless to say, none of this behaviour is documented.

So I guess I have to figure out whether to make gold act like the GNU
linker, even though it doesn't make much sense.

I guess my only comment for now about the libstdc++ version script is
that it lists _ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv
twice, and that is pointless.  Only the first version of that symbol,
the one in GLIBCXX_3.4, will be used.

Ian



More information about the Libstdc++ mailing list