This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
On hppa-linux-gnu the symbol __signbitl@GLIBCXX_3.4 isn't exported anymore (4.4 20090317 built using binutils 2.19.1 and glibc-2.9)
Related to PR32666.
Mine
Created an attachment (id=17649) [edit] adds __signbitl for hppa Bloody hack but will probably work
There is no __signbitl export expected, from config/abi/post/hppa-linux-gnu/baseline_symbols.txt. Where is this from? Assume this would result in an abi_check FAIL? FYI gcc-4.4 hppa-linux results are fine: http://gcc.gnu.org/ml/gcc-testresults/2009-03/msg03004.html gcc-4.5 hppa-linux results with abi_check pass here: http://gcc.gnu.org/ml/gcc-testresults/2009-04/msg01492.html What is the current state on this?
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore > Bloody hack but will probably work Long double on hppa-linux is the same as double (64 bits). Dave
I believe the problem is the symbol was exported when it shouldn't have been. The signbit macro is provided by math.h.
> I believe the problem is the symbol was exported when it shouldn't have been. How? > The signbit macro is provided by math.h. But it's not in the baseline files showing that it is exported. This question was originally asked here: http://gcc.gnu.org/ml/gcc-patches/2008-03/msg00197.html -benjamin
- config/abi/pre/gnu.ver needs the __signbitl symbol mentioned as well. - the patch has an empty #ifdef/#endif at the end with this change the symbol is found in the library. checked with a native build on hppa-linux.
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore > > I believe the problem is the symbol was exported when it shouldn't have been. > > How? This is probably because __signbitl is not present in libc and libm. hppa-linux doesn't need __signbitl because sizeof(long double)==sizeof(double). "l" library functions just call __signbit. Thus, I believe that the lack of __signbitl in glibc caused this preoblem. __signbitl doesn't seem to be required by POSIX. However, LSB 2.1 specifies it. If __signbitl should be provided by glibc, then this is a glibc bug. The signbit macro is as follows: /* Return nonzero value if sign of X is negative. */ # ifdef __NO_LONG_DOUBLE_MATH # define signbit(x) \ (sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x)) # else # define signbit(x) \ (sizeof (x) == sizeof (float) \ ? __signbitf (x) \ : sizeof (x) == sizeof (double) \ ? __signbit (x) : __signbitl (x)) # endif This will fail if the call to __signbitl isn't optimized away. So, either the macro needs to be fixed, or __signbitl needs to be provided by glibc. The isfinite macro would have the same problem, but in that case glibc provides __finitel. > > The signbit macro is provided by math.h. > > But it's not in the baseline files showing that it is exported. This question > was originally asked here: > > http://gcc.gnu.org/ml/gcc-patches/2008-03/msg00197.html Why should a macro be exported? Dave
Gcc always seems to optimize the signbit macro.
Yes, if gcc does not determine that "sizeof (x) == sizeof (double)" then it would have to emit code for the if-then-else statement and this would create a reference to an undefined __signbitl. Has this ever happened? I've never seen it. At present glibc does not create an long double alias for the double __signbit function, but for the sake of correctness it probably should.
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore > At present glibc does not create an long double alias for the double __signbit > function, but for the sake of correctness it probably should. In my build of gcc 4.3.3 and also debian 4.3.2-1.1 (lenny), I see the symbol __signbitl in libstdc++.so.6.0.10. We also have __signbitl@@GLIBCXX_3.4. In libstdc++.a, I see: signbitl.o: 00000000 T __signbitl In 4.3, we had the function signbitl.c in libmath. This was removed in 4.4. Looking at the 4.3 implementation, I see that it assumes a 96-bit long double format. This is wrong for hppa-linux, but I think the signbit extraction works because of the alignment of the long double value in the union. Dave
If hppa-linux has long double the same as double (which raises the question why it hasn't switched over to 128-bit long double together with powerpc*/sparc*/s390*/alpha back in 2006), then __NO_LONG_DOUBLE_MATH should be defined and therefore no code will ever reference __signbitl from signbit macro (and __signbitl isn't a supported API, so nothing should really care). If we really want to change libstdc++ (which I'm not sure about, can you find a single shared library or binary that references __signbitl from libstdc++.so?), then the patch should actually handle __signbitl by calling __signbit and also should be through .symver directive turned into @ symbol instead of @@ to make sure nothing newly linked can reference it from libstdc++.so.
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore > ------- Comment #13 from jakub at gcc dot gnu dot org 2009-04-22 09:12 ------- > If hppa-linux has long double the same as double (which raises the question why > it hasn't switched over to 128-bit long double together with > powerpc*/sparc*/s390*/alpha back in 2006), then __NO_LONG_DOUBLE_MATH should be > defined and therefore no code will ever reference __signbitl from signbit macro > (and __signbitl isn't a supported API, so nothing should really care). The conversion was discussed but 1) HP was unwilling to provide their millicode support, 2) Richard Hendersen expressed an opinion that corner cases in the double double implementation made this approach problematic, and 3) Carlos was busy writing his master's thesis. So, we didn't switch over to a 128-bit long double. > If we really want to change libstdc++ (which I'm not sure about, can you find a > single shared library or binary that references __signbitl from libstdc++.so?), > then the patch should actually handle __signbitl by calling __signbit and also > should be through .symver directive turned into @ symbol instead of @@ to make > sure nothing newly linked can reference it from libstdc++.so. I fully agree. Dave
Well, double double is IMHO really very problematic format, but only powerpc* switched to it. alpha, s390* and sparc* use standard IEEE quad long double.
So what is required to close this issue? * Original submitter is incorrect, there has never been a __signbitl@GLIBCXX_3.4 symbol, and there should not be one now? * glibc on hppa-linux-gnu has never had a __signbitl symbol. * I have changed the glibc hppa-linux-gnu port to define __NO_LONG_DOUBLE_MATH, and therefore the signbit macro, even in the abscense of optimization, will always return a valid signbit function based on the type size.
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore > * Original submitter is incorrect, there has never been a > __signbitl@GLIBCXX_3.4 symbol, and there should not be one now? The symbol is present in libstdc++.so.6.0.9 and libstdc++.so.6.0.10, but not in libstdc++.so.6.0.8 or libstdc++.so.6.0.11. > * I have changed the glibc hppa-linux-gnu port to define __NO_LONG_DOUBLE_MATH, > and therefore the signbit macro, even in the abscense of optimization, will > always return a valid signbit function based on the type size. I'm not convinced this is a good idea at this point. As far as I know, it is ok to have the same size for double and long double. However, they are distinct types. Dave
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore >> * Original submitter is incorrect, there has never been a >> __signbitl@GLIBCXX_3.4 symbol, and there should not be one now? > > The symbol is present in libstdc++.so.6.0.9 and libstdc++.so.6.0.10, > but not in libstdc++.so.6.0.8 or libstdc++.so.6.0.11. If that's the case, then libstdc++ is to blame, and Benjamin's hackish patch should be reviewed and checked in. >> * I have changed the glibc hppa-linux-gnu port to define __NO_LONG_DOUBLE_MATH, >> and therefore the signbit macro, even in the abscense of optimization, will >> always return a valid signbit function based on the type size. > > I'm not convinced this is a good idea at this point. As far as I know, > it is ok to have the same size for double and long double. However, > they are distinct types. Perhaps I wasn't as clear as I should have been. The glibc port for hppa has always been configured never to build any long double code, and has always assumed that long double is not a distinct type. From glibc's perspective there is no such thing as having double and long double with the same size, there is only a configuration where double exists and all the long double functions alias to their double equivalents. The hppa port sets long-double-fcts = no in glibc and this causes all the aliases to be created, otherwise you'd never be able to link anything that used `l' ending math functions. Defining __NO_LONG_DOUBLE_MATH is just another step in the right direction to avoid using long double functions, and use the double functions instead. The upside is that, if and when, long double on hppa becomes the 128-bit quad long double, we can just follow the tried-and-tested procedure to migrate the glibc math routines. Cheers, Carlos.
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore > Perhaps I wasn't as clear as I should have been. The glibc port for > hppa has always been configured never to build any long double code, > and has always assumed that long double is not a distinct type. However, it appears to provide weak aliases for the `l' ending math functions. > From glibc's perspective there is no such thing as having double > and long double with the same size, there is only a configuration > where double exists and all the long double functions alias to their > double equivalents. The hppa port sets long-double-fcts = no in glibc > and this causes all the aliases to be created, otherwise you'd never > be able to link anything that used `l' ending math functions. Defining > __NO_LONG_DOUBLE_MATH is just another step in the right direction to > avoid using long double functions, and use the double functions instead. My concern is that this may remove the `l' ending math functions completely and their declarations. Unless the ABI is bumped, this may break existing code. It not at all clear to me that this is compatible with C99. See for example http://www.cygwin.com/ml/libc-alpha/2005-03/msg00172.html Dave
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore On Wed, 22 Apr 2009, dave at hiauly1 dot hia dot nrc dot ca wrote: > > From glibc's perspective there is no such thing as having double > > and long double with the same size, there is only a configuration > > where double exists and all the long double functions alias to their > > double equivalents. The hppa port sets long-double-fcts = no in glibc > > and this causes all the aliases to be created, otherwise you'd never > > be able to link anything that used `l' ending math functions. Defining > > __NO_LONG_DOUBLE_MATH is just another step in the right direction to > > avoid using long double functions, and use the double functions instead. > > My concern is that this may remove the `l' ending math functions > completely and their declarations. Unless the ABI is bumped, this > may break existing code. It not at all clear to me that this is > compatible with C99. Correct, removing these declarations (as glibc does on these platforms - I think SH is the only one affected not in ports) is not conforming to C99, whereas having the types the same width (but distinct types at the C language level) with the declarations present does conform. This is on my list of C standards issues in glibc, but I think it (and some other issues) may be deliberate on the part of the glibc maintainers. glibc does provide the functions on affected platforms, it just doesn't provide the required header declarations of them in math.h and complex.h.
Created an attachment (id=17682) [edit] glibc-no-long-double-math.patch I agree that even for __NO_LONG_DOUBLE_MATH we should provide *l prototypes (certainly for __USE_ISOC99, not sure about __USE_MISC alone), just redirecting to the non-l functions, though tgmath.h nor signbit/finite/... macros which just use sizeof obviously can stay as is. This patch is totally untested...
>The hppa port sets long-double-fcts = no in glibc > and this causes all the aliases to be created, otherwise you'd never > be able to link anything that used `l' ending math functions. Defining > __NO_LONG_DOUBLE_MATH is just another step in the right direction to > avoid using long double functions, and use the double functions instead. It seems to me like setting long-double-fcts = no in glibc should automatically define __NO_LONG_DOUBLE_MATH.... right? Anyway. From the .so range listed in #18 it looks like this was a regression in 4.2/4.3, perhaps related to C library changes. There was a __signbitl export in gnu.ver. gcc-3.4.6 __signbitl in GLIBCXX_3.4 gcc-4.1.2 __signbitl in GLIBCXX_3.4 gcc-4.2.4 __signbitl in GLIBCXX_3.4 gcc-4.3 __signbitl in GLIBCXX_3.4 So that's how it leaked out of libstdc++ so's. However, this symbol was never actually defined, exported and placed in the abi baseline for hppa-linux-gnu, inclusive gcc-3.4 to trunk. Or any other platform. Thus, why it was removed from gnu.ver, mistakenly as it turns out. . It would be my inclination to fix glibc and then alias as per Jakub's #13 comment for hppa-linux only.
So: * Original submitter is incorrect, there has never been a __signbitl@GLIBCXX_3.4 symbol, and there should not be one now? Right. This should have manifested as an abi-check FAIL starting in gcc-4.2, as a new symbol was added with the original version label. So gcc-4.2/4.3 had a regression from gcc-4.1 that gcc-4.4 fixed. That regression is http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32666 From that first log: http://gcc.gnu.org/bugzilla/attachment.cgi?id=13863&action=view You see: 65 __signbitl version status: incompatible GLIBCXX_3.4 type: function status: added From this I conclude that the libstdc++ abi checking was working, but ignored for 4.2 and the 4.3 release on this platform. That's ok, everybody was busy and there were some issues, but for 4.4 we are back on it. Of course, on the meta level, libstdc++ doing this math library hacking is just wrong and prone to failure: we want the C99 math library assumed and underneath us in either gcc support libs or at the libc level. That's why gcc-4.4/trunk tries to flee from this area after attempting to burn the remains of libmath.
Subject: Re: [4.4/4.5 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ not exported anymore On Thu, 23 Apr 2009, jakub at gcc dot gnu dot org wrote: > ------- Comment #21 from jakub at gcc dot gnu dot org 2009-04-23 06:28 ------- > Created an attachment (id=17682) [edit] > --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=17682&action=view) > glibc-no-long-double-math.patch > > I agree that even for __NO_LONG_DOUBLE_MATH we should provide *l prototypes > (certainly for __USE_ISOC99, not sure about __USE_MISC alone), just redirecting > to the non-l functions, though tgmath.h nor signbit/finite/... macros which > just use sizeof obviously can stay as is. > This patch is totally untested... This patch works for me on ARM (in that math.h and complex.h define the functions with it applied and the glibc test results are as expected).
Jakub's patch works for me on HPPA, and correctly exports the *l prototypes with __NO_LONG_DOUBLE_MATH set.
Action items left: 1) Checkin a patch to libc-ports to define __signbitl as an alias of __signbit on hppa. * Done: http://sourceware.org/ml/glibc-cvs/2009-q2/msg00277.html 2) Someone please add a stub to libstdc++ for __signbitl@GLIBCXX_3.4 that calls __signbitl in glibc. 3) Wait for Jakub to get his patch into glibc core. 4) Enable __NO_LONG_DOUBLE_MATH for hppa (different from NO_LONG_DOUBLE and long-double-fcts = no). #1, #3, and #4 are things I can work on. Can someone please do #2? When #1 and #2 are done we can consider *this* issue closed.
> 2) Someone please add a stub to libstdc++ for __signbitl@GLIBCXX_3.4 that calls > __signbitl in glibc. Hmm. Well, you cannot actually add a new symbol versioned for the first release in the ninth release. That is why this is a 4.2/4.3 regression. I've changed the summary to reflect this.
Exporting a non-default versioned symbol is useless since new programs won't be able to link against that definition. Did 4.2/4.3 export a global default symbol for __signbitl? If we did export a global default symbol for __signbitl then we must continue to export it. The current glibc math.h signbit macro will evaluate to __signbitl if passed a long dobule type, and therefore correct programs using the signbit macro may have ended up referencing __signbitl from libstdc++. Please comment.
The glibc macro AFAIK does: # define signbit(x) \ (sizeof (x) == sizeof (float) \ ? __signbitf (x) \ : sizeof (x) == sizeof (double) \ ? __signbit (x) : __signbitl (x)) when __NO_LONG_DOUBLE_MATH is not defined. For long double x when sizeof (double) == sizeof (long double) AFAIK this is folded to __signbit (x) immediately, already in the *.original dump, at -O0 and higher, so I have no idea how you could ever wind up calling __signbitl. Please explain.
Also, libstdc++.so is definitely not the right home for __signbitl symbol, so we definitely shouldn't allow any newly linked program to use symbol from that library. If __signbitl is ever needed (prove it), then it belongs to libc.so and libm.so, not into libstdc++.so.
Subject: Re: [4.2/4.3 regression] symbol __signbitl@GLIBCXX_3.4 in libstdc++ exported > Also, libstdc++.so is definitely not the right home for __signbitl symbol, so > we definitely shouldn't allow any newly linked program to use symbol from that > library. If __signbitl is ever needed (prove it), then it belongs to libc.so > and libm.so, not into libstdc++.so. I agree. Further, the implementation that leaked in 4.2 and 4.3 may have been broken since it assumed a 128-bit long double format. Dave
No, you are absolutely right and the tree dumps confirm it. I thought it might be possible to trigger a reference by using the right flags, but to no avail, the compiler always folds the if-then-else to __signbit. This proves to me that no program could have ever created a reference to __signbitl unless they specifically called __signbitl, which is a but in the application. I now agree with Benjamin that this is a [4.2/4.3 regression]. Notes: * I am using -fno-builtins to avoid the compiler builtins from being used for signbit[fl]. * I would never want libstdc++ to ever provide a default symbol for __signbitl, only a compat one, but this is now moot since we proved no program could ever reference __signbitl.
Agree with 30, 31, 32 looks like we have consensus.
Removing 4.2 regression, branch no longer maintained.
Closing.