Merge pull request #190 from DrChat/load_module

XexLoadImage support for user modules
This commit is contained in:
Ben Vanik 2015-05-04 20:32:12 -07:00
commit 649eb1cf8e
3 changed files with 48 additions and 3 deletions

View File

@ -77,6 +77,10 @@ KernelState::~KernelState() {
assert_true(shared_kernel_state_ == this); assert_true(shared_kernel_state_ == this);
shared_kernel_state_ = nullptr; shared_kernel_state_ = nullptr;
for (XUserModule* mod : user_modules_) {
mod->Release();
}
} }
KernelState* KernelState::shared() { return shared_kernel_state_; } 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. // Some games request this, for some reason. wtf.
return nullptr; return nullptr;
} else { } else {
// TODO(benvanik): support user modules/loading/etc. std::lock_guard<std::mutex> lock(object_mutex_);
assert_always();
for (XUserModule *module : user_modules_) {
if (module->name() == name) {
module->Retain();
return module;
}
}
return nullptr; 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) { void KernelState::RegisterThread(XThread* thread) {
std::lock_guard<std::mutex> lock(object_mutex_); std::lock_guard<std::mutex> lock(object_mutex_);
threads_by_id_[thread->thread_id()] = thread; threads_by_id_[thread->thread_id()] = thread;

View File

@ -69,6 +69,7 @@ class KernelState {
XModule* GetModule(const char* name); XModule* GetModule(const char* name);
XUserModule* GetExecutableModule(); XUserModule* GetExecutableModule();
void SetExecutableModule(XUserModule* module); void SetExecutableModule(XUserModule* module);
XUserModule* LoadUserModule(const char *name);
void RegisterThread(XThread* thread); void RegisterThread(XThread* thread);
void UnregisterThread(XThread* thread); void UnregisterThread(XThread* thread);
@ -104,6 +105,8 @@ class KernelState {
uint32_t process_type_; uint32_t process_type_;
XUserModule* executable_module_; XUserModule* executable_module_;
std::vector<XUserModule*> user_modules_;
friend class XObject; friend class XObject;
}; };

View File

@ -224,7 +224,14 @@ SHIM_CALL XexLoadImage_shim(PPCContext* ppc_state, KernelState* state) {
result = X_STATUS_SUCCESS; result = X_STATUS_SUCCESS;
} else { } 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); SHIM_SET_RETURN_32(result);