Bug 28718 - Call to -lgcc added prior to user libraries
Summary: Call to -lgcc added prior to user libraries
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: driver (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-08-14 12:13 UTC by Joerg Wunsch
Modified: 2014-02-18 08:35 UTC (History)
5 users (show)

See Also:
Host: *-*-*
Target: avr-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-09-05 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joerg Wunsch 2006-08-14 12:13:26 UTC
When calling avr-g++, the linker driver adds a call to -lgcc before any
of the user libraries entered on the command-line.

On the AVR, this causes the wrong math function implementations taken from
libgcc.a rather than the (user-supplied) libm.a.

This is different from the C compiler driver, why?

Given (any) C++ file foo.cc, using avr-gcc:

% avr-gcc -v foo.cc
Using built-in specs.
Target: avr
Configured with: ./configure --prefix=/tools/i686 --target=avr --disable-libssp --with-dwarf2
Thread model: single
gcc version 4.1.0
 /tools/i686/libexec/gcc/avr/4.1.0/cc1plus -quiet -v foo.cc -quiet -dumpbase foo.cc -auxbase foo -version -fno-rtti -fno-enforce-eh-specs -fno-exceptions -o /tmp/cc7jbBxg.s
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../include/c++/4.1.0"
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../include/c++/4.1.0/avr"
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../include/c++/4.1.0/backward"
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../avr/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /tools/i686/lib/gcc/avr/4.1.0/include
 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/include
End of search list.
GNU C++ version 4.1.0 (avr)
        compiled by GNU C version 3.2.3 20030502 (Red Hat Linux 3.2.3-49).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: e56ae0f62a848350ccb9716b24fc3bd9
 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/bin/as -o /tmp/ccyX7jFq.o /tmp/cc7jbBxg.s
 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/bin/ld -m avr2 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/lib/crts8515.o -L/tools/i686/lib/gcc/avr/4.1.0 -L/tools/i686/lib/gcc/avr/4.1.0/../../../../avr/lib /tmp/ccyX7jFq.o -lgcc -lc -lgcc

Using avr-g++ instead of avr-gcc:

% avr-g++ -v foo.cc
Using built-in specs.
Target: avr
Configured with: ./configure --prefix=/tools/i686 --target=avr --disable-libssp --with-dwarf2
Thread model: single
gcc version 4.1.0
 /tools/i686/libexec/gcc/avr/4.1.0/cc1plus -quiet -v foo.cc -quiet -dumpbase foo.cc -auxbase foo -version -fno-rtti -fno-enforce-eh-specs -fno-exceptions -o /tmp/ccbXCZLa.s
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../include/c++/4.1.0"
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../include/c++/4.1.0/avr"
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../include/c++/4.1.0/backward"
ignoring nonexistent directory "/tools/i686/lib/gcc/avr/4.1.0/../../../../avr/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /tools/i686/lib/gcc/avr/4.1.0/include
 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/include
End of search list.
GNU C++ version 4.1.0 (avr)
        compiled by GNU C version 3.2.3 20030502 (Red Hat Linux 3.2.3-49).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: e56ae0f62a848350ccb9716b24fc3bd9
 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/bin/as -o /tmp/ccSHVtCa.o /tmp/ccbXCZLa.s
 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/bin/ld -m avr2 /tools/i686/lib/gcc/avr/4.1.0/../../../../avr/lib/crts8515.o -L/tools/i686/lib/gcc/avr/4.1.0 -L/tools/i686/lib/gcc/avr/4.1.0/../../../../avr/lib /tmp/ccSHVtCa.o -lgcc -lm -lgcc -lc -lgcc
Comment 1 Andrew Pinski 2006-08-14 13:18:14 UTC
Wait the user did say to link against -lm anyways.  This comes from the specs.  What kind of wrong math functions are being used anyways?  If soft-fp, then you are to think you can override them in libm.a because that is not the job of libm.a.
Comment 2 Joerg Wunsch 2006-08-14 14:13:30 UTC
I know that the current situation for the AVR is suboptimal, there really
are overrides in libm.a for functions that are already present in libgcc.a.
However, this is not so easy to change for a number of logistical reasons
(the functions in question are highly tied into the remaining FP library
framework, but they offer much more optimal code for the user).

However, the main question here is: shouldn't all user-supplied -lXXX options
*always* be processed before any internally added -lgcc options, and why is
the behaviour different when the user calls the compiler "avr-g++" rather
than "avr-gcc"?
Comment 3 Andrew Pinski 2006-08-14 14:15:29 UTC
-lm was not an user supplied option as shown by your commands.
Comment 4 Joerg Wunsch 2006-08-14 14:28:36 UTC
(In reply to comment #3)
> -lm was not an user supplied option as shown by your commands.
>

Oh no, sorry for the confusion: it *is* a user-supplied library.

Sorry, I now see that I somehow copy&pasted the wrong sequence. :-(

OK, here's the essence again, now with the correct commands:

% avr-gcc -v foo.cc -lm
...
/tools/i686/lib/gcc/avr/4.1.0/../../../../avr/bin/ld [...] /tmp/cc6mvtc6.o -lm -lgcc -lc -lgcc

% avr-g++ -v foo.cc -lm
...
/tools/i686/lib/gcc/avr/4.1.0/../../../../avr/bin/ld [...] /tmp/cck5jSBR.o -lgcc -lm -lgcc -lc -lgcc

I hope that makes my question clearer now.
Comment 5 Andrew Pinski 2006-08-15 18:24:40 UTC
Also libm is not supposed to be overriding stuff in libgcc really, it is only supposed to be including the C math functions.
Comment 6 Björn Haase 2006-09-06 16:51:18 UTC
To clear up the issues.

1.) libgcc provides a fp emulation based on compiled c functions that is to my very best knowledge untested for avr and extremely inefficient.
2.) avr-libc provides fp emulation that is hand-tuned assembly and on a less restrictive license than GPL. IIRC, the person who wrote them is no longer active in the field.
3.) the functions supplied by avr-libc are as basic as "single float add 3", "single float multiply 3", "single float convert to integer 2" ...
4.) the hand-tuned assembly routines should really replace the libgcc ones, but that's not easily feasible. Partly due to licensing issues (modified free bsd for avr-libc), partly because it is very very difficult for us developers to get code integrated into mainline gcc.
5.) the externally supplied functions in libm need the hand-tuned assembly versions in order to operate properly and will failed with the untested libgcc variants.
5.) There is only one single libc and libm implementation available for avr that cooperates with gcc: avr-libc.

The suggestion of Joerg Wunsch is, thus, in line with the needs of gcc users for the avr target.

Bjoern.
Comment 7 Andrew Pinski 2006-09-12 08:06:51 UTC
(In reply to comment #6)
> The suggestion of Joerg Wunsch is, thus, in line with the needs of gcc users
> for the avr target.
But not in the line with the rest of GCC.  Really if you cannot get a patch applied to GCC, there is a maintainer problem with the avr target inside GCC.  And second GCC's soft-fp should be correct indepdent of the libc.
So this is not a bug.  Also if libm is only the normal math library and should not include the soft-fp but those should be in libgcc as they are support functions needed for GCC to work even without a libc.
Comment 8 Joerg Wunsch 2006-09-12 08:52:41 UTC
(In reply to comment #7)

> So this is not a bug.  Also if libm is only the normal math library and should
> not include the soft-fp but those should be in libgcc as they are support
> functions needed for GCC to work even without a libc.

The bug is that libstdc++ (in our case: libgcc, as the AVR implementation
doesn't have a libstdc++) and libm are linked *before* any user-supplied
-l options in C++ mode.  This doesn't happen in C mode.  This also happens
for non-AVR targets, so it appears to be a generic bug to me.

This is violating the principle of least astonishment at least.

The AVR user can for sure live (by now) with the artefacts caused by there
not-really-GCC-standard libm.a implementation, as long as they've got
reasonable control about when the GCC-internal libraries are getting
linked in (so the user always gets a chance to override).

Comment 9 abnikant 2009-08-19 15:32:10 UTC
This is because libstdc++ is not build in case of avr(8 bit),I did check it in avr32 there I get flags in the sequence : -lstdc++ -lm -lgcc
Comment 10 Georg-Johann Lay 2011-11-21 16:20:39 UTC
Jörg, could you prepare a list of functions that shall be excluded from libgcc? You can also answer to my mail "PR28718 Infos?" from 2011-11-10.
Comment 11 Joerg Wunsch 2011-11-28 19:45:51 UTC
(In reply to comment #10)
> Jörg, could you prepare a list of functions that shall be excluded from libgcc?
> You can also answer to my mail "PR28718 Infos?" from 2011-11-10.

Well, perhaps.  However, the AVR-part is not the main subject of my
complaint here.  The subject of my complaint was/is that a call to
*any* library is added *prior* to the list of user-supplied libaries
(from -l options).  The point of -l options is to give the users an
override option, which is completely defeated by the current way
libstdc++ is handled.

The fact that the AVR (currently) lacks a libstdc++, and thus libgcc
is linked instead, caused this bug to be escalated due to the side
effects, but this is not the main point here.

This becomes even more puzzling now: apparently, this reordering of
the libraries *only* applies to -lm.  When specifying any other
library, the processing works as one would expect it to be.

The code for this is in gcc/cp/g++spec.c, around line 270:

      /* Make sure -lstdc++ is before the math library, since libstdc++
         itself uses those math routines.  */
      if (!saw_math && (args[i] & MATHLIB) && library > 0)
        {
          --j;
          saw_math = &decoded_options[i];
        }

OK, now the reason is clear.  However, this doesn't handle the case
very well where no libstdc++ is available at all: inserting libgcc in
place of libstdc++ is just a simple workaround, and apparently a too
simple one in our case.  A correct implementation would not try to add
anything at all when libstdc++ is unavailable (and thus have no need
to reorder).

I don't know how many targets are affected at all by the lack of
libstdc++.  If AVR is indeed the only target where this applies to,
then the way you outlined (a configurable list of functions to omit
from libgcc) might be the best compromise.

(Sorry it took me so long to reply, Johan, but I knew it would take me
some time to research all this again, and then create the reply.)
Comment 12 Georg-Johann Lay 2012-09-05 13:02:24 UTC
Not really a doublicate of PR54461, but the new configure option --with-avrlibc introduced in 4.7.2 solves the issue by removing the doublicate functions from libgcc so that the optimized versions from AVR-Libc will be used no matter how the -l order is.

*** This bug has been marked as a duplicate of bug 54461 ***
Comment 13 Joerg Wunsch 2012-09-05 15:08:27 UTC
All this is fighting the symptoms though.

My point (as outlined in comment #8:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28718#c8 )
is:

When operating as a C compiler, *all* user-supplied libraries are passed
to the linker *first*, followed by system libraries.

When operating as a C++ compiler, libstdc++ and libm.a are passed *before*
any user-supplied library.  This leaves the users in a situation where
they are no longer able to supply own overrides for some functions in
system libraries.  Again, all this is in contrast to how the C compiler
works.

In the AVR case, the situation is only worse since there's no libstdc++
(yet), and somehow, libgcc is substituted in place of libstdc++ (which I
think is a completely flawed idea from the beginning).

So despite all the artefacts which leaded to this bug report, I think at
least the last point mentioned is worth fixing: if there's no libstdc++,
there's no point in trying to pretend libgcc could be supplied as a
replacement for libstdc++.  (The AVR-related artefacts are now mostly
fixed after Johann's recent work, the original bug(s) remain(s).)
Comment 14 Georg-Johann Lay 2012-09-05 21:35:00 UTC
CCing Gaby.  He is the only one I know of who is committed to C++ and avr.

(In reply to comment #13)
> All this is fighting the symptoms though.
> 
> My point (as outlined in comment #8) is:
> 
> When operating as a C compiler, *all* user-supplied libraries are passed
> to the linker *first*, followed by system libraries.
> 
> When operating as a C++ compiler, libstdc++ and libm.a are passed *before*
> any user-supplied library.  This leaves the users in a situation where
> they are no longer able to supply own overrides for some functions in
> system libraries.  Again, all this is in contrast to how the C compiler
> works.
> 
> In the AVR case, the situation is only worse since there's no libstdc++
> (yet), and somehow, libgcc is substituted in place of libstdc++ (which I
> think is a completely flawed idea from the beginning).
> 
> So despite all the artefacts which leaded to this bug report, I think at
> least the last point mentioned is worth fixing: if there's no libstdc++,
> there's no point in trying to pretend libgcc could be supplied as a
> replacement for libstdc++.  (The AVR-related artefacts are now mostly
> fixed after Johann's recent work, the original bug(s) remain(s).)

Ok, I untied the two PRs again and set this one to NEW.
Comment 15 Jackie Rosen 2014-02-16 13:12:20 UTC Comment hidden (spam)