|  | Examples | 
|  | ======== | 
|  |  | 
|  | This directory contains a number of examples to understand the system: | 
|  |  | 
|  | 1. [Hello world](01.hello_world) is a simple example with a single compartment. | 
|  | 2. [Compartmentalised hello world](02.hello_compartment) splits the first example into two compartments. | 
|  | 3. [A more secure compartmentalised hello world](03.hello_safe_compartment) protects the UART compartment from the previous example against malicious callers. | 
|  | 4. [A demonstration of heap temporal safety](04.temporal_safety) shows that use-after-free bugs will deterministically trap. | 
|  | 5. [A sealing demonstration](05.sealing) shows how the CHERI sealing mechanism can protect opaque types across compartment boundaries. | 
|  | 6. [A trivial producer-consumer system](06.producer-consumer) shows the basics of inter-thread communication. | 
|  | 7. [Handling errors in compartments](07.error_handling) shows how to recover from crashes in compartments. | 
|  | 8. [Memory safety examples](08.memory_safety) demonstrates how the CHERIoT platform enforces memory safety. | 
|  | 9. [JavaScript](09.javascript) is a simple example embedding a JavaScript VM in a compartment. | 
|  |  | 
|  | Each example contains a readme file explaining what it is showing. | 
|  |  | 
|  | Building an example | 
|  | ------------------- | 
|  |  | 
|  | Each example is built with xmake, which first requires a configure step in the terminal: | 
|  |  | 
|  | ```sh | 
|  | $ cd {example_dir} | 
|  | $ xmake config --sdk={path-to-cheriot-llvm-tools} -P . | 
|  | ``` | 
|  |  | 
|  | If you are using the dev container then the `--sdk` flag will be `--sdk=/cheriot-tools/`. | 
|  |  | 
|  | You can pass some additional flags to this step. | 
|  |  | 
|  | - `-m {debug,release}` will switch between debug and release builds. | 
|  | - `--debug-{allocator,scheduler,loader}={y,n}` will enable verbose output for the specified core RTOS component. | 
|  | - `--board={board name}` to compile for a target other than the default (the interpreter generated from the formal model). | 
|  |  | 
|  | Next, build the firmware image with: | 
|  |  | 
|  | ```sh | 
|  | $ xmake -P . -v | 
|  | ``` | 
|  |  | 
|  | The `-v` (verbose) flag is optional but an xmake bug prevents the objdump output from being generated if it is not specified. | 
|  | You will then end up with a firmware image and a `.dump` file containing the objdump output in `build/cheriot/cheriot/{debug,release}`. | 
|  | The penultimate two status lines of the output will be something like: | 
|  |  | 
|  | ``` | 
|  | [ 95%]: linking firmware build/cheriot/cheriot/debug/producer-consumer | 
|  | [ 95%]: Creating firmware dump build/cheriot/cheriot/debug/producer-consumer.dump | 
|  | ``` | 
|  |  | 
|  | The first of these tells you the path to the firmware image, the second the location of the dump file that is a (somewhat) human-readable version of the same file. | 
|  |  | 
|  | By default, the examples are built targeting the interpreter that is generated from the Sail formal model of the ISA. | 
|  | This is the gold model, so anything that runs there should run on any compliant implementation. | 
|  | This interpreter includes an ELF loader and so can run the examples directly, for example: | 
|  |  | 
|  | ```sh | 
|  | $ cheriot_sim -V ./build/cheriot/cheriot/debug/producer-consumer | 
|  | ``` | 
|  |  | 
|  | Where `debug` is the value that you passed to the `-m` flag (`debug` is the default and the path that ends in `producer-consumer` is the path from the build output. |