minor cleanup

This commit is contained in:
nattthebear 2020-07-08 13:54:47 -04:00
parent a67fa70632
commit b0e6174467
4 changed files with 34 additions and 15 deletions

View File

@ -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

View File

@ -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() {

View File

@ -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),

View File

@ -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,
});