
Hello Tom,
On Wed, 23 Mar 2016 17:36:17 -0400, Tom Rini trini@konsulko.com wrote:
On Wed, Mar 23, 2016 at 06:08:45PM +0100, Albert ARIBAUD wrote:
Hello Tom,
On Wed, 23 Mar 2016 09:22:38 -0400, Tom Rini trini@konsulko.com wrote:
On Wed, Mar 23, 2016 at 01:53:35PM +0100, Albert ARIBAUD wrote:
Hello Marek,
On Sun, 20 Mar 2016 17:15:34 +0100, Marek Vasut marex@denx.de wrote:
This patch decouples U-Boot binary from the toolchain on systems where private libgcc is available. Instead of pulling in functions provided by the libgcc from the toolchain, U-Boot will use it's own set of libgcc functions. These functions are usually imported from Linux kernel, which also uses it's own libgcc functions instead of the ones provided by the toolchain.
This patch solves a rather common problem. The toolchain can usually generate code for many variants of target architecture and often even different endianness. The libgcc on the other hand is usually compiled for one particular configuration and the functions provided by it may or may not be suited for use in U-Boot. This can manifest in two ways, either the U-Boot fails to compile altogether and linker will complain or, in the much worse case, the resulting U-Boot will build, but will misbehave in very subtle and hard to debug ways.
I don't think using private libgcc by default is a good idea.
U-Boot's private libgcc is not a feature of U-Boot, but a fix for some cases where a target cannot properly link with the libgcc provided by the (specific release of the) GCC toolchain in use. Using private libgcc to other cases than these does not fix or improve anything; those other cases were working and did not require any fix in this respect.
This isn't true, exactly. If using clang for example everyone needs to enable this code. We're also using -fno-builtin -ffreestanding which should limit the amount of interference from the toolchain. And we get that.
You mean clang does not produce self-sustained binaries?
clang does not provide "libgcc", so there's no -lgcc providing all of the functions that are (today) in: _ashldi3.S _ashrdi3.S _divsi3.S _lshrdi3.S _modsi3.S _udivsi3.S _umodsi3.S div0.S _uldivmod.S which aside from __modsi3 and __umodsi3 are all __aeabi_xxx
(ok, that explains what you mean by AEABI functions -- those are actually not functions defined by the AEABI, but functions that the GCC folks prefixed with __aeabi.)
I do understand that clang does not provide these functions. What I want to understand is how come code compiled by clang would need them unless we introduced that dependency ourselves. clang does produce correct and self-sufficient code when using 64-bit division, right?
Also, libgcc is not a standalone project that can be frozen, forked or improved freely; it is an internal component of the GCC toolchain. No standard defines what libgcc is or should be, and we have no control over the 'contract' between GCC-emitted code and libgcc. The GCC project may decide to change that contract at any time, and produce a new toolchain and a new libgcc. Using our private libgcc by default will cause all targets to break for no good reason. We've already been bitten by internal GCC changes on which we were dependent; adding more such dependency is not the way to go IMO.
If we truly fear that GCC is *generally* unable to properly build our targets due to its libgcc, then we should not only "snapshot and fix" libgcc; we should "snapshot and fix" the whole GCC toolchain, to make sure we keep a consistent copy of it. I don't think that would be a viable move.
And if we don't believe that GCC is generally unable to properly build U-Boot, then we should always use it as provided unless it is provably buggy, in which case if a private libgcc is a fix, then by all means we should use it.
And whenever we find that a GCC toolchain is provably buggy, we should raise a bug, either to the toolchain provider if the issue is only with a given binary release (e.g. mismatched or badly supported endianness), or to the GCC project if the bug is inherent to GCC (e.g. generation of non-supported opcodes for a given arch/cpu).
Ah, but this shows part of the problem. We don't need "libgcc" as in "the thing which provides gcc'isms". We need "libgcc" as in "the thing which provides AEABI functions".
Not sure I'm getting what you mean. For one thing, I don't see that AEABI specifies any functions. Also, I don't see where it is established that U-Boot "needs AEABI functions". Finally, I don't see that libgcc is a standalone project aiming at providing AEABI functions.
Well, lets unpack things in the order that it matters. If we kludge the toplevel Makefile to not set CONFIG_USE_PRIVATE_LIBGCC nor link in libgcc on ARM, and build work_92105 with an arm-none-eabi GCC we start failing on:
Here you are actively setting the conditions for the build to fail since you prevent the linker from using *any* libgcc implentation despite knowing that the generated code requires one.
arch/arm/cpu/arm926ejs/built-in.o: In function `print_cpuinfo': /home/trini/work/u-boot/u-boot/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c:64: undefined reference to `__aeabi_uidiv' /home/trini/work/u-boot/u-boot/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c:65: undefined reference to `__aeabi_uidiv' /home/trini/work/u-boot/u-boot/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c:66: undefined reference to `__aeabi_uidiv' and fail on and on from there (I see several pages). Line 64-66 are: printf("CPU clock: %uMHz\n", get_hclk_pll_rate() / 1000000); printf("AHB bus clock: %uMHz\n", get_hclk_clk_rate() / 1000000); printf("Peripheral clock: %uMHz\n", get_periph_clk_rate() / 1000000);
Do these errors occur when you do not actively prevent any libgcc from linking? Do they occur when you do not prevent GCC's libgcc from linking?
So, despite being "freestanding" and requring "no builtins" we still requiring the toolchain to give us these functions separately, or just bring them ourself. Note that ARC, SH and MIPS all always follow the kernel model of just providing these bits of functionality rather than rely on getting just those things from libgcc.
Yes, we do require the toolchain to provide these functions, or more to the point, we need to not prevent the toolchain from building our code as it was designed to; and the toolchain was designed to generate code which refers to symbols defined in a library that must be linked with that code; and the toolchain provides that library as "libgcc". That is exactly my point: the toolchain requires *and provides* libgcc. That's an internal design-induced requirement, and users of the toolchain should not even have to meddle with it unless broken.
Again, I an fine with private libgcc as a fix to specific case of buggy toolchain releases. What I am not fine with is replacing a third party tool's mechanism with our own when this mechanism works.
Today we get these from libgcc but we run into cases where this doesn't work quite right (toolchain fun) or simply aren't available (again, clang). So I am in favour of re-syncing with this part of the kernel and mirroring the decision to always include these functions, again, like the kernel does.
If we are using libgcc for providing AEABI services then we are using it wrong. Its role is to support GCC-generated code.
Could you give me an example of this "need for [an] AEABI function"?
See above. And yes, we're using libgcc wrong by IMHO using it at all.
And I think your view of what libgcc is is wrong. It is not something *we* use, it is something that *GCC* uses by design. And it is not something that we have a choice in using as long as we build with GCC.
We don't need it and opt out of it for almost everything, except for the above.
We do need libgcc as long as we use GCC. The best proof is the contrived build above, which you can reproduce with *any* GCC build, cross or native, for bare metal code or for a Linux Hello World application: when we actively deprive GCC from the libgcc that it requires and provides, it won't work, exactly like when we remove gas from a car, it won't run.
-- Tom
Amicalement,