Modules using object_ref.
This commit is contained in:
parent
fff1a7c132
commit
5cfb69434c
|
@ -300,7 +300,9 @@ void Debugger::StopSession() {
|
||||||
shutdown(listen_socket_, SD_SEND);
|
shutdown(listen_socket_, SD_SEND);
|
||||||
closesocket(listen_socket_);
|
closesocket(listen_socket_);
|
||||||
listen_socket_ = INVALID_SOCKET;
|
listen_socket_ = INVALID_SOCKET;
|
||||||
|
if (accept_thread_.joinable()) {
|
||||||
accept_thread_.join();
|
accept_thread_.join();
|
||||||
|
}
|
||||||
|
|
||||||
functions_file_.reset();
|
functions_file_.reset();
|
||||||
functions_trace_file_.reset();
|
functions_trace_file_.reset();
|
||||||
|
|
|
@ -38,21 +38,23 @@ Emulator::~Emulator() {
|
||||||
// Note that we delete things in the reverse order they were initialized.
|
// Note that we delete things in the reverse order they were initialized.
|
||||||
|
|
||||||
// Kill the debugger first, so that we don't have it messing with things.
|
// Kill the debugger first, so that we don't have it messing with things.
|
||||||
debugger_.reset();
|
debugger_->StopSession();
|
||||||
|
|
||||||
// Give the systems time to shutdown before we delete them.
|
// Give the systems time to shutdown before we delete them.
|
||||||
graphics_system_->Shutdown();
|
graphics_system_->Shutdown();
|
||||||
audio_system_->Shutdown();
|
audio_system_->Shutdown();
|
||||||
|
|
||||||
kernel_state_.reset();
|
|
||||||
file_system_.reset();
|
|
||||||
|
|
||||||
input_system_.reset();
|
input_system_.reset();
|
||||||
graphics_system_.reset();
|
graphics_system_.reset();
|
||||||
audio_system_.reset();
|
audio_system_.reset();
|
||||||
|
|
||||||
|
kernel_state_.reset();
|
||||||
|
file_system_.reset();
|
||||||
|
|
||||||
processor_.reset();
|
processor_.reset();
|
||||||
|
|
||||||
|
debugger_.reset();
|
||||||
|
|
||||||
export_resolver_.reset();
|
export_resolver_.reset();
|
||||||
|
|
||||||
// Kill the window last, as until the graphics system/etc is dead it's needed.
|
// Kill the window last, as until the graphics system/etc is dead it's needed.
|
||||||
|
@ -198,10 +200,10 @@ X_STATUS Emulator::LaunchSTFSTitle(const std::wstring& path) {
|
||||||
|
|
||||||
X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
||||||
const std::string& module_path) {
|
const std::string& module_path) {
|
||||||
auto xboxkrnl = static_cast<kernel::XboxkrnlModule*>(
|
auto xboxkrnl_module = kernel_state_->GetModule("xboxkrnl.exe");
|
||||||
kernel_state_->GetModule("xboxkrnl.exe"));
|
auto xboxkrnl = kernel::object_ref<kernel::XboxkrnlModule>(
|
||||||
|
reinterpret_cast<kernel::XboxkrnlModule*>(xboxkrnl_module.release()));
|
||||||
int result = xboxkrnl->LaunchModule(module_path.c_str());
|
int result = xboxkrnl->LaunchModule(module_path.c_str());
|
||||||
xboxkrnl->Release();
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -202,10 +202,11 @@ void CommandProcessor::WorkerThreadMain() {
|
||||||
SwitchToThread();
|
SwitchToThread();
|
||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
write_ptr_index = write_ptr_index_.load();
|
write_ptr_index = write_ptr_index_.load();
|
||||||
} while (pending_fns_.empty() && (write_ptr_index == 0xBAADF00D ||
|
} while (worker_running_ && pending_fns_.empty() &&
|
||||||
|
(write_ptr_index == 0xBAADF00D ||
|
||||||
read_ptr_index_ == write_ptr_index));
|
read_ptr_index_ == write_ptr_index));
|
||||||
// ReturnFromWait();
|
// ReturnFromWait();
|
||||||
if (!pending_fns_.empty()) {
|
if (!worker_running_ || !pending_fns_.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,7 @@ KernelState::KernelState(Emulator* emulator)
|
||||||
memory_(emulator->memory()),
|
memory_(emulator->memory()),
|
||||||
object_table_(nullptr),
|
object_table_(nullptr),
|
||||||
has_notified_startup_(false),
|
has_notified_startup_(false),
|
||||||
process_type_(X_PROCTYPE_USER),
|
process_type_(X_PROCTYPE_USER) {
|
||||||
executable_module_(nullptr) {
|
|
||||||
processor_ = emulator->processor();
|
processor_ = emulator->processor();
|
||||||
file_system_ = emulator->file_system();
|
file_system_ = emulator->file_system();
|
||||||
|
|
||||||
|
@ -70,13 +69,8 @@ KernelState::KernelState(Emulator* emulator)
|
||||||
KernelState::~KernelState() {
|
KernelState::~KernelState() {
|
||||||
SetExecutableModule(nullptr);
|
SetExecutableModule(nullptr);
|
||||||
|
|
||||||
for (auto user_module : user_modules_) {
|
executable_module_.reset();
|
||||||
user_module->Release();
|
|
||||||
}
|
|
||||||
user_modules_.clear();
|
user_modules_.clear();
|
||||||
for (auto kernel_module : kernel_modules_) {
|
|
||||||
kernel_module->Release();
|
|
||||||
}
|
|
||||||
kernel_modules_.clear();
|
kernel_modules_.clear();
|
||||||
|
|
||||||
// Delete all objects.
|
// Delete all objects.
|
||||||
|
@ -116,7 +110,7 @@ bool KernelState::IsKernelModule(const char* name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
XModule* KernelState::GetModule(const char* name) {
|
object_ref<XModule> KernelState::GetModule(const char* name) {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
// NULL name = self.
|
// NULL name = self.
|
||||||
// TODO(benvanik): lookup module from caller address.
|
// TODO(benvanik): lookup module from caller address.
|
||||||
|
@ -128,48 +122,37 @@ XModule* KernelState::GetModule(const char* name) {
|
||||||
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
||||||
for (auto kernel_module : kernel_modules_) {
|
for (auto kernel_module : kernel_modules_) {
|
||||||
if (kernel_module->Matches(name)) {
|
if (kernel_module->Matches(name)) {
|
||||||
kernel_module->Retain();
|
return retain_object(kernel_module.get());
|
||||||
return kernel_module;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto user_module : user_modules_) {
|
for (auto user_module : user_modules_) {
|
||||||
if (user_module->Matches(name)) {
|
if (user_module->Matches(name)) {
|
||||||
user_module->Retain();
|
return retain_object(user_module.get());
|
||||||
return user_module;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
XUserModule* KernelState::GetExecutableModule() {
|
object_ref<XUserModule> KernelState::GetExecutableModule() {
|
||||||
if (!executable_module_) {
|
if (!executable_module_) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
executable_module_->Retain();
|
|
||||||
return executable_module_;
|
return executable_module_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::SetExecutableModule(XUserModule* module) {
|
void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
|
||||||
if (module == executable_module_) {
|
if (module.get() == executable_module_.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
executable_module_ = std::move(module);
|
||||||
if (executable_module_) {
|
|
||||||
executable_module_->Release();
|
|
||||||
}
|
|
||||||
executable_module_ = module;
|
|
||||||
if (executable_module_) {
|
|
||||||
executable_module_->Retain();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::LoadKernelModule(XKernelModule* kernel_module) {
|
void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) {
|
||||||
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
||||||
kernel_modules_.push_back(kernel_module);
|
kernel_modules_.push_back(std::move(kernel_module));
|
||||||
}
|
}
|
||||||
|
|
||||||
XUserModule* KernelState::LoadUserModule(const char* raw_name) {
|
object_ref<XUserModule> KernelState::LoadUserModule(const char* raw_name) {
|
||||||
// Some games try to load relative to launch module, others specify full path.
|
// Some games try to load relative to launch module, others specify full path.
|
||||||
std::string name = xe::find_name_from_path(raw_name);
|
std::string name = xe::find_name_from_path(raw_name);
|
||||||
std::string path(raw_name);
|
std::string path(raw_name);
|
||||||
|
@ -177,28 +160,28 @@ XUserModule* KernelState::LoadUserModule(const char* raw_name) {
|
||||||
path = xe::join_paths(xe::find_base_path(executable_module_->path()), name);
|
path = xe::join_paths(xe::find_base_path(executable_module_->path()), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
XUserModule* module = nullptr;
|
object_ref<XUserModule> module;
|
||||||
{
|
{
|
||||||
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
||||||
|
|
||||||
// See if we've already loaded it
|
// See if we've already loaded it
|
||||||
for (XUserModule* existing_module : user_modules_) {
|
for (auto& existing_module : user_modules_) {
|
||||||
if (existing_module->path() == path) {
|
if (existing_module->path() == path) {
|
||||||
existing_module->Retain();
|
existing_module->Retain();
|
||||||
return existing_module;
|
return retain_object(existing_module.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module wasn't loaded, so load it.
|
// Module wasn't loaded, so load it.
|
||||||
module = new XUserModule(this, path.c_str());
|
module = object_ref<XUserModule>(new XUserModule(this, path.c_str()));
|
||||||
X_STATUS status = module->LoadFromFile(path);
|
X_STATUS status = module->LoadFromFile(path);
|
||||||
if (XFAILED(status)) {
|
if (XFAILED(status)) {
|
||||||
module->Release();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
user_modules_.push_back(module);
|
// Retain when putting into the listing.
|
||||||
module->Retain();
|
module->Retain();
|
||||||
|
user_modules_.push_back(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
module->Dump();
|
module->Dump();
|
||||||
|
|
|
@ -73,16 +73,16 @@ class KernelState {
|
||||||
void RegisterModule(XModule* module);
|
void RegisterModule(XModule* module);
|
||||||
void UnregisterModule(XModule* module);
|
void UnregisterModule(XModule* module);
|
||||||
bool IsKernelModule(const char* name);
|
bool IsKernelModule(const char* name);
|
||||||
XModule* GetModule(const char* name);
|
object_ref<XModule> GetModule(const char* name);
|
||||||
XUserModule* GetExecutableModule();
|
object_ref<XUserModule> GetExecutableModule();
|
||||||
void SetExecutableModule(XUserModule* module);
|
void SetExecutableModule(object_ref<XUserModule> module);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
XKernelModule* LoadKernelModule() {
|
object_ref<XKernelModule> LoadKernelModule() {
|
||||||
auto kernel_module = std::make_unique<T>(emulator_, this);
|
auto kernel_module = object_ref<XKernelModule>(new T(emulator_, this));
|
||||||
LoadKernelModule(kernel_module.get());
|
LoadKernelModule(kernel_module);
|
||||||
return kernel_module.release();
|
return kernel_module;
|
||||||
}
|
}
|
||||||
XUserModule* LoadUserModule(const char* name);
|
object_ref<XUserModule> LoadUserModule(const char* name);
|
||||||
|
|
||||||
void RegisterThread(XThread* thread);
|
void RegisterThread(XThread* thread);
|
||||||
void UnregisterThread(XThread* thread);
|
void UnregisterThread(XThread* thread);
|
||||||
|
@ -102,7 +102,7 @@ class KernelState {
|
||||||
uint32_t extended_error, uint32_t length);
|
uint32_t extended_error, uint32_t length);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadKernelModule(XKernelModule* kernel_module);
|
void LoadKernelModule(object_ref<XKernelModule> kernel_module);
|
||||||
|
|
||||||
Emulator* emulator_;
|
Emulator* emulator_;
|
||||||
Memory* memory_;
|
Memory* memory_;
|
||||||
|
@ -122,9 +122,9 @@ class KernelState {
|
||||||
bool has_notified_startup_;
|
bool has_notified_startup_;
|
||||||
|
|
||||||
uint32_t process_type_;
|
uint32_t process_type_;
|
||||||
XUserModule* executable_module_;
|
object_ref<XUserModule> executable_module_;
|
||||||
std::vector<XKernelModule*> kernel_modules_;
|
std::vector<object_ref<XKernelModule>> kernel_modules_;
|
||||||
std::vector<XUserModule*> user_modules_;
|
std::vector<object_ref<XUserModule>> user_modules_;
|
||||||
|
|
||||||
friend class XObject;
|
friend class XObject;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ ObjectTable::~ObjectTable() {
|
||||||
table_capacity_ = 0;
|
table_capacity_ = 0;
|
||||||
last_free_entry_ = 0;
|
last_free_entry_ = 0;
|
||||||
free(table_);
|
free(table_);
|
||||||
table_ = NULL;
|
table_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) {
|
X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) {
|
||||||
|
|
|
@ -172,7 +172,6 @@ X_STATUS XThread::Create() {
|
||||||
tls_address_ = memory()->SystemHeapAlloc(tls_size);
|
tls_address_ = memory()->SystemHeapAlloc(tls_size);
|
||||||
if (!tls_address_) {
|
if (!tls_address_) {
|
||||||
XELOGW("Unable to allocate thread local storage block");
|
XELOGW("Unable to allocate thread local storage block");
|
||||||
module->Release();
|
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,10 +186,6 @@ X_STATUS XThread::Create() {
|
||||||
memory()->Fill(tls_address_, tls_size, 0);
|
memory()->Fill(tls_address_, tls_size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module) {
|
|
||||||
module->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate processor thread state.
|
// Allocate processor thread state.
|
||||||
// This is thread safe.
|
// This is thread safe.
|
||||||
thread_state_ = new ThreadState(kernel_state()->processor(), thread_id_,
|
thread_state_ = new ThreadState(kernel_state()->processor(), thread_id_,
|
||||||
|
|
|
@ -79,8 +79,6 @@ SHIM_CALL XamGetExecutionId_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
|
|
||||||
SHIM_SET_MEM_32(info_ptr, module->execution_info_ptr());
|
SHIM_SET_MEM_32(info_ptr, module->execution_info_ptr());
|
||||||
|
|
||||||
module->Release();
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0);
|
SHIM_SET_RETURN_32(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,13 +171,12 @@ XboxkrnlModule::~XboxkrnlModule() {
|
||||||
int XboxkrnlModule::LaunchModule(const char* path) {
|
int XboxkrnlModule::LaunchModule(const char* path) {
|
||||||
// Create and register the module. We keep it local to this function and
|
// Create and register the module. We keep it local to this function and
|
||||||
// dispose it on exit.
|
// dispose it on exit.
|
||||||
XUserModule* module = new XUserModule(kernel_state_, path);
|
auto module = object_ref<XUserModule>(new XUserModule(kernel_state_, path));
|
||||||
|
|
||||||
// Load the module into memory from the filesystem.
|
// Load the module into memory from the filesystem.
|
||||||
X_STATUS result_code = module->LoadFromFile(path);
|
X_STATUS result_code = module->LoadFromFile(path);
|
||||||
if (XFAILED(result_code)) {
|
if (XFAILED(result_code)) {
|
||||||
XELOGE("Failed to load module %s: %.8X", path, result_code);
|
XELOGE("Failed to load module %s: %.8X", path, result_code);
|
||||||
module->Release();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,12 +192,9 @@ int XboxkrnlModule::LaunchModule(const char* path) {
|
||||||
kernel_state_->SetExecutableModule(NULL);
|
kernel_state_->SetExecutableModule(NULL);
|
||||||
if (XFAILED(result_code)) {
|
if (XFAILED(result_code)) {
|
||||||
XELOGE("Failed to launch module %s: %.8X", path, result_code);
|
XELOGE("Failed to launch module %s: %.8X", path, result_code);
|
||||||
module->Release();
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
module->Release();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_state,
|
||||||
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
||||||
uint32_t mask = 1 << privilege;
|
uint32_t mask = 1 << privilege;
|
||||||
|
|
||||||
XUserModule* module = state->GetExecutableModule();
|
auto module = state->GetExecutableModule();
|
||||||
if (!module) {
|
if (!module) {
|
||||||
SHIM_SET_RETURN_32(0);
|
SHIM_SET_RETURN_32(0);
|
||||||
return;
|
return;
|
||||||
|
@ -145,8 +145,6 @@ SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_state,
|
||||||
const xe_xex2_header_t* header = xe_xex2_get_header(xex);
|
const xe_xex2_header_t* header = xe_xex2_get_header(xex);
|
||||||
uint32_t result = (header->system_flags & mask) > 0;
|
uint32_t result = (header->system_flags & mask) > 0;
|
||||||
|
|
||||||
module->Release();
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
SHIM_SET_RETURN_32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +155,7 @@ SHIM_CALL XexGetModuleHandle_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
|
|
||||||
XELOGD("XexGetModuleHandle(%s, %.8X)", module_name, module_handle_ptr);
|
XELOGD("XexGetModuleHandle(%s, %.8X)", module_name, module_handle_ptr);
|
||||||
|
|
||||||
XModule* module = nullptr;
|
object_ref<XModule> module;
|
||||||
if (!module_name) {
|
if (!module_name) {
|
||||||
module = state->GetExecutableModule();
|
module = state->GetExecutableModule();
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,8 +170,6 @@ SHIM_CALL XexGetModuleHandle_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
// NOTE: we don't retain the handle for return.
|
// NOTE: we don't retain the handle for return.
|
||||||
SHIM_SET_MEM_32(module_handle_ptr, module->handle());
|
SHIM_SET_MEM_32(module_handle_ptr, module->handle());
|
||||||
|
|
||||||
module->Release();
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,10 +183,11 @@ SHIM_CALL XexGetModuleSection_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
XELOGD("XexGetModuleSection(%.8X, %s, %.8X, %.8X)", handle, name, data_ptr,
|
XELOGD("XexGetModuleSection(%.8X, %s, %.8X, %.8X)", handle, name, data_ptr,
|
||||||
size_ptr);
|
size_ptr);
|
||||||
|
|
||||||
XModule* module = NULL;
|
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||||
X_STATUS result =
|
|
||||||
|
XModule* module = nullptr;
|
||||||
state->object_table()->GetObject(handle, (XObject**)&module);
|
state->object_table()->GetObject(handle, (XObject**)&module);
|
||||||
if (XSUCCEEDED(result)) {
|
if (module) {
|
||||||
uint32_t section_data = 0;
|
uint32_t section_data = 0;
|
||||||
uint32_t section_size = 0;
|
uint32_t section_size = 0;
|
||||||
result = module->GetSection(name, §ion_data, §ion_size);
|
result = module->GetSection(name, §ion_data, §ion_size);
|
||||||
|
@ -198,7 +195,6 @@ SHIM_CALL XexGetModuleSection_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
SHIM_SET_MEM_32(data_ptr, section_data);
|
SHIM_SET_MEM_32(data_ptr, section_data);
|
||||||
SHIM_SET_MEM_32(size_ptr, section_size);
|
SHIM_SET_MEM_32(size_ptr, section_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
module->Release();
|
module->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,16 +214,16 @@ SHIM_CALL XexLoadImage_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
||||||
|
|
||||||
X_HANDLE module_handle = X_INVALID_HANDLE_VALUE;
|
X_HANDLE module_handle = X_INVALID_HANDLE_VALUE;
|
||||||
XModule* module = state->GetModule(module_name);
|
auto module = state->GetModule(module_name);
|
||||||
if (module) {
|
if (module) {
|
||||||
// Existing module found, just add a reference and obtain a handle.
|
// Existing module found, just add a reference and obtain a handle.
|
||||||
result = state->object_table()->AddHandle(module, &module_handle);
|
result = state->object_table()->AddHandle(module.get(), &module_handle);
|
||||||
} else {
|
} else {
|
||||||
// Not found; attempt to load as a user module.
|
// Not found; attempt to load as a user module.
|
||||||
module = state->LoadUserModule(module_name);
|
auto user_module = state->LoadUserModule(module_name);
|
||||||
if (module) {
|
if (user_module) {
|
||||||
module->RetainHandle();
|
user_module->RetainHandle();
|
||||||
module_handle = module->handle();
|
module_handle = user_module->handle();
|
||||||
result = X_STATUS_SUCCESS;
|
result = X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,7 +268,7 @@ SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_state,
|
||||||
|
|
||||||
XModule* module = NULL;
|
XModule* module = NULL;
|
||||||
if (!module_handle) {
|
if (!module_handle) {
|
||||||
module = state->GetExecutableModule();
|
module = state->GetExecutableModule().get();
|
||||||
} else {
|
} else {
|
||||||
result =
|
result =
|
||||||
state->object_table()->GetObject(module_handle, (XObject**)&module);
|
state->object_table()->GetObject(module_handle, (XObject**)&module);
|
||||||
|
|
|
@ -397,24 +397,20 @@ SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_state,
|
||||||
// The only ImageField I've seen in the wild is
|
// The only ImageField I've seen in the wild is
|
||||||
// 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support.
|
// 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support.
|
||||||
|
|
||||||
XUserModule* module = NULL;
|
|
||||||
|
|
||||||
// TODO(benvanik): use xex_header_base to dereference this.
|
// TODO(benvanik): use xex_header_base to dereference this.
|
||||||
// Right now we are only concerned with games making this call on their main
|
// Right now we are only concerned with games making this call on their main
|
||||||
// module, so this hack is fine.
|
// module, so this hack is fine.
|
||||||
module = state->GetExecutableModule();
|
auto module = state->GetExecutableModule();
|
||||||
|
|
||||||
const xe_xex2_header_t* xex_header = module->xex_header();
|
const xe_xex2_header_t* xex_header = module->xex_header();
|
||||||
for (size_t n = 0; n < xex_header->header_count; n++) {
|
for (size_t n = 0; n < xex_header->header_count; n++) {
|
||||||
if (xex_header->headers[n].key == image_field) {
|
if (xex_header->headers[n].key == image_field) {
|
||||||
uint32_t value = xex_header->headers[n].value;
|
uint32_t value = xex_header->headers[n].value;
|
||||||
module->Release();
|
|
||||||
SHIM_SET_RETURN_64(value);
|
SHIM_SET_RETURN_64(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module->Release();
|
|
||||||
SHIM_SET_RETURN_64(0);
|
SHIM_SET_RETURN_64(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue