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
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.
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"?
-lm was not an user supplied option as shown by your commands.
(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.
Also libm is not supposed to be overriding stuff in libgcc really, it is only supposed to be including the C math functions.
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.
(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.
(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).
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
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.
(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.)
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 ***
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).)
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.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.