Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 510906 - sys-devel/clang-3.4.1-r100 tries to build softfp binaries by default on arm hardfloat systems
Summary: sys-devel/clang-3.4.1-r100 tries to build softfp binaries by default on arm h...
Status: RESOLVED OBSOLETE
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] Development (show other bugs)
Hardware: ARM Linux
: Normal normal (vote)
Assignee: Gentoo Clang Team (OBSOLETE)
URL: http://llvm.org/bugs/show_bug.cgi?id=...
Whiteboard:
Keywords: PATCH
Depends on:
Blocks:
 
Reported: 2014-05-21 08:50 UTC by Siarhei Siamashka
Modified: 2016-08-16 16:34 UTC (History)
3 users (show)

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


Attachments
LLVM patch to fix the incorrect default float ABI detection in Clang (gentoo-clang-hardfloat-fix.patch,573 bytes, patch)
2014-05-21 08:58 UTC, Siarhei Siamashka
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Siarhei Siamashka 2014-05-21 08:50:49 UTC
Clang and LLVM identify the floating point ABI based on the toolchain triplet name. And they are relying on the Ubuntu triplet naming conventions where "*-gnueabihf" means hard float ABI. But in Gentoo, the hardfloat toolchain is named as "armv7a-hardfloat-linux-gnueabi" with the second part (vendor) indicating that the ABI is in fact hard float. This problem can be fixed with a simple single liner patch for the sys-devel/llvm-3.4.1-r1 ebuild.

Reproducible: Always

Steps to Reproduce:
$ clang helloworld.c
Actual Results:  
/usr/bin/armv7a-hardfloat-linux-gnueabi-ld: error: a.out uses VFP register arguments, /tmp/helloworld-7d0932.o does not
/usr/bin/armv7a-hardfloat-linux-gnueabi-ld: failed to merge target specific data of file /tmp/helloworld-7d0932.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)


Expected Results:  
Clean compilation without linking errors.
Comment 1 Siarhei Siamashka 2014-05-21 08:58:23 UTC
Created attachment 377332 [details, diff]
LLVM patch to fix the incorrect default float ABI detection in Clang

This patch needs to be applied by the sys-devel/llvm-3.4.1 ebuild (because that's where clang is actually built). It makes clang additionally use the "vendor" part of the toolchain triplet name when doing the hard vs. softfp ABI selection.
Comment 2 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-05-21 10:17:25 UTC
@toolchain, can I get your opinion on this? This is an unexplored area to me. Considering that clang fails because it is relying on ubuntu triplets, I'd think relying on triplets is a bad idea anyway. Is there a better way of identifying hardfloat?
Comment 3 SpanKY gentoo-dev 2014-05-21 15:21:06 UTC
(In reply to Michał Górny from comment #2)

this is one way of doing it, but not the preferred.  you can see in toolchain.eclass (around line 1042) that we default to hardfloat for all armv6/armv7 cpus.  i think clang should do the same (however is easiest for it to do that).
Comment 4 Siarhei Siamashka 2014-05-30 13:57:00 UTC
(In reply to Michał Górny from comment #2)
> @toolchain, can I get your opinion on this? This is an unexplored area to
> me. Considering that clang fails because it is relying on ubuntu triplets,
> I'd think relying on triplets is a bad idea anyway.

That's how upstream LLVM/Clang works at the moment. No matter whether we like it or not.

Unfortunately the hardfloat triplet naming conventions have diverged quite a bit. Gentoo has been one of the first distributions to start providing hardfloat rootfs (starting with the pre-release snapshots of GCC 4.5.0 back in 2010). And AFAIK, the triplet name had been originally selected in a way, that was approved by the upstream GCC developers: http://lists.linaro.org/pipermail/linaro-toolchain/2012-March/002311.html

Then came Ubuntu and invented the "*-gnueabihf" triplet of their own. Then came Red Hat and invented the "armv7hl-*" triplet. I wonder, which distro is next to "innovate" something new? :-)

> Is there a better way of identifying hardfloat?

One more possible alternative is to use the "#ifdef __ARM_PCS_VFP" check in the Clang code instead of checking for the "vendor" part of the triplet in my currently proposed patch. This would make Clang default to the same floating point ABI as used by the Clang binary itself.

However we might want to additionally ensure that Clang also works correctly as the crosscompiler. This would imply that on an x86-64 system, the invocation "clang -target armv7a-hardfloat-linux-gnueabi hello.c" should work correctly as long as the "armv7a-hardfloat-linux-gnueabi" crosscompiler is installed via crossdev. But we are not quite there yet:

$ clang -v -target armv7a-hardfloat-linux-gnueabi -mfloat-abi=hard hello.c
clang version 3.4.1 (tags/RELEASE_34/dot1-final)
Target: armv7a-hardfloat-linux-gnueabi
Thread model: posix
Selected GCC installation: /usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2
 "/usr/bin/clang" -cc1 -triple armv7-hardfloat-linux-gnueabi -S -disable-free -disable-llvm-verifier -main-file-name hello.c -mrelocation-model static -mdisable-fp-elim -fmath-errno -mconstructor-aliases -fuse-init-array -target-cpu cortex-a8 -target-abi aapcs-linux -mfloat-abi hard -target-linker-version 2.23.2 -v -resource-dir /usr/bin/../lib/clang/3.4.1 -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.4.1/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fno-dwarf-directory-asm -fdebug-compilation-dir /tmp -ferror-limit 19 -fmessage-length 117 -mstackrealign -fno-signed-char -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -vectorize-slp -o /tmp/hello-d9df46.s -x c hello.c
clang -cc1 version 3.4.1 based upon LLVM 3.4.1 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../lib/clang/3.4.1/include
 /usr/include
End of search list.
 "/usr/bin/armv7a-hardfloat-linux-gnueabi-as" -mfpu=neon -mfloat-abi=hard -o /tmp/hello-b6ec65.o /tmp/hello-d9df46.s
 "/usr/bin/armv7a-hardfloat-linux-gnueabi-ld" -X --eh-frame-hdr -m armelf_linux_eabi -dynamic-linker /lib/ld-linux.so.3 -o a.out /usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../../../lib/crt1.o /usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../../../lib/crti.o /usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/crtbegin.o -L/usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2 -L/usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../../../armv7a-hardfloat-linux-gnueabi/lib/../lib -L/usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../../../armv7a-hardfloat-linux-gnueabi/lib -L/usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../.. -L/lib -L/usr/lib /tmp/hello-b6ec65.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/crtend.o /usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../../../lib/crtn.o
/usr/lib/gcc/armv7a-hardfloat-linux-gnueabi/4.8.2/../../../../lib/crt1.o: file not recognized: File format not recognized
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This fails because it tries to link with the crt1.o from sys-libs/glibc instead of the crt1.o from cross-armv7a-hardfloat-linux-gnueabi/glibc:

$ equery belongs crt1.o
 * Searching for crt1.o ... 
cross-armv7a-hardfloat-linux-gnueabi/glibc-2.11.2-r3 (/usr/armv7a-hardfloat-linux-gnueabi/usr/lib/crt1.o)
cross-mipsel-unknown-linux-gnu/glibc-2.10.1-r1 (/usr/mipsel-unknown-linux-gnu/usr/lib/crt1.o)
cross-powerpc-unknown-linux-gnu/glibc-2.19 (/usr/powerpc-unknown-linux-gnu/usr/lib/crt1.o)
sys-libs/glibc-2.17 (/usr/lib32/crt1.o)
sys-libs/glibc-2.17 (/usr/lib64/crt1.o)


Basically, many possible alternativs are available for just the native ARM Clang. But if we care about eventually fixing the crosscompilation too, then parsing the triplet name seems to be the most straightforward and less problematic.
Comment 5 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-05-30 14:05:26 UTC
While at it, could you submit the patch upstream? I'll probably add it to the next release.
Comment 6 Siarhei Siamashka 2014-06-01 19:02:50 UTC
(In reply to Michał Górny from comment #5)
> While at it, could you submit the patch upstream? I'll probably add it to
> the next release.

Sure. They already had a bug for this problem in their tracker - http://llvm.org/bugs/show_bug.cgi?id=15557
Comment 7 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-06-01 19:09:26 UTC
(In reply to Siarhei Siamashka from comment #6)
> (In reply to Michał Górny from comment #5)
> > While at it, could you submit the patch upstream? I'll probably add it to
> > the next release.
> 
> Sure. They already had a bug for this problem in their tracker -
> http://llvm.org/bugs/show_bug.cgi?id=15557

Thanks. It would be best if you also submitted it to LLVMdev mailing list, since patches there are more likely to be picked up by LLVM devs.
Comment 8 John Bowler 2014-09-19 19:02:38 UTC
With clang/llvm 3.5.0 this bug causes the build of dhcpcd 6.4.5 to fail on ARM + -mfloat-abi=hard.

This is because that version of dhcpcd looks for compilers with the arm... prefix and suffices "cc clang gcc...".  Because there is no:

/usr/bin/armv7a-hardfloat-linux-gnueabi-cc

dhcpcd configure ends up selecting:

/usr/bin/armv7a-hardfloat-linux-gnueabi-clang

(personally I think that's pretty dumb, but it does) and *that* compiler cannot compile int main(void) {return 0;}:

utilite ~ # echo 'int main(void){return 0;}' >t.c
utilite ~ # /usr/bin/armv7a-hardfloat-linux-gnueabi-clang -o t t.c
/usr/bin/armv7a-hardfloat-linux-gnueabi-ld: error: t uses VFP register argument, /tmp/t-f11429.o does not
/usr/bin/armv7a-hardfloat-linux-gnueabi-ld: failed to merge target specific dat of file /tmp/t-f11429.o
armv7a-hardfloat-linux-gnueabi-clang-3.5.0: error: linker command failed with eit code 1 (use -v to see invocation)


Which is certainly a dumb thing for a compiler called 'armv7-*hardfloat*-linux-gnueabi-clang'

The problem arises here because the 'configure' step of dhcpcd does not include 'CFLAGS' when checking if the compiler works.  That's probably another bug.

(The work round is pretty simple - CC=gcc either in make.conf or in a package specific package.env environment.)
Comment 9 Siarhei Siamashka 2014-09-20 07:37:07 UTC
Hi John,

I have quickly checked the dhcpcd 6.4.5 tarball. And it indeed has its own wacky custom made "configure" script (not generated by autotools). I'm not surprised that it may commit atrocities, such as picking clang instead of gcc on ARM out of blue, not respecting CFLAGS, etc. However the dhcpcd configure problems are not directly related to this particular clang/llvm hardfloat issue and I suggest you to file a separate bug against dhcpcd.

As for the clang/llvm 3.5.0, my old attached patch still works for it just fine. You can create a "/etc/portage/patches/sys-devel/llvm" directory and put the patch there with a *.patch extension. On next llvm emerge, portage will pick it up and you will have the hardfloat problem resolved. Good luck.
Comment 10 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2016-08-16 16:34:30 UTC
Mass-closing of bugs pinned to old clang versions. Please reopen and update summary appropriately if the bug still applies to a newer version (and hasn't been reported separately for it).