Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 415937 - toolchain.eclass: Forcing "--with-fpu=vfpv3-d16" on all arm-hardfp-arches is wrong (crossdev-build toolchain won't work)
Summary: toolchain.eclass: Forcing "--with-fpu=vfpv3-d16" on all arm-hardfp-arches is ...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Eclasses (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Toolchain Maintainers
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-14 13:48 UTC by jannis
Modified: 2012-05-19 02:36 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
armv6-hardfloat-fix.patch (armv6-hardfloat-fix.patch,474 bytes, patch)
2012-05-17 07:19 UTC, Siarhei Siamashka
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description jannis 2012-05-14 13:48:32 UTC
I got the armv6j-hardfp-stage3 running on the Raspberry Pi which works fine there.
Now I tried to built a matching cross-compiler using crossdev:
crossdev -t armv6j-hardfloat-linux-gnueabi
The toolchain builds and installs correctly, compiling works. When checking the resulting (cross-compiled) binaries with "readelf -A" one sees the line:
Tag_FP_arch: VFPv3-D16
which is wrong for the ARMv6 since that one has the VFPv2. Talking with ssvb in #gentoo-embedded he said, that VFPv3 is forced via toolchain.eclass. I changed line 973 from:
confgcc+=" --with-fpu=vfpv3-d16"
to
confgcc+=" --with-fpu=vfp"
rebuilt the toolchain and now the resulting binaries are okay:
Tag_FP_arch: VFPv2

The eclass should use "--with-fpu=vfp" for ARMv6-arches, the right values for the newer ARM-cores and not force VFPv3-d16 for all ARMs.

Reproducible: Always
Comment 1 Raúl Porcel (RETIRED) gentoo-dev 2012-05-14 16:00:04 UTC
+1.

@toolchain: While other main distros(debian, ubuntu) only support armv7 for hardfloat, we don't.
Comment 2 Siarhei Siamashka 2012-05-15 14:24:03 UTC
(In reply to comment #0)
> I got the armv6j-hardfp-stage3 running on the Raspberry Pi which works fine
> there.

I think one clarification is needed: this stage3-armv6j_hardfp-20120427.tar.bz2 mentioned by jannis had been built before the addition of "--with-fpu=vfpv3-d16" to toolchain.eclass

Using -mfpu=vfpv3-d16 produces the binaries, which are unusable on ARM11 as has been already verified before (by initially having -mfpu=vfpv3-d16 in CFLAGS by accident for stage3-armv6j_hardfp).

toolchain.eclass needs to be fixed, otherwise armv6j_hardfp stages are screwed from now on.
Comment 3 Siarhei Siamashka 2012-05-15 14:48:36 UTC
The commit to toolchain.eclass was: http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/eclass/toolchain.eclass?r1=1.533&r2=1.534

"arm: rework default --with-arch selection to be more tolerant of endian variations #414395 by Bertrand Jacquin, to automatically throw away unknown arm encodings #264534, and to select vfpv3-d16 by default for hardfp targets -- people can override this at runtime if they wish via CFLAGS, or via EXTRA_ECONF when building gcc"
Comment 4 Siarhei Siamashka 2012-05-17 07:19:57 UTC
Created attachment 312085 [details, diff]
armv6-hardfloat-fix.patch

Please review the attached patch or apply some other fix.
Comment 5 Siarhei Siamashka 2012-05-17 08:28:19 UTC
(In reply to comment #3)
> ... select vfpv3-d16 by default for hardfp targets
> -- people can override this at runtime if they wish via CFLAGS, or via
> EXTRA_ECONF when building gcc"

I assume this part of the commit message was implying that people can override CFLAGS with better settings, such as -mfpu=neon? And the existence of armv6/vfpv2 hardware was just overlooked by mistake when introducing this change. If yes, then let's just quickly fix it and move on.

Right now running "gcc someprogram.c" may produce a binary, which dies with SIGILL for you on ARM11 hardware with hardfloat rootfs. If anybody is curious about how exactly it breaks, here is an example:

$ cat test.c

#include <stdio.h>

double x = 1;

int main()
{
    printf("hello, x + 0.5 = %f\n", x + 0.5);
    return 0;
}

$ gcc -O2 -g -o test test.c

$ gdb ./test
Program received signal SIGILL, Illegal instruction.
0x000083ec in main ()
(gdb) disassemble
Dump of assembler code for function main:
=> 0x000083ec <+0>:	vmov.f64	d7, #96	; 0x60
   0x000083f0 <+4>:	push	{r3, lr}
   0x000083f4 <+8>:	mov	r0, #1
   0x000083f8 <+12>:	ldr	r3, [pc, #24]	; 0x8418 <main+44>
   0x000083fc <+16>:	ldr	r1, [pc, #24]	; 0x841c <main+48>
   0x00008400 <+20>:	vldr	d6, [r3]
   0x00008404 <+24>:	vadd.f64	d5, d6, d7
   0x00008408 <+28>:	vmov	r2, r3, d5
   0x0000840c <+32>:	bl	0x8334 <__printf_chk>
   0x00008410 <+36>:	mov	r0, #0
   0x00008414 <+40>:	pop	{r3, pc}
   0x00008418 <+44>:	andeq	r1, r1, r8, lsr #32
   0x0000841c <+48>:	muleq	r0, r8, r4

It's just the new instruction that places a floating-point constant in a register (0.5 in this case), as explained in VFPv3 overview here:
    http://infocenter.arm.com/help/topic/com.arm.doc.ddi0344k/Beihdjje.html
Comment 6 SpanKY gentoo-dev 2012-05-18 04:59:54 UTC
the point of the comment was that if you want to target a different fpu, specify it on the command line when compiling, or specify your own configure flags

Raúl: the default for armv7* is now hardfloat vfpv3-d16 unless the user has explicitly selected otherwise.  defaulting to softfloat for armv6+ is dumb.  this code only sets up *defaults*, it does not make it the only possibility.

should be fixed by:
http://sources.gentoo.org/eclass/toolchain.eclass?r1=1.537&r2=1.538
Comment 7 Siarhei Siamashka 2012-05-18 06:39:18 UTC
Thanks for quickly looking into this issue.

(In reply to comment #6)
> the point of the comment was that if you want to target a different fpu,
> specify it on the command line when compiling, or specify your own configure
> flags

Overriding CFLAGS for better fpu in /etc/make.conf is OK.

Overriding CFLAGS for worse fpu would be dangerous because forgetting to do this even once when manually compiling something (unpack tarball, ./configure && make) may result in SIGILL death, and some ebuilds may be potentially doing CFLAGS filtering too. But this is not an issue anymore, thanks.

Overriding ABI in CFLAGS is impossible or at least highly problematic. I mean switching between -mfloat-abi=softfp and -mfloat-abi=hard. But I may be missing something.

EXTRA_ECONF is hardly a good option unless it can be kept persistent via some configuration file. And to my understanding this can't be done (please correct me if I'm wrong):
    http://forums.gentoo.org/viewtopic-t-520162-start-0.html

> Raúl: the default for armv7* is now hardfloat vfpv3-d16 unless the user has
> explicitly selected otherwise.  defaulting to softfloat for armv6+ is dumb. 
> this code only sets up *defaults*, it does not make it the only possibility.
> 
> should be fixed by:
> http://sources.gentoo.org/eclass/toolchain.eclass?r1=1.537&r2=1.538

Based on these changes, looks like -mfloat-abi=softfp is not supported for armv6+ hardware in toolchain.eclass anymore? This is not a great news, because some binary blobs are still available for softfp ABI only. For example, SGX graphics drivers for OMAP3 hardware.
Comment 8 SpanKY gentoo-dev 2012-05-18 13:52:20 UTC
(In reply to comment #7)

use per-package env settings to set whatever defaults you want.  read `man portage` for more details.  crossdev already has explicit options to create cross-compilers easily.

as i said, the toolchain.eclass doesn't force anything.  it only sets the defaults.  you can set your own defaults just as easily.
Comment 9 Siarhei Siamashka 2012-05-18 15:56:48 UTC
(In reply to comment #8)
Thanks for the explanations. I'm just trying to how this toolchain.eclass update affects us.

Apparently now the existing users of armv7a-unknown-linux-gnueabi CHOST (and the gentoo developers building stage3 tarballs for it) must do the following in order to avoid troubles on next gcc emerge:

# mkdir /etc/portage/env
# mkdir /etc/portage/env/sys-devel
# echo 'EXTRA_ECONF="--with-float=softfp"' > /etc/portage/env/sys-devel/gcc.conf

And for building cross toolchain --genv option is required now:

# crossdev -S --genv 'EXTRA_ECONF="--with-float=softfp"' -t armv7a-unknown-linux-gnueabi

Right?
Comment 10 Siarhei Siamashka 2012-05-18 17:24:49 UTC
And by the way, what is the story with *-gnueabihf triplet?

http://wiki.debian.org/Multiarch/Tuples
"The advice given by upstream GCC developers was to use the vendor field in the GNU triplet to express this difference1; however, the vendor field is private by design, making this unreliable for cross-distribution use. Work finally succeeded to push the arm-linux-gnueabihf triplet upstream, but there may still be some broken packages around for a while."

Is armv7a-hardfloat-linux-gnueabi going to be eventually changed to arm-linux-gnueabihf or arm-unknown-linux-gnueabihf (with yet another transition issues for the end users)?
Comment 11 SpanKY gentoo-dev 2012-05-18 17:26:27 UTC
(In reply to comment #10)

yes, that's how you can force softfp.  however, two things:
 - using softfp instead of hard+vfp3 for armv7 makes no sense at all -- vfpv3+ is a hard requirement for armv7 cores
 - gentoo armv7a stages should be hardfloat ... if they aren't they should be fixed, not converted back to softfp
Comment 12 SpanKY gentoo-dev 2012-05-18 17:28:17 UTC
(In reply to comment #10)

not everyone is adopting *-gnueabihf, so i don't see much point in requiring it in Gentoo.  it'll be supported if someone wants to use it, but we'll stick with "armv7a-unknown-linux-gnueabi" by default (e.g. stages/crossdev/etc...).
Comment 13 Siarhei Siamashka 2012-05-18 22:09:30 UTC
(In reply to comment #11)
> (In reply to comment #10)
> 
> yes, that's how you can force softfp.  however, two things:
>  - using softfp instead of hard+vfp3 for armv7 makes no sense at all --
> vfpv3+ is a hard requirement for armv7 cores

Yes, using softfp calling conventions makes no sense for fully open source systems running on armv7 hardware. However some users might want to use binary blobs, such as the graphics drivers, codec packages, browser flash plugin, etc. One good example is the SGX 3D graphics accelerator driver for OMAP3 SoC, which is only available for softfp ABI variant: http://tigraphics.blogspot.com/2012/04/1q-sgx-driver-update-package-available.html
And the guys are clearly willing to already EOL this hardware and move on: http://lists.linaro.org/pipermail/linaro-dev/2011-December/008900.html

Lazy vendors may opt not to support anything but softfp for their blobs. Selecting this ABI just for one reason: because android is using softfp. I don't see softfp going away any time soon.

But in any case, as you said, the users can always select something like a generic arm-softfloat-linux-gnueabi stage, add "-march=armv7-a -mfloat=abi=softfp -mfpu=neon" to CFLAGS or tweak EXTRA_ECONF and rebuild gcc. Then run "emerge -e world" and have the system better optimized for their hardware.

>  - gentoo armv7a stages should be hardfloat ... if they aren't they should
> be fixed, not converted back to softfp

The only problem here is that the ABI change happens under the feet of unsuspecting users. Hopefully not many of them will be hurt.
Comment 14 SpanKY gentoo-dev 2012-05-19 02:36:08 UTC
(In reply to comment #13)

binary vendors are getting the message and making the change.  linaro and all the distros are pushing on this, and gentoo is going to follow suite by default.

there are hardfp drivers for tegra and mail gpus now.  i don't know the status of sgx, but it'll happen as well.  i can try asking the android peeps, but i can't see any reason they would stick to that path when there's such an obvious gain to not, and they don't care about backwards compat in userspace.

if someone really wants to build their own softfp system, they still can.  we could add a *-softfp-* vendor field to make it simpler.

it does suck that the default is changing behavior, but i'm not too worried about this negatively affecting a lot of people.  it'll be a painful bump, but it'll move on.