Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

build: improve armv7 / hard-float detection

  • Loading branch information...
commit 90efdb3a5b7eecb23d78cffee24c3181280efa56 1 parent b0c0111
@adammw adammw authored bnoordhuis committed
Showing with 62 additions and 6 deletions.
  1. +62 −6 configure
View
68 configure
@@ -164,6 +164,12 @@ parser.add_option("--no-ifaddrs",
dest="no_ifaddrs",
help="Use on deprecated SunOS systems that do not support ifaddrs.h")
+parser.add_option("--with-arm-float-abi",
+ action="store",
+ dest="arm_float_abi",
+ help="Specifies which floating-point ABI to use. Valid values are: "
+ "soft, softfp, hard")
+
(options, args) = parser.parse_args()
@@ -189,8 +195,8 @@ def pkg_config(pkg):
return (libs, cflags)
-def host_arch_cc():
- """Host architecture check using the CC command."""
+def cc_macros():
+ """Checks predefined macros using the CC command."""
try:
p = subprocess.Popen(CC.split() + ['-dM', '-E', '-'],
@@ -219,6 +225,52 @@ def host_arch_cc():
key = lst[1]
val = lst[2]
k[key] = val
+ return k
+
+
+def is_arch_armv7():
+ """Check for ARMv7 instructions"""
+ cc_macros_cache = cc_macros()
+ return ('__ARM_ARCH_7__' in cc_macros_cache or
+ '__ARM_ARCH_7A__' in cc_macros_cache or
+ '__ARM_ARCH_7R__' in cc_macros_cache or
+ '__ARM_ARCH_7M__' in cc_macros_cache)
+
+
+def arm_hard_float_abi():
+ """Check for hardfloat or softfloat eabi on ARM"""
+ # GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
+ # the Floating Point ABI used (PCS stands for Procedure Call Standard).
+ # We use these as well as a couple of other defines to statically determine
+ # what FP ABI used.
+ # GCC versions 4.4 and below don't support hard-fp.
+ # GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
+ # __ARM_PCS_VFP.
+
+ if compiler_version() >= (4, 6, 0):
+ return '__ARM_PCS_VFP' in cc_macros()
+ elif compiler_version() < (4, 5, 0):
+ return False
+ elif '__ARM_PCS_VFP' in cc_macros():
+ return True
+ elif ('__ARM_PCS' in cc_macros() or
+ '__SOFTFP' in cc_macros() or
+ not '__VFP_FP__' in cc_macros()):
+ return False
+ else:
+ print '''Node.js configure error: Your version of GCC does not report
+ the Floating-Point ABI to compile for your hardware
+
+ Please manually specify which floating-point ABI to use with the
+ --with-arm-float-abi option.
+ '''
+ sys.exit()
+
+
+def host_arch_cc():
+ """Host architecture check using the CC command."""
+
+ k = cc_macros()
matchup = {
'__x86_64__' : 'x64',
@@ -277,11 +329,15 @@ def configure_node(o):
o['variables']['host_arch'] = host_arch
o['variables']['target_arch'] = target_arch
- # V8 on ARM requires that armv7 is set. We don't have a good way to detect
- # the CPU model right now so we pick a default and hope that it works okay
- # for the majority of users.
+ # V8 on ARM requires that armv7 is set. CPU Model detected by
+ # the presence of __ARM_ARCH_7__ and the like defines in compiler
if target_arch == 'arm':
- o['variables']['armv7'] = 0 # FIXME
+ if options.arm_float_abi:
+ hard_float = options.arm_float_abi == 'hard'
+ else:
+ hard_float = arm_hard_float_abi()
+ o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
+ o['variables']['armv7'] = 1 if is_arch_armv7() else 0
# clang has always supported -fvisibility=hidden, right?
cc_version, is_clang = compiler_version()

9 comments on commit 90efdb3

@TooTallNate
Owner

So, it seems rather strange, but this patch makes the build on the Raspberry Pi result in an invalid binary using the default configuration.

When I compile the v0.8.4 tag, using the env flags specified here: https://gist.github.com/3119325, then node works fine.

But when I apply this patch and attempt to compile again (using the same env flags), then attempting to invoke the resulting "node" results in "Illegal Instruction", and the only symbol mention in the gdb backtrace is OPENSSL_cpuid_setup.

Seems strange to me, but I thought I'd let you know of my discovery.

@bnoordhuis

@TooTallNate Is that from the bundled or the system openssl library? Can you post a backtrace and the output of ldd path/to/node?

@TooTallNate
Owner

@bnoordhuis It's the system openssl. The build fails trying to compile openssl if you try to use the bundled one (I could open a separate issue for that if you'd like). The result of ldd ./node is identical in both the working version (without this patch) and the non working version.

pi@raspberrypi ~ $ ldd ./node
    /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0x4022b000)
    libssl.so.1.0.0 => /usr/lib/arm-linux-gnueabihf/libssl.so.1.0.0 (0x4014f000)
    libcrypto.so.1.0.0 => /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.0.0 (0x40234000)
    librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x40003000)
    libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x400a6000)
    libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x40397000)
    libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x4019e000)
    libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x400cb000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x400f3000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x40464000)
    libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0x40112000)
    /lib/ld-linux-armhf.so.3 (0x40079000)
@bnoordhuis

Yeah, someone else reported that issue as well (that was before this patch though). The best advice I can give you is to not link against the system openssl, I speculate it's an ABI mismatch.

@bnoordhuis

The build fails trying to compile openssl if you try to use the bundled one (I could open a separate issue for that if you'd like).

That should be fixed, yes, so please open an issue.

@adammw

Not exactly related to the problem @TooTallNate is seeing, but apparently V8 has trouble with hard float systems that don't support VFP3, which is exactly what will happen on a Raspberry Pi with hard-float and this patch correctly sets v8_use_arm_eabi_hardfloat however v8 defines CAN_USE_VFP_INSTRUCTIONS when v8_use_arm_eabi_hardfloat=="true" in common.gypi, causing V8 to emit VFP3 instructions that the device doesn't support.
It seems to be a popular belief that hardfp requires VFP3 instructions, when the Raspberry Pi is in fact hardfp without VFP3 (but it does have VFP2).
Originally I thought that because it's not being defined when manually setting -DUSE_EABI_HARDFLOAT in CCFLAGS like https://gist.github.com/3119325, V8 doesn't generate any VFP3 instructions and that's probablly why that build works, however we can't simply remove the CAN_USE_VFP_INSTRUCTIONS declaration when hardfloat is true because there are many places where the ARM codegen assumes VFP3 instructions when hardfloat is enabled. Attempting to remove it produces the output seen at https://gist.github.com/3244239, following the backtrace we can see that it is caused in code-stubs-arm.cc. Qt seem to have a patch supporting VFP2 instructions (which the Rapsberry Pi does support) listed at https://codereview.qt-project.org/#change,27256.

Upstream issue: http://code.google.com/p/v8/issues/detail?id=2168

I have yet to attempt to compile for Raspberry Pi with Qt's patches, I think that is what I will try next.

@adammw

I just spent over an hour composing a great reply to this thread full of research on the issue and related issues, all for Chrome and GitHub to conspire against me and lose the whole lot when clicking comment. Feel so gutted.

I think the gist of it was, not sure if its the same issue that @TooTallNate was having but I found that V8 thinks hardfp means that you have VFP3, so it generates VFP3 instructions causing lots of problems on ARMv6 which doesn't support VFP3 but can support hard float and VFP2 instead. You can't just remove the USE_VFP_INSTRUCTIONS define in common.gypi (that's where it's set because of the earlier stated assumption, and is exacerbated by this commit as it starts to correctly set v8_use_arm_eabi_hardfloat) because then you get this as other parts of the ARM codegen assume that hardfp means VFP3 available, and then the internal checks fail. The proper way to go about this seems to use VFP2, and Qt has a patch for VFP2 that might work at https://codereview.qt-project.org/#change,27256, but I am yet to try it and requires some back-porting to V8 and there's the licensing issues apparently. None of this should be a problem on soft float systems or hard float but ARMv7/VFP3 supported, just for the odd combination that is the Raspberry Pi.

The upstream issue I found for this stuff is: http://code.google.com/p/v8/issues/detail?id=2168

@adammw

Whoops, that's embarassing. Uber cache fail. Anyway, for reference:

Applying the Qt patches in adammw/node@3a42578 seems to produce a binary that works on Raspbian (hard float OS for Raspberry Pi). Tested by cross-compiling with ./configure --without-ssl --without-snapshot. Binaries produced uploaded to https://gist.github.com/3245130
Running the tests - some succeed, some fail, tests eventually crashed with IOError: [Errno 11] Resource temporarily unavailable, similar to issue #3810.

@luismreis

Issue #3755 also seems related to this.

Please sign in to comment.
Something went wrong with that request. Please try again.