diff --git a/src/kernel/modules/xboxkrnl/kernel_state.cc b/src/kernel/modules/xboxkrnl/kernel_state.cc index dcc1e39d7..d9c7facde 100644 --- a/src/kernel/modules/xboxkrnl/kernel_state.cc +++ b/src/kernel/modules/xboxkrnl/kernel_state.cc @@ -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::iterator it = all_objects.begin(); it != all_objects.end(); ++it) { @@ -90,6 +100,9 @@ XObject* KernelState::GetObject(X_HANDLE handle) { std::tr1::unordered_map::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(handle, obj)); + switch (obj->type()) { + case XObject::kTypeModule: + modules_.insert(std::pair( + handle, static_cast(obj))); + break; + case XObject::kTypeThread: + threads_.insert(std::pair( + handle, static_cast(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::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(); + } +} diff --git a/src/kernel/modules/xboxkrnl/kernel_state.h b/src/kernel/modules/xboxkrnl/kernel_state.h index 1e630f465..475b6e4f1 100644 --- a/src/kernel/modules/xboxkrnl/kernel_state.h +++ b/src/kernel/modules/xboxkrnl/kernel_state.h @@ -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 processor_; + XModule* executable_module_; + xe_mutex_t* objects_mutex_; X_HANDLE next_handle_; std::tr1::unordered_map objects_; + std::tr1::unordered_map modules_; + std::tr1::unordered_map threads_; friend class XObject; }; diff --git a/src/kernel/modules/xboxkrnl/objects/xmodule.cc b/src/kernel/modules/xboxkrnl/objects/xmodule.cc index c7fd3ce7e..5809fca11 100644 --- a/src/kernel/modules/xboxkrnl/objects/xmodule.cc +++ b/src/kernel/modules/xboxkrnl/objects/xmodule.cc @@ -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; diff --git a/src/kernel/modules/xboxkrnl/xboxkrnl_module.cc b/src/kernel/modules/xboxkrnl/xboxkrnl_module.cc index 51645b08b..8b45a2f00 100644 --- a/src/kernel/modules/xboxkrnl/xboxkrnl_module.cc +++ b/src/kernel/modules/xboxkrnl/xboxkrnl_module.cc @@ -13,6 +13,7 @@ #include #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 }