Illegal instruction error on Raspberry Pi 1 B+ (with Yocto & meta-rust)

I have posted the same question in https://github.com/meta-rust/meta-rust/issues/262 (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.

Using https://github.com/rust-embedded/meta-rust-bin instead of https://github.com/meta-rust/meta-rust solved my issue and now the binary runs fine on the Raspberry Pi 1 B+

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.