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