[U-Boot] [PATCH 5/5] lib: Enable private libgcc by default

Albert ARIBAUD
2016-03-29T09:18:21Z

Hello Tom,

On Sun, 27 Mar 2016 09:36:41 -0400, Tom Rini <trini@konsulko.com> wrote:
> On Fri, Mar 25, 2016 at 07:37:25AM +0100, Albert ARIBAUD wrote:
> > Hello Tom,
> >
> > On Thu, 24 Mar 2016 20:49:42 -0400, Tom Rini <trini@konsulko.com> wrote:
> > > On Thu, Mar 24, 2016 at 08:50:03AM +0100, Albert ARIBAUD wrote:
> > > > 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.)
> > >
> > > No. For reference,
> > > http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043d/IHI0043D_rtabi.pdf
> > > and chapter 4 is all about the support library. We are entirely in our
> > > right to do either of (a) use the compiler-provided library (b) provide
> > > our own implementation of what we need. The kernel opts for (b) and I
> > > would like us to follow that as well, consistently, rather than ad-hoc.
> >
> > Kk, so you did not mean "whatever happens to be aeabi in libgcc, you
> > meant AEABI itself.
> >
> > But then what you seek is is not a custom libgcc; it is controlled
> > AEABI support library.
>
> No. It's not libgcc. We call it libgcc, but we shouldn't. We should
> call it lib1funcs which is part of the end result of Marek's patches.
> LLVM has its own library which does this. But it's not about LLVM,
> either.

Well then, I don't know which lib the patch is about. AFAIK, libgcc is
described in https://gcc.gnu.org/onlinedocs/gccint/Libgcc.html (which is
part of "GCC internals") as follows:

"GCC provides a low-level runtime library, libgcc.a or
libgcc_s.so.1 on some platforms. GCC generates calls to
routines in this library automatically, whenever it needs to
perform some operation that is too complicated to emit inline
code for."

To me this means that libgcc provides an interface which is private
to the GCC project, and the GCC folks can put in there whatever routine
they want if they think it helps keeping emitted code uncomplicated, an
then emit calls to this routine in the code they generate.

Do we have the same reading of this?

In that respect, LLVM is indeed no different from GCC (or any toolchain
for that matter; a compiler is not bound to emit self-sufficient code
and it is common practice to rely on a support library.

That does not change th fact that libgcc, as described above (and I
suspect that LLVM uses the same language elements to describe its own
support library) is *not* based on a standard and fixed specification,
and is *not* designed as a replaceable implementation of such a spec.

I do understand that you are unhappy with some build(s) of the GCC
toolchain where libgcc is either unfit for the intended target, or
buggy, or both. I also think AEABI support does not belong in libgcc as
it is defined in the reference above. But:

- not all builds of the same version of GCC exhibit the issue you are
raising. This should at least make us consider what it is with those
builds of GCC which exhibit the issue that makes their libgcc unfit
for a target which it is supposed to support.

- not all targets in U-Boot are affected. This should at least make us
consider that bypassing libgcc by default is not the proper approach
as it "fixes a non-bug" for many targets.

> > I'm fine with that, since, contrary to libgcc, it has an external,
> > stable, definition.
> >
> > But that is *unrelated* to libgcc, which is not described nor intended
> > as "AEABI support" -- libgcc exists in all architectures, even non-ARM,
> > and provides AEABI in the ARM case by accident -- or, more to the point,
> > by sub-optimal design IMO.
>
> Yes, "libgcc" often, but not always, is how U-Boot provides the
> architecture specific compiler support library functions. Or rather,
> ARM and PowerPC are the big cases where we rely on -lgcc and everywhere
> else simply provides the required functionality in U-Boot.

Just because some arches decided to bypass libgcc does not make it the
right design decision.

> > The right design for solving the problems raised by Marek is therefore
> > to rename U-Boot's "custom libgcc" as U-Boot's "AEABI support library"
> > and link U-Boot *first* against this AEABI support library, *then*
> > against GCC's libgcc.
> >
> > Essentially, this 'hijacks' whatever is AEABI from libgcc while not
> > interfering with what is not AEABI (i.e. what is purely GCC/libgcc
> > internals).
>
> ... but we don't need to link vs libgcc (or the compiler-dependent
> helper library), ever.

Yes we do as long as we use GCC, because we do not know what calls GCC
might emit to some routine it provides in the corresponding libgcc.
This interface between GCC-emitted code is not public. It is not
controlled by us. It is controlled by GCC and by hijacking all of
libgcc, we break this interface and force GCC to fail, but that's not a
shortcoming of GCC, it is a shortcoming of us.

> We can provide all of the functions we need
> normally.

Again, this is not about functions we need. This is about fonctions the
GCC project decides it needs, and decides to generate calls to in code
emitted by their compiler and provide and implementation in their
libgcc.

> What we need to do, and Marek's patch is fixing about half of
> the problem, is always provide the required functionality so that we can
> link ourself.

Yes, and for the routines that GCC emits calls to in the course of
compiling our code, the corresponding functionality is provided by
GCC's libgcc.

If we need something because GCC-emitted code calls it, then libgcc
provides it.

If we need something because GCC-emitted code calls it but which our
toolchain of choice does not provide in its libgcc, then it's a GCC or
toolchain build issue, and I'm fine with overriding *that* thing with a
custom libgcc -- which we can do without entirely bypassing the
toolchain's own libgcc.

Last, if we need something which is not called by GCC-emitted code but
explicitly by us, then we should provide that thing, but then there is
no reason to put it in libgcc since that thing is no a way for the
compiler to avoid emiggint inline code -- which is all what libgcc is about.

> Once we have Marek's patch in, only PowerPC is relying on
> "libgcc" for some number of functions, and once that's done we can just
> remove "LIBGCC" from the system.

Or, with Marek's patch redesigned, we can keep using GCC in a proper
way *and* fix exactly what needs to be fixed, for targets that need it
fixed, without interfering with a third party tool's internal
interfaces.

> > That way,
> >
> > 0) U-Boot gets the stable and controlled AEABI support you want;
>
> To be clear, what I want is for U-Boot to not rely on having a specific
> configuration of gcc available.

If by this you mean you do not want U-Boot not to rely on a given GCC
build's defaults such as default endianness, default CPU, default arch,
etc, I'm 100% with you. If you mean you want to use any ARM GCC build
for any ARM target regardless of whether that build actually has
support for it, then I would disagree.

As a simple example: if your ARM GCC build has compiler support for big-
and little-endian, but only provides libgcc for little-endian, then I
expect that GCC build to succeed in building all little-endian U-Boot
ARM targets, but I don't expect it to build big-endian ones, since as a
toolchain, it does not support big-endian.

> We do not build today with various (and
> correctly configured) toolchains because they are not multi-lib and we
> do not allow hard float.

So what you mean is that you're using a toolchain which only supports
hard float and want to build non-hard float targets. You're using a
tool which is not suited to your needs.

> The massive number of places that tell people
> to "fix" this problem by just removing -msoft-float is very wrong.

Agreed.

> And
> we aren't going to fix that problem by jumping all over stack overflow,
> we're going to fix that by making it not be a problem.

Indeed, but the solution is not to let people use inadequate
toolchains. We don't hesitate to tell people not to use too old a
U-Boot version; we don't hesitate to tell people not to use too old a
GCC version; why hesitate in telling them not to use too inadequate a
GCC version? All the more when a simple buildman command wll provide
them with a working one.

> > 1) GCC keeps its somewhat stable but uncontrolled internal "generated
> > code / libgcc" interface;
> >
> > 2) U-Boot won't interfere with non-aeabi-related stuff in GCC+libgcc,
> > i.e. whatever ibgcc-related but non-AEABI-related changes occur in
> > a GCC release, we won't break them changes in non-AEABI ;
> >
> > 3) GCC+libgcc won't interfere with AEABI any more, i.e. whatever AEABI
> > breakages happen in a given GCC toolchain will not break U-Boot.
> >
> > 4) This design works with any ARM toolchain -- which is kind of evident
> > since it separates generic ARM EABI support from specific toolchain
> > support.
>
> The problem here is what once we do this we are never using anything
> from linking against libgcc, so there's no reason to.

That's only if you follow this proposal *and* insist on *still*
replacing GCC'slibgcc entirely with our custom libgcc by default (and
still assume GCC will never ever change anything to its libgcc, too).

My proposal assumes custom libgcc is only used to fix bugs in libgcc
(for those versions of GCC that exhibit such bugs) or to support GCC
builds when no other GCC toolchain build exists that can build a given
target. No bugs and there is an easily accessible GCC build for the
target? No need for private libgcc.

(also, custom libgcc should not *replace* libgcc. It should replace
*those symbols* in libgcc which require replacing -- the same way
that we don't entirely replace libc just because we have better
versions of memmove/memcpy/memset.)

> --
> Tom

Amicalement,
--
Albert.