Better module handling.

This commit is contained in:
Ben Vanik 2013-01-31 11:27:05 -08:00
parent 9cfc01940e
commit c77bcbf879
4 changed files with 104 additions and 24 deletions

View File

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

View File

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

View File

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

View File

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