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

Reply via email to