minor cleanup
This commit is contained in:
parent
a67fa70632
commit
b0e6174467
|
@ -14,10 +14,10 @@ get going:
|
|||
`wbx_activate_host()`
|
||||
2. Connect exports from the guest executable to your host system
|
||||
`wbx_get_proc_addr()`
|
||||
3. Run the guest system's init, using function pointers it exposed through wbx_get_proc_addr()
|
||||
3. Run the guest system's init, using function pointers it exposed through `wbx_get_proc_addr()`
|
||||
4. Get ready to take savestates
|
||||
`wbx_seal()`
|
||||
5. Run emulation, using frameadvance or other advance functions exposed by the guest through wbx_get_proc_addr()
|
||||
5. Run emulation, using frameadvance or other advance functions exposed by the guest through `wbx_get_proc_addr()`
|
||||
6. Save and load states as needed
|
||||
`wbx_save_state()`
|
||||
`wbx_load_state()`
|
||||
|
@ -25,8 +25,13 @@ get going:
|
|||
`wbx_deactivate_host()`
|
||||
`wbx_destroy_host()`
|
||||
|
||||
If you're keeping around multiple hosts that may compete for the same address space, use `wbx_activate_host` and `wbx_deactivate_host`
|
||||
to switch between them. If you'd like to expose files to the virtual filesystem, see `wbx_mount_file` and `wbx_unmount_file`
|
||||
Some more advanced features:
|
||||
|
||||
* If you're keeping around multiple hosts that may compete for the same address space,
|
||||
use `wbx_activate_host()` and `wbx_deactivate_host()` to switch between them.
|
||||
* If you'd like to expose files to the virtual filesystem, see `wbx_mount_file()` and `wbx_unmount_file()`.
|
||||
* If you need to call dynamically exposed functions that are not part of the static exports, see `wbx_get_callin_addr()`.
|
||||
* If you'd like the guest code to be able to call callbacks that you pass to it, see `wbx_get_callback_addr()`.
|
||||
|
||||
## Building
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ const CALL_GUEST_SIMPLE_ADDR: usize = ORG + 64;
|
|||
|
||||
pub const CALLBACK_SLOTS: usize = 64;
|
||||
/// Retrieves a function pointer suitable for sending to the guest that will cause
|
||||
/// the host to callback to `slot` when called
|
||||
/// the host to callback to `slot` when called. Slot must be less than CALLBACK_SLOTS
|
||||
pub fn get_callback_ptr(slot: usize) -> usize{
|
||||
assert!(slot < CALLBACK_SLOTS);
|
||||
ORG + 0x100 + slot * 16
|
||||
|
@ -52,27 +52,44 @@ pub fn call_guest_simple(entry_point: usize, context: &mut Context) -> usize{
|
|||
unsafe { (CALL_GUEST_SIMPLE.f)(entry_point, context) }
|
||||
}
|
||||
|
||||
|
||||
/// Allowed type for callback functions that Waterbox cores can make back into the real world.
|
||||
pub type ExternalCallback = extern "sysv64" fn(
|
||||
a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize) -> usize;
|
||||
/// Allowed type of the syscall service function
|
||||
pub type SyscallCallback = extern "sysv64" fn(
|
||||
a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize, nr: SyscallNumber, h: &mut ActivatedWaterboxHost) -> SyscallReturn;
|
||||
|
||||
/// Structure used to track information for calls into waterbox code
|
||||
/// Layout must be synced with interop.s
|
||||
#[repr(C)]
|
||||
pub struct Context {
|
||||
/// Used internally to track the host's most recent rsp when transitioned to Waterbox code.
|
||||
pub host_rsp: usize,
|
||||
/// Sets the guest's starting rsp, and used internally to track the guest's most recent rsp when transitioned to extcall or syscall
|
||||
pub guest_rsp: usize,
|
||||
/// syscall service function
|
||||
pub dispatch_syscall: SyscallCallback,
|
||||
/// This will be passed as the final parameter to dispatch_syscall, and is not otherwise used by the context tracking code
|
||||
pub host_ptr: usize,
|
||||
/// Host function pointers that will be called when the guest calls an extcall slot thunk (returned from `get_callback_ptr`)
|
||||
pub extcall_slots: [Option<ExternalCallback>; 64],
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Returns a suitably initialized context. It's almost ready to use, but host_ptr must be set before each usage
|
||||
pub fn new(initial_guest_rsp: usize, dispatch_syscall: SyscallCallback) -> Context {
|
||||
Context {
|
||||
host_rsp: 0,
|
||||
guest_rsp: initial_guest_rsp,
|
||||
dispatch_syscall,
|
||||
host_ptr: 0,
|
||||
extcall_slots: [None; 64]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
thread_local!(static TIB: Box<[usize; 4]> = Box::new([0usize; 4]));
|
||||
|
||||
|
||||
/// Prepares this host thread to be allowed to call guest code. Noop if already called.
|
||||
/// Only needs to happen once per host thread
|
||||
pub fn prepare_thread() {
|
||||
|
|
|
@ -11,6 +11,7 @@ use std::collections::HashMap;
|
|||
|
||||
const THUNK_SIZE: usize = 32;
|
||||
|
||||
/// tracks thunks for calling into waterbox code
|
||||
pub struct ThunkManager {
|
||||
memory: AddressRange,
|
||||
lookup: HashMap<usize, usize>,
|
||||
|
@ -25,6 +26,8 @@ impl ThunkManager {
|
|||
}
|
||||
/// Generates a thunk for calling into waterbox.
|
||||
/// Only valid so long as this ThunkManager is alive and set_context_ptr is kept up to date
|
||||
/// See also `call_guest_simple`, which directly performs a call of the sort that these thunks do, but requires
|
||||
/// Context to be passed at the time of call and cannot pass arguments to the guest
|
||||
pub fn get_thunk_for_proc(&mut self, guest_entry_point: usize, context: *mut Context) -> anyhow::Result<usize> {
|
||||
match self.lookup.get(&guest_entry_point) {
|
||||
Some(p) => return Ok(*p),
|
||||
|
|
|
@ -41,13 +41,7 @@ impl WaterboxHost {
|
|||
active: false,
|
||||
sealed: false,
|
||||
image_file,
|
||||
context: Context {
|
||||
host_rsp: 0,
|
||||
guest_rsp: layout.main_thread.end(),
|
||||
dispatch_syscall: syscall,
|
||||
host_ptr: 0,
|
||||
extcall_slots: [None; 64],
|
||||
},
|
||||
context: Context::new(layout.main_thread.end(), syscall),
|
||||
thunks,
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue