On 06/10/10 15:48, Loïc Minier wrote:
On Wed, Oct 06, 2010, John Rigby wrote:
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.
The CodeSourcery toolchain has "multilibs" to support this. That is, there is one copy of libgcc (and glibc/newlib/uclibc, depending on the SG++ you choose) per -march option. Other options (such as -mfloat and -marm/-mthumb, endian, etc) also have specialist libraries available.
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.
The Linaro/Ubuntu binary releases are configured specifically for the architectures they are intended to run on. If you try to build for something else then you're not using the right tool for the job.
I would recommend either building a Linaro compiler from source, with the desired config, or else using a CodeSourcery compiler (the two are *very* closely related).
If however libgcc.a was ARM then it would just work.
This would work, but it doesn't really make much sense for the libgcc to be configured differently to the entire rest of the distribution (and you'd need to do some build system hackery to get gcc installed that way).
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.
Agreed. You should use a compiler built for the job.
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
This statement is false. Code compiled with -march=armv7a will only run on ARMv7a or compatible. It's possible that simple programs might, by chance, work on older cores, but relying on this behaviour even there is just broken.
- libgcc built with -mthumb is NOT compatible with CPUs lacking thumb, even if you pass -marm
No, that's why multilibed compilers (such as CodeSourcery's) substitute a different libgcc when you use those options.
[snip]
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?
See above. Some routines might work on some older hardware, by chance, but it's subject to change at any moment, and I doubt the entire library is backward compatible.
There's another issue here: using a Linux user-space compiler to build for bare-metal is a bad plan. libgcc is built assuming that system calls and exceptions etc. work as they do in Linux user-mode. The Linux kernel is built with a user-space compiler for convenience, but a) the kernel is always configured for the same hardware as the user-space, and b) it has it's own versions of (at least some of) the libgcc routines, customized for it's own environment.
I strongly suggest you use a bare-metal compiler configured for the right architecture(s), such as CodeSourcery's ARM EABI Lite toolchain.
Andrew