Converting everything to C++ cause I'm a masochist.
This commit is contained in:
@@ -10,87 +10,62 @@
|
||||
#include <xenia/kernel/export.h>
|
||||
|
||||
|
||||
bool xe_kernel_export_is_implemented(const xe_kernel_export_t *kernel_export) {
|
||||
if (kernel_export->flags & kXEKernelExportFlagFunction) {
|
||||
if (kernel_export->function_data.impl) {
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
bool KernelExport::IsImplemented() {
|
||||
switch (type) {
|
||||
case Function:
|
||||
if (function_data.impl) {
|
||||
return true;
|
||||
}
|
||||
} else if (kernel_export->flags & kXEKernelExportFlagVariable) {
|
||||
if (kernel_export->variable_data) {
|
||||
break;
|
||||
case Variable:
|
||||
if (variable_data) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char name[32];
|
||||
xe_kernel_export_t *exports;
|
||||
size_t count;
|
||||
} xe_kernel_export_table_t;
|
||||
#define kXEKernelExportResolverTableMaxCount 8
|
||||
|
||||
|
||||
struct xe_kernel_export_resolver {
|
||||
xe_ref_t ref;
|
||||
|
||||
xe_kernel_export_table_t tables[kXEKernelExportResolverTableMaxCount];
|
||||
size_t table_count;
|
||||
};
|
||||
|
||||
|
||||
xe_kernel_export_resolver_ref xe_kernel_export_resolver_create() {
|
||||
xe_kernel_export_resolver_ref resolver = (xe_kernel_export_resolver_ref)
|
||||
xe_calloc(sizeof(xe_kernel_export_resolver));
|
||||
xe_ref_init((xe_ref)resolver);
|
||||
|
||||
return resolver;
|
||||
ExportResolver::ExportResolver() {
|
||||
}
|
||||
|
||||
void xe_kernel_export_resolver_dealloc(xe_kernel_export_resolver_ref resolver) {
|
||||
ExportResolver::~ExportResolver() {
|
||||
}
|
||||
|
||||
xe_kernel_export_resolver_ref xe_kernel_export_resolver_retain(
|
||||
xe_kernel_export_resolver_ref resolver) {
|
||||
xe_ref_retain((xe_ref)resolver);
|
||||
return resolver;
|
||||
void ExportResolver::RegisterTable(
|
||||
const char* library_name, KernelExport* exports, const size_t count) {
|
||||
ExportTable table;
|
||||
XEIGNORE(xestrcpya(table.name, XECOUNT(table.name), library_name));
|
||||
table.exports = exports;
|
||||
table.count = count;
|
||||
tables_.push_back(table);
|
||||
}
|
||||
|
||||
void xe_kernel_export_resolver_release(xe_kernel_export_resolver_ref resolver) {
|
||||
xe_ref_release((xe_ref)resolver,
|
||||
(xe_ref_dealloc_t)xe_kernel_export_resolver_dealloc);
|
||||
}
|
||||
|
||||
void xe_kernel_export_resolver_register_table(
|
||||
xe_kernel_export_resolver_ref resolver, const char *library_name,
|
||||
xe_kernel_export_t *exports, const size_t count) {
|
||||
XEASSERT(resolver->table_count + 1 < kXEKernelExportResolverTableMaxCount);
|
||||
xe_kernel_export_table_t *table = &resolver->tables[resolver->table_count++];
|
||||
XEIGNORE(xestrcpya(table->name, XECOUNT(table->name), library_name));
|
||||
table->exports = exports;
|
||||
table->count = count;
|
||||
}
|
||||
|
||||
xe_kernel_export_t *xe_kernel_export_resolver_get_by_ordinal(
|
||||
xe_kernel_export_resolver_ref resolver, const char *library_name,
|
||||
const uint32_t ordinal) {
|
||||
// TODO(benvanik): binary search everything.
|
||||
for (size_t n = 0; n < resolver->table_count; n++) {
|
||||
const xe_kernel_export_table_t *table = &resolver->tables[n];
|
||||
if (!xestrcmpa(library_name, table->name)) {
|
||||
// TODO(benvanik): binary search table.
|
||||
for (size_t m = 0; m < table->count; m++) {
|
||||
if (table->exports[m].ordinal == ordinal) {
|
||||
return &table->exports[m];
|
||||
KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name,
|
||||
const uint32_t ordinal) {
|
||||
for (std::vector<ExportTable>::iterator it = tables_.begin();
|
||||
it != tables_.end(); ++it) {
|
||||
if (!xestrcmp(library_name, it->name)) {
|
||||
// TODO(benvanik): binary search?
|
||||
for (size_t n = 0; n < it->count; n++) {
|
||||
if (it->exports[n].ordinal == ordinal) {
|
||||
return &it->exports[n];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xe_kernel_export_t *xe_kernel_export_resolver_get_by_name(
|
||||
xe_kernel_export_resolver_ref resolver, const char *library_name,
|
||||
const char *name) {
|
||||
KernelExport* ExportResolver::GetExportByName(const char* library_name,
|
||||
const char* name) {
|
||||
// TODO(benvanik): lookup by name.
|
||||
XEASSERTALWAYS();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/kernel.h>
|
||||
|
||||
#include "kernel/modules/modules.h"
|
||||
|
||||
|
||||
typedef struct xe_kernel {
|
||||
xe_ref_t ref;
|
||||
|
||||
xe_kernel_options_t options;
|
||||
|
||||
xe_pal_ref pal;
|
||||
xe_memory_ref memory;
|
||||
xe_cpu_ref cpu;
|
||||
xe_kernel_export_resolver_ref export_resolver;
|
||||
|
||||
struct {
|
||||
xe_xam_ref xam;
|
||||
xe_xbdm_ref xbdm;
|
||||
xe_xboxkrnl_ref xboxkrnl;
|
||||
} modules;
|
||||
} xe_kernel_t;
|
||||
|
||||
|
||||
xe_kernel_ref xe_kernel_create(xe_pal_ref pal, xe_cpu_ref cpu,
|
||||
xe_kernel_options_t options) {
|
||||
xe_kernel_ref kernel = (xe_kernel_ref)xe_calloc(sizeof(xe_kernel));
|
||||
xe_ref_init((xe_ref)kernel);
|
||||
|
||||
xe_copy_struct(&kernel->options, &options, sizeof(xe_kernel_options_t));
|
||||
|
||||
kernel->pal = xe_pal_retain(pal);
|
||||
kernel->memory = xe_cpu_get_memory(cpu);
|
||||
kernel->cpu = xe_cpu_retain(cpu);
|
||||
kernel->export_resolver = xe_kernel_export_resolver_create();
|
||||
|
||||
kernel->modules.xam =
|
||||
xe_xam_create(kernel->pal, kernel->memory, kernel->export_resolver);
|
||||
kernel->modules.xbdm =
|
||||
xe_xbdm_create(kernel->pal, kernel->memory, kernel->export_resolver);
|
||||
kernel->modules.xboxkrnl =
|
||||
xe_xboxkrnl_create(kernel->pal, kernel->memory, kernel->export_resolver);
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
void xe_kernel_dealloc(xe_kernel_ref kernel) {
|
||||
xe_xboxkrnl_release(kernel->modules.xboxkrnl);
|
||||
xe_xbdm_release(kernel->modules.xbdm);
|
||||
xe_xam_release(kernel->modules.xam);
|
||||
|
||||
xe_kernel_export_resolver_release(kernel->export_resolver);
|
||||
xe_cpu_release(kernel->cpu);
|
||||
xe_memory_release(kernel->memory);
|
||||
xe_pal_release(kernel->pal);
|
||||
}
|
||||
|
||||
xe_kernel_ref xe_kernel_retain(xe_kernel_ref kernel) {
|
||||
xe_ref_retain((xe_ref)kernel);
|
||||
return kernel;
|
||||
}
|
||||
|
||||
void xe_kernel_release(xe_kernel_ref kernel) {
|
||||
xe_ref_release((xe_ref)kernel, (xe_ref_dealloc_t)xe_kernel_dealloc);
|
||||
}
|
||||
|
||||
xe_pal_ref xe_kernel_get_pal(xe_kernel_ref kernel) {
|
||||
return xe_pal_retain(kernel->pal);
|
||||
}
|
||||
|
||||
xe_memory_ref xe_kernel_get_memory(xe_kernel_ref kernel) {
|
||||
return xe_memory_retain(kernel->memory);
|
||||
}
|
||||
|
||||
xe_cpu_ref xe_kernel_get_cpu(xe_kernel_ref kernel) {
|
||||
return xe_cpu_retain(kernel->cpu);
|
||||
}
|
||||
|
||||
const xechar_t *xe_kernel_get_command_line(xe_kernel_ref kernel) {
|
||||
return kernel->options.command_line;
|
||||
}
|
||||
|
||||
xe_kernel_export_resolver_ref xe_kernel_get_export_resolver(
|
||||
xe_kernel_ref kernel) {
|
||||
return xe_kernel_export_resolver_retain(kernel->export_resolver);
|
||||
}
|
||||
|
||||
xe_module_ref xe_kernel_load_module(xe_kernel_ref kernel,
|
||||
const xechar_t *path) {
|
||||
xe_module_ref module = xe_kernel_get_module(kernel, path);
|
||||
if (module) {
|
||||
return module;
|
||||
}
|
||||
|
||||
// TODO(benvanik): map file from filesystem
|
||||
xe_mmap_ref mmap = xe_mmap_open(kernel->pal, kXEFileModeRead, path, 0, 0);
|
||||
if (!mmap) {
|
||||
return NULL;
|
||||
}
|
||||
void *addr = xe_mmap_get_addr(mmap);
|
||||
size_t length = xe_mmap_get_length(mmap);
|
||||
|
||||
xe_module_options_t options;
|
||||
xe_zero_struct(&options, sizeof(xe_module_options_t));
|
||||
XEIGNORE(xestrcpy(options.path, XECOUNT(options.path), path));
|
||||
module = xe_module_load(kernel->memory, kernel->export_resolver,
|
||||
addr, length, options);
|
||||
|
||||
// TODO(benvanik): retain memory somehow? is it needed?
|
||||
xe_mmap_release(mmap);
|
||||
|
||||
if (!module) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Prepare the module.
|
||||
XEEXPECTZERO(xe_cpu_prepare_module(kernel->cpu, module,
|
||||
kernel->export_resolver));
|
||||
|
||||
// Stash in modules list (takes reference).
|
||||
// TODO(benvanik): stash in list.
|
||||
return xe_module_retain(module);
|
||||
|
||||
XECLEANUP:
|
||||
xe_module_release(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xe_kernel_launch_module(xe_kernel_ref kernel, xe_module_ref module) {
|
||||
//const xe_xex2_header_t *xex_header = xe_module_get_xex_header(module);
|
||||
|
||||
// TODO(benvanik): set as main module/etc
|
||||
// xekXexExecutableModuleHandle = xe_module_get_handle(module);
|
||||
|
||||
// XEEXPECTTRUE(XECPUPrepareModule(XEGetCPU(), module->xex, module->pe, module->address_space, module->address_space_size));
|
||||
|
||||
// Setup the heap (and TLS?).
|
||||
// xex_header->exe_heap_size;
|
||||
|
||||
// Launch thread.
|
||||
// XHANDLE thread_handle;
|
||||
// XDWORD thread_id;
|
||||
// XBOOL result = xekExCreateThread(&thread_handle, xex_header->exe_stack_size, &thread_id, NULL, (void*)xex_header->exe_entry_point, NULL, 0);
|
||||
|
||||
// Wait until thread completes.
|
||||
// XLARGE_INTEGER timeout = XINFINITE;
|
||||
// xekNtWaitForSingleObjectEx(thread_handle, TRUE, &timeout);
|
||||
}
|
||||
|
||||
xe_module_ref xe_kernel_get_module(xe_kernel_ref kernel, const xechar_t *path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xe_kernel_unload_module(xe_kernel_ref kernel, xe_module_ref module) {
|
||||
//
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
#ifndef XENIA_KERNEL_MODULES_H_
|
||||
#define XENIA_KERNEL_MODULES_H_
|
||||
|
||||
#include "kernel/modules/xam/xam.h"
|
||||
#include "kernel/modules/xbdm/xbdm.h"
|
||||
#include "kernel/modules/xboxkrnl/xboxkrnl.h"
|
||||
#include "kernel/modules/xam/xam_module.h"
|
||||
#include "kernel/modules/xbdm/xbdm_module.h"
|
||||
#include "kernel/modules/xboxkrnl/xboxkrnl_module.h"
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'xam.cc',
|
||||
'xam_module.cc',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "kernel/modules/xam/xam.h"
|
||||
|
||||
#include "kernel/modules/xam/xam_table.h"
|
||||
|
||||
|
||||
struct xe_xam {
|
||||
xe_ref_t ref;
|
||||
};
|
||||
|
||||
|
||||
xe_xam_ref xe_xam_create(
|
||||
xe_pal_ref pal, xe_memory_ref memory,
|
||||
xe_kernel_export_resolver_ref export_resolver) {
|
||||
xe_xam_ref module = (xe_xam_ref)xe_calloc(sizeof(xe_xam));
|
||||
xe_ref_init((xe_ref)module);
|
||||
|
||||
xe_kernel_export_resolver_register_table(export_resolver, "xam.xex",
|
||||
xe_xam_export_table, XECOUNT(xe_xam_export_table));
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
void xe_xam_dealloc(xe_xam_ref module) {
|
||||
}
|
||||
|
||||
xe_xam_ref xe_xam_retain(xe_xam_ref module) {
|
||||
xe_ref_retain((xe_ref)module);
|
||||
return module;
|
||||
}
|
||||
|
||||
void xe_xam_release(xe_xam_ref module) {
|
||||
xe_ref_release((xe_ref)module, (xe_ref_dealloc_t)xe_xam_dealloc);
|
||||
}
|
||||
28
src/kernel/modules/xam/xam_module.cc
Normal file
28
src/kernel/modules/xam/xam_module.cc
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "kernel/modules/xam/xam_module.h"
|
||||
|
||||
#include "kernel/modules/xam/xam_table.h"
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xam;
|
||||
|
||||
|
||||
XamModule::XamModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> resolver) :
|
||||
KernelModule(pal, memory, resolver) {
|
||||
resolver->RegisterTable(
|
||||
"xam.xex", xam_export_table, XECOUNT(xam_export_table));
|
||||
}
|
||||
|
||||
XamModule::~XamModule() {
|
||||
}
|
||||
@@ -14,18 +14,25 @@
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
struct xe_xam;
|
||||
typedef struct xe_xam* xe_xam_ref;
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
|
||||
|
||||
xe_xam_ref xe_xam_create(
|
||||
xe_pal_ref pal, xe_memory_ref memory,
|
||||
xe_kernel_export_resolver_ref export_resolver);
|
||||
class XamModule : public KernelModule {
|
||||
public:
|
||||
XamModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> resolver);
|
||||
virtual ~XamModule();
|
||||
};
|
||||
|
||||
xe_xam_ref xe_xam_retain(xe_xam_ref module);
|
||||
void xe_xam_release(xe_xam_ref module);
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XAM_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'xbdm.cc',
|
||||
'xbdm_module.cc',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "kernel/modules/xbdm/xbdm.h"
|
||||
|
||||
#include "kernel/modules/xbdm/xbdm_table.h"
|
||||
|
||||
|
||||
struct xe_xbdm {
|
||||
xe_ref_t ref;
|
||||
};
|
||||
|
||||
|
||||
xe_xbdm_ref xe_xbdm_create(
|
||||
xe_pal_ref pal, xe_memory_ref memory,
|
||||
xe_kernel_export_resolver_ref export_resolver) {
|
||||
xe_xbdm_ref module = (xe_xbdm_ref)xe_calloc(sizeof(xe_xbdm));
|
||||
xe_ref_init((xe_ref)module);
|
||||
|
||||
xe_kernel_export_resolver_register_table(export_resolver, "xbdm.exe",
|
||||
xe_xbdm_export_table, XECOUNT(xe_xbdm_export_table));
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
void xe_xbdm_dealloc(xe_xbdm_ref module) {
|
||||
}
|
||||
|
||||
xe_xbdm_ref xe_xbdm_retain(xe_xbdm_ref module) {
|
||||
xe_ref_retain((xe_ref)module);
|
||||
return module;
|
||||
}
|
||||
|
||||
void xe_xbdm_release(xe_xbdm_ref module) {
|
||||
xe_ref_release((xe_ref)module, (xe_ref_dealloc_t)xe_xbdm_dealloc);
|
||||
}
|
||||
28
src/kernel/modules/xbdm/xbdm_module.cc
Normal file
28
src/kernel/modules/xbdm/xbdm_module.cc
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "kernel/modules/xbdm/xbdm_module.h"
|
||||
|
||||
#include "kernel/modules/xbdm/xbdm_table.h"
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xbdm;
|
||||
|
||||
|
||||
XbdmModule::XbdmModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> resolver) :
|
||||
KernelModule(pal, memory, resolver) {
|
||||
resolver->RegisterTable(
|
||||
"xbdm.exe", xbdm_export_table, XECOUNT(xbdm_export_table));
|
||||
}
|
||||
|
||||
XbdmModule::~XbdmModule() {
|
||||
}
|
||||
@@ -7,25 +7,32 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_H_
|
||||
#ifndef XENIA_KERNEL_MODULES_XBDM_MODULE_H_
|
||||
#define XENIA_KERNEL_MODULES_XBDM_MODULE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
struct xe_xboxkrnl;
|
||||
typedef struct xe_xboxkrnl* xe_xboxkrnl_ref;
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xbdm {
|
||||
|
||||
|
||||
xe_xboxkrnl_ref xe_xboxkrnl_create(
|
||||
xe_pal_ref pal, xe_memory_ref memory,
|
||||
xe_kernel_export_resolver_ref export_resolver);
|
||||
|
||||
xe_xboxkrnl_ref xe_xboxkrnl_retain(xe_xboxkrnl_ref module);
|
||||
void xe_xboxkrnl_release(xe_xboxkrnl_ref module);
|
||||
class XbdmModule : public KernelModule {
|
||||
public:
|
||||
XbdmModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> resolver);
|
||||
virtual ~XbdmModule();
|
||||
};
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_H_
|
||||
} // namespace xbdm
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBDM_MODULE_H_
|
||||
@@ -13,14 +13,24 @@
|
||||
#include <xenia/kernel/export.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xbdm {
|
||||
|
||||
|
||||
#define FLAG(t) kXEKernelExportFlag##t
|
||||
|
||||
|
||||
static xe_kernel_export_t xe_xbdm_export_table[] = {
|
||||
static KernelExport xbdm_export_table[] = {
|
||||
};
|
||||
|
||||
|
||||
#undef FLAG
|
||||
|
||||
|
||||
} // namespace xbdm
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBDM_TABLE_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'xboxkrnl.cc',
|
||||
'xboxkrnl_module.cc',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "kernel/modules/xboxkrnl/xboxkrnl.h"
|
||||
|
||||
#include "kernel/modules/xboxkrnl/xboxkrnl_table.h"
|
||||
|
||||
|
||||
struct xe_xboxkrnl {
|
||||
xe_ref_t ref;
|
||||
};
|
||||
|
||||
|
||||
xe_xboxkrnl_ref xe_xboxkrnl_create(
|
||||
xe_pal_ref pal, xe_memory_ref memory,
|
||||
xe_kernel_export_resolver_ref export_resolver) {
|
||||
xe_xboxkrnl_ref module = (xe_xboxkrnl_ref)xe_calloc(sizeof(xe_xboxkrnl));
|
||||
xe_ref_init((xe_ref)module);
|
||||
|
||||
xe_kernel_export_resolver_register_table(export_resolver, "xboxkrnl.exe",
|
||||
xe_xboxkrnl_export_table, XECOUNT(xe_xboxkrnl_export_table));
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
void xe_xboxkrnl_dealloc(xe_xboxkrnl_ref module) {
|
||||
}
|
||||
|
||||
xe_xboxkrnl_ref xe_xboxkrnl_retain(xe_xboxkrnl_ref module) {
|
||||
xe_ref_retain((xe_ref)module);
|
||||
return module;
|
||||
}
|
||||
|
||||
void xe_xboxkrnl_release(xe_xboxkrnl_ref module) {
|
||||
xe_ref_release((xe_ref)module, (xe_ref_dealloc_t)xe_xboxkrnl_dealloc);
|
||||
}
|
||||
28
src/kernel/modules/xboxkrnl/xboxkrnl_module.cc
Normal file
28
src/kernel/modules/xboxkrnl/xboxkrnl_module.cc
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "kernel/modules/xboxkrnl/xboxkrnl_module.h"
|
||||
|
||||
#include "kernel/modules/xboxkrnl/xboxkrnl_table.h"
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
XboxkrnlModule::XboxkrnlModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> resolver) :
|
||||
KernelModule(pal, memory, resolver) {
|
||||
resolver->RegisterTable(
|
||||
"xboxkrnl.exe", xboxkrnl_export_table, XECOUNT(xboxkrnl_export_table));
|
||||
}
|
||||
|
||||
XboxkrnlModule::~XboxkrnlModule() {
|
||||
}
|
||||
@@ -7,25 +7,32 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_MODULES_XBDM_H_
|
||||
#define XENIA_KERNEL_MODULES_XBDM_H_
|
||||
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
struct xe_xbdm;
|
||||
typedef struct xe_xbdm* xe_xbdm_ref;
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
xe_xbdm_ref xe_xbdm_create(
|
||||
xe_pal_ref pal, xe_memory_ref memory,
|
||||
xe_kernel_export_resolver_ref export_resolver);
|
||||
|
||||
xe_xbdm_ref xe_xbdm_retain(xe_xbdm_ref module);
|
||||
void xe_xbdm_release(xe_xbdm_ref module);
|
||||
class XboxkrnlModule : public KernelModule {
|
||||
public:
|
||||
XboxkrnlModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> resolver);
|
||||
virtual ~XboxkrnlModule();
|
||||
};
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBDM_H_
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
||||
File diff suppressed because it is too large
Load Diff
139
src/kernel/runtime.cc
Normal file
139
src/kernel/runtime.cc
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/kernel/runtime.h>
|
||||
|
||||
#include "kernel/modules/modules.h"
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
Runtime::Runtime(xe_pal_ref pal, shared_ptr<cpu::Processor> processor,
|
||||
const xechar_t* command_line) {
|
||||
pal_ = xe_pal_retain(pal);
|
||||
memory_ = processor->memory();
|
||||
processor_ = processor;
|
||||
XEIGNORE(xestrcpy(command_line_, XECOUNT(command_line_), command_line));
|
||||
export_resolver_ = shared_ptr<ExportResolver>(new ExportResolver());
|
||||
|
||||
kernel_modules_.push_back(
|
||||
new xboxkrnl::XboxkrnlModule(pal_, memory_, export_resolver_));
|
||||
kernel_modules_.push_back(
|
||||
new xbdm::XbdmModule(pal_, memory_, export_resolver_));
|
||||
kernel_modules_.push_back(
|
||||
new xam::XamModule(pal_, memory_, export_resolver_));
|
||||
}
|
||||
|
||||
Runtime::~Runtime() {
|
||||
for (std::map<const xechar_t*, UserModule*>::iterator it =
|
||||
user_modules_.begin(); it != user_modules_.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
for (std::vector<KernelModule*>::iterator it = kernel_modules_.begin();
|
||||
it != kernel_modules_.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
xe_memory_release(memory_);
|
||||
xe_pal_release(pal_);
|
||||
}
|
||||
|
||||
xe_pal_ref Runtime::pal() {
|
||||
return xe_pal_retain(pal_);
|
||||
}
|
||||
|
||||
xe_memory_ref Runtime::memory() {
|
||||
return xe_memory_retain(memory_);
|
||||
}
|
||||
|
||||
shared_ptr<cpu::Processor> Runtime::processor() {
|
||||
return processor_;
|
||||
}
|
||||
|
||||
shared_ptr<ExportResolver> Runtime::export_resolver() {
|
||||
return export_resolver_;
|
||||
}
|
||||
|
||||
const xechar_t* Runtime::command_line() {
|
||||
return command_line_;
|
||||
}
|
||||
|
||||
int Runtime::LoadModule(const xechar_t* path) {
|
||||
if (GetModule(path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(benvanik): map file from filesystem
|
||||
xe_mmap_ref mmap = xe_mmap_open(pal_, kXEFileModeRead, path, 0, 0);
|
||||
if (!mmap) {
|
||||
return NULL;
|
||||
}
|
||||
void* addr = xe_mmap_get_addr(mmap);
|
||||
size_t length = xe_mmap_get_length(mmap);
|
||||
|
||||
UserModule* module = new UserModule(memory_);
|
||||
int result_code = module->Load(addr, length, path);
|
||||
|
||||
// TODO(benvanik): retain memory somehow? is it needed?
|
||||
xe_mmap_release(mmap);
|
||||
|
||||
if (result_code) {
|
||||
delete module;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Prepare the module.
|
||||
XEEXPECTZERO(processor_->PrepareModule(module, export_resolver_));
|
||||
|
||||
// Stash in modules list (takes reference).
|
||||
user_modules_.insert(std::pair<const xechar_t*, UserModule*>(path, module));
|
||||
|
||||
return 0;
|
||||
|
||||
XECLEANUP:
|
||||
delete module;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Runtime::LaunchModule(UserModule* user_module) {
|
||||
//const xe_xex2_header_t *xex_header = xe_module_get_xex_header(module);
|
||||
|
||||
// TODO(benvanik): set as main module/etc
|
||||
// xekXexExecutableModuleHandle = xe_module_get_handle(module);
|
||||
|
||||
// XEEXPECTTRUE(XECPUPrepareModule(XEGetCPU(), module->xex, module->pe, module->address_space, module->address_space_size));
|
||||
|
||||
// Setup the heap (and TLS?).
|
||||
// xex_header->exe_heap_size;
|
||||
|
||||
// Launch thread.
|
||||
// XHANDLE thread_handle;
|
||||
// XDWORD thread_id;
|
||||
// XBOOL result = xekExCreateThread(&thread_handle, xex_header->exe_stack_size, &thread_id, NULL, (void*)xex_header->exe_entry_point, NULL, 0);
|
||||
|
||||
// Wait until thread completes.
|
||||
// XLARGE_INTEGER timeout = XINFINITE;
|
||||
// xekNtWaitForSingleObjectEx(thread_handle, TRUE, &timeout);
|
||||
}
|
||||
|
||||
UserModule* Runtime::GetModule(const xechar_t* path) {
|
||||
std::map<const xechar_t*, UserModule*>::iterator it =
|
||||
user_modules_.find(path);
|
||||
if (it != user_modules_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Runtime::UnloadModule(UserModule* user_module) {
|
||||
// TODO(benvanik): unload module
|
||||
XEASSERTALWAYS();
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
{
|
||||
'sources': [
|
||||
'export.cc',
|
||||
'kernel.cc',
|
||||
'module.cc',
|
||||
'runtime.cc',
|
||||
'user_module.cc',
|
||||
'xex2.cc',
|
||||
],
|
||||
|
||||
|
||||
@@ -7,97 +7,72 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/kernel/module.h>
|
||||
#include <xenia/kernel/user_module.h>
|
||||
|
||||
#include <third_party/pe/pe_image.h>
|
||||
|
||||
|
||||
#define kXEModuleMaxSectionCount 32
|
||||
|
||||
typedef struct xe_module {
|
||||
xe_ref_t ref;
|
||||
|
||||
xe_module_options_t options;
|
||||
xechar_t name[256];
|
||||
|
||||
xe_memory_ref memory;
|
||||
xe_kernel_export_resolver_ref export_resolver;
|
||||
|
||||
uint32_t handle;
|
||||
xe_xex2_ref xex;
|
||||
|
||||
size_t section_count;
|
||||
xe_module_pe_section_t sections[kXEModuleMaxSectionCount];
|
||||
} xe_module_t;
|
||||
using namespace xe;
|
||||
using namespace kernel;
|
||||
|
||||
|
||||
int xe_module_load_pe(xe_module_ref module);
|
||||
UserModule::UserModule(xe_memory_ref memory) {
|
||||
memory_ = xe_memory_retain(memory);
|
||||
xex_ = NULL;
|
||||
}
|
||||
|
||||
|
||||
xe_module_ref xe_module_load(xe_memory_ref memory,
|
||||
xe_kernel_export_resolver_ref export_resolver,
|
||||
const void *addr, const size_t length,
|
||||
xe_module_options_t options) {
|
||||
xe_module_ref module = (xe_module_ref)xe_calloc(sizeof(xe_module));
|
||||
xe_ref_init((xe_ref)module);
|
||||
|
||||
xe_copy_struct(&module->options, &options, sizeof(xe_module_options_t));
|
||||
xechar_t *slash = xestrrchr(options.path, '/');
|
||||
if (slash) {
|
||||
xestrcpy(module->name, XECOUNT(module->name), slash + 1);
|
||||
UserModule::~UserModule() {
|
||||
for (std::vector<PESection*>::iterator it = sections_.begin();
|
||||
it != sections_.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
module->memory = xe_memory_retain(memory);
|
||||
module->export_resolver = xe_kernel_export_resolver_retain(export_resolver);
|
||||
xe_xex2_release(xex_);
|
||||
xe_memory_release(memory_);
|
||||
}
|
||||
|
||||
int UserModule::Load(const void* addr, const size_t length,
|
||||
const xechar_t* path) {
|
||||
XEIGNORE(xestrcpy(path_, XECOUNT(path_), path));
|
||||
const xechar_t *slash = xestrrchr(path, '/');
|
||||
if (slash) {
|
||||
XEIGNORE(xestrcpy(name_, XECOUNT(name_), slash + 1));
|
||||
}
|
||||
|
||||
xe_xex2_options_t xex_options;
|
||||
module->xex = xe_xex2_load(memory, addr, length, xex_options);
|
||||
XEEXPECTNOTNULL(module->xex);
|
||||
xex_ = xe_xex2_load(memory_, addr, length, xex_options);
|
||||
XEEXPECTNOTNULL(xex_);
|
||||
|
||||
XEEXPECTZERO(xe_module_load_pe(module));
|
||||
XEEXPECTZERO(LoadPE());
|
||||
|
||||
return module;
|
||||
return 0;
|
||||
|
||||
XECLEANUP:
|
||||
xe_module_release(module);
|
||||
return NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xe_module_dealloc(xe_module_ref module) {
|
||||
xe_kernel_export_resolver_release(module->export_resolver);
|
||||
xe_memory_release(module->memory);
|
||||
const xechar_t* UserModule::path() {
|
||||
return path_;
|
||||
}
|
||||
|
||||
xe_module_ref xe_module_retain(xe_module_ref module) {
|
||||
xe_ref_retain((xe_ref)module);
|
||||
return module;
|
||||
const xechar_t* UserModule::name() {
|
||||
return name_;
|
||||
}
|
||||
|
||||
void xe_module_release(xe_module_ref module) {
|
||||
xe_ref_release((xe_ref)module, (xe_ref_dealloc_t)xe_module_dealloc);
|
||||
uint32_t UserModule::handle() {
|
||||
return handle_;
|
||||
}
|
||||
|
||||
const xechar_t *xe_module_get_path(xe_module_ref module) {
|
||||
return module->options.path;
|
||||
xe_xex2_ref UserModule::xex() {
|
||||
return xe_xex2_retain(xex_);
|
||||
}
|
||||
|
||||
const xechar_t *xe_module_get_name(xe_module_ref module) {
|
||||
return module->name;
|
||||
const xe_xex2_header_t* UserModule::xex_header() {
|
||||
return xe_xex2_get_header(xex_);
|
||||
}
|
||||
|
||||
uint32_t xe_module_get_handle(xe_module_ref module) {
|
||||
return module->handle;
|
||||
}
|
||||
|
||||
xe_xex2_ref xe_module_get_xex(xe_module_ref module) {
|
||||
return xe_xex2_retain(module->xex);
|
||||
}
|
||||
|
||||
const xe_xex2_header_t *xe_module_get_xex_header(xe_module_ref module) {
|
||||
return xe_xex2_get_header(module->xex);
|
||||
}
|
||||
|
||||
void *xe_module_get_proc_address(xe_module_ref module, const uint32_t ordinal) {
|
||||
void* UserModule::GetProcAddress(const uint32_t ordinal) {
|
||||
XEASSERTALWAYS();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -116,10 +91,10 @@ typedef struct IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY_t {
|
||||
};
|
||||
} IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY;
|
||||
|
||||
int xe_module_load_pe(xe_module_ref module) {
|
||||
const xe_xex2_header_t *xex_header = xe_xex2_get_header(module->xex);
|
||||
uint8_t *mem = (uint8_t*)xe_memory_addr(module->memory, 0);
|
||||
const uint8_t *p = mem + xex_header->exe_address;
|
||||
int UserModule::LoadPE() {
|
||||
const xe_xex2_header_t* xex_header = xe_xex2_get_header(xex_);
|
||||
uint8_t* mem = xe_memory_addr(memory_, 0);
|
||||
const uint8_t* p = mem + xex_header->exe_address;
|
||||
|
||||
// Verify DOS signature (MZ).
|
||||
const IMAGE_DOS_HEADER* doshdr = (const IMAGE_DOS_HEADER*)p;
|
||||
@@ -172,14 +147,6 @@ int xe_module_load_pe(xe_module_ref module) {
|
||||
// IAT Import Address Table ptr
|
||||
//opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_X].VirtualAddress / .Size
|
||||
|
||||
// Verify section count not overrun.
|
||||
// NOTE: if this ever asserts, change to a dynamic section list.
|
||||
XEASSERT(filehdr->NumberOfSections <= kXEModuleMaxSectionCount);
|
||||
if (filehdr->NumberOfSections > kXEModuleMaxSectionCount) {
|
||||
return 1;
|
||||
}
|
||||
module->section_count = filehdr->NumberOfSections;
|
||||
|
||||
// Quick scan to determine bounds of sections.
|
||||
size_t upper_address = 0;
|
||||
const IMAGE_SECTION_HEADER* sechdr = IMAGE_FIRST_SECTION(nthdr);
|
||||
@@ -192,7 +159,7 @@ int xe_module_load_pe(xe_module_ref module) {
|
||||
// Setup/load sections.
|
||||
sechdr = IMAGE_FIRST_SECTION(nthdr);
|
||||
for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) {
|
||||
xe_module_pe_section_t *section = &module->sections[n];
|
||||
PESection* section = (PESection*)xe_calloc(sizeof(PESection));
|
||||
xe_copy_memory(section->name, sizeof(section->name),
|
||||
sechdr->Name, sizeof(sechdr->Name));
|
||||
section->name[8] = 0;
|
||||
@@ -201,6 +168,7 @@ int xe_module_load_pe(xe_module_ref module) {
|
||||
section->address = xex_header->exe_address + sechdr->VirtualAddress;
|
||||
section->size = sechdr->Misc.VirtualSize;
|
||||
section->flags = sechdr->Characteristics;
|
||||
sections_.push_back(section);
|
||||
}
|
||||
|
||||
//DumpTLSDirectory(pImageBase, pNTHeader, (PIMAGE_TLS_DIRECTORY32)0);
|
||||
@@ -208,48 +176,45 @@ int xe_module_load_pe(xe_module_ref module) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
xe_module_pe_section_t *xe_module_get_section(xe_module_ref module,
|
||||
const char *name) {
|
||||
for (size_t n = 0; n < module->section_count; n++) {
|
||||
if (xestrcmpa(module->sections[n].name, name) == 0) {
|
||||
return &module->sections[n];
|
||||
PESection* UserModule::GetSection(const char *name) {
|
||||
for (std::vector<PESection*>::iterator it = sections_.begin();
|
||||
it != sections_.end(); ++it) {
|
||||
if (!xestrcmpa((*it)->name, name)) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int xe_module_get_method_hints(xe_module_ref module,
|
||||
xe_module_pe_method_info_t **out_method_infos,
|
||||
size_t *out_method_info_count) {
|
||||
uint8_t *mem = (uint8_t*)xe_memory_addr(module->memory, 0);
|
||||
int UserModule::GetMethodHints(PEMethodInfo** out_method_infos,
|
||||
size_t* out_method_info_count) {
|
||||
uint8_t* mem = xe_memory_addr(memory_, 0);
|
||||
|
||||
*out_method_infos = NULL;
|
||||
*out_method_info_count = 0;
|
||||
|
||||
const IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY *entry = NULL;
|
||||
const IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY* entry = NULL;
|
||||
|
||||
// Find pdata, which contains the exception handling entries.
|
||||
xe_module_pe_section_t *pdata = xe_module_get_section(module, ".pdata");
|
||||
PESection* pdata = GetSection(".pdata");
|
||||
if (!pdata) {
|
||||
// No exception data to go on.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Resolve.
|
||||
const uint8_t *p = mem + pdata->address;
|
||||
const uint8_t* p = mem + pdata->address;
|
||||
|
||||
// Entry count = pdata size / sizeof(entry).
|
||||
const size_t entry_count =
|
||||
pdata->size / sizeof(IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY);
|
||||
if (entry_count == 0) {
|
||||
size_t entry_count = pdata->size / sizeof(IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY);
|
||||
if (!entry_count) {
|
||||
// Empty?
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate output.
|
||||
xe_module_pe_method_info_t *method_infos =
|
||||
(xe_module_pe_method_info_t*)xe_calloc(
|
||||
entry_count * sizeof(xe_module_pe_method_info_t));
|
||||
PEMethodInfo* method_infos = (PEMethodInfo*)xe_calloc(
|
||||
entry_count * sizeof(PEMethodInfo));
|
||||
XEEXPECTNOTNULL(method_infos);
|
||||
|
||||
// Parse entries.
|
||||
@@ -258,7 +223,7 @@ int xe_module_get_method_hints(xe_module_ref module,
|
||||
entry = (const IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY*)p;
|
||||
IMAGE_XBOX_RUNTIME_FUNCTION_ENTRY temp_entry;
|
||||
for (size_t n = 0; n < entry_count; n++, entry++) {
|
||||
xe_module_pe_method_info_t *method_info = &method_infos[n];
|
||||
PEMethodInfo* method_info = &method_infos[n];
|
||||
method_info->address = XESWAP32BE(entry->FuncStart);
|
||||
|
||||
// The bitfield needs to be swapped by hand.
|
||||
@@ -278,12 +243,12 @@ XECLEANUP:
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xe_module_dump(xe_module_ref module) {
|
||||
//const uint8_t *mem = (const uint8_t*)xe_memory_addr(module->memory, 0);
|
||||
const xe_xex2_header_t *header = xe_xex2_get_header(module->xex);
|
||||
void UserModule::Dump(ExportResolver* export_resolver) {
|
||||
//const uint8_t *mem = (const uint8_t*)xe_memory_addr(memory_, 0);
|
||||
const xe_xex2_header_t* header = xe_xex2_get_header(xex_);
|
||||
|
||||
// XEX info.
|
||||
printf("Module %s:\n\n", module->options.path);
|
||||
printf("Module %s:\n\n", path_);
|
||||
printf(" Module Flags: %.8X\n", header->module_flags);
|
||||
printf(" System Flags: %.8X\n", header->system_flags);
|
||||
printf("\n");
|
||||
@@ -320,11 +285,11 @@ void xe_module_dump(xe_module_ref module) {
|
||||
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];
|
||||
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);
|
||||
@@ -334,14 +299,14 @@ void xe_module_dump(xe_module_ref module) {
|
||||
// Resources.
|
||||
printf("Resources:\n");
|
||||
printf(" %.8X, %db\n", header->resource_info.address,
|
||||
header->resource_info.size);
|
||||
header->resource_info.size);
|
||||
printf(" TODO\n");
|
||||
printf("\n");
|
||||
|
||||
// Section info.
|
||||
printf("Sections:\n");
|
||||
for (size_t n = 0, i = 0; n < header->section_count; n++) {
|
||||
const xe_xex2_section_t *section = &header->sections[n];
|
||||
const xe_xex2_section_t* section = &header->sections[n];
|
||||
const char* type = "UNKNOWN";
|
||||
switch (section->info.type) {
|
||||
case XEX_SECTION_CODE:
|
||||
@@ -354,10 +319,10 @@ void xe_module_dump(xe_module_ref module) {
|
||||
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);
|
||||
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);
|
||||
@@ -369,7 +334,8 @@ void xe_module_dump(xe_module_ref module) {
|
||||
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,
|
||||
printf(" %-8s : %d.%d.%d.%d\n",
|
||||
library->name, library->major,
|
||||
library->minor, library->build, library->qfe);
|
||||
}
|
||||
printf("\n");
|
||||
@@ -377,11 +343,11 @@ void xe_module_dump(xe_module_ref module) {
|
||||
// Imports.
|
||||
printf("Imports:\n");
|
||||
for (size_t n = 0; n < header->import_library_count; n++) {
|
||||
const xe_xex2_import_library_t *library = &header->import_libraries[n];
|
||||
const xe_xex2_import_library_t* library = &header->import_libraries[n];
|
||||
|
||||
xe_xex2_import_info_t* import_infos;
|
||||
size_t import_info_count;
|
||||
if (!xe_xex2_get_import_infos(module->xex, library,
|
||||
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",
|
||||
@@ -398,13 +364,12 @@ void xe_module_dump(xe_module_ref module) {
|
||||
int impl_count = 0;
|
||||
int unimpl_count = 0;
|
||||
for (size_t m = 0; m < import_info_count; m++) {
|
||||
const xe_xex2_import_info_t *info = &import_infos[m];
|
||||
const xe_kernel_export_t *kernel_export =
|
||||
xe_kernel_export_resolver_get_by_ordinal(
|
||||
module->export_resolver, library->name, info->ordinal);
|
||||
const xe_xex2_import_info_t* info = &import_infos[m];
|
||||
KernelExport* kernel_export =
|
||||
export_resolver->GetExportByOrdinal(library->name, info->ordinal);
|
||||
if (kernel_export) {
|
||||
known_count++;
|
||||
if (xe_kernel_export_is_implemented(kernel_export)) {
|
||||
if (kernel_export->IsImplemented()) {
|
||||
impl_count++;
|
||||
}
|
||||
} else {
|
||||
@@ -423,15 +388,14 @@ void xe_module_dump(xe_module_ref module) {
|
||||
|
||||
// Listing.
|
||||
for (size_t m = 0; m < import_info_count; m++) {
|
||||
const xe_xex2_import_info_t *info = &import_infos[m];
|
||||
const xe_kernel_export_t *kernel_export =
|
||||
xe_kernel_export_resolver_get_by_ordinal(
|
||||
module->export_resolver, library->name, info->ordinal);
|
||||
const xe_xex2_import_info_t* info = &import_infos[m];
|
||||
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 = xe_kernel_export_is_implemented(kernel_export);
|
||||
implemented = kernel_export->IsImplemented();
|
||||
}
|
||||
if (info->thunk_address) {
|
||||
printf(" F %.8X %.8X %.3X (%3d) %s %s\n",
|
||||
Reference in New Issue
Block a user