On 02/19/2013 07:22 PM, Florian Weimer wrote:
On 02/19/2013 07:06 PM, Stephan Bergmann wrote:
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:
We tracked this down to a bug in ld:
<http://sourceware.org/bugzilla/show_bug.cgi?id=15107>
I'm not sure that bug is relevant to my problem. (I admittedly cannot
make much from that bug report itself, but when I look at the referenced
thread <http://sourceware.org/ml/binutils/2013-01/msg00362.html> "ld:
linking to GNU_UNIQUE symbol does not set ELFOSABI_GNU" I get the
impression that this is about an .so erroneously marked as "OS/ABI: UNIX
- System V" instead of "OS/ABI: UNIX - GNU" even though it references a
GNU_UNIQUE symbol. But all the relevant libraries in my Fedora 18 case,
both /usr/lib64/libstdc++.so.6 and those other libraries using
_ZNSs4_Rep20_S_empty_rep_storageE, are marked as "OS/ABI: UNIX - GNU"
anway---maybe "by luck" because of something else.)
Again, my problem is as follows: I have a C++ file that instantiates
static class template member
template<typename _CharT, typename _Traits, typename _Alloc>
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
(sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
sizeof(size_type)];
from the GCC libstdc++ with _CharT = char, _Traits =
std::char_traits<char>, _Alloc = std::allocator<char>. In both my
cases, the relevant parts of the preprocessed output are the same, but
in the SLED 11 case, the GCC .s output of that C++ file contains
.weak _ZNSs4_Rep20_S_empty_rep_storageE
.section
.bss._ZNSs4_Rep20_S_empty_rep_storageE,"awG",@nobits,_ZNSs4_Rep20_S_empty_rep_storageE,comdat
.align 32
.type _ZNSs4_Rep20_S_empty_rep_storageE, @object
.size _ZNSs4_Rep20_S_empty_rep_storageE, 32
_ZNSs4_Rep20_S_empty_rep_storageE:
.zero 32
(i.e., "@object") while in the Fedora 18 case, it contains
.weak _ZNSs4_Rep20_S_empty_rep_storageE
.section
.bss._ZNSs4_Rep20_S_empty_rep_storageE,"awG",@nobits,_ZNSs4_Rep20_S_empty_rep_storageE,comdat
.align 32
.type _ZNSs4_Rep20_S_empty_rep_storageE, @gnu_unique_object
.size _ZNSs4_Rep20_S_empty_rep_storageE, 32
_ZNSs4_Rep20_S_empty_rep_storageE:
.zero 32
(i.e., "@gnu_unique_object"). My take (backed by my experience that the
former case leads to runtime trouble while the latter does not) is that
the former case is incorrect. So there must be something that causes
the erroneous labeling as "@object" instead of "@gnu_unique_object" in
the GCC .s output in the former case, and I'd like to understand what
that something is.
Now, one could assume that the toolchain of the former case is old
enough to not support that "unique global symbol" GNU extension at all.
However, there are two things that speak against that:
For one, the former case has
$ 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
so there /are/ symbols marked as "u" there. Just, oddly,
_ZNSs4_Rep20_S_empty_rep_storageE is not.
For another, when I look at libraries built on another old toolchain
(RHEL 5), the situation is rather different there, in that libstdc++
consistently offers those symbols as "V"
$ nm -D /opt/libreoffice4.0/ure/lib/libstdc++.so.6 | grep empty_rep_storage
00000000002efee0 V _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE
00000000002efe00 V _ZNSs4_Rep20_S_empty_rep_storageE
while those other libraries that use _ZNSs4_Rep20_S_empty_rep_storageE
reference it as "U"
$ nm -D /opt/libreoffice4.0/program/libsdlo.so | grep empty_rep_storage
U _ZNSs4_Rep20_S_empty_rep_storageE
Stephan