embive 0.0.0

A low-level sandboxing library for RISC-V bytecode
Documentation
# Embive (Embedded RISC-V)

Embive is a low-level sandboxing library focused on the embedding of untrusted code for constrained environments.  
As it interprets RISC-V bytecode, multiple languages are supported out of the box by Embive (Rust, C, C++, Zig, TinyGo, etc.).  
By default, Embive doesn’t require any external crate, dynamic memory allocation or the standard library (`no_std` and `no_alloc`).

Currently, it supports the `RV32I[M]` unprivileged instruction set (M extension enabled by default).

## Example

```rust,ignore
use embive::engine::{memory::Memory, register::Register, Engine, SYSCALL_ARGS};

// A simple syscall example. Check [`engine::SyscallFn`] for more information.
fn syscall(nr: i32, args: [i32; SYSCALL_ARGS], memory: &mut Memory) -> (i32, i32) {
    println!("{}: {:?}", nr, args);
    match nr {
        1 => (args[0] + args[1], 0), // Add two numbers (arg[0] + arg[1])
        2 => match memory.load(args[0] as u32) { // Load from RAM (arg[0])
            Ok(val) => (i32::from_le_bytes(val), 0),
            Err(_) => (0, 1),
        },
        _ => (0, 2),
    }
}

fn main() {
    // "10 + 20" using syscalls (load from ram and add two numbers)
    let code = &[
        0x93, 0x08, 0x20, 0x00, // li   a7, 2      (Syscall nr)
        0x13, 0x05, 0x10, 0x00, // li   a0, 1      (arg0, set first bit)
        0x13, 0x15, 0xf5, 0x01, // slli a0, a0, 31 (arg0, shift-left 31 bits)
        0x73, 0x00, 0x00, 0x00, // ecall           (Syscall, load from arg0)
        0x93, 0x08, 0x10, 0x00, // li   a7, 1      (Syscall nr)
        0x93, 0x05, 0x40, 0x01, // li   a1,20      (arg1, 20)
        0x73, 0x00, 0x00, 0x00, // ecall           (Syscall, add two args)
        0x73, 0x00, 0x10, 0x00  // ebreak          (Halt, exit VM)
    ];
    let mut ram = [0; 1024];
    ram[..4].copy_from_slice(&u32::to_le_bytes(10));

    // Create engine
    let mut engine = Engine::new(code, &mut ram, Some(syscall)).unwrap();

    // Run it
    engine.run().unwrap();

    // Check the result
   assert_eq!(engine.registers().get(Register::A0 as usize).unwrap(), 30);
   assert_eq!(engine.registers().get(Register::A1 as usize).unwrap(), 0);
}
```

## Roadmap

- [ ] Fully support `RV32G` (RV32IMAFDZicsr_Zifencei)
    - [x] RV32I Base Integer Instruction Set
    - [x] M Extension (Multiplication and Division Instructions)
    - [x] Zifencei
        - Implemented as a no-operation as it isn't applicable (Single HART, no cache, no memory-mapped devices, etc.).
    - [ ] Zicsr
        - At least the unprivileged CSRs
    - [ ] F Extension (Single-Precision Floating-Point Instructions)
    - [ ] D Extension (Double-Precision Floating-Point Instructions)
    - [ ] A Extension (Atomic Instructions)
- [x] System Calls
    - Function calls from interpreted to native code
- [ ] Resource limiter
    - Yield the engine after a configurable amount of instructions are executed.
- [ ] CI/CD
    - Incorporate more tests into the repository and create test automations for PRs
- [ ] Bytecode optimization (AOT and JIT)
    - Allow in-place JIT and AOT compilation to a format easier to parse.
        - Less bit-shifting, faster instruction matching, etc.
    - Should be kept as close as possible to native RISC-V bytecode.
- [ ] Callbacks
    - Function calls from native to interpreted code.
- [ ] Macros for converting native functions to system calls / callbacks
    - Use Rust type-system instead of only allowing `i32` arguments / results
- [ ] Support C Extension (Compressed Instructions)
    - This is a maybe, but good to keep in mind while developing other features (especially AOT/JIT).


## Minimum supported Rust version (MSRV)

Embive is guaranteed to compile on stable Rust 1.81 and up.

## License


Embive is licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or
  <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT]LICENSE-MIT or <http://opensource.org/licenses/MIT>)

at your option.

## Contribution


Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.