1use libriscv::{Machine, Options, Registers, Result, SyscallRegistry};
2
3fn reserve_stack(regs: &mut Registers<'_>, size: usize) -> Result<u64> {
4 let sp = regs.x(2)?;
5 let new_sp = sp.wrapping_sub(size as u64) & !0xFu64;
6 regs.set_x(2, new_sp)?;
7 Ok(new_sp)
8}
9
10fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
11 let args: Vec<String> = std::env::args().collect();
12 if args.len() < 2 {
13 eprintln!("Usage: {} [program file] [arguments ...]", args[0]);
14 std::process::exit(1);
15 }
16
17 let elf = std::fs::read(&args[1])?;
18 let options = Options::builder()
19 .max_memory(64 * 1024 * 1024)
20 .args(args[1..].iter())
21 .build()?;
22
23 let registry = SyscallRegistry::empty();
24 let mut machine = Machine::new(elf, options, ®istry)?;
25 machine.run(32_000_000)?;
26
27 if let Some(addr) = machine.address_of("my_function")? {
28 machine.setup_vmcall(addr)?;
29 let msg = b"Hello Sandboxed World!\0";
30 let str_addr = {
31 let mut regs = machine.registers()?;
32 reserve_stack(&mut regs, msg.len())?
33 };
34 machine.copy_to_guest(str_addr, msg)?;
35 {
36 let mut regs = machine.registers()?;
37 regs.set_x(10, str_addr)?;
38 }
39 machine.run(u64::MAX)?;
40 } else {
41 eprintln!("Symbol my_function not found");
42 }
43
44 println!("Program exited with status: {}", machine.return_value());
45 Ok(())
46}