Skip to content

Support older versions of the ARM architecture #25

Closed
@japaric

Description

@japaric

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 like AtomicUsize from libcore making it impossible to build libstd as std depends on those atomic types. The built-in target armv5te-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": ""
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions