clang-format on most of kernel/

This commit is contained in:
Ben Vanik
2014-08-17 13:13:03 -07:00
parent 854bcdb60a
commit 1c4dcd5e0e
76 changed files with 2075 additions and 3169 deletions

View File

@@ -9,17 +9,15 @@
#include <xenia/kernel/objects/xenumerator.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::kernel;
XEnumerator::XEnumerator(KernelState* kernel_state)
: XObject(kernel_state, kTypeEnumerator) {}
XEnumerator::~XEnumerator() {}
XEnumerator::XEnumerator(KernelState* kernel_state) :
XObject(kernel_state, kTypeEnumerator) {
}
void XEnumerator::Initialize() {}
XEnumerator::~XEnumerator() {
}
void XEnumerator::Initialize() {
}
} // namespace kernel
} // namespace xe

View File

@@ -11,27 +11,22 @@
#define XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XEnumerator : public XObject {
public:
public:
XEnumerator(KernelState* kernel_state);
virtual ~XEnumerator();
void Initialize();
private:
private:
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_

View File

@@ -9,15 +9,11 @@
#include <xenia/kernel/objects/xevent.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::kernel;
XEvent::XEvent(KernelState* kernel_state) :
XObject(kernel_state, kTypeEvent),
handle_(NULL) {
}
XEvent::XEvent(KernelState* kernel_state)
: XObject(kernel_state, kTypeEvent), handle_(NULL) {}
XEvent::~XEvent() {
if (handle_) {
@@ -36,15 +32,15 @@ void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) {
bool manual_reset;
switch (header.type_flags >> 24) {
case 0x00: // EventNotificationObject (manual reset)
manual_reset = true;
break;
case 0x01: // EventSynchronizationObject (auto reset)
manual_reset = false;
break;
default:
assert_always();
return;
case 0x00: // EventNotificationObject (manual reset)
manual_reset = true;
break;
case 0x01: // EventSynchronizationObject (auto reset)
manual_reset = false;
break;
default:
assert_always();
return;
}
bool initial_state = header.signal_state ? true : false;
@@ -60,10 +56,9 @@ int32_t XEvent::Pulse(uint32_t priority_increment, bool wait) {
return PulseEvent(handle_) ? 1 : 0;
}
int32_t XEvent::Reset() {
return ResetEvent(handle_) ? 1 : 0;
}
int32_t XEvent::Reset() { return ResetEvent(handle_) ? 1 : 0; }
void XEvent::Clear() {
ResetEvent(handle_);
}
void XEvent::Clear() { ResetEvent(handle_); }
} // namespace kernel
} // namespace xe

View File

@@ -11,16 +11,13 @@
#define XENIA_KERNEL_XBOXKRNL_XEVENT_H_
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XEvent : public XObject {
public:
public:
XEvent(KernelState* kernel_state);
virtual ~XEvent();
@@ -34,13 +31,11 @@ public:
virtual void* GetWaitHandle() { return handle_; }
private:
private:
HANDLE handle_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XEVENT_H_

View File

@@ -12,14 +12,11 @@
#include <xenia/kernel/async_request.h>
#include <xenia/kernel/objects/xevent.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::kernel;
XFile::XFile(KernelState* kernel_state, fs::Mode mode) :
mode_(mode), position_(0),
XObject(kernel_state, kTypeFile) {
XFile::XFile(KernelState* kernel_state, fs::Mode mode)
: mode_(mode), position_(0), XObject(kernel_state, kTypeFile) {
async_event_ = new XEvent(kernel_state);
async_event_->Initialize(false, false);
}
@@ -30,9 +27,7 @@ XFile::~XFile() {
async_event_->Delete();
}
void* XFile::GetWaitHandle() {
return async_event_->GetWaitHandle();
}
void* XFile::GetWaitHandle() { return async_event_->GetWaitHandle(); }
X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) {
@@ -40,7 +35,8 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
// Read from current position.
byte_offset = position_;
}
X_STATUS result = ReadSync(buffer, buffer_length, byte_offset, out_bytes_read);
X_STATUS result =
ReadSync(buffer, buffer_length, byte_offset, out_bytes_read);
if (XSUCCEEDED(result)) {
position_ += *out_bytes_read;
}
@@ -52,7 +48,10 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
// Also tack on our event so that any waiters wake.
request->AddWaitEvent(async_event_);
position_ = byte_offset;
//return entry_->ReadAsync(buffer, buffer_length, byte_offset, request);
// return entry_->ReadAsync(buffer, buffer_length, byte_offset, request);
X_STATUS result = X_STATUS_NOT_IMPLEMENTED;
return result;
}
} // namespace kernel
} // namespace xe

View File

@@ -14,7 +14,6 @@
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
@@ -22,14 +21,14 @@ class XAsyncRequest;
class XEvent;
class XFileInfo {
public:
public:
// FILE_NETWORK_OPEN_INFORMATION
uint64_t creation_time;
uint64_t last_access_time;
uint64_t last_write_time;
uint64_t change_time;
uint64_t allocation_size;
uint64_t file_length;
uint64_t creation_time;
uint64_t last_access_time;
uint64_t last_write_time;
uint64_t change_time;
uint64_t allocation_size;
uint64_t file_length;
X_FILE_ATTRIBUTES attributes;
void Write(uint8_t* base, uint32_t p) {
@@ -40,24 +39,24 @@ public:
poly::store_and_swap<uint64_t>(base + p + 32, allocation_size);
poly::store_and_swap<uint64_t>(base + p + 40, file_length);
poly::store_and_swap<uint32_t>(base + p + 48, attributes);
poly::store_and_swap<uint32_t>(base + p + 52, 0); // pad
poly::store_and_swap<uint32_t>(base + p + 52, 0); // pad
}
};
class XDirectoryInfo {
public:
public:
// FILE_DIRECTORY_INFORMATION
uint32_t next_entry_offset;
uint32_t file_index;
uint64_t creation_time;
uint64_t last_access_time;
uint64_t last_write_time;
uint64_t change_time;
uint64_t end_of_file;
uint64_t allocation_size;
uint32_t next_entry_offset;
uint32_t file_index;
uint64_t creation_time;
uint64_t last_access_time;
uint64_t last_write_time;
uint64_t change_time;
uint64_t end_of_file;
uint64_t allocation_size;
X_FILE_ATTRIBUTES attributes;
uint32_t file_name_length;
char file_name[1];
uint32_t file_name_length;
char file_name[1];
void Write(uint8_t* base, uint32_t p) {
uint8_t* dst = base + p;
@@ -75,7 +74,8 @@ public:
poly::store_and_swap<uint64_t>(dst + 48, info->allocation_size);
poly::store_and_swap<uint32_t>(dst + 56, info->attributes);
poly::store_and_swap<uint32_t>(dst + 60, info->file_name_length);
xe_copy_memory(dst + 64, info->file_name_length, info->file_name, info->file_name_length);
xe_copy_memory(dst + 64, info->file_name_length, info->file_name,
info->file_name_length);
dst += info->next_entry_offset;
src += info->next_entry_offset;
} while (info->next_entry_offset != 0);
@@ -85,13 +85,13 @@ static_assert_size(XDirectoryInfo, 72);
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff540287(v=vs.85).aspx
class XVolumeInfo {
public:
public:
// FILE_FS_VOLUME_INFORMATION
uint64_t creation_time;
uint32_t serial_number;
uint32_t label_length;
uint32_t supports_objects;
char label[1];
uint64_t creation_time;
uint32_t serial_number;
uint32_t label_length;
uint32_t supports_objects;
char label[1];
void Write(uint8_t* base, uint32_t p) {
uint8_t* dst = base + p;
@@ -99,32 +99,35 @@ public:
poly::store_and_swap<uint32_t>(dst + 8, this->serial_number);
poly::store_and_swap<uint32_t>(dst + 12, this->label_length);
poly::store_and_swap<uint32_t>(dst + 16, this->supports_objects);
xe_copy_memory(dst + 20, this->label_length, this->label, this->label_length);
xe_copy_memory(dst + 20, this->label_length, this->label,
this->label_length);
}
};
static_assert_size(XVolumeInfo, 24);
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff540251(v=vs.85).aspx
class XFileSystemAttributeInfo {
public:
public:
// FILE_FS_ATTRIBUTE_INFORMATION
uint32_t attributes;
int32_t maximum_component_name_length;
uint32_t fs_name_length;
char fs_name[1];
uint32_t attributes;
int32_t maximum_component_name_length;
uint32_t fs_name_length;
char fs_name[1];
void Write(uint8_t* base, uint32_t p) {
uint8_t* dst = base + p;
poly::store_and_swap<uint32_t>(dst + 0, this->attributes);
poly::store_and_swap<uint32_t>(dst + 4, this->maximum_component_name_length);
poly::store_and_swap<uint32_t>(dst + 4,
this->maximum_component_name_length);
poly::store_and_swap<uint32_t>(dst + 8, this->fs_name_length);
xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name, this->fs_name_length);
xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name,
this->fs_name_length);
}
};
static_assert_size(XFileSystemAttributeInfo, 16);
class XFile : public XObject {
public:
public:
virtual ~XFile();
virtual const std::string& path() const = 0;
@@ -148,24 +151,21 @@ public:
virtual void* GetWaitHandle();
protected:
protected:
XFile(KernelState* kernel_state, fs::Mode mode);
virtual X_STATUS ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) = 0;
virtual X_STATUS ReadSync(void* buffer, size_t buffer_length,
size_t byte_offset, size_t* out_bytes_read) = 0;
private:
fs::Mode mode_;
XEvent* async_event_;
private:
fs::Mode mode_;
XEvent* async_event_;
// TODO(benvanik): create flags, open state, etc.
size_t position_;
size_t position_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XFILE_H_

View File

@@ -13,14 +13,11 @@
#include <xenia/cpu/cpu.h>
#include <xenia/kernel/objects/xthread.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;
XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) :
XModule(kernel_state, path) {
XKernelModule::XKernelModule(KernelState* kernel_state, const char* path)
: XModule(kernel_state, path) {
emulator_ = kernel_state->emulator();
memory_ = emulator_->memory();
export_resolver_ = kernel_state->emulator()->export_resolver();
@@ -28,11 +25,13 @@ XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) :
OnLoad();
}
XKernelModule::~XKernelModule() {
}
XKernelModule::~XKernelModule() {}
void* XKernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
// TODO(benvanik): check export tables.
XELOGE("GetProcAddressByOrdinal not implemented");
return NULL;
}
} // namespace kernel
} // namespace xe

View File

@@ -14,29 +14,26 @@
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS1(xe, ExportResolver);
XEDECLARECLASS2(xe, kernel, KernelState);
namespace xe {
namespace kernel {
class KernelState;
class XKernelModule : public XModule {
public:
public:
XKernelModule(KernelState* kernel_state, const char* path);
virtual ~XKernelModule();
virtual void* GetProcAddressByOrdinal(uint16_t ordinal);
protected:
Emulator* emulator_;
Memory* memory_;
ExportResolver* export_resolver_;
protected:
Emulator* emulator_;
Memory* memory_;
ExportResolver* export_resolver_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XKERNEL_MODULE_H_

View File

@@ -11,14 +11,11 @@
#include <xdb/protocol.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;
XModule::XModule(KernelState* kernel_state, const std::string& path) :
XObject(kernel_state, kTypeModule), path_(path) {
XModule::XModule(KernelState* kernel_state, const std::string& path)
: XObject(kernel_state, kTypeModule), path_(path) {
auto last_slash = path.find_last_of('/');
if (last_slash == path.npos) {
last_slash = path.find_last_of('\\');
@@ -54,8 +51,10 @@ void XModule::OnLoad() {
kernel_state_->RegisterModule(this);
}
X_STATUS XModule::GetSection(
const char* name,
uint32_t* out_section_data, uint32_t* out_section_size) {
X_STATUS XModule::GetSection(const char* name, uint32_t* out_section_data,
uint32_t* out_section_size) {
return X_STATUS_UNSUCCESSFUL;
}
} // namespace kernel
} // namespace xe

View File

@@ -13,16 +13,13 @@
#include <string>
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XModule : public XObject {
public:
public:
XModule(KernelState* kernel_state, const std::string& path);
virtual ~XModule();
@@ -30,20 +27,17 @@ public:
const std::string& name() const { return name_; }
virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0;
virtual X_STATUS GetSection(
const char* name,
uint32_t* out_section_data, uint32_t* out_section_size);
virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data,
uint32_t* out_section_size);
protected:
protected:
void OnLoad();
std::string name_;
std::string path_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XMODULE_H_

View File

@@ -9,15 +9,11 @@
#include <xenia/kernel/objects/xmutant.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::kernel;
XMutant::XMutant(KernelState* kernel_state) :
XObject(kernel_state, kTypeMutant),
handle_(NULL) {
}
XMutant::XMutant(KernelState* kernel_state)
: XObject(kernel_state, kTypeMutant), handle_(NULL) {}
XMutant::~XMutant() {
if (handle_) {
@@ -38,8 +34,8 @@ void XMutant::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) {
assert_always();
}
X_STATUS XMutant::ReleaseMutant(
uint32_t priority_increment, bool abandon, bool wait) {
X_STATUS XMutant::ReleaseMutant(uint32_t priority_increment, bool abandon,
bool wait) {
// TODO(benvanik): abandoning.
assert_false(abandon);
BOOL result = ReleaseMutex(handle_);
@@ -49,3 +45,6 @@ X_STATUS XMutant::ReleaseMutant(
return X_STATUS_MUTANT_NOT_OWNED;
}
}
} // namespace kernel
} // namespace xe

View File

@@ -11,16 +11,13 @@
#define XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XMutant : public XObject {
public:
public:
XMutant(KernelState* kernel_state);
virtual ~XMutant();
@@ -31,13 +28,11 @@ public:
virtual void* GetWaitHandle() { return handle_; }
private:
private:
HANDLE handle_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XMUTANT_H_

View File

@@ -9,15 +9,14 @@
#include <xenia/kernel/objects/xnotify_listener.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::kernel;
XNotifyListener::XNotifyListener(KernelState* kernel_state) :
XObject(kernel_state, kTypeNotifyListener),
wait_handle_(NULL), mask_(0), notification_count_(0) {
}
XNotifyListener::XNotifyListener(KernelState* kernel_state)
: XObject(kernel_state, kTypeNotifyListener),
wait_handle_(NULL),
mask_(0),
notification_count_(0) {}
XNotifyListener::~XNotifyListener() {
kernel_state_->UnregisterNotifyListener(this);
@@ -48,13 +47,13 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) {
} else {
// New.
notification_count_++;
notifications_.insert({ id, data });
notifications_.insert({id, data});
}
SetEvent(wait_handle_);
}
bool XNotifyListener::DequeueNotification(
XNotificationID* out_id, uint32_t* out_data) {
bool XNotifyListener::DequeueNotification(XNotificationID* out_id,
uint32_t* out_data) {
std::lock_guard<std::mutex> lock(lock_);
bool dequeued = false;
if (notification_count_) {
@@ -71,8 +70,8 @@ bool XNotifyListener::DequeueNotification(
return dequeued;
}
bool XNotifyListener::DequeueNotification(
XNotificationID id, uint32_t* out_data) {
bool XNotifyListener::DequeueNotification(XNotificationID id,
uint32_t* out_data) {
std::lock_guard<std::mutex> lock(lock_);
bool dequeued = false;
if (notification_count_) {
@@ -89,3 +88,6 @@ bool XNotifyListener::DequeueNotification(
}
return dequeued;
}
} // namespace kernel
} // namespace xe

View File

@@ -7,25 +7,19 @@
******************************************************************************
*/
// This should probably be in XAM, but I don't want to build an extensible
// object system. Meh.
#ifndef XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
#define XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
#include <mutex>
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XNotifyListener : public XObject {
public:
public:
XNotifyListener(KernelState* kernel_state);
virtual ~XNotifyListener();
@@ -37,7 +31,7 @@ public:
virtual void* GetWaitHandle() { return wait_handle_; }
private:
private:
HANDLE wait_handle_;
std::mutex lock_;
std::unordered_map<XNotificationID, uint32_t> notifications_;
@@ -45,9 +39,7 @@ private:
uint64_t mask_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_

View File

@@ -9,15 +9,11 @@
#include <xenia/kernel/objects/xsemaphore.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::kernel;
XSemaphore::XSemaphore(KernelState* kernel_state) :
XObject(kernel_state, kTypeSemaphore),
handle_(NULL) {
}
XSemaphore::XSemaphore(KernelState* kernel_state)
: XObject(kernel_state, kTypeSemaphore), handle_(NULL) {}
XSemaphore::~XSemaphore() {
if (handle_) {
@@ -43,3 +39,6 @@ int32_t XSemaphore::ReleaseSemaphore(int32_t release_count) {
::ReleaseSemaphore(handle_, release_count, &previous_count);
return previous_count;
}
} // namespace kernel
} // namespace xe

View File

@@ -11,16 +11,13 @@
#define XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XSemaphore : public XObject {
public:
public:
XSemaphore(KernelState* kernel_state);
virtual ~XSemaphore();
@@ -31,13 +28,11 @@ public:
virtual void* GetWaitHandle() { return handle_; }
private:
private:
HANDLE handle_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_

View File

@@ -16,41 +16,34 @@
#include <xenia/kernel/objects/xevent.h>
#include <xenia/kernel/objects/xuser_module.h>
namespace xe {
namespace kernel {
using namespace alloy;
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;
uint32_t next_xthread_id = 0;
thread_local XThread* current_thread_tls;
std::mutex critical_region_;
XThread* shared_kernel_thread_ = 0;
namespace {
static uint32_t next_xthread_id = 0;
static thread_local XThread* current_thread_tls;
static std::mutex critical_region_;
static XThread* shared_kernel_thread_ = 0;
}
XThread::XThread(KernelState* kernel_state,
uint32_t stack_size,
uint32_t xapi_thread_startup,
uint32_t start_address, uint32_t start_context,
uint32_t creation_flags) :
XObject(kernel_state, kTypeThread),
thread_id_(++next_xthread_id),
thread_handle_(0),
thread_state_address_(0),
thread_state_(0),
event_(NULL),
irql_(0) {
creation_params_.stack_size = stack_size;
creation_params_.xapi_thread_startup = xapi_thread_startup;
creation_params_.start_address = start_address;
creation_params_.start_context = start_context;
XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
uint32_t xapi_thread_startup, uint32_t start_address,
uint32_t start_context, uint32_t creation_flags)
: XObject(kernel_state, kTypeThread),
thread_id_(++next_xthread_id),
thread_handle_(0),
thread_state_address_(0),
thread_state_(0),
event_(NULL),
irql_(0) {
creation_params_.stack_size = stack_size;
creation_params_.xapi_thread_startup = xapi_thread_startup;
creation_params_.start_address = start_address;
creation_params_.start_context = start_context;
// top 8 bits = processor ID (or 0 for default)
// bit 0 = 1 to create suspended
creation_params_.creation_flags = creation_flags;
creation_params_.creation_flags = creation_flags;
// Adjust stack size - min of 16k.
if (creation_params_.stack_size < 16 * 1024) {
@@ -108,8 +101,7 @@ XThread* XThread::GetCurrentThread() {
XThread::EnterCriticalRegion();
thread = shared_kernel_thread_;
if (!thread) {
thread = new XThread(
KernelState::shared(), 32 * 1024, 0, 0, 0, 0);
thread = new XThread(KernelState::shared(), 32 * 1024, 0, 0, 0, 0);
shared_kernel_thread_ = thread;
current_thread_tls = thread;
}
@@ -127,21 +119,17 @@ uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) {
return poly::load_and_swap<uint32_t>(thread_state_block + 0x14C);
}
uint32_t XThread::thread_state() {
return thread_state_address_;
}
uint32_t XThread::thread_state() { return thread_state_address_; }
uint32_t XThread::thread_id() {
return thread_id_;
}
uint32_t XThread::thread_id() { return thread_id_; }
uint32_t XThread::last_error() {
uint8_t *p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->Translate(thread_state_address_);
return poly::load_and_swap<uint32_t>(p + 0x160);
}
void XThread::set_last_error(uint32_t error_code) {
uint8_t *p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->Translate(thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x160, error_code);
}
@@ -163,8 +151,8 @@ X_STATUS XThread::Create() {
// 0x160: last error
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the
// structure.
thread_state_address_ = (uint32_t)memory()->HeapAlloc(
0, 2048, MEMORY_FLAG_ZERO);
thread_state_address_ =
(uint32_t)memory()->HeapAlloc(0, 2048, alloy::MEMORY_FLAG_ZERO);
if (!thread_state_address_) {
XELOGW("Unable to allocate thread state block");
return X_STATUS_NO_MEMORY;
@@ -178,14 +166,14 @@ X_STATUS XThread::Create() {
// Allocate thread scratch.
// This is used by interrupts/APCs/etc so we can round-trip pointers through.
scratch_size_ = 4 * 16;
scratch_address_ = (uint32_t)memory()->HeapAlloc(
0, scratch_size_, MEMORY_FLAG_ZERO);
scratch_address_ =
(uint32_t)memory()->HeapAlloc(0, scratch_size_, alloy::MEMORY_FLAG_ZERO);
// Allocate TLS block.
const xe_xex2_header_t* header = module->xex_header();
uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size;
tls_address_ = (uint32_t)memory()->HeapAlloc(
0, tls_size, MEMORY_FLAG_ZERO);
tls_address_ =
(uint32_t)memory()->HeapAlloc(0, tls_size, alloy::MEMORY_FLAG_ZERO);
if (!tls_address_) {
XELOGW("Unable to allocate thread local storage block");
module->Release();
@@ -194,22 +182,21 @@ X_STATUS XThread::Create() {
// Copy in default TLS info.
// TODO(benvanik): is this correct?
memory()->Copy(
tls_address_, header->tls_info.raw_data_address, tls_size);
memory()->Copy(tls_address_, header->tls_info.raw_data_address, tls_size);
// Setup the thread state block (last error/etc).
uint8_t *p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->Translate(thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x000, tls_address_);
poly::store_and_swap<uint32_t>(p + 0x100, thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x14C, thread_id_);
poly::store_and_swap<uint32_t>(p + 0x150, 0); // ?
poly::store_and_swap<uint32_t>(p + 0x160, 0); // last error
poly::store_and_swap<uint32_t>(p + 0x150, 0); // ?
poly::store_and_swap<uint32_t>(p + 0x160, 0); // last error
// Allocate processor thread state.
// This is thread safe.
thread_state_ = new XenonThreadState(
kernel_state()->processor()->runtime(),
thread_id_, creation_params_.stack_size, thread_state_address_);
thread_state_ =
new XenonThreadState(kernel_state()->processor()->runtime(), thread_id_,
creation_params_.stack_size, thread_state_address_);
X_STATUS return_code = PlatformCreate();
if (XFAILED(return_code)) {
@@ -268,13 +255,10 @@ static uint32_t __stdcall XThreadStartCallbackWin32(void* param) {
X_STATUS XThread::PlatformCreate() {
bool suspended = creation_params_.creation_flags & 0x1;
thread_handle_ = CreateThread(
NULL,
creation_params_.stack_size,
(LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32,
this,
suspended ? CREATE_SUSPENDED : 0,
NULL);
thread_handle_ =
CreateThread(NULL, creation_params_.stack_size,
(LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this,
suspended ? CREATE_SUSPENDED : 0, NULL);
if (!thread_handle_) {
uint32_t last_error = GetLastError();
// TODO(benvanik): translate?
@@ -319,20 +303,15 @@ X_STATUS XThread::PlatformCreate() {
if (creation_params_.creation_flags & 0x1) {
#if XE_PLATFORM_OSX
result_code = pthread_create_suspended_np(
reinterpret_cast<pthread_t*>(&thread_handle_),
&attr,
&XThreadStartCallbackPthreads,
this);
reinterpret_cast<pthread_t*>(&thread_handle_), &attr,
&XThreadStartCallbackPthreads, this);
#else
// TODO(benvanik): pthread_create_suspended_np on linux
assert_always();
#endif // OSX
} else {
result_code = pthread_create(
reinterpret_cast<pthread_t*>(&thread_handle_),
&attr,
&XThreadStartCallbackPthreads,
this);
result_code = pthread_create(reinterpret_cast<pthread_t*>(&thread_handle_),
&attr, &XThreadStartCallbackPthreads, this);
}
pthread_attr_destroy(&attr);
@@ -389,28 +368,21 @@ void XThread::EnterCriticalRegion() {
critical_region_.lock();
}
void XThread::LeaveCriticalRegion() {
critical_region_.unlock();
}
void XThread::LeaveCriticalRegion() { critical_region_.unlock(); }
uint32_t XThread::RaiseIrql(uint32_t new_irql) {
return irql_.exchange(new_irql);
}
void XThread::LowerIrql(uint32_t new_irql) {
irql_ = new_irql;
}
void XThread::LowerIrql(uint32_t new_irql) { irql_ = new_irql; }
void XThread::LockApc() {
apc_lock_.lock();
}
void XThread::LockApc() { apc_lock_.lock(); }
void XThread::UnlockApc() {
bool needs_apc = apc_list_->HasPending();
apc_lock_.unlock();
if (needs_apc) {
QueueUserAPC(reinterpret_cast<PAPCFUNC>(DeliverAPCs),
thread_handle_,
QueueUserAPC(reinterpret_cast<PAPCFUNC>(DeliverAPCs), thread_handle_,
reinterpret_cast<ULONG_PTR>(this));
}
}
@@ -447,16 +419,15 @@ void XThread::DeliverAPCs(void* data) {
poly::store_and_swap<uint32_t>(scratch_ptr + 4, normal_context);
poly::store_and_swap<uint32_t>(scratch_ptr + 8, system_arg1);
poly::store_and_swap<uint32_t>(scratch_ptr + 12, system_arg2);
// kernel_routine(apc_address, &normal_routine, &normal_context, &system_arg1, &system_arg2)
// kernel_routine(apc_address, &normal_routine, &normal_context,
// &system_arg1, &system_arg2)
uint64_t kernel_args[] = {
apc_address,
thread->scratch_address_ + 0,
thread->scratch_address_ + 4,
thread->scratch_address_ + 8,
thread->scratch_address_ + 12,
apc_address, thread->scratch_address_ + 0,
thread->scratch_address_ + 4, thread->scratch_address_ + 8,
thread->scratch_address_ + 12,
};
processor->ExecuteInterrupt(
0, kernel_routine, kernel_args, poly::countof(kernel_args));
processor->ExecuteInterrupt(0, kernel_routine, kernel_args,
poly::countof(kernel_args));
normal_routine = poly::load_and_swap<uint32_t>(scratch_ptr + 0);
normal_context = poly::load_and_swap<uint32_t>(scratch_ptr + 4);
system_arg1 = poly::load_and_swap<uint32_t>(scratch_ptr + 8);
@@ -467,9 +438,9 @@ void XThread::DeliverAPCs(void* data) {
if (normal_routine) {
thread->UnlockApc();
// normal_routine(normal_context, system_arg1, system_arg2)
uint64_t normal_args[] = { normal_context, system_arg1, system_arg2 };
processor->ExecuteInterrupt(
0, normal_routine, normal_args, poly::countof(normal_args));
uint64_t normal_args[] = {normal_context, system_arg1, system_arg2};
processor->ExecuteInterrupt(0, normal_routine, normal_args,
poly::countof(normal_args));
thread->LockApc();
}
}
@@ -493,17 +464,15 @@ void XThread::RundownAPCs() {
// Call the rundown routine.
if (rundown_routine) {
// rundown_routine(apc)
uint64_t args[] = { apc_address };
kernel_state()->processor()->ExecuteInterrupt(
0, rundown_routine, args, poly::countof(args));
uint64_t args[] = {apc_address};
kernel_state()->processor()->ExecuteInterrupt(0, rundown_routine, args,
poly::countof(args));
}
}
UnlockApc();
}
int32_t XThread::QueryPriority() {
return GetThreadPriority(thread_handle_);
}
int32_t XThread::QueryPriority() { return GetThreadPriority(thread_handle_); }
void XThread::SetPriority(int32_t increment) {
SetThreadPriority(thread_handle_, increment);
@@ -538,8 +507,8 @@ X_STATUS XThread::Suspend(uint32_t* out_suspend_count) {
}
}
X_STATUS XThread::Delay(
uint32_t processor_mode, uint32_t alertable, uint64_t interval) {
X_STATUS XThread::Delay(uint32_t processor_mode, uint32_t alertable,
uint64_t interval) {
int64_t timeout_ticks = interval;
DWORD timeout_ms;
if (timeout_ticks > 0) {
@@ -549,21 +518,22 @@ X_STATUS XThread::Delay(
timeout_ms = 0;
} else if (timeout_ticks < 0) {
// Relative time.
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
} else {
timeout_ms = 0;
}
DWORD result = SleepEx(timeout_ms, alertable ? TRUE : FALSE);
switch (result) {
case 0:
return X_STATUS_SUCCESS;
case WAIT_IO_COMPLETION:
return X_STATUS_USER_APC;
default:
return X_STATUS_ALERTED;
case 0:
return X_STATUS_SUCCESS;
case WAIT_IO_COMPLETION:
return X_STATUS_USER_APC;
default:
return X_STATUS_ALERTED;
}
}
void* XThread::GetWaitHandle() {
return event_->GetWaitHandle();
}
void* XThread::GetWaitHandle() { return event_->GetWaitHandle(); }
} // namespace kernel
} // namespace xe

View File

@@ -15,26 +15,21 @@
#include <string>
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
XEDECLARECLASS2(xe, cpu, XenonThreadState);
namespace xe {
namespace kernel {
class NativeList;
class XEvent;
class XThread : public XObject {
public:
XThread(KernelState* kernel_state,
uint32_t stack_size,
uint32_t xapi_thread_startup,
uint32_t start_address, uint32_t start_context,
uint32_t creation_flags);
public:
XThread(KernelState* kernel_state, uint32_t stack_size,
uint32_t xapi_thread_startup, uint32_t start_address,
uint32_t start_context, uint32_t creation_flags);
virtual ~XThread();
static XThread* GetCurrentThread();
@@ -68,12 +63,12 @@ public:
X_STATUS Resume(uint32_t* out_suspend_count);
X_STATUS Suspend(uint32_t* out_suspend_count);
X_STATUS Delay(
uint32_t processor_mode, uint32_t alertable, uint64_t interval);
X_STATUS Delay(uint32_t processor_mode, uint32_t alertable,
uint64_t interval);
virtual void* GetWaitHandle();
private:
private:
X_STATUS PlatformCreate();
void PlatformDestroy();
X_STATUS PlatformExit(int exit_code);
@@ -82,33 +77,31 @@ private:
void RundownAPCs();
struct {
uint32_t stack_size;
uint32_t xapi_thread_startup;
uint32_t start_address;
uint32_t start_context;
uint32_t creation_flags;
uint32_t stack_size;
uint32_t xapi_thread_startup;
uint32_t start_address;
uint32_t start_context;
uint32_t creation_flags;
} creation_params_;
uint32_t thread_id_;
void* thread_handle_;
uint32_t scratch_address_;
uint32_t scratch_size_;
uint32_t tls_address_;
uint32_t thread_state_address_;
uint32_t thread_id_;
void* thread_handle_;
uint32_t scratch_address_;
uint32_t scratch_size_;
uint32_t tls_address_;
uint32_t thread_state_address_;
cpu::XenonThreadState* thread_state_;
std::string name_;
std::string name_;
std::atomic<uint32_t> irql_;
std::mutex apc_lock_;
NativeList* apc_list_;
NativeList* apc_list_;
XEvent* event_;
XEvent* event_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XTHREAD_H_

View File

@@ -11,15 +11,11 @@
#include <xenia/cpu/processor.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::kernel;
XTimer::XTimer(KernelState* kernel_state) :
XObject(kernel_state, kTypeTimer),
handle_(NULL) {
}
XTimer::XTimer(KernelState* kernel_state)
: XObject(kernel_state, kTypeTimer), handle_(NULL) {}
XTimer::~XTimer() {
if (handle_) {
@@ -32,33 +28,32 @@ void XTimer::Initialize(uint32_t timer_type) {
bool manual_reset = false;
switch (timer_type) {
case 0: // NotificationTimer
manual_reset = true;
break;
case 1: // SynchronizationTimer
manual_reset = false;
break;
default:
assert_always();
break;
case 0: // NotificationTimer
manual_reset = true;
break;
case 1: // SynchronizationTimer
manual_reset = false;
break;
default:
assert_always();
break;
}
handle_ = CreateWaitableTimer(NULL, manual_reset, NULL);
}
X_STATUS XTimer::SetTimer(
int64_t due_time, uint32_t period_ms,
uint32_t routine, uint32_t routine_arg, bool resume) {
X_STATUS XTimer::SetTimer(int64_t due_time, uint32_t period_ms,
uint32_t routine, uint32_t routine_arg, bool resume) {
// Stash routine for callback.
current_routine_ = routine;
current_routine_arg_ = routine_arg;
LARGE_INTEGER due_time_li;
due_time_li.QuadPart = due_time;
BOOL result = SetWaitableTimer(
handle_, &due_time_li, period_ms,
routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL, this,
resume ? TRUE : FALSE);
BOOL result =
SetWaitableTimer(handle_, &due_time_li, period_ms,
routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL,
this, resume ? TRUE : FALSE);
// Caller is checking for STATUS_TIMER_RESUME_IGNORED.
// This occurs if result == TRUE but error is set.
@@ -69,8 +64,8 @@ X_STATUS XTimer::SetTimer(
return result ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL;
}
void XTimer::CompletionRoutine(
XTimer* timer, DWORD timer_low, DWORD timer_high) {
void XTimer::CompletionRoutine(XTimer* timer, DWORD timer_low,
DWORD timer_high) {
assert_true(timer->current_routine_);
// Queue APC to call back routine with (arg, low, high).
@@ -81,6 +76,9 @@ void XTimer::CompletionRoutine(
}
X_STATUS XTimer::Cancel() {
return CancelWaitableTimer(handle_) == 0 ?
X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL;
return CancelWaitableTimer(handle_) == 0 ? X_STATUS_SUCCESS
: X_STATUS_UNSUCCESSFUL;
}
} // namespace kernel
} // namespace xe

View File

@@ -11,41 +11,36 @@
#define XENIA_KERNEL_XBOXKRNL_XTIMER_H_
#include <xenia/kernel/xobject.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XTimer : public XObject {
public:
public:
XTimer(KernelState* kernel_state);
virtual ~XTimer();
void Initialize(uint32_t timer_type);
// completion routine, arg to completion routine
X_STATUS SetTimer(int64_t due_time, uint32_t period_ms,
uint32_t routine, uint32_t routine_arg, bool resume);
X_STATUS SetTimer(int64_t due_time, uint32_t period_ms, uint32_t routine,
uint32_t routine_arg, bool resume);
X_STATUS Cancel();
virtual void* GetWaitHandle() { return handle_; }
private:
private:
HANDLE handle_;
uint32_t current_routine_;
uint32_t current_routine_arg_;
static void CompletionRoutine(
XTimer* timer, DWORD timer_low, DWORD timer_high);
static void CompletionRoutine(XTimer* timer, DWORD timer_low,
DWORD timer_high);
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_TIMER_H_

View File

@@ -14,24 +14,17 @@
#include <xenia/kernel/objects/xfile.h>
#include <xenia/kernel/objects/xthread.h>
namespace xe {
namespace kernel {
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;
XUserModule::XUserModule(KernelState* kernel_state, const char* path)
: XModule(kernel_state, path), xex_(NULL) {}
XUserModule::XUserModule(KernelState* kernel_state, const char* path) :
XModule(kernel_state, path),
xex_(NULL) {
}
XUserModule::~XUserModule() { xe_xex2_release(xex_); }
XUserModule::~XUserModule() {
xe_xex2_release(xex_);
}
xe_xex2_ref XUserModule::xex() {
return xe_xex2_retain(xex_);
}
xe_xex2_ref XUserModule::xex() { return xe_xex2_retain(xex_); }
const xe_xex2_header_t* XUserModule::xex_header() {
return xe_xex2_get_header(xex_);
@@ -134,9 +127,8 @@ void* XUserModule::GetProcAddressByOrdinal(uint16_t ordinal) {
return NULL;
}
X_STATUS XUserModule::GetSection(
const char* name,
uint32_t* out_section_data, uint32_t* out_section_size) {
X_STATUS XUserModule::GetSection(const char* name, uint32_t* out_section_data,
uint32_t* out_section_size) {
auto header = xe_xex2_get_header(xex_);
for (size_t n = 0; n < header->resource_info_count; n++) {
auto& res = header->resource_infos[n];
@@ -158,12 +150,8 @@ X_STATUS XUserModule::Launch(uint32_t flags) {
Dump();
// Create a thread to run in.
XThread* thread = new XThread(
kernel_state(),
header->exe_stack_size,
0,
header->exe_entry_point, NULL,
0);
XThread* thread = new XThread(kernel_state(), header->exe_stack_size, 0,
header->exe_entry_point, NULL, 0);
X_STATUS result = thread->Create();
if (XFAILED(result)) {
@@ -196,11 +184,10 @@ void XUserModule::Dump() {
printf("\n");
printf(" Execution Info:\n");
printf(" Media ID: %.8X\n", header->execution_info.media_id);
printf(" Version: %d.%d.%d.%d\n",
header->execution_info.version.major,
header->execution_info.version.minor,
header->execution_info.version.build,
header->execution_info.version.qfe);
printf(
" Version: %d.%d.%d.%d\n", header->execution_info.version.major,
header->execution_info.version.minor,
header->execution_info.version.build, header->execution_info.version.qfe);
printf(" Base Version: %d.%d.%d.%d\n",
header->execution_info.base_version.major,
header->execution_info.base_version.minor,
@@ -222,14 +209,14 @@ void XUserModule::Dump() {
printf(" Slot Count: %d\n", header->tls_info.slot_count);
printf(" Data Size: %db\n", header->tls_info.data_size);
printf(" Address: %.8X, %db\n", header->tls_info.raw_data_address,
header->tls_info.raw_data_size);
header->tls_info.raw_data_size);
printf("\n");
printf(" Headers:\n");
for (size_t n = 0; n < header->header_count; n++) {
const xe_xex2_opt_header_t* opt_header = &header->headers[n];
printf(" %.8X (%.8X, %4db) %.8X = %11d\n",
opt_header->key, opt_header->offset, opt_header->length,
opt_header->value, opt_header->value);
printf(" %.8X (%.8X, %4db) %.8X = %11d\n", opt_header->key,
opt_header->offset, opt_header->length, opt_header->value,
opt_header->value);
}
printf("\n");
@@ -237,8 +224,8 @@ void XUserModule::Dump() {
printf("Resources:\n");
for (size_t n = 0; n < header->resource_info_count; n++) {
auto& res = header->resource_infos[n];
printf(" %-8s %.8X-%.8X, %db\n",
res.name, res.address, res.address + res.size, res.size);
printf(" %-8s %.8X-%.8X, %db\n", res.name, res.address,
res.address + res.size, res.size);
}
printf("\n");
@@ -248,23 +235,23 @@ void XUserModule::Dump() {
const xe_xex2_section_t* section = &header->sections[n];
const char* type = "UNKNOWN";
switch (section->info.type) {
case XEX_SECTION_CODE:
type = "CODE ";
break;
case XEX_SECTION_DATA:
type = "RWDATA ";
break;
case XEX_SECTION_READONLY_DATA:
type = "RODATA ";
break;
case XEX_SECTION_CODE:
type = "CODE ";
break;
case XEX_SECTION_DATA:
type = "RWDATA ";
break;
case XEX_SECTION_READONLY_DATA:
type = "RODATA ";
break;
}
const size_t start_address =
header->exe_address + (i * xe_xex2_section_length);
const size_t end_address =
start_address + (section->info.page_count * xe_xex2_section_length);
printf(" %3d %s %3d pages %.8X - %.8X (%d bytes)\n",
(int)n, type, section->info.page_count, (int)start_address,
(int)end_address, section->info.page_count * xe_xex2_section_length);
printf(" %3d %s %3d pages %.8X - %.8X (%d bytes)\n", (int)n, type,
section->info.page_count, (int)start_address, (int)end_address,
section->info.page_count * xe_xex2_section_length);
i += section->info.page_count;
}
printf("\n");
@@ -272,9 +259,8 @@ void XUserModule::Dump() {
// Static libraries.
printf("Static Libraries:\n");
for (size_t n = 0; n < header->static_library_count; n++) {
const xe_xex2_static_library_t *library = &header->static_libraries[n];
printf(" %-8s : %d.%d.%d.%d\n",
library->name, library->major,
const xe_xex2_static_library_t* library = &header->static_libraries[n];
printf(" %-8s : %d.%d.%d.%d\n", library->name, library->major,
library->minor, library->build, library->qfe);
}
printf("\n");
@@ -286,15 +272,15 @@ void XUserModule::Dump() {
xe_xex2_import_info_t* import_infos;
size_t import_info_count;
if (!xe_xex2_get_import_infos(xex_, library,
&import_infos, &import_info_count)) {
if (!xe_xex2_get_import_infos(xex_, library, &import_infos,
&import_info_count)) {
printf(" %s - %d imports\n", library->name, (int)import_info_count);
printf(" Version: %d.%d.%d.%d\n",
library->version.major, library->version.minor,
library->version.build, library->version.qfe);
printf(" Min Version: %d.%d.%d.%d\n",
library->min_version.major, library->min_version.minor,
library->min_version.build, library->min_version.qfe);
printf(" Version: %d.%d.%d.%d\n", library->version.major,
library->version.minor, library->version.build,
library->version.qfe);
printf(" Min Version: %d.%d.%d.%d\n", library->min_version.major,
library->min_version.minor, library->min_version.build,
library->min_version.qfe);
printf("\n");
// Counts.
@@ -323,30 +309,28 @@ void XUserModule::Dump() {
(int)(known_count / (float)import_info_count * 100.0f),
known_count, unknown_count);
printf(" Implemented: %3d%% (%d implemented, %d unimplemented)\n",
(int)(impl_count / (float)import_info_count * 100.0f),
impl_count, unimpl_count);
(int)(impl_count / (float)import_info_count * 100.0f), impl_count,
unimpl_count);
printf("\n");
// Listing.
for (size_t m = 0; m < import_info_count; m++) {
const xe_xex2_import_info_t* info = &import_infos[m];
KernelExport* kernel_export = export_resolver->GetExportByOrdinal(
library->name, info->ordinal);
const char *name = "UNKNOWN";
KernelExport* kernel_export =
export_resolver->GetExportByOrdinal(library->name, info->ordinal);
const char* name = "UNKNOWN";
bool implemented = false;
if (kernel_export) {
name = kernel_export->name;
implemented = kernel_export->is_implemented;
}
if (kernel_export && kernel_export->type == KernelExport::Variable) {
printf(" V %.8X %.3X (%3d) %s %s\n",
info->value_address, info->ordinal, info->ordinal,
implemented ? " " : "!!", name);
printf(" V %.8X %.3X (%3d) %s %s\n", info->value_address,
info->ordinal, info->ordinal, implemented ? " " : "!!", name);
} else if (info->thunk_address) {
printf(" F %.8X %.8X %.3X (%3d) %s %s\n",
info->value_address, info->thunk_address, info->ordinal,
info->ordinal, implemented ? " " : "!!", name);
printf(" F %.8X %.8X %.3X (%3d) %s %s\n", info->value_address,
info->thunk_address, info->ordinal, info->ordinal,
implemented ? " " : "!!", name);
}
}
}
@@ -359,3 +343,6 @@ void XUserModule::Dump() {
printf(" TODO\n");
printf("\n");
}
} // namespace kernel
} // namespace xe

View File

@@ -13,16 +13,14 @@
#include <xenia/kernel/objects/xmodule.h>
#include <xenia/export_resolver.h>
#include <xenia/xbox.h>
#include <xenia/kernel/util/xex2.h>
#include <xenia/xbox.h>
namespace xe {
namespace kernel {
class XUserModule : public XModule {
public:
public:
XUserModule(KernelState* kernel_state, const char* path);
virtual ~XUserModule();
@@ -33,23 +31,20 @@ public:
X_STATUS LoadFromMemory(const void* addr, const size_t length);
virtual void* GetProcAddressByOrdinal(uint16_t ordinal);
virtual X_STATUS GetSection(
const char* name,
uint32_t* out_section_data, uint32_t* out_section_size);
virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data,
uint32_t* out_section_size);
X_STATUS Launch(uint32_t flags);
void Dump();
private:
private:
int LoadPE();
xe_xex2_ref xex_;
xe_xex2_ref xex_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOXKRNL_XUSER_MODULE_H_