Merge pull request #190 from DrChat/load_module
XexLoadImage support for user modules
This commit is contained in:
commit
649eb1cf8e
|
@ -77,6 +77,10 @@ KernelState::~KernelState() {
|
|||
|
||||
assert_true(shared_kernel_state_ == this);
|
||||
shared_kernel_state_ = nullptr;
|
||||
|
||||
for (XUserModule* mod : user_modules_) {
|
||||
mod->Release();
|
||||
}
|
||||
}
|
||||
|
||||
KernelState* KernelState::shared() { return shared_kernel_state_; }
|
||||
|
@ -107,8 +111,15 @@ XModule* KernelState::GetModule(const char* name) {
|
|||
// Some games request this, for some reason. wtf.
|
||||
return nullptr;
|
||||
} else {
|
||||
// TODO(benvanik): support user modules/loading/etc.
|
||||
assert_always();
|
||||
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||
|
||||
for (XUserModule *module : user_modules_) {
|
||||
if (module->name() == name) {
|
||||
module->Retain();
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -136,6 +147,30 @@ void KernelState::SetExecutableModule(XUserModule* module) {
|
|||
}
|
||||
}
|
||||
|
||||
XUserModule* KernelState::LoadUserModule(const char *name) {
|
||||
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||
|
||||
// See if we've already loaded it
|
||||
for (XUserModule *module : user_modules_) {
|
||||
if (module->name() == name) {
|
||||
module->Retain();
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
// Module wasn't loaded, so load it.
|
||||
XUserModule *module = new XUserModule(this, name);
|
||||
X_STATUS status = module->LoadFromFile(name);
|
||||
if (XFAILED(status)) {
|
||||
module->Release();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
user_modules_.push_back(module);
|
||||
module->Retain();
|
||||
return module;
|
||||
}
|
||||
|
||||
void KernelState::RegisterThread(XThread* thread) {
|
||||
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||
threads_by_id_[thread->thread_id()] = thread;
|
||||
|
|
|
@ -69,6 +69,7 @@ class KernelState {
|
|||
XModule* GetModule(const char* name);
|
||||
XUserModule* GetExecutableModule();
|
||||
void SetExecutableModule(XUserModule* module);
|
||||
XUserModule* LoadUserModule(const char *name);
|
||||
|
||||
void RegisterThread(XThread* thread);
|
||||
void UnregisterThread(XThread* thread);
|
||||
|
@ -104,6 +105,8 @@ class KernelState {
|
|||
uint32_t process_type_;
|
||||
XUserModule* executable_module_;
|
||||
|
||||
std::vector<XUserModule*> user_modules_;
|
||||
|
||||
friend class XObject;
|
||||
};
|
||||
|
||||
|
|
|
@ -224,7 +224,14 @@ SHIM_CALL XexLoadImage_shim(PPCContext* ppc_state, KernelState* state) {
|
|||
|
||||
result = X_STATUS_SUCCESS;
|
||||
} else {
|
||||
result = X_STATUS_NO_SUCH_FILE;
|
||||
XUserModule* usermod = state->LoadUserModule(module_name);
|
||||
if (usermod) {
|
||||
result = X_STATUS_SUCCESS;
|
||||
|
||||
usermod->RetainHandle();
|
||||
SHIM_SET_MEM_32(handle_ptr, usermod->handle());
|
||||
usermod->Release();
|
||||
}
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN_32(result);
|
||||
|
|
Loading…
Reference in New Issue