I believe that the libgcc.a in our toolchain contains Thumb-2 code. I verified this by doing objdump on libgcc.a and I see combinations of 16 and 32 bit instructions. So does that mean that the toolchain is only usable for ARM versions that support Thumb-2?
Thanks, John
On Wed, Oct 6, 2010 at 10:44 AM, John Rigby john.rigby@linaro.org wrote:
I believe that the libgcc.a in our toolchain contains Thumb-2 code. I verified this by doing objdump on libgcc.a and I see combinations of 16 and 32 bit instructions. So does that mean that the toolchain is only usable for ARM versions that support Thumb-2?
Our focus is Thumb-2 on Cortex-A processors. We try to 'do no harm', so Linaro GCC should be as good as the FSF GCC on older ARM architectures or non-ARM architectures such as i686 and x86_64.
The included libgcc is compiled for processors with Thumb-2 and VFPv3-D16. I'm afraid I have no plans for other variants at the moment, but you might want to talk with Marcin and Wookey about this.
-- Michael
Thanks Michael. Just wanted to make sure I understood. The "do no harm" goal and the Thumb2 libgcc seem to be somewhat contradictory however. I realize that choices need to be made and only odd ducks like me will likely run into issues. My particular case is wanting to build u-boot for old and new ARM chips with the same gcc. U-Boot has its own libgcc that I can use as a work around.
John
On Tue, Oct 5, 2010 at 3:57 PM, Michael Hope michael.hope@linaro.org wrote:
On Wed, Oct 6, 2010 at 10:44 AM, John Rigby john.rigby@linaro.org wrote:
I believe that the libgcc.a in our toolchain contains Thumb-2 code. I verified this by doing objdump on libgcc.a and I see combinations of 16 and 32 bit instructions. So does that mean that the toolchain is only usable for ARM versions that support Thumb-2?
Our focus is Thumb-2 on Cortex-A processors. We try to 'do no harm', so Linaro GCC should be as good as the FSF GCC on older ARM architectures or non-ARM architectures such as i686 and x86_64.
The included libgcc is compiled for processors with Thumb-2 and VFPv3-D16. I'm afraid I have no plans for other variants at the moment, but you might want to talk with Marcin and Wookey about this.
-- Michael
On Wed, Oct 6, 2010 at 11:23 AM, John Rigby john.rigby@linaro.org wrote:
Thanks Michael. Just wanted to make sure I understood. The "do no harm" goal and the Thumb2 libgcc seem to be somewhat contradictory however. I realize that choices need to be made and only odd ducks like me will likely run into issues.
I'd like to use our toolchain on my N800 and Cortex-M3 boards as well. The 'do no harm' is at the source level - you should be able to take the Linaro GCC tarball and build a compiler for your particular situation that is as good as and probably more correct than the FSF GCC. Unfortunately we can't make one libgcc that covers all ARM products as some like the Cortex-M series are Thumb-2 only, some like the Cortex-M0 are Thumb-1 only, and some (very old ones) are ARM only. Then you add the floating point options into the mix.
It would be nice to ship multiple builds of libgcc with the cross compiler but that's currently out of scope.
-- Michael
On Tue, Oct 05, 2010 at 04:23:01PM -0600, John Rigby wrote:
Thanks Michael. Just wanted to make sure I understood. The "do no harm" goal and the Thumb2 libgcc seem to be somewhat contradictory however. I realize that choices need to be made and only odd ducks like me will likely run into issues. My particular case is wanting to build u-boot for old and new ARM chips with the same gcc. U-Boot has its own libgcc that I can use as a work around.
However, the "harm" here comes not from any work the Linaro Toolchain WG is doing, it comes from the fact that you're using the Ubuntu toolchain packages, where ARMv7 is targeted as the baseline - and this was the case even before Linaro was off the ground. :) (Even if libgcc were not Thumb2 enabled, you could still have arbitrary, if more subtle, compatibility problems with the Ubuntu armel libgcc and non-ARMv7 chips.)
It sounds like what you need for this is a multilib-enabled armel compiler build, that includes a libgcc build for ARMv7 as well as separate libgcc builds for whichever other ARM targets you're after. You should coordinate this with Marcin (cc:ed), who can help with the toolchain packaging details for either a native or cross- compiler.
OOI, what are the U-Boot targets you're looking to build for that don't support ARMv7? A gcc multilib package for armel will be easy to implement but hard to maintain, and certainly none of the systems Linaro is targeting should require a pre-Thumb-2 U-Boot, so I'm very doubtful that the ongoing effort to maintain such a toolchain in Ubuntu is justified (unless we find that it becomes substantially easier with multiarch, I guess, but we're a ways away from that yet).
Cheers,
On Wednesday 06 October 2010, Steve Langasek wrote:
It sounds like what you need for this is a multilib-enabled armel compiler build, that includes a libgcc build for ARMv7 as well as separate libgcc builds for whichever other ARM targets you're after. You should coordinate this with Marcin (cc:ed), who can help with the toolchain packaging details for either a native or cross- compiler.
The question is how far we want to go, since a real multilib toolchain would require multilib-versions of not only libgcc but also (at least) glibc and libstdc++.
The linaro toolchain is currently very much usable to build a pre-v7 kernel and anything that uses -ffreestanding, and IMHO we should try to keep it that way.
Would there be anything that we might want to build besides u-boot that requires an matching libgcc but not also an matching glibc?
Arnd
On Tue, Oct 05, 2010, Steve Langasek wrote:
OOI, what are the U-Boot targets you're looking to build for that don't support ARMv7? A gcc multilib package for armel will be easy to implement but hard to maintain, and certainly none of the systems Linaro is targeting should require a pre-Thumb-2 U-Boot, so I'm very doubtful that the ongoing effort to maintain such a toolchain in Ubuntu is justified (unless we find that it becomes substantially easier with multiarch, I guess, but we're a ways away from that yet).
Isn't Thumb 2 the actual issue here? U-Boot is built with -marm; does it cause any issue to mix with our Thumb-2 libgcc?
I'm really sorry to have started this, but for completeness here is the rest of the story. The hypothetical scenario is a developer that maintains u-boot for multiple platforms. Using a codesourcery or eldk (from denx.de) toolchain one can use the appropriate -march= to get the right code from the compiler. Also the libgcc.a is ARM so all is well. Using a linaro toolchain using the same -march= you get the right code from the compiler but the result will get linked with a Thumb-2 libgcc.a and the resulting binary will not run on an older ARM. If however libgcc.a was ARM then it would just work. Again, I'm not saying this is a bug or even something for Linaro to care about. It just means that the Linaro toolchain is not something that this hypothetical u-boot maintainer would want to use as his/her one and only toolchain.
The naive magical solution would be to for the linker to understand the -march="old non Thumb-2 ARM" and flag an error when linking with a Thumb-2 libgcc.a. Even better would be for the toolchain to have multiple libgcc's and use the right one.
The answer is that the developer just needs to know that the libgcc in the Linaro toolchain is Thumb-2 so they must use the libgcc included in the u-boot source when building for old ARM targets.
Again, sorry for injecting this noise. My question is answered.
John
On Wed, Oct 6, 2010 at 6:41 AM, Loïc Minier loic.minier@linaro.org wrote:
On Tue, Oct 05, 2010, Steve Langasek wrote:
OOI, what are the U-Boot targets you're looking to build for that don't support ARMv7? A gcc multilib package for armel will be easy to implement but hard to maintain, and certainly none of the systems Linaro is targeting should require a pre-Thumb-2 U-Boot, so I'm very doubtful that the ongoing effort to maintain such a toolchain in Ubuntu is justified (unless we find that it becomes substantially easier with multiarch, I guess, but we're a ways away from that yet).
Isn't Thumb 2 the actual issue here? U-Boot is built with -marm; does it cause any issue to mix with our Thumb-2 libgcc?
-- Loďc Minier
On Wed, Oct 06, 2010, John Rigby wrote:
I'm really sorry to have started this, but for completeness here is the rest of the story.
No need to be sorry, I think you're doing right to bring this up
The hypothetical scenario is a developer that
maintains u-boot for multiple platforms. Using a codesourcery or eldk (from denx.de) toolchain one can use the appropriate -march= to get the right code from the compiler. Also the libgcc.a is ARM so all is well. Using a linaro toolchain using the same -march= you get the right code from the compiler but the result will get linked with a Thumb-2 libgcc.a and the resulting binary will not run on an older ARM. If however libgcc.a was ARM then it would just work. Again, I'm not saying this is a bug or even something for Linaro to care about. It just means that the Linaro toolchain is not something that this hypothetical u-boot maintainer would want to use as his/her one and only toolchain.
So it strikes me as a toolchain bug; if I understand what you're saying above: - libgcc built with -march=armv7a can be used with ARMv4, v5, v6, v7 CPUs (if you pass the correct -march=), so it's backwards compatible even if libgcc is built with -march=armv7a - libgcc built with -mthumb is NOT compatible with CPUs lacking thumb, even if you pass -marm
It gets a bit muddier if one considers that some armv7 CPUs could support Thumb-2 only, but these aren't ARMv7*A*, so I don't think that's relevant for the discussion.
I remember we had a similar case for a VFP libgcc back in jaunty, where doko had experienced a multilib VFP libgcc along the regular non-VFP libgcc.
Is it purely accidental that libgcc built for -march=armv7 works on older CPUs? Why can't this mechanism be extended to -marm/-mthumb and to VFP options?
+++ John Rigby [2010-10-06 08:31 -0600]:
I'm really sorry to have started this, but for completeness here is the rest of the story. The hypothetical scenario is a developer that maintains u-boot for multiple platforms. Using a codesourcery or eldk (from denx.de) toolchain one can use the appropriate -march= to get the right code from the compiler. Also the libgcc.a is ARM so all is well. Using a linaro toolchain using the same -march= you get the right code from the compiler but the result will get linked with a Thumb-2 libgcc.a and the resulting binary will not run on an older ARM. If however libgcc.a was ARM then it would just work. Again, I'm not saying this is a bug or even something for Linaro to care about. It just means that the Linaro toolchain is not something that this hypothetical u-boot maintainer would want to use as his/her one and only toolchain.
You bring up an issue that has bugged me for a while. The way gcc is currently designed, whilst you can choose compile time options (like -march=arm), that doesn't do what someone who is targeting, say, a v5 machine wants, unless the toolchain was built with the relevant multilib options so that it actually has several libgccs (and potentially libgomps and libmudflaps and whatever else it spits out these days).
So in practice you can only really set a 'flavour' (as I shall call the choice of instruction set(s)) at compiler build-time, not package build time.
Your average developer would much prefer it if they could easily choose the flavour at build-time of their package/software, and not have to rebuild the toolchain for that flavour first. And we, as distibutors of binary cross-toolchains, would also like to be able to support people targetting multiple flavours with one toolchain, without having to do that by picking lowest-common-denominator, or build lots of different toolchains.
gcc has the multilib feature, but the way it is implemented means it works well for about 2 or 3 options, but you rapidly get combinatorial explosion of libgcc instances if you try to do more things than that. (i.e if you ask for v5, v6, v7, vfp, and neon options you get 25 versions of libgcc1, most of which are silly combinations)
Joseph Myers of Codesourcery has been looking at making this into a more flexible mechanism where you just choose the combinations you actually cared about, not every possible one. I hope that the output of that work would mean we (or someone else like Debian) could choose to support a couple of other useful options, and maybe even a nice runtime way of selecting them.
This has not been a huge issue to date because few people were using pre-built packaged cross-toolchains - they were building the toolchain for their target. Of course that's still quite easy to do, and indeed ARM (well, linaro/ARM in the form of ppearse) are doing it internally for v5 and v6 targets for ALIP builds. But they won't/can't make those packages available because of legal paranoia about shipping gcc so someone else should do this outside and make a handy repo.
Until then the easiest approach is just to use the emdebian cross-toolchains which are built to Debian armel's v4t-nothumb-novfp maximum-compatibilty flavour: http://emdebian.org/crosstools.html ('binary toolcahins' link).
This issue is a useful subject for UDS discussion, I believe.
Wookey
On 07/10/10 12:03, Wookey wrote:
gcc has the multilib feature, but the way it is implemented means it works well for about 2 or 3 options, but you rapidly get combinatorial explosion of libgcc instances if you try to do more things than that. (i.e if you ask for v5, v6, v7, vfp, and neon options you get 25 versions of libgcc1, most of which are silly combinations)
It's not really the implementation that gives the "combinatorial explosion", so much as the problem.
E.g. Say you want enough libraries to be able to build for: * ARM mode or Thumb mode, * with FP, or without, and * both big endian and little endian.
That's 8 different libraries: 1. ARM FP LE 2. ARM FP BE 3. ARM noFP LE 4. ARM noFP BE 5. Thumb FP LE 6. Thumb FP BE 7. Thumb noFP LE 8. Thumb noFP BE
Joseph Myers of Codesourcery has been looking at making this into a more flexible mechanism where you just choose the combinations you actually cared about, not every possible one. I hope that the output of that work would mean we (or someone else like Debian) could choose to support a couple of other useful options, and maybe even a nice runtime way of selecting them.
SuperH already has this. When you build the toolchain you can choose exactly what multilibs will be available with a few configuration options. Other architectures only let you choose what the default will be, and whether to build all the multilibs or not.
CodeSourcery limits the number of multilibs in our product builds by adding our own custom configuration files into the GCC sources, but these are hardly flexible.
All these solutions still require pre-baking the decision into the toolchain.
A possible solution to the problem would be to include the sources to libgcc.a in the installation, and teach gcc to compile it on-the-fly, as necessary. Obviously, you'd still want to pre-bake the most commonly used configuration, for performance reasons. This wouldn't work for libgcc.so, but you probably wouldn't want it to ...
Andrew
+++ Andrew Stubbs [2010-10-07 12:46 +0100]:
On 07/10/10 12:03, Wookey wrote: A possible solution to the problem would be to include the sources to libgcc.a in the installation, and teach gcc to compile it on-the-fly, as necessary.
If it was possible to separate-out libgcc somewhat so that it could be built outside the whole compiler build, that would be marvelous, but my (vague) understanding of the way things are done was that this was not really practical. Is it?
And whilst on the subject - do the other libs like gomp mudflap and erm <any others> that come of of toolchain builds need to be built in the same set of flavours or is this issue restricted to libgcc?
Wookey
Hi,
On Thu, Oct 7, 2010 at 3:13 PM, Wookey wookey@wookware.org wrote: [...]
And whilst on the subject - do the other libs like gomp mudflap and erm <any others> that come of of toolchain builds need to be built in the same set of flavours or is this issue restricted to libgcc?
I think that libgcc is the only thing you can "unintentionally" end up dependent on - it's a special case. My understanding was that gomp and mpfr are used by GCC, not by its output code(?) The C language doesn't natively support arbitrary-precision arithmetic yet...
If you build with gcc -fzany-library-dependent-feature (for example), you can probably expect gcc to try and link in -lzany-library-dependent-feature, but I think it's reasonable in that case to expect that the user knows what he's doing.
Someone who attempts to build a bare-metal project using such features is probably doing the wrong thing in most cases.
Does that sound reasonable?
---Dave
On Thursday 07 October 2010 13:03:14 Wookey wrote:
gcc has the multilib feature, but the way it is implemented means it works well for about 2 or 3 options, but you rapidly get combinatorial explosion of libgcc instances if you try to do more things than that. (i.e if you ask for v5, v6, v7, vfp, and neon options you get 25 versions of libgcc1, most of which are silly combinations)
If I understood Uli correctly, you can have one version of libgcc that is used as the fallback in a multilib setup, and most variants are backwards compatible.
We could have one version for the variant we're targetting (v7-a, thumb2, vfp, neon) and one version as a fallback for most older targets (v5 or v4, arm, novfp, noneon) which would get us a _long_ way, and it would still be compatible with the version we normally use.
There are however some incompatible options (big-endian, thumb 1, hardfloat) that might need an extra multilib variant if we really want them.
Arnd
On 07/10/10 12:54, arnd@arndb.de wrote:
On Thursday 07 October 2010 13:03:14 Wookey wrote:
gcc has the multilib feature, but the way it is implemented means it works well for about 2 or 3 options, but you rapidly get combinatorial explosion of libgcc instances if you try to do more things than that. (i.e if you ask for v5, v6, v7, vfp, and neon options you get 25 versions of libgcc1, most of which are silly combinations)
If I understood Uli correctly, you can have one version of libgcc that is used as the fallback in a multilib setup, and most variants are backwards compatible.
Yes, with some carefully thought out custom configuration patches we can certainly do something like what you suggest.
You can tell GCC exactly what arches you want multilibs for, and what options (neon, vfp, etc) you want multilibs for, and it will automatically fill in the N-dimensional matrix that gives you all those options.
Like Wookey said, this can produce a selection of pointless libraries that either make no sense, or else are duplicates of other libraries, so GCC has ways to deal with this:
1. You can disable any specific option combination you like.
2. You can specify that one set of options should use the library from another, compatible set of options.
3. You can add custom "specs" rules that tell it what to do in the "fall back" case (normal procedure is to use the default library - the primary target for the toolchain, but in this case, we're talking about having a fall-back to a lowest-common-denominator library, which would be far less optimal).
All this can be done with a small patch to two or three files. It's quite easy, but we just need to know what it is we want to achieve. Any such patch should be done in a way that plays nice with other people requirements for building the sources, and even then would probably not be acceptable upstream.
Although these things *can* be done, I'm really not sure that they *should*. As has been pointed out already, this use case really is an abuse of a Linux user-space compiler, and will add features that 99.99% of users will never care about, yet will increase both the build and test burden for developers/packagers all the time, possibly considerably.
Andrew