pub struct ImageCap {
pub code: Vec<u8>,
pub endpoints: Vec<(Key, EndpointDef)>,
pub mappings: Vec<MemoryMapping>,
pub pinned: Vec<ImageSlotEntry>,
pub initial: Vec<ImageSlotEntry>,
pub yield_receiver_slot: Option<Key>,
pub gas_slots: Vec<Key>,
pub quota_slots: Vec<Key>,
}Expand description
§Validation model: structure is eager, semantics are lazy
An ImageCap is admitted from untrusted input under a two-layer
discipline:
-
Structure — validated eagerly (here / in
image_cap, the “deblob”). The metadata that frames execution:codelength (≤ MAX_CODE_SIZE), memory-mapping bounds, slot indices, source-path depth, endpoint indices. A malformed structural field has no clean execution point to fault on — it would diverge between engines or panic the host — so it is rejected at construction. This is cheap (O(#endpoints + #mappings + #slots), it never scans the code) and therefore compatible with lazy compilation. -
Semantics — validated lazily (at execution, by both engines identically). The instruction stream itself: illegal/forbidden encodings, and
jal/branch/jalr/entry_pctargets. These are not rejected at admission — anycodebytes are accepted. A forbidden encoding decodes as illegal and an off-bb_starttarget is refused only when reached, asε = panic. Lazy (not eager deblob) because, without an instruction bitmask, a linear validator can’t tell code from data — eager rejection would reject legitimate code-as-data; lazy also keeps admission version-independent (a future ISA extension forks only at execution, never the cap set at admission) and preserves lazy compilation. The consensus requirement is that the two engines agree on what panics, not that the bytes are pre-screened. The producer toolchain still rejects forbidden encodings at build time as a diagnostic — that is UX, not a consensus rule.
Fields§
§code: Vec<u8>The (single) code region: raw RV+C+custom-0 bytes, page-aligned
so the kernel can direct-map it RO at the fixed protocol
constant crate::layout::CODE_BASE. Empty for codeless
images. See ImageCap::code_mapping.
endpoints: Vec<(Key, EndpointDef)>Endpoint definitions, keyed by a Key selector. A sparse, sorted
association list (Dict-style — kept sorted by key, no fixed capacity);
an absent key is an undefined endpoint. There is no dense array and no
entry_pc == 0 sentinel, so an endpoint may legitimately start at code
offset 0. (Vec<(Key, _)> rather than BTreeMap because the rkyv wire
form has no Ord on the archived key.)
mappings: Vec<MemoryMapping>Memory mappings.
pinned: Vec<ImageSlotEntry>Pinned read-only slots (Cap::Data / Cap::Image). Images only
ever reference content-addressed caps, so the target is a
plain CapHash.
initial: Vec<ImageSlotEntry>Initial mutable slot state for non-pinned slots.
yield_receiver_slot: Option<Key>Slot holding Cap::Instance[YieldReceiver] (the catch-set), if any.
gas_slots: Vec<Key>Cnode slots holding the Cap::Instance[Gas{meter_key}] unit handles,
consulted in order. See crate::image::Image::gas_slots.
quota_slots: Vec<Key>Cnode slots holding the Cap::Instance[Quota{quota_key}] unit handles.
Implementations§
Source§impl ImageCap
impl ImageCap
Sourcepub fn code_mapping(&self) -> Option<(u32, &[u8])>
pub fn code_mapping(&self) -> Option<(u32, &[u8])>
The executable code region as (code_base, bytes). code_base
is the fixed protocol constant crate::layout::CODE_BASE, so a
PVM PC is code_base + byte_offset. None if the image declares
no code (empty region) — such an image cannot execute.
Sourcepub fn mapping_is_pinned(&self, start: u32) -> bool
pub fn mapping_is_pinned(&self, start: u32) -> bool
True iff the memory mapping starting at guest VA start draws
from a pinned (read-only) slot, so it must be laid read-only — a
guest store to it faults. Mirrors the recompiler’s pinned-vs-
initial slot classification (nub-arch-x86 build_runtime).
Derived from Self::pinned at lay time, so a mapping carries no
per-mapping permission field; the interpreter drivers (javm
build_entry, nub-arch-local) call this so they classify
identically to the recompiler.
Trait Implementations§
Source§impl Archive for ImageCapwhere
Vec<u8>: Archive,
Vec<(Key, EndpointDef)>: Archive,
Vec<MemoryMapping>: Archive,
Vec<ImageSlotEntry>: Archive,
Option<Key>: Archive,
Vec<Key>: Archive,
impl Archive for ImageCapwhere
Vec<u8>: Archive,
Vec<(Key, EndpointDef)>: Archive,
Vec<MemoryMapping>: Archive,
Vec<ImageSlotEntry>: Archive,
Option<Key>: Archive,
Vec<Key>: Archive,
Source§const COPY_OPTIMIZATION: CopyOptimization<Self>
const COPY_OPTIMIZATION: CopyOptimization<Self>
serialize. Read moreSource§type Archived = ArchivedImageCap
type Archived = ArchivedImageCap
Source§type Resolver = ImageCapResolver
type Resolver = ImageCapResolver
Source§impl<__D: Fallible + ?Sized> Deserialize<ImageCap, __D> for Archived<ImageCap>where
Vec<u8>: Archive,
<Vec<u8> as Archive>::Archived: Deserialize<Vec<u8>, __D>,
Vec<(Key, EndpointDef)>: Archive,
<Vec<(Key, EndpointDef)> as Archive>::Archived: Deserialize<Vec<(Key, EndpointDef)>, __D>,
Vec<MemoryMapping>: Archive,
<Vec<MemoryMapping> as Archive>::Archived: Deserialize<Vec<MemoryMapping>, __D>,
Vec<ImageSlotEntry>: Archive,
<Vec<ImageSlotEntry> as Archive>::Archived: Deserialize<Vec<ImageSlotEntry>, __D>,
Option<Key>: Archive,
<Option<Key> as Archive>::Archived: Deserialize<Option<Key>, __D>,
Vec<Key>: Archive,
<Vec<Key> as Archive>::Archived: Deserialize<Vec<Key>, __D>,
impl<__D: Fallible + ?Sized> Deserialize<ImageCap, __D> for Archived<ImageCap>where
Vec<u8>: Archive,
<Vec<u8> as Archive>::Archived: Deserialize<Vec<u8>, __D>,
Vec<(Key, EndpointDef)>: Archive,
<Vec<(Key, EndpointDef)> as Archive>::Archived: Deserialize<Vec<(Key, EndpointDef)>, __D>,
Vec<MemoryMapping>: Archive,
<Vec<MemoryMapping> as Archive>::Archived: Deserialize<Vec<MemoryMapping>, __D>,
Vec<ImageSlotEntry>: Archive,
<Vec<ImageSlotEntry> as Archive>::Archived: Deserialize<Vec<ImageSlotEntry>, __D>,
Option<Key>: Archive,
<Option<Key> as Archive>::Archived: Deserialize<Option<Key>, __D>,
Vec<Key>: Archive,
<Vec<Key> as Archive>::Archived: Deserialize<Vec<Key>, __D>,
Auto Trait Implementations§
impl Freeze for ImageCap
impl RefUnwindSafe for ImageCap
impl Send for ImageCap
impl Sync for ImageCap
impl Unpin for ImageCap
impl UnsafeUnpin for ImageCap
impl UnwindSafe for ImageCap
Blanket Implementations§
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
§impl<T> ArchiveUnsized for Twhere
T: Archive,
impl<T> ArchiveUnsized for Twhere
T: Archive,
§type Archived = <T as Archive>::Archived
type Archived = <T as Archive>::Archived
Archive, it may be
unsized. Read more