Running nodejs 6.11.2 on FPU-less ARMv7: SIGILL

65 views
Skip to first unread message

Alex Potapenko

unread,
Aug 10, 2017, 2:19:50 PM8/10/17
to nodejs
Hi, I'm trying to get node 6.11.2 to work on an ARMv7 router:

# cat /proc/cpuinfo
Processor       : ARMv7 Processor rev 0 (v7l)
processor      
: 0
BogoMIPS        : 1599.07


processor      
: 1
BogoMIPS        : 1595.80


Features        : swp half thumb fastmult edsp
CPU implementer
: 0x41
CPU architecture
: 7
CPU variant    
: 0x3
CPU part        
: 0xc09
CPU revision    
: 0


Hardware        : Northstar Prototype
Revision        : 0000
Serial          : 0000000000000000

I've written a patch for node to build without VFP3, VFP32DREGS, or NEON:
--- a/configure
+++ b/configure
@@ -49,9 +49,9 @@
 valid_arch
= ('arm', 'arm64', 'ia32', 'mips', 'mipsel', 'mips64el', 'ppc',
               
'ppc64', 'x32','x64', 'x86', 's390', 's390x')
 valid_arm_float_abi
= ('soft', 'softfp', 'hard')
-valid_arm_fpu = ('vfp', 'vfpv3', 'vfpv3-d16', 'neon')
+valid_arm_fpu = ('vfp', 'vfpv3', 'vfpv3-d16', 'neon', 'none')
 valid_mips_arch
= ('loongson', 'r1', 'r2', 'r6', 'rx')
-valid_mips_fpu = ('fp32', 'fp64', 'fpxx')
+valid_mips_fpu = ('fp32', 'fp64', 'fpxx', 'soft')
 valid_mips_float_abi
= ('soft', 'hard')
 valid_intl_modes
= ('none', 'small-icu', 'full-icu', 'system-icu')
 
--- a/deps/v8/build/toolchain.gypi
+++ b/deps/v8/build/toolchain.gypi
@@ -56,10 +56,24 @@
     
'arm_test_noprobe%': 'off',
 
     
# Similar to vfp but on MIPS.
-    'v8_can_use_fpu_instructions%': 'true',
+    'conditions': [
+      ['mips_fpu_mode!="soft"', {
+        'v8_can_use_fpu_instructions%': 'true',
+      }],
+      ['mips_fpu_mode=="soft"', {
+        'v8_can_use_fpu_instructions%': 'false',
+      }],
+    ],
 
     
# Similar to the ARM hard float ABI but on MIPS.
-    'v8_use_mips_abi_hardfloat%': 'true',
+    'conditions': [
+      ['mips_fpu_mode!="soft"', {
+        'v8_use_mips_abi_hardfloat%': 'true',
+      }],
+      ['mips_fpu_mode=="soft"', {
+        'v8_use_mips_abi_hardfloat%': 'false',
+      }],
+    ],
 
     
# Force disable libstdc++ debug mode.
     
'disable_glibcxx_debug%': 0,
@@ -207,7 +221,7 @@
                   
}],
                   
[ 'arm_version==7 or arm_version=="default"', {
                     
'conditions': [
-                      [ 'arm_fpu!="default"', {
+                      [ 'arm_fpu!="default" and arm_fpu!="none"', {
                         
'cflags': ['-mfpu=<(arm_fpu)',],
                       
}],
                     
],
@@ -250,7 +264,7 @@
                   
}],
                   
[ 'arm_version==7 or arm_version=="default"', {
                     
'conditions': [
-                      [ 'arm_fpu!="default"', {
+                      [ 'arm_fpu!="default" and arm_fpu!="none"', {
                         
'cflags': ['-mfpu=<(arm_fpu)',],
                       
}],
                     
],
@@ -526,6 +540,11 @@
                           
'FPU_MODE_FP32',
                         
],
                       
}],
+                      ['mips_fpu_mode=="soft"', {
+                        'defines': [
+                          '_MIPS_ARCH_MIPS32R2',
+                        ],
+                      }],
                     
],
                   
}],
                   
['mips_arch_variant=="r1"', {
@@ -665,6 +684,12 @@
                       
[ 'clang==0', {
                         
'cflags': ['-Wa,-mips32r2'],
                       
}],
+                      ['mips_fpu_mode=="soft"', {
+                        'defines': [
+                          '_MIPS_ARCH_MIPS32R2',
+                        ],
+                        'cflags': ['-msoft-float'],
+                      }],
                     
],
                     
'cflags': ['-mips32r2'],
                     
'ldflags': ['-mips32r2'],
--- a/deps/v8/src/base/build_config.h
+++ b/deps/v8/src/base/build_config.h
@@ -71,7 +71,7 @@
     
defined(__ARM_ARCH_7__)
 
# define CAN_USE_ARMV7_INSTRUCTIONS 1
 
# ifndef CAN_USE_VFP3_INSTRUCTIONS
-#  define CAN_USE_VFP3_INSTRUCTIONS
+//#  define CAN_USE_VFP3_INSTRUCTIONS
 
# endif
 
#endif
 
--- a/deps/v8/src/base/cpu.cc
+++ b/deps/v8/src/base/cpu.cc
@@ -137,6 +137,7 @@
 
 
#if V8_HOST_ARCH_MIPS
 
int __detect_fp64_mode(void) {
+#ifndef __mips_soft_float
   
double result = 0;
   
// Bit representation of (double)1 is 0x3FF0000000000000.
   __asm__
volatile(
@@ -153,6 +154,9 @@
       
: "t0", "$f0", "$f1", "memory");
 
   
return !(result == 1);
+#else
+  return 0;
+#endif
 
}
 
 
(This also adds support for softfloat mips target supported (which was tested to work fine on a softfloat mipsel router))

For the armv7 router node results in being configured without VFP3, VFP32DREGS or NEON:
# node --v8-options|head -2
target arm v7 vfp2 softfp
ARMv8=0 ARMv7=1 VFP3=0 VFP32DREGS=0 NEON=0 SUDIV=0 MLS=1UNALIGNED_ACCESSES=1 MOVW_MOVT_IMMEDIATE_LOADS=0 COHERENT_CACHE=0 USE_EABI_HARDFLOAT=0

Calling node without arguments crashes with SIGILL:
# gdb node
GNU gdb
(GDB) 7.11
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from node...done.
(gdb) run
Starting program: /opt/bin/node
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/opt/lib/libthread_db.so.1".
[New Thread 0x401514c0 (LWP 8059)]
[New Thread 0x422ef4c0 (LWP 8060)]
[New Thread 0x425ac4c0 (LWP 8061)]
[New Thread 0x428564c0 (LWP 8062)]
[New Thread 0x42ac24c0 (LWP 8063)]


Thread 1 "node" received signal SIGILL, Illegal instruction.
0x01161d0c in v8::internal::(anonymous namespace)::Flag::IsDefault (this=0xb5b768 <_start>) at ../deps/v8/src/flags.cc:116
116     ../deps/v8/src/flags.cc: No such file or directory.
(gdb) bt full
#0  0x01161d0c in v8::internal::(anonymous namespace)::Flag::IsDefault (this=0xb5b768 <_start>) at ../deps/v8/src/flags.cc:116
No locals.
#1  0x01163618 in v8::internal::ComputeFlagListHash () at ../deps/v8/src/flags.cc:559
        current
= 0x1cc674c <v8::internal::(anonymous namespace)::flags>
        i
= 0
        modified_args_as_string
= <incomplete type>
        args
= {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x40087490 "H{\b@"}}
#2  0x01164090 in v8::internal::FlagList::EnforceFlagImplications () at ../deps/v8/src/flags.cc:575
No locals.
#3  0x015d5314 in v8::internal::V8::InitializeOncePerProcessImpl () at ../deps/v8/src/v8.cc:57
No locals.
#4  0x01906704 in v8::base::CallOnceImpl (once=0x1cd06ac <v8::internal::init_once>, init_func=0x15d5304 <v8::internal::V8::InitializeOncePerProcessImpl()>, arg=0x0) at ../deps/v8/src/base/once.cc:37
        state
= 0
#5  0x00c46258 in v8::base::CallOnce (once=0x1cd06ac <v8::internal::init_once>, init_func=0x15d5304 <v8::internal::V8::InitializeOncePerProcessImpl()>) at ../deps/v8/src/base/once.h:86
No locals.
#6  0x015d546c in v8::internal::V8::InitializeOncePerProcess () at ../deps/v8/src/v8.cc:90
No locals.
#7  0x015d52c8 in v8::internal::V8::Initialize () at ../deps/v8/src/v8.cc:39
No locals.
#8  0x00ba1834 in v8::V8::Initialize () at ../deps/v8/src/api.cc:5537
No locals.
#9  0x01745e48 in node::Start (argc=1, argv=0x1cd7740) at ../src/node.cc:4773
        __PRETTY_FUNCTION__
= "int node::Start(int, char**)"
        exec_argc
= 0
        exec_argv
= 0x1cd7760
        exit_code
= 0
#10 0x0177d0c0 in main (argc=1, argv=0xbeeb1d64) at ../src/node_main.cc:57
No locals.

If I comment out the problematic part in flags.cc to see how far it goes then:
/*    if (!current->IsDefault()) {
      modified_args_as_string << i;
      modified_args_as_string << *current;
    }*/

It crashes here:
# gdb node
GNU gdb
(GDB) 7.11
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from node...done.
(gdb) run
Starting program: /opt/bin/node
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/opt/lib/libthread_db.so.1".
[New Thread 0x4005f4c0 (LWP 2169)]
[New Thread 0x422c94c0 (LWP 2170)]
[New Thread 0x4253b4c0 (LWP 2171)]
[New Thread 0x427864c0 (LWP 2172)]
[New Thread 0x4298c4c0 (LWP 2173)]


Thread 1 "node" received signal SIGILL, Illegal instruction.
0x017f582c in v8::platform::DefaultPlatform::MonotonicallyIncreasingTime (this=0x1cd8908) at ../deps/v8/src/libplatform/default-platform.cc:166
166     ../deps/v8/src/libplatform/default-platform.cc: No such file or directory.
(gdb) bt full
#0  0x017f582c in v8::platform::DefaultPlatform::MonotonicallyIncreasingTime (this=0x1cd8908) at ../deps/v8/src/libplatform/default-platform.cc:166
No locals.
#1  0x011bb044 in v8::internal::Heap::MonotonicallyIncreasingTimeInMs (this=0x1cd9798) at ../deps/v8/src/heap/heap.cc:4389
No locals.
#2  0x011935c8 in v8::internal::GCTracer::GCTracer (this=0x1cfc580, heap=0x1cd9798) at ../deps/v8/src/heap/gc-tracer.cc:136
No locals.
#3  0x011be72c in v8::internal::Heap::SetUp (this=0x1cd9798) at ../deps/v8/src/heap/heap.cc:5365
No locals.
#4  0x012ad0b0 in v8::internal::Isolate::Init (this=0x1cd9788, des=0x0) at ../deps/v8/src/isolate.cc:2223
        always_allocate
= {heap_ = 0x1cd9798}
        create_heap_objects
= 190
#5  0x00bac3f0 in v8::Isolate::New (params=...) at ../deps/v8/src/api.cc:7373
        isolate
= 0x1cd9788
        v8_isolate
= 0x1cd9788
        code_event_handler
= 0x0
        isolate_scope
= {isolate_ = 0x1cd9788}
#6  0x01745fa4 in node::StartNodeInstance (arg=0xbe977bd8) at ../src/node.cc:4645
        instance_data
= 0xbe977bd8
       
params = {entry_hook = 0x0, code_event_handler = 0x0, constraints = {max_semi_space_size_ = 0, max_old_space_size_ = 0, max_executable_size_ = 0, stack_limit_ = 0x0, code_range_size_ = 0},
          snapshot_blob
= 0x0, counter_lookup_callback = 0x0, create_histogram_callback = 0x0, add_histogram_sample_callback = 0x0, array_buffer_allocator = 0x1cd9778}
        array_buffer_allocator
= 0x1cd9778
        isolate
= 0xbe977bac
        __PRETTY_FUNCTION__
= "void node::StartNodeInstance(void*)"
#7  0x0174654c in node::Start (argc=1, argv=0x1cd8740) at ../src/node.cc:4784
        instance_data
= {node_instance_type_ = node::MAIN, exit_code_ = 1, event_loop_ = 0x401075f8 <default_loop_struct>, argc_ = 1, argv_ = 0x1cd8740, exec_argc_ = 0, exec_argv_ = 0x1cd8760,
          use_debug_agent_flag_
= false}
        __PRETTY_FUNCTION__
= "int node::Start(int, char**)"
        exec_argc
= 0
        exec_argv
= 0x1cd8760
        exit_code
= 1
#8  0x0177d768 in main (argc=1, argv=0xbe977d64) at ../src/node_main.cc:57
No locals.
at these lines:
double DefaultPlatform::MonotonicallyIncreasingTime() {
 
return base::TimeTicks::HighResolutionNow().ToInternalValue() /
         
static_cast<double>(base::Time::kMicrosecondsPerSecond);
}

So, the question is: what am I doing wrong, or FPU-less ARMv7 platform isn't supported? `./configure --help` has following lines:
 --with-arm-float-abi=ARM_FLOAT_ABI
                        specifies which floating
-point ABI to use (soft,
                        softfp
, hard).
which left me thinking node should work without an FPU.

Any ideas?

Thanks,
Alex
Reply all
Reply to author
Forward
0 new messages