CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Toggle main menu visibility
Loading...
Searching...
No Matches
sdk
include
fail-simulator-on-error.h
1
#include "compartment.h"
2
#include <
cheri.hh
>
3
#include <
debug.hh
>
4
#include <priv/riscv.h>
5
#include <simulator.h>
6
7
using
DebugErrorHandler = ConditionalDebug<
8
#ifdef NDEBUG
9
false
10
#else
11
true
12
#endif
13
,
14
"Error handler"
>;
15
16
/**
17
* A error handler that reports unexpected traps and calls the scheduler to
18
* request that the simulator exit with exit code 1 (FAILURE).
19
*
20
* This is useful because the default behaviour in the absence of an error
21
* handler is to unwind the trusted stack and exit the thread when the top of
22
* the stack is reached. If all threads exit then the scheduler will exit the
23
* simulation with SUCCESS, which might mask errors.
24
*
25
* We attempt to detect the trap that occurs when a thread returns from its
26
* entry point function and do not halt the simulation as this is considered
27
* normal.
28
*
29
* Unwinds caused by errors in called compartments are also detected and are not
30
* treated as errors -- instead we resume execution at the call point with a
31
* return value of -1 as though this handler is not present.
32
*
33
* On non-simulation platforms this error handler reverts to the default force
34
* unwind behaviour.
35
*
36
* If NDEBUG is not defined then errors and thread exits will be logged.
37
*
38
* To use this simply include this file in your compartment's c / cc file.
39
*/
40
extern
"C"
ErrorRecoveryBehaviour
41
compartment_error_handler(
ErrorState
*frame,
size_t
mcause,
size_t
mtval)
42
{
43
if
(mcause == priv::MCAUSE_CHERI)
44
{
45
// An unexpected error -- log it and end the simulation with error.
46
// Note: handle CZR differently as `get_register_value` will return a
47
// nullptr which we cannot dereference.
48
49
auto
[exceptionCode, registerNumber] =
50
CHERI::extract_cheri_mtval
(mtval);
51
52
DebugErrorHandler::log(
53
"{} error at {} (return address: {}), with capability register "
54
"{}: {}"
,
55
exceptionCode,
56
frame->
pcc
,
57
frame->
get_register_value
<
CHERI::RegisterNumber::CRA
>(),
58
registerNumber,
59
registerNumber ==
CHERI::RegisterNumber::CZR
60
?
nullptr
61
: *frame->
get_register_value
(registerNumber));
62
}
63
else
64
{
65
// other error (e.g. __builtin_trap causes ReservedInstruciton)
66
// log and end simulation with error.
67
DebugErrorHandler::log(
"Unhandled error {} at {}"
, mcause, frame->
pcc
);
68
}
69
70
#ifdef SIMULATION
71
/*
72
* simulation exit may fail (say, we're not on a simulator or there isn't
73
* enough stack space to invoke the function. In that case, just fall back
74
* to forcibly unwinding.
75
*/
76
(void)scheduler_simulation_exit(1);
77
#endif
78
79
return
ErrorRecoveryBehaviour::ForceUnwind;
80
}
cheri.hh
C++ helpers for operating on capabilities.
CHERI::RegisterNumber::CZR
@ CZR
The zero register, which always contains the NULL capability.
Definition
cheri.hh:1445
CHERI::RegisterNumber::CRA
@ CRA
$c1 / $cra used by the ABI as the return address.
Definition
cheri.hh:1450
CHERI::extract_cheri_mtval
std::pair< CauseCode, RegisterNumber > extract_cheri_mtval(uint32_t mtval)
Decompose the value reported in the mtval CSR on CHERI exception into a pair of CauseCode and Registe...
Definition
cheri.hh:1579
debug.hh
C++ APIs for assertions, invariants, and writing formatted debug messages to a UART.
ErrorState
State for error handlers to use.
Definition
compartment.h:21
ErrorState::get_register_value
void *& get_register_value()
Templated method to get a reference to value of given CHERI::RegisterNumber.
Definition
compartment.h:49
ErrorState::pcc
void * pcc
The faulting program counter.
Definition
compartment.h:32
Generated by
1.18.0