Better module handling.
This commit is contained in:
parent
9cfc01940e
commit
c77bcbf879
|
@ -10,6 +10,8 @@
|
||||||
#include "kernel/modules/xboxkrnl/kernel_state.h"
|
#include "kernel/modules/xboxkrnl/kernel_state.h"
|
||||||
|
|
||||||
#include "kernel/modules/xboxkrnl/xobject.h"
|
#include "kernel/modules/xboxkrnl/xobject.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/objects/xmodule.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/objects/xthread.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
|
@ -24,6 +26,7 @@ namespace {
|
||||||
|
|
||||||
KernelState::KernelState(Runtime* runtime) :
|
KernelState::KernelState(Runtime* runtime) :
|
||||||
runtime_(runtime),
|
runtime_(runtime),
|
||||||
|
executable_module_(NULL),
|
||||||
next_handle_(0) {
|
next_handle_(0) {
|
||||||
pal_ = runtime->pal();
|
pal_ = runtime->pal();
|
||||||
memory_ = runtime->memory();
|
memory_ = runtime->memory();
|
||||||
|
@ -34,6 +37,11 @@ KernelState::KernelState(Runtime* runtime) :
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelState::~KernelState() {
|
KernelState::~KernelState() {
|
||||||
|
if (executable_module_) {
|
||||||
|
executable_module_->Release();
|
||||||
|
executable_module_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete all objects.
|
// Delete all objects.
|
||||||
// We first copy the list to another list so that the deletion of the objects
|
// We first copy the list to another list so that the deletion of the objects
|
||||||
// doesn't mess up iteration.
|
// doesn't mess up iteration.
|
||||||
|
@ -44,6 +52,8 @@ KernelState::~KernelState() {
|
||||||
all_objects.push_back(it->second);
|
all_objects.push_back(it->second);
|
||||||
}
|
}
|
||||||
objects_.clear();
|
objects_.clear();
|
||||||
|
modules_.clear();
|
||||||
|
threads_.clear();
|
||||||
xe_mutex_unlock(objects_mutex_);
|
xe_mutex_unlock(objects_mutex_);
|
||||||
for (std::vector<XObject*>::iterator it = all_objects.begin();
|
for (std::vector<XObject*>::iterator it = all_objects.begin();
|
||||||
it != all_objects.end(); ++it) {
|
it != all_objects.end(); ++it) {
|
||||||
|
@ -90,6 +100,9 @@ XObject* KernelState::GetObject(X_HANDLE handle) {
|
||||||
std::tr1::unordered_map<X_HANDLE, XObject*>::iterator it =
|
std::tr1::unordered_map<X_HANDLE, XObject*>::iterator it =
|
||||||
objects_.find(handle);
|
objects_.find(handle);
|
||||||
XObject* value = it != objects_.end() ? it->second : NULL;
|
XObject* value = it != objects_.end() ? it->second : NULL;
|
||||||
|
if (value) {
|
||||||
|
value->Retain();
|
||||||
|
}
|
||||||
xe_mutex_unlock(objects_mutex_);
|
xe_mutex_unlock(objects_mutex_);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +111,16 @@ X_HANDLE KernelState::InsertObject(XObject* obj) {
|
||||||
xe_mutex_lock(objects_mutex_);
|
xe_mutex_lock(objects_mutex_);
|
||||||
X_HANDLE handle = 0x00001000 + (++next_handle_);
|
X_HANDLE handle = 0x00001000 + (++next_handle_);
|
||||||
objects_.insert(std::pair<X_HANDLE, XObject*>(handle, obj));
|
objects_.insert(std::pair<X_HANDLE, XObject*>(handle, obj));
|
||||||
|
switch (obj->type()) {
|
||||||
|
case XObject::kTypeModule:
|
||||||
|
modules_.insert(std::pair<X_HANDLE, XModule*>(
|
||||||
|
handle, static_cast<XModule*>(obj)));
|
||||||
|
break;
|
||||||
|
case XObject::kTypeThread:
|
||||||
|
threads_.insert(std::pair<X_HANDLE, XThread*>(
|
||||||
|
handle, static_cast<XThread*>(obj)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
xe_mutex_unlock(objects_mutex_);
|
xe_mutex_unlock(objects_mutex_);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -107,3 +130,35 @@ void KernelState::RemoveObject(XObject* obj) {
|
||||||
objects_.erase(obj->handle());
|
objects_.erase(obj->handle());
|
||||||
xe_mutex_unlock(objects_mutex_);
|
xe_mutex_unlock(objects_mutex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XModule* KernelState::GetModule(const char* name) {
|
||||||
|
XModule* found = NULL;
|
||||||
|
xe_mutex_lock(objects_mutex_);
|
||||||
|
for (std::tr1::unordered_map<X_HANDLE, XModule*>::iterator it =
|
||||||
|
modules_.begin(); it != modules_.end(); ++it) {
|
||||||
|
if (xestrcmpa(name, it->second->name()) == 0) {
|
||||||
|
found = it->second;
|
||||||
|
found->Retain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xe_mutex_unlock(objects_mutex_);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
XModule* KernelState::GetExecutableModule() {
|
||||||
|
if (executable_module_) {
|
||||||
|
executable_module_->Retain();
|
||||||
|
return executable_module_;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernelState::SetExecutableModule(XModule* module) {
|
||||||
|
if (executable_module_ && executable_module_ != module) {
|
||||||
|
executable_module_->Release();
|
||||||
|
}
|
||||||
|
executable_module_ = module;
|
||||||
|
if (executable_module_) {
|
||||||
|
executable_module_->Retain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ namespace xboxkrnl {
|
||||||
|
|
||||||
|
|
||||||
class XObject;
|
class XObject;
|
||||||
|
class XModule;
|
||||||
|
class XThread;
|
||||||
|
|
||||||
|
|
||||||
class KernelState {
|
class KernelState {
|
||||||
|
@ -31,13 +33,17 @@ public:
|
||||||
KernelState(Runtime* runtime);
|
KernelState(Runtime* runtime);
|
||||||
~KernelState();
|
~KernelState();
|
||||||
|
|
||||||
XObject* GetObject(X_HANDLE handle);
|
|
||||||
|
|
||||||
Runtime* runtime();
|
Runtime* runtime();
|
||||||
xe_pal_ref pal();
|
xe_pal_ref pal();
|
||||||
xe_memory_ref memory();
|
xe_memory_ref memory();
|
||||||
cpu::Processor* processor();
|
cpu::Processor* processor();
|
||||||
|
|
||||||
|
XObject* GetObject(X_HANDLE handle);
|
||||||
|
|
||||||
|
XModule* GetModule(const char* name);
|
||||||
|
XModule* GetExecutableModule();
|
||||||
|
void SetExecutableModule(XModule* module);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
X_HANDLE InsertObject(XObject* obj);
|
X_HANDLE InsertObject(XObject* obj);
|
||||||
void RemoveObject(XObject* obj);
|
void RemoveObject(XObject* obj);
|
||||||
|
@ -47,9 +53,13 @@ private:
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
shared_ptr<cpu::Processor> processor_;
|
shared_ptr<cpu::Processor> processor_;
|
||||||
|
|
||||||
|
XModule* executable_module_;
|
||||||
|
|
||||||
xe_mutex_t* objects_mutex_;
|
xe_mutex_t* objects_mutex_;
|
||||||
X_HANDLE next_handle_;
|
X_HANDLE next_handle_;
|
||||||
std::tr1::unordered_map<X_HANDLE, XObject*> objects_;
|
std::tr1::unordered_map<X_HANDLE, XObject*> objects_;
|
||||||
|
std::tr1::unordered_map<X_HANDLE, XModule*> modules_;
|
||||||
|
std::tr1::unordered_map<X_HANDLE, XThread*> threads_;
|
||||||
|
|
||||||
friend class XObject;
|
friend class XObject;
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,8 +93,8 @@ void* XModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||||
X_STATUS XModule::Launch(uint32_t flags) {
|
X_STATUS XModule::Launch(uint32_t flags) {
|
||||||
const xe_xex2_header_t* header = xex_header();
|
const xe_xex2_header_t* header = xex_header();
|
||||||
|
|
||||||
// TODO(benvanik): set as main module/etc
|
// Set as the main module, while running.
|
||||||
// xekXexExecutableModuleHandle = xe_module_get_handle(module);
|
kernel_state()->SetExecutableModule(this);
|
||||||
|
|
||||||
// Create a thread to run in.
|
// Create a thread to run in.
|
||||||
XThread* thread = new XThread(
|
XThread* thread = new XThread(
|
||||||
|
@ -118,6 +118,7 @@ X_STATUS XModule::Launch(uint32_t flags) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kernel_state()->SetExecutableModule(NULL);
|
||||||
thread->Release();
|
thread->Release();
|
||||||
|
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <xenia/kernel/xex2.h>
|
#include <xenia/kernel/xex2.h>
|
||||||
|
|
||||||
#include "kernel/shim_utils.h"
|
#include "kernel/shim_utils.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/objects/xmodule.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
|
@ -45,19 +46,20 @@ void XexCheckExecutablePrivilege_shim(
|
||||||
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
||||||
uint32_t mask = 1 << privilege;
|
uint32_t mask = 1 << privilege;
|
||||||
|
|
||||||
// TODO(benvanik): pull from xex header:
|
XModule* module = state->GetExecutableModule();
|
||||||
// XEKernelModuleRef module = XEKernelGetExecutableModule(XEGetKernel());
|
if (!module) {
|
||||||
// const XEXHeader* xexhdr = XEKernelModuleGetXEXHeader(module);
|
SHIM_SET_RETURN(0);
|
||||||
// return xexhdr->systemFlags & mask;
|
return;
|
||||||
|
|
||||||
if (mask == XEX_SYSTEM_PAL50_INCOMPATIBLE) {
|
|
||||||
// Only one we've seen.
|
|
||||||
} else {
|
|
||||||
XELOGW(XT("XexCheckExecutablePrivilege: %.8X is NOT IMPLEMENTED"),
|
|
||||||
privilege);
|
|
||||||
}
|
}
|
||||||
|
xe_xex2_ref xex = module->xex();
|
||||||
|
|
||||||
SHIM_SET_RETURN(0);
|
const xe_xex2_header_t* header = xe_xex2_get_header(xex);
|
||||||
|
uint32_t result = (header->system_flags & mask) > 0;
|
||||||
|
|
||||||
|
xe_xex2_release(xex);
|
||||||
|
module->Release();
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,20 +77,30 @@ void XexGetModuleHandle_shim(
|
||||||
XT("XexGetModuleHandle(%s, %.8X)"),
|
XT("XexGetModuleHandle(%s, %.8X)"),
|
||||||
module_name, module_handle_ptr);
|
module_name, module_handle_ptr);
|
||||||
|
|
||||||
XEASSERTALWAYS();
|
XModule* module = state->GetModule(module_name);
|
||||||
|
if (!module) {
|
||||||
// TODO(benvanik): get module
|
|
||||||
// XEKernelModuleRef module = XEKernelGetModuleByName(XEGetKernel(), ModuleName);
|
|
||||||
// if (!module) {
|
|
||||||
SHIM_SET_RETURN(0);
|
SHIM_SET_RETURN(0);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// SHIM_SET_MEM_32(module_handle_ptr, module->handle());
|
// NOTE: we don't retain the handle for return.
|
||||||
// SHIM_SET_RETURN(1);
|
SHIM_SET_MEM_32(module_handle_ptr, module->handle());
|
||||||
|
SHIM_SET_RETURN(1);
|
||||||
|
|
||||||
|
module->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// void XexGetModuleSection_shim(
|
||||||
|
// xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// void XexGetProcedureAddress_shim(
|
||||||
|
// xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,6 +115,8 @@ void xe::kernel::xboxkrnl::RegisterModuleExports(
|
||||||
SHIM_SET_MAPPING(0x00000194, XexCheckExecutablePrivilege_shim, NULL);
|
SHIM_SET_MAPPING(0x00000194, XexCheckExecutablePrivilege_shim, NULL);
|
||||||
|
|
||||||
SHIM_SET_MAPPING(0x00000195, XexGetModuleHandle_shim, NULL);
|
SHIM_SET_MAPPING(0x00000195, XexGetModuleHandle_shim, NULL);
|
||||||
|
// SHIM_SET_MAPPING(0x00000196, XexGetModuleSection_shim, NULL);
|
||||||
|
// SHIM_SET_MAPPING(0x00000197, XexGetProcedureAddress_shim, NULL);
|
||||||
|
|
||||||
#undef SET_MAPPING
|
#undef SET_MAPPING
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue