Bug 43968 - undefined references to `std::{num_get, num_put, money_get, money_put}< [...] >::id' with -static
Summary: undefined references to `std::{num_get, num_put, money_get, money_put}< [...]...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-03 08:05 UTC by Uroš Bizjak
Modified: 2010-05-05 06:24 UTC (History)
2 users (show)

See Also:
Host: alpha-linux-gnu
Target: alpha-linux-gnu
Build: alpha-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2010-05-03 17:44:18


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Uroš Bizjak 2010-05-03 08:05:20 UTC
libmudflap.c++/pass41-frag.cxx test case fails with -static [1] due to link problem in libstdc++:

FAIL: libmudflap.c++/pass41-frag.cxx (-static) (test for excess errors)
WARNING: libmudflap.c++/pass41-frag.cxx (-static) compilation failed to produce executable

The problem can be triggered with following command:

/home/uros/gcc-build/gcc/g++ -B/home/uros/gcc-build/gcc -I/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/include/alphaev68-unknown-linux-gnu -I/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/include -I/home/uros/gcc-svn/trunk/libstdc++-v3/libsupc++ -L/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs -static pass41-frag.cxx

and compilation fails with:

/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:421: undefined reference to `std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::id'
/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:422: undefined reference to `std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::id'
/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:423: undefined reference to `std::money_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::id'
/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:424: undefined reference to `std::money_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::id'
/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:426: undefined reference to `std::num_get<wchar_t, std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::id'
/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:427: undefined reference to `std::num_put<wchar_t, std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::id'
/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:428: undefined reference to `std::money_get<wchar_t, std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::id'
/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(locale.o):/home/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/src/../../../../gcc-svn/trunk/libstdc++-v3/src/locale.cc:429: undefined reference to `std::money_put<wchar_t, std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::id'
collect2: ld returned 1 exit status

Without -static, everything works OK.

[1] http://gcc.gnu.org/ml/gcc-testresults/2010-05/msg00240.html
Comment 1 Uroš Bizjak 2010-05-03 08:14:17 UTC
The testcase:

#include <string>
#include <iostream>

int
main (int argc, char *argv[])
{
    std::string myStr = "Hello, World!";
    std::cout << myStr << std::endl;
    return 0;
}
Comment 2 Paolo Carlini 2010-05-03 10:52:00 UTC
Before we do anything here, you should try to explain why the problem happens only on alpha, because on x86_64 it doesn't and those symbols are exported ("V"). Are the symbols exported on alpha? Are we **really** sure that aging target is otherwise ok, binutils included?
Comment 3 Uroš Bizjak 2010-05-03 11:46:46 UTC
(In reply to comment #2)
> Before we do anything here, you should try to explain why the problem happens
> only on alpha, because on x86_64 it doesn't and those symbols are exported
> ("V"). Are the symbols exported on alpha? Are we **really** sure that aging
> target is otherwise ok, binutils included?

In the hope it helps, this is what I get from libstdc++-v3/src/.libs/libstdc++.a:

$ c++filt _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::id

$ nm libstdc++.a | grep _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
                 U _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
0000000000000000 u _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE


Comment 4 Uroš Bizjak 2010-05-03 11:50:33 UTC
As shown, these symbols are exported as "u":

    `u'
          The symbol is a unique global symbol.  This is a GNU
          extension to the standard set of ELF symbol bindings.  For
          such a symbol the dynamic linker will make sure that in the
          entire process there is just one symbol with this name and
          type in use.
Comment 5 Paolo Carlini 2010-05-03 11:52:18 UTC
This is what I get on x86_64:

nm libstdc++.a | grep _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
                 U _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
                 U _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
0000000000000000 V _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE

thus, seems a target problem to me.
Comment 6 Uroš Bizjak 2010-05-03 12:12:49 UTC
(In reply to comment #5)
> This is what I get on x86_64:

> thus, seems a target problem to me.

Do you have any advice, where/how these symbols get exported? I would like to analyze the failure, so we can blame some other tool ;)

(No, I'm not sure that binutils work correctly...)

Comment 7 Paolo Carlini 2010-05-03 12:17:19 UTC
In locale-inst.o

Comment 8 Uroš Bizjak 2010-05-03 17:25:55 UTC
(In reply to comment #7)
> In locale-inst.o

Strange, on alpha it is defined in compatibility-ldbl.o.
Comment 9 Paolo Carlini 2010-05-03 17:41:58 UTC
Ah yes, it's probably because of the strange workarounds put in place for long double. Anyway, if you encounter special issues having to do with that, Jakub is the reference person.
Comment 10 Uroš Bizjak 2010-05-03 17:44:18 UTC
(In reply to comment #9)
> Ah yes, it's probably because of the strange workarounds put in place for long
> double. Anyway, if you encounter special issues having to do with that, Jakub
> is the reference person.

Added to CC.

Comment 11 Uroš Bizjak 2010-05-04 12:31:14 UTC
I belive this problem also shows on powerpc64-linux-gnu, configured with
--with-long-double-128 [1]:

FAIL: libmudflap.c++/pass28-frag.cxx (-static) (test for excess errors)
WARNING: libmudflap.c++/pass28-frag.cxx (-static) compilation failed to produce executable
FAIL: libmudflap.c++/pass41-frag.cxx (-static) (test for excess errors)
WARNING: libmudflap.c++/pass41-frag.cxx (-static) compilation failed to produce executable
FAIL: libmudflap.c++/pass55-frag.cxx (-static) (test for excess errors)
WARNING: libmudflap.c++/pass55-frag.cxx (-static) compilation failed to produce executable
FAIL: libmudflap.c++/pass57-frag.cxx (-static) (test for excess errors)
WARNING: libmudflap.c++/pass57-frag.cxx (-static) compilation failed to produce executable

It looks that long-double support in libstdc++ is broken for certain symbols.

[1] http://gcc.gnu.org/ml/gcc-testresults/2010-05/msg00285.html
Comment 12 Paolo Carlini 2010-05-04 12:35:53 UTC
Can well be, personally I *never* checked -static on the targets affected by the 128 bit long double issue. I'm not even sure if Jakub himself did...
Comment 13 Jakub Jelinek 2010-05-04 13:57:24 UTC
I guess this must be related to STB_GNU_UNIQUE, at least I can't reproduce this on ppc on Fedora 11 where STB_GNU_UNIQUE wasn't supported (even with recentish gcc), while according to log I see these
WARNING: libmudflap.c++/pass41-frag.cxx (-static) compilation failed to produce executable
on ppc, ppc64, s390 and s390x when doing 4.4.*-RH package builds in Fedora 12+ where STB_GNU_UNIQUE is supported.

libstdc++.a symbols look good though:
0000000000000000 V _ZGVNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
0000000000000000 u _ZNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
0000000000000000 V _ZGVNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
0000000000000000 u _ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE
Comment 14 Uroš Bizjak 2010-05-04 14:16:27 UTC
(In reply to comment #13)
> I guess this must be related to STB_GNU_UNIQUE, at least I can't reproduce this
> on ppc on Fedora 11 where STB_GNU_UNIQUE wasn't supported (even with recentish
> gcc), while according to log I see these
> WARNING: libmudflap.c++/pass41-frag.cxx (-static) compilation failed to produce
> executable
> on ppc, ppc64, s390 and s390x when doing 4.4.*-RH package builds in Fedora 12+
> where STB_GNU_UNIQUE is supported.

Thanks for your comments!

FYI, my binutils are "GNU ld (GNU Binutils) 2.20.1 20100303".

I don't know when binutils was upgraded, but looking back, I see that at the end of april, results on alpha for this test were clean [1].

[1] http://gcc.gnu.org/ml/gcc-testresults/2010-04/msg02616.html
Comment 15 Jakub Jelinek 2010-05-04 15:31:33 UTC
Ah, seems a generic ar/ranlib bug, apparently STB_GNU_UNIQUE symbols aren't added into ar index :(.
Wonder why it hasn't showed up elsewhere yet.  The reason why this doesn't hit us in libstdc++.a on x86-64 is that the STB_GNU_UNIQUE symbols locale-inst.o
needs are in locale-inst.o rather than compatibility-ldbl.o.
Looking into it.
Comment 16 Paolo Carlini 2010-05-04 15:33:27 UTC
Thanks Jakub.
Comment 18 Uroš Bizjak 2010-05-04 17:42:31 UTC
(In reply to comment #15)
> Ah, seems a generic ar/ranlib bug, apparently STB_GNU_UNIQUE symbols aren't
> added into ar index :(.
> Wonder why it hasn't showed up elsewhere yet.  The reason why this doesn't hit
> us in libstdc++.a on x86-64 is that the STB_GNU_UNIQUE symbols locale-inst.o
> needs are in locale-inst.o rather than compatibility-ldbl.o.
> Looking into it.

Now that you mentioned - the problem was uncovered by [1]:

2010-04-28  Uros Bizjak  <ubizjak@gmail.com>

	* config/alpha/elf.h (ASM_DECLARE_OBJECT_NAME): Use gnu_unique_object
	type if available.

[1] http://gcc.gnu.org/ml/gcc-patches/2010-04/msg01751.html

I wonder if the ar/ranlib bug is severe enough that we need to check for newer version of the binutils in configure.ac. Currently we have:

 [gcc_GAS_CHECK_FEATURE([gnu_unique_object], gcc_cv_as_gnu_unique_object,
   [elf,2,19,52],,
Comment 19 Uroš Bizjak 2010-05-05 06:24:07 UTC
Not a gcc bug.