public inbox for crossgcc@sourceware.org
 help / color / mirror / Atom feed
* Bizarre behavior of armeb toolchain
@ 2013-06-20 13:41 Thomas Petazzoni
  2013-06-20 13:49 ` [Buildroot] " Will Newton
  2013-06-20 13:52 ` Thomas Petazzoni
  0 siblings, 2 replies; 3+ messages in thread
From: Thomas Petazzoni @ 2013-06-20 13:41 UTC (permalink / raw)
  To: crossgcc, buildroot

Hello,

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
variants:

 * 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.

See
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0338g/ch06s05s01.html
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
follows:

	--target=armeb-buildroot-linux-uclibcgnueabi
	--with-abi=aapcs-linux
	--with-arch=armv7-a
	--with-tune=cortex-a8

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.

Any ideas?

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Buildroot] Bizarre behavior of armeb toolchain
  2013-06-20 13:41 Bizarre behavior of armeb toolchain Thomas Petazzoni
@ 2013-06-20 13:49 ` Will Newton
  2013-06-20 13:52 ` Thomas Petazzoni
  1 sibling, 0 replies; 3+ messages in thread
From: Will Newton @ 2013-06-20 13:49 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: crossgcc, buildroot, linaro-toolchain

On Thu, Jun 20, 2013 at 2:41 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> Hello,
>
> 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
> variants:
>
>  * 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.
>
> See
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0338g/ch06s05s01.html
> 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
> follows:
>
>         --target=armeb-buildroot-linux-uclibcgnueabi
>         --with-abi=aapcs-linux
>         --with-arch=armv7-a
>         --with-tune=cortex-a8
>
> 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.
>
> Any ideas?

Hi Thomas,

I added linaro-toolchain to CC as there may be someone there who knows
the answer.

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Buildroot] Bizarre behavior of armeb toolchain
  2013-06-20 13:41 Bizarre behavior of armeb toolchain Thomas Petazzoni
  2013-06-20 13:49 ` [Buildroot] " Will Newton
@ 2013-06-20 13:52 ` Thomas Petazzoni
  1 sibling, 0 replies; 3+ messages in thread
From: Thomas Petazzoni @ 2013-06-20 13:52 UTC (permalink / raw)
  To: crossgcc, buildroot


On Thu, 20 Jun 2013 15:41:30 +0200, Thomas Petazzoni wrote:

>  (*) 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).

Interestingly, this problem is visible when you run gcc with the -v
option, and look at the options passed to collect2.

when no options are passed to gcc (and it generates incorrect BE32
code), the options passed to collect2 are:

/home/test/outputs/armv7be/host/usr/libexec/gcc/armeb-buildroot-linux-uclibcgnueabi/4.7.3/collect2
	--sysroot=/home/test/outputs/armv7be/host/usr/armeb-buildroot-linux-uclibcgnueabi/sysroot
	--eh-frame-hdr
	-dynamic-linker /lib/ld-uClibc.so.0
	-X -m armelfb_linux_eabi -o toto
	[...]
	/tmp/ccJDVjCg.o

When -mbig-endian is passed to gcc, gcc then passes the following
options to collect2:

/home/test/outputs/armv7be/host/usr/libexec/gcc/armeb-buildroot-linux-uclibcgnueabi/4.7.3/collect2
	--sysroot=/home/test/outputs/armv7be/host/usr/armeb-buildroot-linux-uclibcgnueabi/sysroot
	--eh-frame-hdr
	--be8
	-dynamic-linker /lib/ld-uClibc.so.0
	-X -EB -m armelfb_linux_eabi -o toto
	[...]
	/tmp/ccnje5oi.o

Notice how it passes -EB and more importantly --be8, which indicates to
ld that it should swap code to make it little endian again (after it
has been generated big endian by as).

Best regards,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-06-20 13:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-20 13:41 Bizarre behavior of armeb toolchain Thomas Petazzoni
2013-06-20 13:49 ` [Buildroot] " Will Newton
2013-06-20 13:52 ` Thomas Petazzoni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).