-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Description
I'm trying to use rust binaries on an armv5te gateway using yocto(thud, meta-atmel).
Depending on the configuration(rust-version, target-flags, lto, optimization) I have anything from a (luckily) working binary over wrong logic-level behavior to segmentation faults.
During runtime, these problems are deterministic and are introduced during compile-time.
I've uploaded a minmial example of one of these symptoms for you to be able to reproduce the problem: https://github.com/M1cha/rust_armfault/tree/arcswap
config:
- rustup's stable toolchain(
stable-x86_64-unknown-linux-gnu,rustc 1.31.1 (b6c32da9b 2018-12-18)) - arm-unknown-linux-gnueabi toolchain built by crosstools-ng
1:1.24.0.r6.gafaf7b9a-1 - the following
~/.cargo/config
[target.armv5te-unknown-linux-gnueabi]
linker = "arm-linux-gnueabi-gcc"
- build command:
cargo build --release --target armv5te-unknown-linux-gnueabi
This specific fault only occurs with LTO enabled, during optimization levels 2 and 3.
To be clear, unless I'm fighting multiple bugs at once, this bug is NOT caused by LTO, it just happens to occur in that config. I have other symptoms which occur without LTO and optimization level 1, but I can't reproduce them outside of my yocto environment.(e.g. a segfault during regex::Regex::new).
This is the call-stack during the fault:
#0 0xffff0fc0 in ?? ()
#1 0x00457d68 in compiler_builtins::arm_linux::__kuser_cmpxchg ()
at rustc/compiler_builtins_shim/../../libcompiler_builtins/src/arm_linux.rs:8
#2 compiler_builtins::arm_linux::atomic_cmpxchg ()
at rustc/compiler_builtins_shim/../../libcompiler_builtins/src/arm_linux.rs:85
#3 __sync_val_compare_and_swap_4 () at rustc/compiler_builtins_shim/../../libcompiler_builtins/src/arm_linux.rs:103
#4 0x00403ab0 in <arc_swap::ArcSwapAny<T, S>>::wait_for_readers ()
#5 0x004169e4 in armfault::main ()
#6 0x00416a94 in std::rt::lang_start::{{closure}} ()
#7 0x00416498 in main ()
registers:
r0 0x0 0
r1 0x0 0
r2 0x45acdc 4566236
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x45acdc 4566236
r7 0xffff0fc0 4294905792
r8 0x474100 4669696
r9 0x4740c4 4669636
r10 0xbefffb20 3204447008
r11 0x0 0
r12 0x473ee4 4669156
sp 0xbefffae0 0xbefffae0
lr 0x457d68 4554088
pc 0xffff0fc0 0xffff0fc0
cpsr 0x60000010 1610612752
user_debug kernel log:
armfault: unhandled page fault (11) at 0x0045acdc, code 0x81f
pgd = 6ca4b731
[0045acdc] *pgd=25d04831, *pte=2406d18f, *ppte=2406daae
CPU: 0 PID: 28225 Comm: armfault Not tainted 4.19.61-yocto-standard #1
Hardware name: Atmel AT91SAM9
PC is at _einittext+0x3f902c00/0xffe43ce8
LR is at 0x457d68
pc : [<ffff0fc0>] lr : [<00457d68>] psr: 60000010
sp : befffae0 ip : 00473ee4 fp : 00000000
r10: befffb20 r9 : 004740c4 r8 : 00474100
r7 : ffff0fc0 r6 : 0045acdc r5 : 00000000 r4 : 00000000
r3 : 00000000 r2 : 0045acdc r1 : 00000000 r0 : 00000000
Flags: nZCv IRQs on FIQs on Mode USER_32 ISA ARM Segment user
Control: 0005317f Table: 25fa4000 DAC: 00000055
CPU: 0 PID: 28225 Comm: armfault Not tainted 4.19.61-yocto-standard #1
Hardware name: Atmel AT91SAM9
[<c000faf0>] (unwind_backtrace) from [<c000d248>] (show_stack+0x10/0x14)
[<c000d248>] (show_stack) from [<c000fe3c>] (__do_user_fault+0x94/0xf0)
[<c000fe3c>] (__do_user_fault) from [<c001015c>] (do_page_fault+0x250/0x284)
[<c001015c>] (do_page_fault) from [<c0010304>] (do_DataAbort+0x48/0xe8)
[<c0010304>] (do_DataAbort) from [<c0009d0c>] (__dabt_usr+0x4c/0x60)
Exception stack(0xc5c79fb0 to 0xc5c79ff8)
9fa0: 00000000 00000000 0045acdc 00000000
9fc0: 00000000 00000000 0045acdc ffff0fc0 00474100 004740c4 befffb20 00000000
9fe0: 00473ee4 befffae0 00457d68 ffff0fc0 60000010 ffffffff
Program received signal SIGSEGV, Segmentation fault.
instructions at pc, pc+4, pc+8:
(gdb) x/i $pc
=> 0xffff0fc0: ldr r3, [r2]
(gdb) x/i $pc + 4
0xffff0fc4: subs r3, r3, r0
(gdb) x/i $pc + 8
0xffff0fc8: streq r1, [r2]
At first glance this looks like a fault-on-read but due to how __kuser_cmpxchg is implemented it actually faults at the write(0xffff0fc8), then jumps back to 0xffff0fc0 and then informs gdb via ptrace.
The address it tries to write to is 0x45acdc which maps to 0x5acdc inside the elf binary.
This area is part of the rodata section:
[15] .rodata PROGBITS 0005ab80 05ab80 00616c 00 A 0 0 64
There's no symbol at that location though.
I hope that this helps you to track down the bug because this keeps me from using rust on this architecture.