#include <rex/kernel/function_dispatcher.h>
|
| | FunctionDispatcher (kernel::GuestAddressSpace *memory) |
| virtual | ~FunctionDispatcher () |
|
kernel::GuestAddressSpace * | GetAddressSpace () const |
| u64 | Execute (ThreadState *thread_state, u32 address, u64 args[], size_t arg_count) |
| u64 | ExecuteInterrupt (ThreadState *thread_state, u32 address, u64 args[], size_t arg_count) |
| void | SetGraphicsInterrupt (u32 callback, u32 user_data) |
| void | RaiseGraphicsInterrupt (u32 source, u32 cpu) |
| u64 | ExecuteTrap (ThreadState *thread_state, u32 address, u64 args[], size_t arg_count) |
| bool | InitializeFunctionTable (u32 code_base, u32 code_size, u32 image_base, u32 image_size, bool is_entrypoint=false) |
| bool | SetFunction (u32 guest_address, ::PPCFunc *func) override |
| ::PPCFunc * | GetFunction (u32 guest_address) |
| u32 | AllocateThunk (::PPCFunc *func, u32 caller_address) |
| u32 | FindCallerModuleBase (u32 guest_address) |
| void | RegisterModule (const std::string &module_id, u32 code_base, RegisterFn register_func, std::span< const u8 > recompiled_code={}) |
| void | AddRecompiledCode (std::span< const u8 > code) |
| std::optional< std::pair< u32, u32 > > | UnregisterModule (const std::string &module_id) |
|
|
| NonCopyable (const NonCopyable &)=delete |
|
NonCopyable & | operator= (const NonCopyable &)=delete |
Maps guest addresses to recompiled functions and runs them on guest threads.
◆ FunctionDispatcher()
Builds a dispatcher with no modules.
◆ ~FunctionDispatcher()
| virtual rex::kernel::FunctionDispatcher::~FunctionDispatcher |
( |
| ) |
|
|
virtual |
Removes the recompiled code of every registered module.
◆ AddRecompiledCode()
| void rex::kernel::FunctionDispatcher::AddRecompiledCode |
( |
std::span< const u8 > | code | ) |
|
Registers recompiled code, where a stop may redirect a thread.
◆ AllocateThunk()
| u32 rex::kernel::FunctionDispatcher::AllocateThunk |
( |
::PPCFunc * | func, |
|
|
u32 | caller_address ) |
Allocates a thunk in the pool of the calling module.
- Parameters
-
| func | The function the thunk calls. |
| caller_address | An address inside a registered module, or 0 for the entrypoint pool. |
◆ Execute()
| u64 rex::kernel::FunctionDispatcher::Execute |
( |
ThreadState * | thread_state, |
|
|
u32 | address, |
|
|
u64 | args[], |
|
|
size_t | arg_count ) |
Runs recompiled code on a thread and restores its register file afterwards.
- Returns
- The value in r3 when the call returns, or 0xDEADBABE when no function is set there.
◆ ExecuteInterrupt()
| u64 rex::kernel::FunctionDispatcher::ExecuteInterrupt |
( |
ThreadState * | thread_state, |
|
|
u32 | address, |
|
|
u64 | args[], |
|
|
size_t | arg_count ) |
Runs recompiled code as a DPC level interrupt, then queued DPCs when the outermost ends.
- Parameters
-
| args | The call arguments, at most 5. |
- Returns
- The value in r3 when the call returns, or 0xDEADBABE when no function is set there.
◆ ExecuteTrap()
| u64 rex::kernel::FunctionDispatcher::ExecuteTrap |
( |
ThreadState * | thread_state, |
|
|
u32 | address, |
|
|
u64 | args[], |
|
|
size_t | arg_count ) |
Runs recompiled code like a trap frame APC delivery, then restores the register state.
- Returns
- The value in r3 when the call returns, or 0xDEADBABE when it could not run.
◆ FindCallerModuleBase()
| u32 rex::kernel::FunctionDispatcher::FindCallerModuleBase |
( |
u32 | guest_address | ) |
|
Returns the code base of the module containing an address, or 0 when no module covers the address.
◆ GetFunction()
| ::PPCFunc * rex::kernel::FunctionDispatcher::GetFunction |
( |
u32 | guest_address | ) |
|
Returns the function at a guest address, null when none is set.
◆ InitializeFunctionTable()
| bool rex::kernel::FunctionDispatcher::InitializeFunctionTable |
( |
u32 | code_base, |
|
|
u32 | code_size, |
|
|
u32 | image_base, |
|
|
u32 | image_size, |
|
|
bool | is_entrypoint = false ) |
Initializes the function table of a module at image_base + image_size.
AllocateThunk with caller_address 0 uses the pool of the entrypoint module.
- Parameters
-
| code_base | The first guest address of the code. |
| is_entrypoint | True for the host loaded entrypoint module. |
◆ RaiseGraphicsInterrupt()
| void rex::kernel::FunctionDispatcher::RaiseGraphicsInterrupt |
( |
u32 | source, |
|
|
u32 | cpu ) |
Runs the graphics interrupt callback on the calling thread, if the title set one.
- Parameters
-
| cpu | The guest CPU the interrupt is for, 0xFFFFFFFF for CPU 2. |
◆ RegisterModule()
| void rex::kernel::FunctionDispatcher::RegisterModule |
( |
const std::string & | module_id, |
|
|
u32 | code_base, |
|
|
RegisterFn | register_func, |
|
|
std::span< const u8 > | recompiled_code = {} ) |
Registers a module and tracks the guest addresses it sets through SetFunction.
- Parameters
-
| code_base | The code base passed to InitializeFunctionTable for the same module. |
| recompiled_code | The recompiled code of the module, where a stop may redirect a thread. |
◆ SetFunction()
| bool rex::kernel::FunctionDispatcher::SetFunction |
( |
u32 | guest_address, |
|
|
::PPCFunc * | func ) |
|
overridevirtual |
◆ SetGraphicsInterrupt()
| void rex::kernel::FunctionDispatcher::SetGraphicsInterrupt |
( |
u32 | callback, |
|
|
u32 | user_data ) |
Sets the graphics interrupt callback the title registered.
- Parameters
-
| callback | The guest address of the routine, 0 to clear it. |
◆ UnregisterModule()
| std::optional< std::pair< u32, u32 > > rex::kernel::FunctionDispatcher::UnregisterModule |
( |
const std::string & | module_id | ) |
|
Unregisters a module and clears its function table and thunk pool.
- Returns
- The cleared thunk pool range [lo, hi) for cache invalidation, or nullopt when the module was not registered.
◆ kThunkReserveSize
| u32 rex::kernel::FunctionDispatcher::kThunkReserveSize = 0x10000 |
|
staticconstexpr |
Bytes of thunk region reserved per module.
The documentation for this class was generated from the following file: