[Buildroot] Bizarre behavior of armeb toolchain
thomas.petazzoni at free-electrons.com
Thu Jun 20 13:41:30 UTC 2013
I'm facing a bizarre problem with an armeb toolchain built by
Buildroot. I'm also posting this to the crossgcc@ list since there are
some gcc/binutils experts out there.
First, a little bit of background. ARM Big Endian comes into two
* BE32, which was used up to ARMv5, where both the instructions and
the data are Big Endian.
* BE8, which is used since ARMv6, where the instructions remain
little-endian and only the data are big-endian.
for some details about this.
So, I've built an ARMv7 Cortex-A8 toolchain, with the armeb
architecture selected. The CROSS-gcc -v shows that it was configured as
Then, I wrote a simple program that contains some data and
instructions, built it under several conditions, and observed with
hexdump whether the data and code was little-endian or big-endian.
And the results are somewhat surprising: when I explicitly pass
-mbig-endian, I get the proper behavior (BE8 code with code in little
endian and data in big endian), but when I don't pass any flags to the
compiler, I get an incorrect behavior: both the code and data are big
endian, as if the BE8 wasn't used (and readelf confirms that it wasn't
used). See below the detailed results.
Note that the compiler is supposed to automatically use BE8 on
ARMv6/ARMv7 and BE32 on ARMv5 and earlier cores.
The data is DEADBEEF, and the instruction is E52DB004.
Flags used Observed data Observed code Comment
======================= =============== =============== =========================================
-mlittle-endian EFBEADDE 04B02DE5 Code and data in LE -> OK
-mbig-endian DEADBEEF 04B02DE5 Code LE, data BE, binary marked BE8 -> OK
no flags DEADBEEF E52DB004 Data BE (ok!), code BE (*NOT* ok) -> NOK
-march=armv5t -mbig-endian DEADBEEF E52DB004 Code and data in BE, on ARMv5 -> OK
-march=armv5t DEADBEEF E52DB004 Code and data in BE, on ARMv5 -> OK
As can be seen in this table:
(*) On ARMv5, regardless of whether -mbig-endian is passed or not, the
code produced is correct (both code and data are big endian, which is
correct for ARMv5 where the big endian mode is BE32)
(*) On ARMv7 however, the code is different whether -mbig-endian is
passed or not, even though an "armeb-linux" compiler is supposed to
generate big endian code by default. When no flags is passed, both the
data *and* code are big-endian (so it's BE32 like on ARMv5), but
passing -mbig-endian makes the thing behave properly (code is
little-endian, data is big-endian).
I'm using binutils 2.23.2 and gcc 4.7.3.
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
More information about the buildroot