XexLoadImage for user modules

This commit is contained in:
Dr. Chat 2015-05-03 17:17:22 -05:00
parent 00c1b5fbbc
commit 9f0663efa2
3 changed files with 40 additions and 3 deletions

View File

@ -107,8 +107,13 @@ 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();
for (XUserModule *module : user_modules_) {
if (module->name() == name) {
module->Retain();
return module;
}
}
return nullptr;
}
}
@ -136,6 +141,28 @@ void KernelState::SetExecutableModule(XUserModule* module) {
}
}
XUserModule* KernelState::LoadUserModule(const char *name) {
// 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)) {
delete module;
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;

View File

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

View File

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