ReXGlue SDK
Loading...
Searching...
No Matches
function_dispatcher.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#include <atomic>
16#include <mutex>
17#include <optional>
18#include <span>
19#include <string>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include <rex/platform.h>
25#include <rex/types.h>
26#include <rex/memory.h>
30#include <rex/kernel/thread_state.h>
31#include <rex/utility.h>
32
33namespace rex::kernel {
34
35class ThreadState;
36
37class IFunctionRegistrar : public NonCopyable {
38 public:
39 virtual ~IFunctionRegistrar() = default;
40
44 virtual bool SetFunction(u32 guest_address, ::PPCFunc* func) = 0;
45};
46
49 public:
50 using RegisterFn = void (*)(IFunctionRegistrar*);
51
56
57 kernel::GuestAddressSpace* GetAddressSpace() const { return memory_; }
58
64 u64 Execute(ThreadState* thread_state, u32 address, u64 args[], size_t arg_count);
71 u64 ExecuteInterrupt(ThreadState* thread_state, u32 address, u64 args[], size_t arg_count);
72
78 void SetGraphicsInterrupt(u32 callback, u32 user_data);
79
85 void RaiseGraphicsInterrupt(u32 source, u32 cpu);
86
92 u64 ExecuteTrap(ThreadState* thread_state, u32 address, u64 args[], size_t arg_count);
93
95 static constexpr u32 kThunkReserveSize = 0x10000;
96
105 bool InitializeFunctionTable(u32 code_base, u32 code_size, u32 image_base, u32 image_size,
106 bool is_entrypoint = false);
110 bool SetFunction(u32 guest_address, ::PPCFunc* func) override;
112 ::PPCFunc* GetFunction(u32 guest_address);
119 u32 AllocateThunk(::PPCFunc* func, u32 caller_address);
120
125 u32 FindCallerModuleBase(u32 guest_address);
126
133 void RegisterModule(const std::string& module_id, u32 code_base, RegisterFn register_func,
134 std::span<const u8> recompiled_code = {});
135
137 void AddRecompiledCode(std::span<const u8> code);
138
145 std::optional<std::pair<u32, u32>> UnregisterModule(const std::string& module_id);
146
147 private:
148 bool Run(ThreadState* thread_state, u32 address, std::span<const u64> args);
149 u64 RunInterrupt(ThreadState* thread_state, u32 address, u64 args[], size_t arg_count);
150
151 struct ModuleTable {
152 u32 code_base;
153 u32 code_size;
154 u32 image_base;
155 u32 image_size;
156 u32 next_thunk_address;
157 u32 thunk_limit;
158 };
159
160 ModuleTable* FindModuleByAddress(u32 guest_address);
161
162 kernel::GuestAddressSpace* memory_ = nullptr;
163
164 std::unordered_map<u32, ::PPCFunc*> function_table_;
165
166 std::vector<ModuleTable> module_tables_;
167
169 u32 entrypoint_code_base_ = 0;
170
171 bool registering_ = false;
172 std::vector<u32> registered_addresses_;
173
174 struct ModuleRegistration {
175 u32 code_base;
176 std::vector<u32> addresses;
177 };
178
179 std::unordered_map<std::string, ModuleRegistration> module_addresses_;
180
182 mutable std::recursive_mutex dispatch_mutex_;
183 std::atomic<u64> graphics_interrupt_{0};
184
186
187 mutable std::mutex recompiled_code_mutex_;
188 std::vector<std::pair<std::string, std::span<const u8>>> recompiled_code_;
189};
190
191} // namespace rex::kernel
u32 AllocateThunk(::PPCFunc *func, u32 caller_address)
bool InitializeFunctionTable(u32 code_base, u32 code_size, u32 image_base, u32 image_size, bool is_entrypoint=false)
void SetGraphicsInterrupt(u32 callback, u32 user_data)
static constexpr u32 kThunkReserveSize
Definition function_dispatcher.h:95
void RaiseGraphicsInterrupt(u32 source, u32 cpu)
bool SetFunction(u32 guest_address, ::PPCFunc *func) override
::PPCFunc * GetFunction(u32 guest_address)
FunctionDispatcher(kernel::GuestAddressSpace *memory)
std::optional< std::pair< u32, u32 > > UnregisterModule(const std::string &module_id)
u64 ExecuteTrap(ThreadState *thread_state, u32 address, u64 args[], size_t arg_count)
void RegisterModule(const std::string &module_id, u32 code_base, RegisterFn register_func, std::span< const u8 > recompiled_code={})
u32 FindCallerModuleBase(u32 guest_address)
void AddRecompiledCode(std::span< const u8 > code)
u64 ExecuteInterrupt(ThreadState *thread_state, u32 address, u64 args[], size_t arg_count)
u64 Execute(ThreadState *thread_state, u32 address, u64 args[], size_t arg_count)
Definition heap.h:594
Definition function_dispatcher.h:37
virtual bool SetFunction(u32 guest_address, ::PPCFunc *func)=0
Definition thread_state.h:40
Definition lock_order.h:52
constexpr LockRank kInterruptState
Definition lock_order.h:114
Definition export.h:24
Definition endian.h:27
Platform flags, packing macros and export markers.
#define REX_KERNEL_API
Definition platform.h:297
Integer types, byte order wrappers and size literals.
Move only function, const propagating pointer and scope guard.