Can buffers passed between user apps and capsules be complex data types? #445
-
Can buffers passed between user apps and capsules be data types more complex than byte arrays, such as structs? The examples I have seen so far such as console or in the libtock-c repo always end up being byte arrays. I've checked the syscall documentation but it is unclear to me if it is possible. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Generally, Tock's system calls are not aware of the structure or semantics of allow-data passed in. Fundamentally, this layer is limited to passing byte arrays to capsules (and, in the case of IPC, also other applications, though that may be unsupported in While in C it is possible to overlay a given region of memory with a structure simply through pointer casts, in Rust this is inherently unsafe, as writes to the underlying in-memory representation could violate arbitrary invariants. For example, if this were a safe operation, one could dereference arbitrary pointers and thus invoke unsoundness simply by writing to the memory location shadowing a Rust reference. See Presumably, a tightly-packed Rust struct containing a safe subset of types could technically be converted back-and-forth from a byte array without violating any Rust invariants in on itself, but as far as I know Rust does not have any special, safe mechanism to represent these transformations. This means that you will likely have to write your own marshalling and unmarshalling operations for the structs you want to pass through system calls, which further include required sanity checks. A good API for this could be something like the following: struct MyStruct;
impl MyStruct {
pub fn from_bytes(b: &[u8]) -> Option<MyStruct> {
// Check the minimum required slice length once at the beginning, to help Rust/LLVM elide these checks below.
if b.len() < N {
return None;
}
unimplemented!()
}
pub fn to_bytes(self, &mut [u8]) -> bool {
// Same length check here
unimplemented!()
}
} For certain data representations with simple marshalling/unmarshalling mechanisms, the Tock kernel's |
Beta Was this translation helpful? Give feedback.
Generally, Tock's system calls are not aware of the structure or semantics of allow-data passed in. Fundamentally, this layer is limited to passing byte arrays to capsules (and, in the case of IPC, also other applications, though that may be unsupported in
libtock-rs
right now).While in C it is possible to overlay a given region of memory with a structure simply through pointer casts, in Rust this is inherently unsafe, as writes to the underlying in-memory representation could violate arbitrary invariants. For example, if this were a safe operation, one could dereference arbitrary pointers and thus invoke unsoundness simply by writing to the memory location shadowing a Rust reference. See
…