Shuffle some code around.

This commit is contained in:
Dr. Chat
2015-06-29 00:48:24 -05:00
parent e44ac54eed
commit fe87c08424
5 changed files with 162 additions and 37 deletions

View File

@@ -21,6 +21,8 @@
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/objects/xmodule.h"
#include "third_party/crypto/rijndael-alg-fst.h"
namespace xe {
namespace cpu {
@@ -45,6 +47,74 @@ XexModule::XexModule(Processor* processor, KernelState* kernel_state)
XexModule::~XexModule() { xe_xex2_dealloc(xex_); }
bool XexModule::GetOptHeader(const xex2_header* header, xe_xex2_header_keys key,
void** out_ptr) {
assert_not_null(header);
assert_not_null(out_ptr);
for (uint32_t i = 0; i < header->header_count; i++) {
const xex2_opt_header& opt_header = header->headers[i];
if (opt_header.key == key) {
// Match!
switch (key & 0xFF) {
case 0x00: {
// We just return the value of the optional header.
*out_ptr = (void*)((uint64_t)opt_header.value);
} break;
case 0x01: {
// Pointer to the value on the optional header.
*out_ptr = (void*)&opt_header.value;
} break;
default: {
// Pointer to the header.
*out_ptr = (void*)((uint8_t*)header + opt_header.offset);
} break;
}
return true;
}
}
return false;
}
bool XexModule::ApplyPatch(XexModule* module) {
auto header = reinterpret_cast<const xex2_header*>(module->xex_header());
if (!(header->module_flags &
(XEX_MODULE_MODULE_PATCH | XEX_MODULE_PATCH_DELTA |
XEX_MODULE_PATCH_FULL))) {
// This isn't a XEX2 patch.
return false;
}
// Grab the delta descriptor and get to work.
xex2_opt_delta_patch_descriptor* patch_header = nullptr;
GetOptHeader(header, XEX_HEADER_DELTA_PATCH_DESCRIPTOR,
(void**)&patch_header);
assert_not_null(patch_header);
// TODO!
return true;
}
bool XexModule::Load(const std::string& name, const std::string& path,
const void* xex_addr, size_t xex_length) {
// TODO: Move loading code here
xex_ = xe_xex2_load(memory(), xex_addr, xex_length, {0});
if (!xex_) {
return false;
}
// Make a copy of the xex header.
auto src_header = reinterpret_cast<const xex2_header*>(xex_addr);
xex_header_ = (xex2_header*)new char[src_header->header_size];
std::memcpy(xex_header_, src_header, src_header->header_size);
return Load(name, path, xex_);
}
bool XexModule::Load(const std::string& name, const std::string& path,
xe_xex2_ref xex) {
xex_ = xex;

View File

@@ -14,6 +14,7 @@
#include "xenia/cpu/module.h"
#include "xenia/kernel/util/xex2.h"
#include "xenia/kernel/util/xex2_info.h"
namespace xe {
@@ -32,7 +33,17 @@ class XexModule : public xe::cpu::Module {
virtual ~XexModule();
xe_xex2_ref xex() const { return xex_; }
const xex2_header* xex_header() const { return xex_header_; }
// Gets an optional header. Returns NULL if not found.
// Special case: if key & 0xFF == 0x00, this function will return the value,
// not a pointer!
static bool GetOptHeader(const xex2_header* header, xe_xex2_header_keys key,
void** out_ptr);
bool ApplyPatch(XexModule* module);
bool Load(const std::string& name, const std::string& path,
const void* xex_addr, size_t xex_length);
bool Load(const std::string& name, const std::string& path, xe_xex2_ref xex);
const std::string& name() const override { return name_; }
@@ -50,6 +61,7 @@ class XexModule : public xe::cpu::Module {
std::string name_;
std::string path_;
xe_xex2_ref xex_;
xex2_header* xex_header_;
uint32_t base_address_;
uint32_t low_address_;