I have posted the same question in [Raspberry Pi 1 B+] Illegal instruction error · Issue #262 · meta-rust/meta-rust · GitHub (I'm using Yocto + meta-rust), but since I'm not sure if the issue is related to meta-rust, my own stupidity or maybe a bug in rust, I'm posting my question here as well.
In short, I'm using Yocto with meta-rust to cross-compile my project and build Raspberry Pi images. This works fine for the Raspberry Pi 3, but I'm stuck with cross-compiling to the Raspberry Pi 1 B+. The project compiles fine, but the application crashes after a certain instruction.
I have gathered the following debug information using gdb
:
Core was generated by `chirpstack-concentratord-sx1301 -c /etc/chirpstack-concentratord/sx1301/global.'.
Program terminated with signal SIGILL, Illegal instruction.
#0 0x0088e394 in <chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default () at /usr/src/debug/chirpstack-concentratord-sx1301/3.0.0-test.5-r6/git/target/arm-oe-linux-gnueabi/debug/build/chirpstack_api-9ec9e0ee96ff6d13/out/gw/gw.rs:103
This is what the gdb backtrace looks like:
#0 0x0088e394 in <chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default () at /usr/src/debug/chirpstack-concentratord-sx1301/3.0.0-test.5-r6/git/target/arm-oe-linux-gnueabi/debug/build/chirpstack_api-9ec9e0ee96ff6d13/out/gw/gw.rs:103
#1 0x0053011c in chirpstack_concentratord_sx1301::wrapper::uplink_to_proto (gateway_id=..., packet=0xb5bfe4a8) at chirpstack-concentratord-sx1301/src/wrapper/mod.rs:107
#2 0x004e794c in chirpstack_concentratord_sx1301::handler::uplink::handle_loop (gateway_id=...) at chirpstack-concentratord-sx1301/src/handler/uplink.rs:17
#3 0x004e9d98 in chirpstack_concentratord_sx1301::cmd::root::run::{{closure}} () at chirpstack-concentratord-sx1301/src/cmd/root/mod.rs:36
#4 0x0055adfc in std::sys_common::backtrace::__rust_begin_short_backtrace (f=...) at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libstd/sys_common/backtrace.rs:126
#5 0x0053dc64 in std::thread::Builder::spawn_unchecked::{{closure}}::{{closure}} () at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libstd/thread/mod.rs:470
#6 0x0052ae74 in <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once (self=..., _args=()) at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libstd/panic.rs:315
#7 0x004e9a90 in std::panicking::try::do_call (data=0xb5bfeb34 "\350\261\251\000") at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libstd/panicking.rs:292
#8 0x009bfc7c in __rust_maybe_catch_panic ()
#9 0x004e908c in std::panicking::try (f=...) at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libstd/panicking.rs:271
#10 0x0052aee0 in std::panic::catch_unwind (f=...) at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libstd/panic.rs:394
#11 0x0053d4ec in std::thread::Builder::spawn_unchecked::{{closure}} () at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libstd/thread/mod.rs:469
#12 0x00504af4 in core::ops::function::FnOnce::call_once{{vtable-shim}} () at /usr/src/debug/libstd-rs/1.39.0-r0/rustc-1.39.0-src/src/libcore/ops/function.rs:227
#13 0x009bd018 in <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once ()
#14 0x009b2730 in std::sys_common::thread::start_thread ()
#15 0x009bf7bc in std::sys::unix::thread::Thread::new::thread_start ()
#16 0xb6f754d4 in ?? () from /lib/libpthread.so.0
And when running gdb layout asm I get:
│0x88e364 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+140> sub r0, r11, #64 ; 0x40 │
│0x88e368 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+144> bl 0x89144c <core::ptr::real_drop_in_place> │
│0x88e36c <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+148> b 0x88e31c <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+68> │
│0x88e370 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+152> bl 0x88eba4 <<chirpstack_api::gw::CrcStatus as core::default::Default>::default> │
│0x88e374 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+156> str r0, [sp, #32] │
│0x88e378 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+160> b 0x88e388 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+176> │
│0x88e37c <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+164> sub r0, r11, #32 │
│0x88e380 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+168> bl 0x891318 <core::ptr::real_drop_in_place> │
│0x88e384 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+172> b 0x88e364 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+140> │
│0x88e388 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+176> ldr r2, [pc, #336] ; 0x88e4e0 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+520> │
│0x88e38c <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+180> ldr r0, [pc, #336] ; 0x88e4e4 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+524> │
│0x88e390 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+184> ldr r1, [pc, #336] ; 0x88e4e8 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+528> │
>│0x88e394 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+188> vldr d16, [pc, #316] ; 0x88e4d8 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+512> │
│0x88e398 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+192> ldr r3, [pc, #332] ; 0x88e4ec <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+532> │
│0x88e39c <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+196> ldr r12, [sp, #44] ; 0x2c │
│0x88e3a0 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+200> ldr lr, [sp, #40] ; 0x28 │
│0x88e3a4 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+204> str r12, [lr, #128] ; 0x80 │
│0x88e3a8 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+208> ldr r12, [sp, #48] ; 0x30 │ │
│0x88e3b0 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+216> ldr r12, [sp, #52] ; 0x34 │
│0x88e3b4 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+220> str r12, [lr, #136] ; 0x88 │
│0x88e3b8 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+224> add r12, sp, #56 ; 0x38 │
│0x88e3bc <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+228> str r0, [sp, #28] │
│0x88e3c0 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+232> mov r0, lr │
│0x88e3c4 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+236> str r1, [sp, #24] │
│0x88e3c8 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+240> mov r1, r12 │
│0x88e3cc <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+244> str r2, [sp, #20] │
│0x88e3d0 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+248> mov r2, r3 │
│0x88e3d4 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+252> vstr d16, [sp, #8] │
│0x88e3d8 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+256> str r3, [sp, #4] │
│0x88e3dc <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+260> bl 0x4aede8 <memcpy@plt> │
│0x88e3e0 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+264> ldr r0, [sp, #40] ; 0x28 │
│0x88e3e4 <<chirpstack_api::gw::UplinkRxInfo as core::default::Default>::default+268> add r1, r0, #24 │
I guess the "Illegal instruction" is because the vldr
instruction is not supported by the Raspberry Pi 1 B+:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGGHHA.html
The VLDR pseudo-instruction loads a constant value into every element of a 64-bit NEON vector, or into a VFP single-precision or double-precision register.
However, the Raspberry Pi 1 B+ does not support NEON.
The reason why I initially opened an issue at meta-rust is because I thought that this would be an incorrect flag generated by their Yocto scripts / classes.
However, it seems that meta-rust generates the following target configuration:
yocto@1f4bd9e63345:/build/tmp/raspberrypi/raspberrypi-glibc/work/x86_64-linux/rust-cross-arm/1.39.0-r0/targets$ cat arm-oe-linux-gnueabi.json
{
"llvm-target": "arm-unknown-linux-gnueabihf",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"max-atomic-width": "64",
"target-pointer-width": "32",
"target-c-int-width": "32",
"target-endian": "little",
"arch": "arm",
"os": "linux",
"env": "gnu",
"vendor": "unknown",
"target-family": "unix",
"linker": "arm-oe-linux-gnueabi-gcc",
"ar": "arm-oe-linux-gnueabi-ar",
"cpu": "generic",
"features": "+vfp2,+v6",
"dynamic-linking": true,
"executables": true,
"linker-is-gnu": true,
"linker-flavor": "gcc",
"has-rpath": true,
"has-elf-tls": true,
"position-independent-executables": true,
"panic-strategy": "unwind"
}
I do not see a +neon
feature in this definition. I have added -neon
and re-compiled everything, but it doesn't seem to make any difference.
Does somebody have any advice what I could try to debug this further or any advice what I could try to fix this? Please let me know if more information is needed.