FTBFS on armhf: clang defaults NEON instructions (Debian diary)

This is a little subject matter I came across recently. Since American Fuzzy Lop (AFL) was started to build with LLVM higher than 3.7 there were problems on the officially supported port armhf. The build always breaks over an illegal instruction while trying to compile the tests for the instrumentation:

[*] Testing the CC wrapper and instrumentation output...
../afl-clang-fast -g -O2 -fdebug-prefix-map=/«PKGBUILDDIR»=. -fPIE -fstack-protector-strong
-Wformat -Werror=format-security -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign
-DAFL_PATH=\"/usr/lib/afl\" -DBIN_PATH=\"/usr/bin\" -DVERSION=\"2.30b\"  ../test-instr.c -o
test-instr -fPIE -pie -Wl,-z,relro -Wl,-z,now
Illegal instruction
Makefile:97: recipe for target 'test_build' failed
make[2]: *** [test_build] Error 132

The bug report on this was commented by Paul Wise (great stuff!). On the armhf machines1 some instructions are generated which can’t be exectured (the other ports passed through), and the build breaks with a SIGILL from afl-clang-fast. afl-clang-fast(1) is simply a wrapper around clang with injects the instrumentation for the fuzzying process into executables which are going to be tested.

It came into focus that clang greater than 3.7 passes NEON instructions2 by default, and thus the build breaks when this package hits a build machine which couldn’t provide that extension3. That chosen default of LLVM is currently under discussion. However, emitting any NEON instructions can be prevented by telling the compiler explicitly. The option -mfpu=vfpv3 restricts to the VFPv3 floating-point extension and disables the NEON SIMD extension.

Until this issue gets solved in the llvm-toolchain-3.8 and 3.9 packages (the original bug report got cloned for the LLVM packages), the afl Debian package could make good use of a temporary fix. I’ve changed debian/rules to pass custom $CFLAGS and $CXXFLAGS (I’ve initially missed that, thanks to Michał Zalewski) to the things to compile in llvm_mode/:

ifeq "$(shell dpkg-architecture -q DEB_HOST_ARCH)" "armhf"
clang_cflags := $(CFLAGS) -mfpu=vfpv3
clang_cxxflags := $(CXXFLAGS) -mfpu=vfpv3

Now, we’re again in front with AFL on Debian, the package dropped out of Testing for some time now (the reason was #828178: clang-3.7 doesn’t support -fdebug-prefix-map. Since that feature from reproducible builds has been applied to Sid the AFL package went FTBFS). Instead of sticking with the current default LLVM version (3.8), I’ve bumped the old debian/patches/hardcode-clang-version.patch to work with clang-3.9. With that move, avoid-builtin-return-address.patch could be dropped (clang SEGFAULT on s390x, #818380), and also -fstack-protector could be again enabled throughout (#786599). The current package (2.34b-5) gets uploaded to unstable (for fixing this bug the experimental branch again was used), then the update to latest 2.35b would be next.

  1. armhf is the ARM port on Debian for 32-bit hard floating-point units with ARMv7 instruction set. See Steve McIntyre’s presentation on the DebConf 14. There’s also a fine German article on the ARM chips in Linux-Magazin 01/2015. [return]
  2. Some of ARM’s Cortex-A cores (application profile for computational intensive tasks) contain NEON (128-bit SIMD) engines which accelerate certain applications. In the v7 class, it’s default for Cortex-A8 and optional in Cortex-A9. Among the Debian machines, the armhf porterboxes asachi and harris support that set, abel doesn’t (that could be found in /proc/cpuinfo). [return]
  3. The armhf build machines which have been used (hoiby, henze, hasse, and antheil) are equally equipped with Marvell Armada XP MV78460 development boards. The ARMv7-compliant chips feature VFP3-16 floating point units. [return]