diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index d9a47d24b..4517a4caf 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -153,12 +153,13 @@ X_STATUS XUserModule::GetOptHeader(xe_xex2_header_keys key, return X_STATUS_UNSUCCESSFUL; } - auto ptr = xex2_get_opt_header(header, key); - if (!ptr) { + uint32_t field_value = + xex2_get_opt_header(memory()->virtual_membase(), header, key); + if (!field_value) { return X_STATUS_NOT_FOUND; } - *out_header_guest_ptr = (uint32_t)(ptr - memory()->virtual_membase()); + *out_header_guest_ptr = field_value; return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 25c5b4fd5..8b4c4fba1 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -29,23 +29,29 @@ namespace xe { namespace kernel { -uint8_t *xex2_get_opt_header(const xex2_header *header, uint32_t key) { +uint32_t xex2_get_opt_header(uint8_t *membase, 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); + switch (opt_header.key & 0xFF) { + case 0x00: + // Return data stored in header value. + return opt_header.value; + case 0x01: + // Return pointer to data stored in header value. + return uint32_t((uint8_t *)&opt_header.value - membase); + default: + // Data stored at offset to header. + return uint32_t((uint8_t *)&header->headers[0] - membase) + + opt_header.offset; } } - return nullptr; + return 0; } uint32_t xex2_get_header_size(const xex2_header *header) { diff --git a/src/xenia/kernel/util/xex2.h b/src/xenia/kernel/util/xex2.h index 87999ae98..b91524798 100644 --- a/src/xenia/kernel/util/xex2.h +++ b/src/xenia/kernel/util/xex2.h @@ -15,8 +15,8 @@ namespace xe { namespace kernel { -uint8_t* xex2_get_opt_header(const xex2_header* header, uint32_t key); - +uint32_t xex2_get_opt_header(uint8_t* membase, const xex2_header* header, + uint32_t key); uint32_t xex2_get_header_size(const xex2_header* header); } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 1a53429f3..7184090de 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -394,12 +394,9 @@ SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_context, return; } - uint8_t* field_ptr = xex2_get_opt_header(header, image_field); - if (!field_ptr) { - SHIM_SET_RETURN_32(0); - return; - } - SHIM_SET_RETURN_32(uint32_t(field_ptr - kernel_memory()->virtual_membase())); + uint32_t field_value = + xex2_get_opt_header(SHIM_MEM_BASE, header, image_field); + SHIM_SET_RETURN_32(field_value); } // Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one