How does _ZNSs4_Rep20_S_empty_rep_storageE (not) become a unique global symbol?

Stephan Bergmann sbergman@redhat.com
Tue Feb 19 18:07:00 GMT 2013


I'm puzzled by the following on Linux, where I don't understand what 
causes it that a given symbol is exported as "u" (when viewed with nm, 
which documents "u" as "a unique global symbol. This is a GNU 
extension...") or not:

* On an older toolchain (SLED 11 with GCC 4.3.4 and binutils 2.21.1), we 
have

> $ nm -D /usr/lib64/libstdc++.so.6.0.16 | grep empty_rep_storage
> 00000000002f7660 u _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE
> 00000000002f7580 B _ZNSs4_Rep20_S_empty_rep_storageE

where the latter (aka "std::basic_string<char, std::char_traits<char>, 
std::allocator<char> >::_Rep::_S_empty_rep_storage") is not exported as 
"u" while the former (aka "std::basic_string<wchar_t, 
std::char_traits<wchar_t>, std::allocator<wchar_t> 
 >::_Rep::_S_empty_rep_storage") is.  Also, in other dynamic libraries 
linked with that toolchain, _ZNSs4_Rep20_S_empty_rep_storageE is 
exported as "V", and:

** If libstdc++.so.6 is loaded after one of those other libraries, all 
libraries consistently bind to that other libraries' symbol, and 
everything works well.

** However, if libstdc++.so.6 is loaded first, it binds to its symbol, 
but all those other libraries loaded later bind to one of those other 
libaries' symbol, and there is an invalid delete on an address "0 bytes 
inside data symbol '_ZNSs4_Rep20_S_empty_rep_storageE'" from 
std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> 
 >::overflow(int) (in /usr/lib64/libstdc++.so.6.0.16), as reported by 
valgrind.

* But on a more recent toolchain (F18 with GCC 4.7.2 and binutils 
2.23.51), we have

> $ nm -D /usr/lib64/libstdc++.so.6.0.17 | grep empty_rep_storage
> 0000003c831024e0 u _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE
> 0000003c831024c0 u _ZNSs4_Rep20_S_empty_rep_storageE

Also, in dynamic libraries linked with that toolchain, 
_ZNSs4_Rep20_S_empty_rep_storageE is also exported as "u" and runtime 
behavior is just fine.

Now, why is _ZNSs4_Rep20_S_empty_rep_storageE exported as "B" resp. "V" 
in the first case, while it is consistently "u" in the second?

Stephan



More information about the Gcc mailing list