This is a fork of Rust which adds experimental support for Morello. Morello is an experimental processor architecture that adds CHERI protections to ARM (AArch64). This repository contains the compiler, standard library, and documentation.
As of 2025-09-15 the compiler has been tested and should be fully functional, but it's still somewhat experimental and may well still have bugs and design flaws.
This fork is not built or maintained by the Rust project proper, please don't complain to them if you have issues with it, they will not be able to help. We can be contacted via email or GitHub issues but don't really have the capacity to offer much support.
- compiler prints a lot of LLVM warnings (
cheri-bound-allocas: Don't know how to handle intrinsic.), this is normal - the compiler must be built with a specific, moderately old version of Morello LLVM, and CHERI BSD must be built with the same version to avoid ABI issues
- backtraces cause an error message to be printed by libunwind (
libunwind: evaluated out-of-bounds/invalid CFA expression for pc <address>: 0xc0), but otherwise work correctly - allocating large zeroed values can overflow the stack if the stack size is small,
Box::new(std::mem::zeroed::<[u8; STACK_SIZE*2]>()will fail,Box::new([0 as u8; STACK_SIZE*2])andvec![0 as u8; STACK_SIZE*2]should work (seetests/ui/codegen/issue-28950.rs) - unaligned references and pointers cannot be used to access data due to the limitations of capabilities, but trying to do so does not cause an error at compile time
- stack overflow detection can fail to detect overflows when stack size is limited to a small value using
limits - the compatible version of Morello LLVM does not support the
Cregister class specifier, but Rust's assembly semantics require specifiers on Morello, as a workaround it seemsxcan be used instead (asm!("gctag {:x} {:x}", out(reg) valid, in(reg) pointer))
This fork is intended to be used as a cross compiler. We have not yet tried running the compiler itself on Morello.
The fork has been used and tested compiling from x86-64 Linux and M1 Mac OS Ventura. Mac OS requires some additional setup. Other platforms may or may not work.
Programs can be compiled for CheriBSD running on Morello, and other targets already supported by Rust.
There are two ways to install the compiler:
- download a pre-built binary (if one is available for your platform)
- build the compiler from source
See https://github.com/kent-weak-memory/rust/releases for available builds. Releases as of January 2024 should work straight from the directory they are extracted into, and include:
- the Rust compiler,
rustc - the Rust package manager,
cargo - the Rust standard library for Morello FreeBSD, AArch64 FreeBSD, and the platform the release is for
- supporting system libraries for Morello and AArch64
- extra tools for Morello and AArch64
- a simple example program
Note that releases from before January 2024 had a different structure and content, and will be more awkward to use.
Programs can be built either with the Rust package manager, Cargo, or manually with just the compiler.
Cargo
Cargo must be told to use the correct compiler and linker for Morello via a .cargo/config configuration file in either your home directory or the top level directory of the project you are trying to build.
See the example in example_project.
The following sets the Rust compiler for all platforms, and the linker for Morello and AArch64, you will need to modify the paths for your installation:
[build]
rustc = "/path/to/release/bin/rustc"
[target.aarch64-unknown-freebsd]
linker = "/path/to/release/bin/clang-freebsd.sh"
[target.aarch64-unknown-freebsd-purecap]
linker = "/path/to/release/bin/clang-morello.sh"
The following commands, run from the root directory of your project, will build it for Morello, AArch64, and the local machine's architecture respectively:
/path/to/release/bin/cargo build --target aarch64-unknown-freebsd-purecap
/path/to/release/bin/cargo build --target aarch64-unknown-freebsd
/path/to/release/bin/cargo build
The resulting executable will appear at target/aarch64-unknown-freebsd-purecap/debug/program-name for Morello, and similarly named directories for other targets.
Manual
To build for Morello Purecap:
/path/to/release/bin/rustc --out-dir /tmp/build -g --target aarch64-unknown-freebsd-purecap -C linker=/path/to/release/bin/clang-morello.sh program.rs
The resulting binary will appear at /tmp/build/program
To build for AArch64:
/path/to/release/bin/rustc --out-dir /tmp/build -g --target aarch64-unknown-freebsd -C linker=/path/to/release/bin/clang-freebsd.sh program.rs
To build for the architecture of the local machine:
/path/to/release/bin/rustc --out-dir /tmp/build -g program.rs
At a high level the steps to build from source are:
- compile Morello LLVM
- compile CheriBSD
- apply patches to Morello LLVM
- compile Rust compiler and libraries
- compile additional Rust tools
Cheribuild is required to compile Morello LLVM and CHERI BSD.
Clone it from https://github.com/CTSRD-CHERI/cheribuild and follow their setup instructions for your platform.
The compiler uses Morello LLVM as a backend, and we need a specific version. Clone it manually to get the right version:
cd /path/to/cheribuild-working-directory
git clone --revision 671d6dbe2b74525702368edfa086e68f5afadc24 --depth 1 https://git.morello-project.org/morello/llvm-project.git morello-llvm-project
Then use Cheribuild to compile it:
cd /path/to/cheribuild
./cheribuild.py morello-llvm-native --skip-update
Building libraries and programs requires a build of CHERI BSD to compile against. Use Cheribuild to clone and compile CHERI BSD, this will use the version of Morello LLVM we just compiled:
cd /path/to/cheribuild
./cheribuild.py -d cheribsd-morello-purecap
If you have not done so already, clone this repository so it is available for later steps. Be aware that the complete repository is very large. Using a shallow clone can save time and storage if you don't need the entire commit history:
git clone --depth=1 https://github.com/kent-weak-memory/rust.git
Our compiler requires minor changes to Morello LLVM to function properly. Apply the included patches to Morello LLVM:
cd /path/to/cheribuild-working-directory/morello-llvm-project
git apply /path/to/rust-repository/llvm.patch
Rebuild Morello LLVM:
cd /path/to/cheribuild
./cheribuild.py --skip-update morello-llvm
Rust requires a config.toml which provides details of how to build the compiler.
In addition, our fork also requires paths to tools to be set in cheri-config.sh.
Modify cheri-config.sh to point at your Cheribuild output directory.
By default this will be ~/cheri/ on UNIX-like systems.
Create a config.toml, with contents along the lines of the example below.
Some values will need to be replaced with the correct ones for your environment:
/path/to/cheribuild-working-directoryreplace with the absolute path to your Cheribuild working directory/path/to/rust-repositoryreplace with the absolute path to your clone of this compiler repositoryaarch64-apple-darwinreplace with the architecture for the system you want to run the compiler on (aarch64-apple-darwinfor M1 Mac OS,x86_64-unknown-linux-gnufor x86-64 Linux)
profile = "codegen"
changelog-seen = 2
[build]
target = ["aarch64-apple-darwin", "aarch64-unknown-freebsd-purecap", "aarch64-unknown-freebsd"]
[target.aarch64-apple-darwin]
llvm-config = "/path/to/cheribuild-working-directory/output/morello-sdk/bin/llvm-config"
# This section tells the compiler to use custom scripts for linking AArch64 programs.
[target.aarch64-unknown-freebsd]
cc = "/path/to/rust-repository/clang-freebsd.sh"
cxx = "/path/to/rust-repository/clang++-freebsd.sh"
linker = "/path/to/rust-repository/clang-freebsd.sh"
ar = "/path/to/cheribuild-working-directory/output/morello-sdk/bin/ar"
ranlib = "/path/to/cheribuild-working-directory/output/morello-sdk/bin/ranlib"
# This section tells the compiler to use custom scripts for linking Purecap programs.
[target.aarch64-unknown-freebsd-purecap]
cc = "/path/to/rust-repository/clang-morello.sh"
cxx = "/path/to/rust-repository/clang++-morello.sh"
ar = "/path/to/cheribuild-working-directory/output/morello-sdk/bin/ar"
ranlib = "/path/to/cheribuild-working-directory/output/morello-sdk/bin/ranlib"
linker = "/path/to/rust-repository/clang-morello.sh"Building programs requires a build of the compiler, a build of the Rust standard libraries for the architecture of the machine that will run the compiler (for build scripts), and a build of the standard libraries for the target machine.
Build the compiler and standard libraries:
cd /path/to/rust-repository
python3 x.py build
Note that this process will download large amounts of source code from the internet.
You may also want to build the package manager Cargo:
python3 x.py build tools/cargo
Programs can be built either with the Rust package manager, Cargo, or manually with just the compiler.
Cargo
Assuming you have already built Cargo, it can be run from /path/to/rust-repository/build/aarch64-apple-darwin/stage1-tools-bin/cargo (replacing aarch64-apple-darwin if your machine has a different architecture).
Cargo must be told to use the correct compiler and linker for Morello via a .cargo/config configuration file in either your home directory or the top level directory of the project you are trying to build.
The following sets the Rust compiler for all platforms, and the linker for Morello and AArch64, you will need to modify the paths for your installation and architecture:
[build]
rustc = "/path/to/rust-repository/build/aarch64-apple-darwin/stage1/bin/rustc"
[target.aarch64-unknown-freebsd]
linker = "/path/to/rust-repository/clang-freebsd.sh"
[target.aarch64-unknown-freebsd-purecap]
linker = "/path/to/rust-repository/clang-morello.sh"
The following commands, run from the root directory of your project, will build it for Morello, AArch64, and the local machine's architecture respectively:
/path/to/rust-repository/build/aarch64-apple-darwin/stage1-tools-bin/cargo build --target aarch64-unknown-freebsd-purecap
/path/to/rust-repository/build/aarch64-apple-darwin/stage1-tools-bin/cargo build --target aarch64-unknown-freebsd
/path/to/rust-repository/build/aarch64-apple-darwin/stage1-tools-bin/cargo build
The resulting executable will appear at target/aarch64-unknown-freebsd-purecap/debug/program-name for Morello, and similarly named directories for other targets.
Manual
The compiler itself can be found in /path/to/rust-repository/build/aarch64-apple-darwin/stage1/bin/rustc
It will default to building for the machine it is running on, so building for the current machine looks like this:
/path/to/rust-repository/build/aarch64-apple-darwin/stage1/bin/rustc --out-dir /tmp/build -g program.rs
The resulting binary will appear at /tmp/build/program
To build for Morello Purecap, specify the architecture and linker:
/path/to/rust-repository/build/aarch64-apple-darwin/stage1/bin/rustc --out-dir /tmp/build -g --target aarch64-unknown-freebsd-purecap -C linker=/path/to/rust-repository/clang-morello.sh program.rs
To build for AArch64:
/path/to/rust-repository/build/aarch64-apple-darwin/stage1/bin/rustc --out-dir /tmp/build -g --target aarch64-unknown-freebsd -C linker=/path/to/rust-repository/clang-freebsd.sh program.rs
There are a couple of problems on Mac OS.
libarchive
Firstly, there's a packaging issue with upstream libarchive, and the brew install doesn't work perfectly.
To fix this remove Requires.private: iconv from /opt/homebrew/opt/libarchive/lib/pkgconfig/libarchive.pc.
You might need to do chmod +w first.
There are issues tracking this here, and here.
failed to installworld
There's some weird interaction between a new feature in Mac OS 13 (Ventura) and the Cheribuild script. You need to disable SIP by following the Apple instructions here. There is an issue tracking this here.
Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses.
See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.