LLVM & Clang
LLVM and Clang translate language pointers, calling conventions, bounds, permissions, and capability operations into code for multiple CHERI targets.
A processor can check capability bounds only if the software stack creates and preserves useful capabilities. The compiler is where source-language pointers, object layouts, calls, and optimisations meet the CHERI architecture.
LLVM and Clang provide the main compiler infrastructure used across CheriBSD, Morello, CHERI-RISC-V, and CHERIoT.
What Clang does
Clang parses C and C++ and applies the target’s language and application binary interface (ABI) rules. In a CHERI environment, it may:
- represent language-visible pointers as capabilities
- select hybrid or pure-capability calling conventions
- create bounds for stack objects and selected subobjects
- preserve capability metadata through casts and operations
- diagnose unsafe pointer-to-integer assumptions
- expose capability intrinsics and platform headers
- emit target-specific relocations and metadata
The exact behaviour depends on the target and compiler flags. There is no single -mcheri setting that describes every platform.
What LLVM does
LLVM’s intermediate representation and code generators must preserve distinctions that conventional compilers often collapse. A capability may have a larger in-memory representation than its address range, carry protected external tag state, and occupy a target-specific address space.
Optimisations must not replace a valid capability with a plain integer or extend its authority. The back end then selects CHERI instructions, capability registers, and ABI-specific code sequences for the target.
The linker and loader complete the path by creating valid capabilities for code and data that cannot be represented as ordinary static bytes alone.
Supported ecosystem routes
CheriBSD and CHERI-RISC-V
cheribuild builds a compatible CHERI LLVM/Clang, target system headers and libraries (sysroot), linker, QEMU, and CheriBSD stack. It supports current 64-bit CHERI-RISC-V pure-capability work and target variants documented by the project.
Morello
Morello uses an Arm-targeted CHERI compiler and ABI. cheribuild can build Morello LLVM and the matching CheriBSD software development kit (SDK). A generic AArch64 compiler does not preserve Morello capabilities unless it includes the required CHERI support.
CHERIoT
The CHERIoT development container supplies a Clang-based toolchain aligned with the CHERIoT instruction-set architecture (ISA), real-time operating system (RTOS), linker, and build system. Use the container or an explicitly supported release to avoid mixing incompatible revisions.
Mainline LLVM
Some CHERI-related infrastructure is present in the main LLVM project, and work to integrate broader target support continues through its community. Platform SDKs may still rely on CHERI-specific branches or release processes. Check the selected platform rather than assuming that a stock host Clang supports the required target completely.
Useful diagnostics during a port
CHERI-aware Clang can reveal code that:
- narrows a pointer into an integer
- assumes pointer size equals address size
- mixes incompatible pointer address spaces
- uses questionable casts between data and function pointers
- loses qualifiers or capability types across an interface
- relies on object access that conflicts with selected bounds policy
Treat warnings as evidence about the source model. Suppressing them without understanding the authority change can produce a binary that runs with weaker protection.
Bounds policy and compatibility
The compiler may be able to bound pointers at allocation, complete-object, array, or subobject granularity. Tighter bounds catch more invalid accesses. They can also expose C patterns that recover an enclosing structure from a member pointer or temporarily operate outside formal object bounds.
Record the selected policy with test results. “Compiled with CHERI Clang” does not tell a reviewer how precise the object bounds are.
Verify the toolchain
Capture:
clang --version
clang --print-target-triple
Then inspect a compiled object using the SDK’s llvm-readelf, llvm-objdump, or equivalent tools. Confirm:
- target architecture
- hybrid or pure-capability ABI
- linked sysroot and C library
- expected capability relocations and sections
- compatibility with the target loader
The final check is runtime behaviour in the matching environment, including a platform conformance test and a controlled capability fault.
Important limits
- Compiler support varies by architecture and branch.
- Successful compilation does not prove that all dependencies use the intended ABI.
- Undefined C and C++ behaviour remains undefined even when hardware catches a resulting access.
- Optimisation level can change whether a small invalid test reaches hardware.
- Compiler correctness is part of the trusted computing base and needs testing and, where required, assurance.
Use cheribuild for CheriBSD and Morello toolchains, and the CHERIoT getting-started guide for the embedded toolchain.
