diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index e52d2d319..b4de37959 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -22,14 +22,9 @@ namespace kernel { using namespace xe::cpu; XUserModule::XUserModule(KernelState* kernel_state, const char* path) - : XModule(kernel_state, ModuleType::kUserModule, path), - xex_(nullptr), - execution_info_ptr_(0) {} + : XModule(kernel_state, ModuleType::kUserModule, path), xex_(nullptr) {} -XUserModule::~XUserModule() { - kernel_state()->memory()->SystemHeapFree(execution_info_ptr_); - xe_xex2_dealloc(xex_); -} +XUserModule::~XUserModule() { xe_xex2_dealloc(xex_); } xe_xex2_ref XUserModule::xex() { return xex_; } @@ -114,7 +109,7 @@ X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) { auto ldr_data = memory()->TranslateVirtual(hmodule_ptr_); - ldr_data->dll_base = 0; // GetProcAddress will read this. + ldr_data->dll_base = 0; // GetProcAddress will read this. ldr_data->xex_header_base = xex_header_; // Prepare the module for execution. @@ -156,6 +151,24 @@ X_STATUS XUserModule::GetSection(const char* name, uint32_t* out_section_data, return X_STATUS_UNSUCCESSFUL; } +X_STATUS XUserModule::GetOptHeader(xe_xex2_header_keys key, + uint32_t* out_header_guest_ptr) { + assert_not_null(out_header_guest_ptr); + + auto header = memory()->TranslateVirtual(xex_header_); + if (!header) { + return X_STATUS_UNSUCCESSFUL; + } + + auto ptr = xex2_get_opt_header(header, key); + if (!ptr) { + return X_STATUS_NOT_FOUND; + } + + *out_header_guest_ptr = (uint32_t)(ptr - memory()->virtual_membase()); + return X_STATUS_SUCCESS; +} + X_STATUS XUserModule::Launch(uint32_t flags) { const xe_xex2_header_t* header = xex_header(); diff --git a/src/xenia/kernel/objects/xuser_module.h b/src/xenia/kernel/objects/xuser_module.h index 03ad4c389..3026a02a7 100644 --- a/src/xenia/kernel/objects/xuser_module.h +++ b/src/xenia/kernel/objects/xuser_module.h @@ -35,6 +35,7 @@ class XUserModule : public XModule { uint32_t GetProcAddressByName(const char* name) override; X_STATUS GetSection(const char* name, uint32_t* out_section_data, uint32_t* out_section_size) override; + X_STATUS GetOptHeader(xe_xex2_header_keys key, uint32_t* out_header_guest_ptr); X_STATUS Launch(uint32_t flags); diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 36f17fb4b..2eea304be 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -29,7 +29,26 @@ namespace xe { namespace kernel { -uint32_t xex2_get_header_size(const xex2_header* header) { +uint8_t* xex2_get_opt_header(const xex2_header* header, uint32_t key) { + for (uint32_t i = 0; i < header->header_count; i++) { + const xex2_opt_header& opt_header = header->headers[i]; + if (opt_header.key != key) { + continue; + } + + if ((opt_header.key & 0xFF) == 0x01) { + // Data is stored in the opt header + return (uint8_t*)&opt_header.value; + } else { + // Data stored at offset. + return ((uint8_t*)&header->headers[0] + opt_header.offset); + } + } + + return nullptr; +} + +uint32_t xex2_get_header_size(const xex2_header *header) { return header->exe_offset; } } // namespace kernel diff --git a/src/xenia/kernel/util/xex2.h b/src/xenia/kernel/util/xex2.h index 82380daee..87999ae98 100644 --- a/src/xenia/kernel/util/xex2.h +++ b/src/xenia/kernel/util/xex2.h @@ -15,29 +15,11 @@ namespace xe { namespace kernel { -template -T* xex2_get_opt_header(const xex2_header* header, uint32_t key) { - for (uint32_t i = 0; i < header->header_count; i++) { - const xex2_opt_header& opt_header = header->headers[i]; - if (opt_header.key != key) { - continue; - } - - if ((opt_header.key & 0xFF) == 0x01) { - // Data is stored in the opt header - return (T*)&opt_header.value; - } else { - // Data stored at offset. - return (T*)((uint8_t*)&header->headers[0] + opt_header.offset); - } - } - - return nullptr; -} +uint8_t* xex2_get_opt_header(const xex2_header* header, uint32_t key); uint32_t xex2_get_header_size(const xex2_header* header); -} // namespace kernel -} // namespace xe +} // namespace kernel +} // namespace xe typedef struct { int reserved; } xe_xex2_options_t; diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index 7121d056e..e2cc7de17 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -77,9 +77,16 @@ SHIM_CALL XamGetExecutionId_shim(PPCContext* ppc_context, auto module = kernel_state->GetExecutableModule(); assert_not_null(module); - SHIM_SET_MEM_32(info_ptr, module->execution_info_ptr()); + uint32_t guest_hdr_ptr; + X_STATUS result = module->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &guest_hdr_ptr); - SHIM_SET_RETURN_32(0); + if (XFAILED(result)) { + SHIM_SET_RETURN_32(result); + return; + } + + SHIM_SET_MEM_32(info_ptr, guest_hdr_ptr); + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } SHIM_CALL XamLoaderSetLaunchData_shim(PPCContext* ppc_context,