Machine

Struct Machine 

Source
pub struct Machine { /* private fields */ }
Expand description

A running instance of the libriscv machine.

Implementations§

Source§

impl Machine

Source

pub fn new( elf: impl AsRef<[u8]>, options: Options, _registry: &SyscallRegistry, ) -> Result<Self>

Examples found in repository?
examples/basic.rs (line 17)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let args: Vec<String> = std::env::args().collect();
5    if args.len() < 2 {
6        eprintln!("Usage: {} [program file] [arguments ...]", args[0]);
7        std::process::exit(1);
8    }
9
10    let elf = std::fs::read(&args[1])?;
11    let options = Options::builder()
12        .max_memory(256 * 1024 * 1024)
13        .args(args[1..].iter())
14        .build()?;
15
16    let registry = SyscallRegistry::empty();
17    let mut machine = Machine::new(elf, options, &registry)?;
18    machine.run(u64::MAX)?;
19    println!("Program exited with status: {}", machine.return_value());
20    Ok(())
21}
More examples
Hide additional examples
examples/vmcall.rs (line 24)
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, &registry)?;
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}
examples/advanced_syscalls.rs (line 166)
149fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
150    let args: Vec<String> = std::env::args().collect();
151    if args.len() < 2 {
152        eprintln!("Usage: {} [program file]", args[0]);
153        std::process::exit(1);
154    }
155
156    let elf = std::fs::read(&args[1])?;
157
158    let registry = host_syscalls::registry()?;
159
160    let options = Options::builder()
161        .stdout_handler(stdout_callback_handler())
162        .error_handler(error_callback_handler())
163        .args(["program"])
164        .build()?;
165
166    let mut machine = Machine::new(elf, options, &registry)?;
167    machine.run(u64::MAX)?;
168
169    let addr = HOST_FN_ADDR.load(Ordering::Relaxed);
170    if addr != 0 {
171        machine.setup_vmcall(addr)?;
172        let msg = b"Hello from a callback function!\0";
173        let str_addr = {
174            let mut regs = machine.registers()?;
175            reserve_stack(&mut regs, msg.len())?
176        };
177        machine.copy_to_guest(str_addr, msg)?;
178        {
179            let mut regs = machine.registers()?;
180            regs.set_x(10, str_addr)?;
181        }
182        machine.run(u64::MAX)?;
183    } else {
184        eprintln!("Host function 502 was not called");
185    }
186
187    println!("Done");
188    Ok(())
189}
Source

pub fn with_defaults( elf: impl AsRef<[u8]>, registry: &SyscallRegistry, ) -> Result<Self>

Source

pub fn as_raw(&self) -> *mut RISCVMachine

Source

pub fn run(&mut self, instruction_limit: u64) -> Result<()>

Examples found in repository?
examples/basic.rs (line 18)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let args: Vec<String> = std::env::args().collect();
5    if args.len() < 2 {
6        eprintln!("Usage: {} [program file] [arguments ...]", args[0]);
7        std::process::exit(1);
8    }
9
10    let elf = std::fs::read(&args[1])?;
11    let options = Options::builder()
12        .max_memory(256 * 1024 * 1024)
13        .args(args[1..].iter())
14        .build()?;
15
16    let registry = SyscallRegistry::empty();
17    let mut machine = Machine::new(elf, options, &registry)?;
18    machine.run(u64::MAX)?;
19    println!("Program exited with status: {}", machine.return_value());
20    Ok(())
21}
More examples
Hide additional examples
examples/vmcall.rs (line 25)
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, &registry)?;
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}
examples/advanced_syscalls.rs (line 167)
149fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
150    let args: Vec<String> = std::env::args().collect();
151    if args.len() < 2 {
152        eprintln!("Usage: {} [program file]", args[0]);
153        std::process::exit(1);
154    }
155
156    let elf = std::fs::read(&args[1])?;
157
158    let registry = host_syscalls::registry()?;
159
160    let options = Options::builder()
161        .stdout_handler(stdout_callback_handler())
162        .error_handler(error_callback_handler())
163        .args(["program"])
164        .build()?;
165
166    let mut machine = Machine::new(elf, options, &registry)?;
167    machine.run(u64::MAX)?;
168
169    let addr = HOST_FN_ADDR.load(Ordering::Relaxed);
170    if addr != 0 {
171        machine.setup_vmcall(addr)?;
172        let msg = b"Hello from a callback function!\0";
173        let str_addr = {
174            let mut regs = machine.registers()?;
175            reserve_stack(&mut regs, msg.len())?
176        };
177        machine.copy_to_guest(str_addr, msg)?;
178        {
179            let mut regs = machine.registers()?;
180            regs.set_x(10, str_addr)?;
181        }
182        machine.run(u64::MAX)?;
183    } else {
184        eprintln!("Host function 502 was not called");
185    }
186
187    println!("Done");
188    Ok(())
189}
Source

pub fn stop(&mut self)

Source

pub fn allow_file<P: AsRef<Path>>(&mut self, path: P) -> Result<()>

Source

pub fn return_value(&self) -> i64

Examples found in repository?
examples/basic.rs (line 19)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let args: Vec<String> = std::env::args().collect();
5    if args.len() < 2 {
6        eprintln!("Usage: {} [program file] [arguments ...]", args[0]);
7        std::process::exit(1);
8    }
9
10    let elf = std::fs::read(&args[1])?;
11    let options = Options::builder()
12        .max_memory(256 * 1024 * 1024)
13        .args(args[1..].iter())
14        .build()?;
15
16    let registry = SyscallRegistry::empty();
17    let mut machine = Machine::new(elf, options, &registry)?;
18    machine.run(u64::MAX)?;
19    println!("Program exited with status: {}", machine.return_value());
20    Ok(())
21}
More examples
Hide additional examples
examples/vmcall.rs (line 44)
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, &registry)?;
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}
Source

pub fn address_of(&self, name: &str) -> Result<Option<u64>>

Examples found in repository?
examples/vmcall.rs (line 27)
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, &registry)?;
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}
Source

pub fn opaque(&self) -> *mut c_void

Source

pub fn instruction_counter(&self) -> u64

Source

pub fn max_instruction_counter(&mut self) -> Option<&mut u64>

Source

pub fn jump(&mut self, address: u64) -> Result<()>

Source

pub fn setup_vmcall(&mut self, address: u64) -> Result<()>

Examples found in repository?
examples/vmcall.rs (line 28)
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, &registry)?;
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}
More examples
Hide additional examples
examples/advanced_syscalls.rs (line 171)
149fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
150    let args: Vec<String> = std::env::args().collect();
151    if args.len() < 2 {
152        eprintln!("Usage: {} [program file]", args[0]);
153        std::process::exit(1);
154    }
155
156    let elf = std::fs::read(&args[1])?;
157
158    let registry = host_syscalls::registry()?;
159
160    let options = Options::builder()
161        .stdout_handler(stdout_callback_handler())
162        .error_handler(error_callback_handler())
163        .args(["program"])
164        .build()?;
165
166    let mut machine = Machine::new(elf, options, &registry)?;
167    machine.run(u64::MAX)?;
168
169    let addr = HOST_FN_ADDR.load(Ordering::Relaxed);
170    if addr != 0 {
171        machine.setup_vmcall(addr)?;
172        let msg = b"Hello from a callback function!\0";
173        let str_addr = {
174            let mut regs = machine.registers()?;
175            reserve_stack(&mut regs, msg.len())?
176        };
177        machine.copy_to_guest(str_addr, msg)?;
178        {
179            let mut regs = machine.registers()?;
180            regs.set_x(10, str_addr)?;
181        }
182        machine.run(u64::MAX)?;
183    } else {
184        eprintln!("Host function 502 was not called");
185    }
186
187    println!("Done");
188    Ok(())
189}
Source

pub fn copy_to_guest(&mut self, dst: u64, src: &[u8]) -> Result<()>

Examples found in repository?
examples/vmcall.rs (line 34)
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, &registry)?;
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}
More examples
Hide additional examples
examples/advanced_syscalls.rs (line 177)
149fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
150    let args: Vec<String> = std::env::args().collect();
151    if args.len() < 2 {
152        eprintln!("Usage: {} [program file]", args[0]);
153        std::process::exit(1);
154    }
155
156    let elf = std::fs::read(&args[1])?;
157
158    let registry = host_syscalls::registry()?;
159
160    let options = Options::builder()
161        .stdout_handler(stdout_callback_handler())
162        .error_handler(error_callback_handler())
163        .args(["program"])
164        .build()?;
165
166    let mut machine = Machine::new(elf, options, &registry)?;
167    machine.run(u64::MAX)?;
168
169    let addr = HOST_FN_ADDR.load(Ordering::Relaxed);
170    if addr != 0 {
171        machine.setup_vmcall(addr)?;
172        let msg = b"Hello from a callback function!\0";
173        let str_addr = {
174            let mut regs = machine.registers()?;
175            reserve_stack(&mut regs, msg.len())?
176        };
177        machine.copy_to_guest(str_addr, msg)?;
178        {
179            let mut regs = machine.registers()?;
180            regs.set_x(10, str_addr)?;
181        }
182        machine.run(u64::MAX)?;
183    } else {
184        eprintln!("Host function 502 was not called");
185    }
186
187    println!("Done");
188    Ok(())
189}
Source

pub fn copy_from_guest(&mut self, src: u64, dst: &mut [u8]) -> Result<()>

Source

pub fn read_memory(&mut self, src: u64, len: usize) -> Result<Vec<u8>>

Source

pub fn write_memory(&mut self, dst: u64, data: &[u8]) -> Result<()>

Source

pub fn memstring(&mut self, src: u64, maxlen: u32) -> Result<Vec<u8>>

Source

pub fn registers(&mut self) -> Result<Registers<'_>>

Examples found in repository?
examples/vmcall.rs (line 31)
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, &registry)?;
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}
More examples
Hide additional examples
examples/advanced_syscalls.rs (line 174)
149fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
150    let args: Vec<String> = std::env::args().collect();
151    if args.len() < 2 {
152        eprintln!("Usage: {} [program file]", args[0]);
153        std::process::exit(1);
154    }
155
156    let elf = std::fs::read(&args[1])?;
157
158    let registry = host_syscalls::registry()?;
159
160    let options = Options::builder()
161        .stdout_handler(stdout_callback_handler())
162        .error_handler(error_callback_handler())
163        .args(["program"])
164        .build()?;
165
166    let mut machine = Machine::new(elf, options, &registry)?;
167    machine.run(u64::MAX)?;
168
169    let addr = HOST_FN_ADDR.load(Ordering::Relaxed);
170    if addr != 0 {
171        machine.setup_vmcall(addr)?;
172        let msg = b"Hello from a callback function!\0";
173        let str_addr = {
174            let mut regs = machine.registers()?;
175            reserve_stack(&mut regs, msg.len())?
176        };
177        machine.copy_to_guest(str_addr, msg)?;
178        {
179            let mut regs = machine.registers()?;
180            regs.set_x(10, str_addr)?;
181        }
182        machine.run(u64::MAX)?;
183    } else {
184        eprintln!("Host function 502 was not called");
185    }
186
187    println!("Done");
188    Ok(())
189}
Source

pub unsafe fn trigger_exception(&mut self, exception: u32, data: u64)

Only safe to call from a syscall handler.

§Safety

The caller must ensure this is invoked from a valid syscall handler context for the current machine instance.

Trait Implementations§

Source§

impl Drop for Machine

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.