Я создал копию rockdb для erlang (gitlab.com/Vagabond1/erlang-rocksdb@8708fe8) для цели на основе armv7. Это процессор iMX6 SoloX, вот информация о процессоре:
processor : 0
model name : ARMv7 Processor rev 10 (v7l)
BogoMIPS : 7.54
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x2
CPU part : 0xc09
CPU revision : 10
Hardware : Freescale i.MX6 SoloX (Device Tree)
Revision : 0500
У меня есть программа, которая загружает скомпилированный liberocksdb.so
, но вылетает с SIGILL, вот обратная трассировка:
#0 0xb1b2a7b0 in std::__detail::_Mod_range_hashing::operator()(unsigned int, unsigned int) const () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#1 0xb1b79b48 in std::__detail::_Hash_code_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, std::__detail::_Select1st, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::_M_bucket_index(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int) const () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#2 0xb1b751d4 in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_bucket_index(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) const ()
from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#3 0xb1b6e01c in std::pair<std::__detail::_Node_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, false, true>, bool> std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_insert<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> const&, std::__detail::_AllocNode<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, true> > > >(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> const&, std::__detail::_AllocNode<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, true> > > const&, std::integral_constant<bool, true>) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#4 0xb1b63edc in std::__detail::_Insert_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::insert(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> const&) ()
from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#5 0xb1b568b8 in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> const*>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> const*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> const*, unsigned int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::__detail::_Mod_range_hashing const&, std::__detail::_Default_ranged_hash const&, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::__detail::_Select1st const&, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> > const&) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#6 0xb1b489fc in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Hashtable(std::initializer_list<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> >, unsigned int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> > const&) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#7 0xb1b3c10c in std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, rocksdb::OptionsSanityCheckLevel, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> > >::unordered_map(std::initializer_list<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> >, unsigned int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, rocksdb::OptionsSanityCheckLevel> > const&) () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#8 0xb1b28b04 in __static_initialization_and_destruction_0 () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#9 0xb1b29d30 in _GLOBAL__sub_I_db_impl.cc () from /opt/miner/lib/rocksdb-1.5.0/priv/liberocksdb.so
#10 0xb6fddff8 in ?? () from /lib/ld-linux-armhf.so.3
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Вот разборка:
(gdb) disas /m
Dump of assembler code for function _ZNKSt8__detail18_Mod_range_hashingclEjj:
0xb1b2a790 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0xb1b2a794 <+4>: add r11, sp, #0
0xb1b2a798 <+8>: sub sp, sp, #20
0xb1b2a79c <+12>: str r0, [r11, #-8]
0xb1b2a7a0 <+16>: str r1, [r11, #-12]
0xb1b2a7a4 <+20>: str r2, [r11, #-16]
0xb1b2a7a8 <+24>: ldr r3, [r11, #-12]
0xb1b2a7ac <+28>: ldr r2, [r11, #-16]
=> 0xb1b2a7b0 <+32>: udiv r2, r3, r2
0xb1b2a7b4 <+36>: ldr r1, [r11, #-16]
0xb1b2a7b8 <+40>: mul r2, r1, r2
0xb1b2a7bc <+44>: sub r3, r3, r2
0xb1b2a7c0 <+48>: mov r0, r3
0xb1b2a7c4 <+52>: add sp, r11, #0
0xb1b2a7c8 <+56>: pop {r11} ; (ldr r11, [sp], #4)
0xb1b2a7cc <+60>: bx lr
End of assembler dump.
Я не эксперт в этой области, но, насколько я понимаю, программа дала сбой, потому что инструкция udiv
недопустима для моего процессора.
Я проверил веб-сайт разработчика ARM, это инструкция Cortex M3 , и я считаю, что мой процессор Cortex M4, поэтому я думаю, что в нем должна быть эта инструкция?
Возможно, мой анализ неверен и это что-то другое?
Моя кросс-компиляция была сделана с помощью кросс-тулчейна для этого процессора и rootfs и содержала такие аргументы, как -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard
, которые должны предоставлять совместимые двоичные файлы.
Спасибо
Здесь я достиг предела своих знаний. Как выбирается ядро при выполнении программы? Означает ли это, что Linux запускал программу на A9 и пытался запустить инструкцию, предназначенную для M4? Как я могу запустить программу на M4? Код, генерирующий этот SIGILL, не мой, он взят из зависимости rockdb.
Возможно, сам линукс работает только на А9? Тогда как используется М4? Я знаю, что мой вопрос сформулирован не очень точно, но я пытаюсь заставить эту программу работать на моей цели, и я не тот, кто ее разработал, и у меня мало опыта работы с процессором, инструкциями и кросс-компиляцией.
Это почти на 100% уверено, что этот Linux работает только на Cortex-A9. Какова именно ваша цель? CortexA9 с запущенным Linux-приложением? Я бы предположил, что это так, но не могли бы вы быть более точным?
NXP предоставляет программную поддержку для выполнения, скажем, приложения FreeRTOS на Cortex-M4. Вам нужно будет обратиться к документации NXP для получения более подробной информации о том, как это сделать.
Спасибо за пояснения, очень помогает. Моя цель - A9 для приложения Linux. Я скомпилировал с помощью -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard
, поэтому не понимаю, почему сгенерированный .so содержит инструкцию, предназначенную для Cortex-M...
Я бы предложил дополнить ваш вопрос версией g++, которую вы используете, а также точной процедурой, которой вы следовали для компиляции rockdb, чтобы другие могли собрать ее точно так же, как вы.
Сценарий cmake заставил использовать -march=armv8-a+crc
, который не совместим с моим процессором.
https://gitlab.com/Vagabond1/erlang-rocksdb/-/commit/6bf4a440b8132ef643682ba87dee6de87dc47d58
То, как вы сформулировали свой вопрос, меня смущает. i.MX 6SoloX — это многоядерная система с Cortex®-A9 (не Cortex®-A7) и Cortex®-M4. Таким образом, любая программа, скомпилированная с помощью
-march=armv7-a -marm -mfpu=neon -mfloat-abi=hard
, должна выполняться только на Cortex®-A9, а программы, скомпилированные с помощью-march=armv7-m -mtune=cortex-m4
, должны выполняться только на Cortex®-M4. У вас может быть несоответствие между опциями/программами/ядрами компилятора.