2014-01-12 01:24:09 +00:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
|
|
******************************************************************************
|
|
|
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
|
2015-09-07 01:07:52 +00:00
|
|
|
#ifndef XENIA_KERNEL_USER_MODULE_H_
|
|
|
|
#define XENIA_KERNEL_USER_MODULE_H_
|
2014-01-12 01:24:09 +00:00
|
|
|
|
2015-05-09 07:56:42 +00:00
|
|
|
#include <string>
|
2014-01-12 01:24:09 +00:00
|
|
|
|
2015-05-02 09:11:11 +00:00
|
|
|
#include "xenia/cpu/export_resolver.h"
|
2015-06-29 06:39:07 +00:00
|
|
|
#include "xenia/cpu/xex_module.h"
|
|
|
|
#include "xenia/kernel/util/xex2_info.h"
|
2015-09-07 01:07:52 +00:00
|
|
|
#include "xenia/kernel/xmodule.h"
|
2015-02-01 06:49:47 +00:00
|
|
|
#include "xenia/xbox.h"
|
2014-01-12 01:24:09 +00:00
|
|
|
|
|
|
|
namespace xe {
|
2015-08-16 07:52:47 +00:00
|
|
|
namespace cpu {
|
|
|
|
class XexModule;
|
|
|
|
class ElfModule;
|
|
|
|
} // namespace cpu
|
2015-12-01 23:25:47 +00:00
|
|
|
namespace kernel {
|
|
|
|
class XThread;
|
|
|
|
} // namespace kernel
|
2015-09-07 01:07:52 +00:00
|
|
|
} // namespace xe
|
2015-08-16 07:52:47 +00:00
|
|
|
|
2015-09-07 01:07:52 +00:00
|
|
|
namespace xe {
|
2014-01-12 01:24:09 +00:00
|
|
|
namespace kernel {
|
|
|
|
|
2015-09-07 01:07:52 +00:00
|
|
|
class UserModule : public XModule {
|
2014-08-17 20:13:03 +00:00
|
|
|
public:
|
2015-12-28 19:25:04 +00:00
|
|
|
UserModule(KernelState* kernel_state);
|
2015-09-07 01:07:52 +00:00
|
|
|
~UserModule() override;
|
2014-01-12 01:24:09 +00:00
|
|
|
|
2015-08-16 07:52:47 +00:00
|
|
|
enum ModuleFormat {
|
|
|
|
kModuleFormatUndefined = 0,
|
|
|
|
kModuleFormatXex,
|
|
|
|
kModuleFormatElf,
|
|
|
|
};
|
|
|
|
|
2015-06-29 05:48:24 +00:00
|
|
|
const xe::cpu::XexModule* xex_module() const {
|
2015-08-16 07:52:47 +00:00
|
|
|
assert_true(module_format_ == kModuleFormatXex);
|
2015-06-29 05:48:24 +00:00
|
|
|
return reinterpret_cast<xe::cpu::XexModule*>(processor_module_);
|
|
|
|
}
|
2015-07-05 19:03:00 +00:00
|
|
|
xe::cpu::XexModule* xex_module() {
|
2015-08-16 07:52:47 +00:00
|
|
|
assert_true(module_format_ == kModuleFormatXex);
|
2015-07-05 19:03:00 +00:00
|
|
|
return reinterpret_cast<xe::cpu::XexModule*>(processor_module_);
|
|
|
|
}
|
2014-01-12 01:24:09 +00:00
|
|
|
|
2015-06-29 06:39:07 +00:00
|
|
|
const xex2_header* xex_header() const { return xex_module()->xex_header(); }
|
2015-07-03 03:00:45 +00:00
|
|
|
uint32_t guest_xex_header() const { return guest_xex_header_; }
|
2015-12-31 06:58:22 +00:00
|
|
|
// The title ID in the xex header or 0 if this is not a xex.
|
|
|
|
uint32_t title_id() const;
|
2016-10-24 16:00:22 +00:00
|
|
|
bool is_executable() const { return processor_module_->is_executable(); }
|
2015-12-31 06:58:22 +00:00
|
|
|
bool is_dll_module() const { return is_dll_module_; }
|
2015-06-29 06:39:07 +00:00
|
|
|
|
|
|
|
uint32_t entry_point() const { return entry_point_; }
|
|
|
|
uint32_t stack_size() const { return stack_size_; }
|
|
|
|
|
2015-05-09 07:56:42 +00:00
|
|
|
X_STATUS LoadFromFile(std::string path);
|
2015-08-30 02:35:43 +00:00
|
|
|
X_STATUS LoadFromMemory(const void* addr, const size_t length);
|
2015-07-05 19:03:00 +00:00
|
|
|
X_STATUS Unload();
|
2014-01-12 01:24:09 +00:00
|
|
|
|
2015-05-06 01:52:37 +00:00
|
|
|
uint32_t GetProcAddressByOrdinal(uint16_t ordinal) override;
|
|
|
|
uint32_t GetProcAddressByName(const char* name) override;
|
|
|
|
X_STATUS GetSection(const char* name, uint32_t* out_section_data,
|
|
|
|
uint32_t* out_section_size) override;
|
2015-06-28 21:01:53 +00:00
|
|
|
|
2015-07-03 03:00:45 +00:00
|
|
|
// Get optional header - FOR HOST USE ONLY!
|
[CPU] Move XEX2 code into XexModule class, autodetect XEX key
Code is mainly just copy/pasted from kernel/util/xex2.cc, I've tried fixing it up to work better in a class, but there's probably some things I missed.
Also includes some minor improvements to the XEX loader, like being able to try both XEX keys (retail/devkit) automatically, and some fixes to how the base address is determined.
(Previously there was code that would get base address from optional header, code that'd get it from xex_security_info, code that'd use a stored base address value...
Now everything reads it from a single stored value instead, which is set either from the xex_security_info, or if it exists from the optional header instead.
Maybe this can help improve compatibility with any weird XEX's that don't have a base address optional header?)
Compressed XEX loader also has some extra checks to make sure the compressed data hash matches what's expected.
Might increase loading times by a fraction, but could save reports from people unknowingly using corrupt XEXs.
(still no checks for non-compressed data though, maybe need to compare data with xex_security_info->ImageHash?)
2018-10-20 03:18:18 +00:00
|
|
|
X_STATUS GetOptHeader(xex2_header_keys key, void** out_ptr);
|
2015-06-29 06:39:07 +00:00
|
|
|
|
2015-07-03 15:24:11 +00:00
|
|
|
// Get optional header - FOR HOST USE ONLY!
|
|
|
|
template <typename T>
|
[CPU] Move XEX2 code into XexModule class, autodetect XEX key
Code is mainly just copy/pasted from kernel/util/xex2.cc, I've tried fixing it up to work better in a class, but there's probably some things I missed.
Also includes some minor improvements to the XEX loader, like being able to try both XEX keys (retail/devkit) automatically, and some fixes to how the base address is determined.
(Previously there was code that would get base address from optional header, code that'd get it from xex_security_info, code that'd use a stored base address value...
Now everything reads it from a single stored value instead, which is set either from the xex_security_info, or if it exists from the optional header instead.
Maybe this can help improve compatibility with any weird XEX's that don't have a base address optional header?)
Compressed XEX loader also has some extra checks to make sure the compressed data hash matches what's expected.
Might increase loading times by a fraction, but could save reports from people unknowingly using corrupt XEXs.
(still no checks for non-compressed data though, maybe need to compare data with xex_security_info->ImageHash?)
2018-10-20 03:18:18 +00:00
|
|
|
X_STATUS GetOptHeader(xex2_header_keys key, T* out_ptr) {
|
2015-07-03 15:24:11 +00:00
|
|
|
return GetOptHeader(key, reinterpret_cast<void**>(out_ptr));
|
|
|
|
}
|
|
|
|
|
2015-07-03 03:00:45 +00:00
|
|
|
// Get optional header that can safely be returned to guest code.
|
[CPU] Move XEX2 code into XexModule class, autodetect XEX key
Code is mainly just copy/pasted from kernel/util/xex2.cc, I've tried fixing it up to work better in a class, but there's probably some things I missed.
Also includes some minor improvements to the XEX loader, like being able to try both XEX keys (retail/devkit) automatically, and some fixes to how the base address is determined.
(Previously there was code that would get base address from optional header, code that'd get it from xex_security_info, code that'd use a stored base address value...
Now everything reads it from a single stored value instead, which is set either from the xex_security_info, or if it exists from the optional header instead.
Maybe this can help improve compatibility with any weird XEX's that don't have a base address optional header?)
Compressed XEX loader also has some extra checks to make sure the compressed data hash matches what's expected.
Might increase loading times by a fraction, but could save reports from people unknowingly using corrupt XEXs.
(still no checks for non-compressed data though, maybe need to compare data with xex_security_info->ImageHash?)
2018-10-20 03:18:18 +00:00
|
|
|
X_STATUS GetOptHeader(xex2_header_keys key, uint32_t* out_header_guest_ptr);
|
2015-06-28 21:01:53 +00:00
|
|
|
static X_STATUS GetOptHeader(uint8_t* membase, const xex2_header* header,
|
[CPU] Move XEX2 code into XexModule class, autodetect XEX key
Code is mainly just copy/pasted from kernel/util/xex2.cc, I've tried fixing it up to work better in a class, but there's probably some things I missed.
Also includes some minor improvements to the XEX loader, like being able to try both XEX keys (retail/devkit) automatically, and some fixes to how the base address is determined.
(Previously there was code that would get base address from optional header, code that'd get it from xex_security_info, code that'd use a stored base address value...
Now everything reads it from a single stored value instead, which is set either from the xex_security_info, or if it exists from the optional header instead.
Maybe this can help improve compatibility with any weird XEX's that don't have a base address optional header?)
Compressed XEX loader also has some extra checks to make sure the compressed data hash matches what's expected.
Might increase loading times by a fraction, but could save reports from people unknowingly using corrupt XEXs.
(still no checks for non-compressed data though, maybe need to compare data with xex_security_info->ImageHash?)
2018-10-20 03:18:18 +00:00
|
|
|
xex2_header_keys key,
|
2015-06-28 21:01:53 +00:00
|
|
|
uint32_t* out_header_guest_ptr);
|
2014-01-12 01:24:09 +00:00
|
|
|
|
|
|
|
void Dump();
|
|
|
|
|
2015-12-06 01:37:48 +00:00
|
|
|
bool Save(ByteStream* stream) override;
|
|
|
|
static object_ref<UserModule> Restore(KernelState* kernel_state,
|
|
|
|
ByteStream* stream, std::string path);
|
|
|
|
|
2014-08-17 20:13:03 +00:00
|
|
|
private:
|
2018-10-20 03:36:21 +00:00
|
|
|
X_STATUS LoadXexContinue();
|
|
|
|
|
2015-08-16 07:52:47 +00:00
|
|
|
uint32_t guest_xex_header_ = 0;
|
|
|
|
ModuleFormat module_format_ = kModuleFormatUndefined;
|
2015-06-29 06:39:07 +00:00
|
|
|
|
2015-12-31 06:58:22 +00:00
|
|
|
bool is_dll_module_ = false;
|
2015-09-07 01:07:52 +00:00
|
|
|
uint32_t entry_point_ = 0;
|
|
|
|
uint32_t stack_size_ = 0;
|
2014-01-12 01:24:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace kernel
|
|
|
|
} // namespace xe
|
|
|
|
|
2015-09-07 01:07:52 +00:00
|
|
|
#endif // XENIA_KERNEL_USER_MODULE_H_
|