Description
As of 2017-05-23 Rust officially supports only the ARMv6 and ARMv7 architectures. For ARM Linux, binary releases of std are provided for these targets. For bare metal ARM, there are built-in targets for ARM Cortex-M microcontrollers.
These are two cases that I know of that are currently unsupported:
- ARMv5 processors that run Linux
- ARMv4 processors (microcontrollers?) that operate without an OS
ARMv5 Linux
std
These targets want to use std
but from the POV of LLVM these targets don't support atomics as there are no atomic load / store instructions in the instruction set. This leaves these targets with two options:
-
Declare
max-atomic-width
as being 0. This removes atomic types likeAtomicUsize
from libcore making it impossible to build libstd as std depends on those atomic types. The built-in targetarmv5te-unknown-linux-gnueabi
does this. -
Declare
max-atomic-width
as being 32. With this change libstd can be compiled but trying to link a std program will result in linker errors of the form: "undefined reference to__sync_fetch_and_foo
". As there are no atomic instructions LLVM lower atomic operations to these intrinsics. These intrinsics will have to be provide by the user as there's no implementation for then in the compiler-rt project. One possible implementation for these intrinsics is to use Linux's kernel user helpers as suggested here.
uclibc
Some of these targets want to use uclibc instead of glibc because that's what their systems' OS uses. The complication here is that the libc crate does not support uclibc. However the libc crate does compile when compiled for an uclibc target, but it will actually assume that the target is using glibc. This is rather bad because uclibc and glibc don't have the same ABI so using the libc crate for an uclibc target can result in a segfault / crash at runtime.
Important: All std programs make use of the libc crate so all std programs are affected by this issue.
Bare metal ARMv4
I don't have details for this target but since it's a bare metal target it will work in no_std
mode. A custom target will be required as there's no built-in target in rustc. The specification of that custom target can probably derived from the specification of an existing target. thumbv6m-none-eabi
seems like a good base target:
$ rustc -Z unstable-options --print target-spec-json --target thumbv6m-none-eabi
{
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"win64",
"sysv64"
],
"arch": "arm",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"env": "",
"executables": true,
"features": "+strict-align",
"is-builtin": true,
"linker": "arm-none-eabi-gcc",
"linker-flavor": "gcc",
"llvm-target": "thumbv6m-none-eabi",
"max-atomic-width": 0,
"os": "none",
"panic-strategy": "abort",
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32",
"vendor": ""
}