1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//! `baryl`: whole-machine emulation you can write code inside of.
//!
//! A baryl run boots a real disk image under an emulator that has been opened
//! up: you can stop the guest at an address, read and write its memory, ask its
//! kernel what a process is, checkpoint the whole machine and rewind to that
//! point as often as you like. This crate is how you get at that, and there are
//! two ways in.
//!
//! Requires a licence, free, from <https://baryl.crystalpeaksecurity.com>.
//!
//! # Writing a component
//!
//! A component is a `cdylib` a run loads. It subscribes to events by writing an
//! attribute on a method, and each handler is passed a `Control` — every
//! subsystem the run has, in one value.
//!
//! ```ignore
//! use baryl::clap::{self, Parser};
//! use baryl::{Control, component};
//!
//! #[derive(Parser)]
//! #[command(no_binary_name = true)]
//! pub struct Hello {
//! #[arg(long, default_value = "world")]
//! who: String,
//! }
//!
//! #[component("hello")]
//! impl Hello {
//! #[core(first_ring_three)]
//! fn greet(&mut self, t: &mut Control) {
//! baryl::logging::info!("hello, {}", self.who);
//! baryl::logging::info!("{} processes", t.subs.enlighten.processes().len());
//! }
//! }
//! ```
//!
//! With `crate-type = ["cdylib"]` in `Cargo.toml`, that builds a `libhello.so`
//! a run loads with `--component ./libhello.so --arg hello:who=there`.
//!
//! Events come from `#[core(...)]` for the run's own lifecycle, and from
//! `#[cov]`, `#[arch]`, `#[net]` and `#[fuzz]` for the subsystem that owns
//! them. Subscribing to a subsystem's event is also what asks for that
//! subsystem to be loaded; anything else you cannot run without goes in
//! `#[component("name", requires(engine, breakpoints))]`, and the run refuses
//! to start rather than handing you a handle that is not there.
//!
//! State that must survive a checkpoint goes in the pool — see the `alloc`
//! module, and [`abi::SandboxSafe`] for what may go there. Ordinary Rust state
//! is fine for anything a rewind should forget.
//!
//! # Driving a run from your own program
//!
//! `Baryl` opens an image — a disk to boot or a checkpoint to restore, read
//! from the file rather than named by you — and `Options` carries everything
//! else. Reading through `Baryl::control` runs no guest instructions, so a
//! program can open a checkpoint, inspect it, and close it again.
//!
//! ```ignore
//! use baryl::{Baryl, Options};
//!
//! let baryl = Baryl::open(Path::new("boot.ck"), &Options::default())?;
//! for p in baryl.control().subs.enlighten.processes() {
//! println!("{} {:?}", p.pid, p.name());
//! }
//! ```
//!
//! # Features
//!
//! `component` and `x86_64` are on by default.
//!
//! - `component` — everything a component needs. Requires nightly.
//! - `cli` — `Baryl`, `Options` and the argument types in the `cli` module, for
//! a runner of your own. Not on by default: `baryl = { version = "…",
//! features = ["cli"] }`.
//! - `x86_64` — the x86-64 register file, page-table attributes and fault
//! decoding. Without it `arch` is the handle and nothing ISA-specific.
//! - `control`, `config`, `logging` — the pieces the two above are built from,
//! for a build that wants one without the rest.
/// The vocabulary a component writes in, so `use baryl::VirtAddr` works without
/// naming [`abi`]. The exported macros land here too.
pub use crate;
/// The two pool-backed collections.
pub use crate;
/// The descriptor a component exports and the callback shapes its slots hold.
/// `#[component]` builds one; these are what a hand-written descriptor needs.
pub use crate;
/// `Control`, and the `BARYL_SUB_*` id of every subsystem a `requires(...)`
/// word or a subscribed event can name.
pub use crate;
/// Opening and running a machine from your own program.
pub use crate;
/// The window of runtime ABI revisions this build can load. A runtime outside
/// it is refused when the library is opened, rather than misread.
pub use crate;
/// `#[component]`, and one attribute per subsystem whose events a method can
/// subscribe to. The coverage one is spelled `#[cov]`.
pub use ;
/// The clap `#[component]` expands into and a runner derives its verbs on.
/// Reach it through here — `use baryl::clap::{self, Parser}` — and your crate
/// needs no clap dependency of its own.
pub use clap;
/// What `#[component]` implements on your type. Never write one by hand.