Kernel function work.
This commit is contained in:
parent
42009cda88
commit
23378443e8
2
TODO.md
2
TODO.md
|
@ -9,8 +9,6 @@ Ordered:
|
||||||
```
|
```
|
||||||
RtlInitializeCriticalSection/RtlInitializeCriticalSectionAndSpinCount
|
RtlInitializeCriticalSection/RtlInitializeCriticalSectionAndSpinCount
|
||||||
RtlEnterCriticalSection/RtlLeaveCriticalSection
|
RtlEnterCriticalSection/RtlLeaveCriticalSection
|
||||||
XexCheckExecutablePrivilege
|
|
||||||
XGetAVPack
|
|
||||||
ExGetXConfigSetting
|
ExGetXConfigSetting
|
||||||
KeTlsAlloc
|
KeTlsAlloc
|
||||||
KeTlsSetValue
|
KeTlsSetValue
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#define XENIA_KERNEL_MODULES_H_
|
#define XENIA_KERNEL_MODULES_H_
|
||||||
|
|
||||||
#include "kernel/modules/xam/xam_module.h"
|
#include "kernel/modules/xam/xam_module.h"
|
||||||
#include "kernel/modules/xbdm/xbdm_module.h"
|
#include "kernel/modules/xboxkrnl/module.h"
|
||||||
#include "kernel/modules/xboxkrnl/xboxkrnl_module.h"
|
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_MODULES_H_
|
#endif // XENIA_KERNEL_MODULES_H_
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
{
|
{
|
||||||
'includes': [
|
'includes': [
|
||||||
'xam/sources.gypi',
|
'xam/sources.gypi',
|
||||||
'xbdm/sources.gypi',
|
|
||||||
'xboxkrnl/sources.gypi',
|
'xboxkrnl/sources.gypi',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||||
{
|
{
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'xam_info.cc',
|
||||||
'xam_module.cc',
|
'xam_module.cc',
|
||||||
|
'xam_state.cc',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* 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_info.h"
|
||||||
|
|
||||||
|
#include "kernel/shim_utils.h"
|
||||||
|
#include "kernel/modules/xam/xam_module.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::kernel;
|
||||||
|
using namespace xe::kernel::xam;
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
void XGetAVPack_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, XamState* state) {
|
||||||
|
// DWORD
|
||||||
|
// Not sure what the values are for this, but 6 is VGA.
|
||||||
|
// Other likely values are 3/4/8 for HDMI or something.
|
||||||
|
// Games seem to use this as a PAL check - if the result is not 3/4/6/8
|
||||||
|
// they explode with errors if not in PAL mode.
|
||||||
|
SHIM_SET_RETURN(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xe::kernel::xam::RegisterInfoExports(
|
||||||
|
ExportResolver* export_resolver, XamState* state) {
|
||||||
|
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||||
|
export_resolver->SetFunctionMapping("xam.xex", ordinal, \
|
||||||
|
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||||
|
|
||||||
|
SHIM_SET_MAPPING(0x000003CB, XGetAVPack_shim, NULL);
|
||||||
|
|
||||||
|
#undef SET_MAPPING
|
||||||
|
}
|
|
@ -7,31 +7,23 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_KERNEL_MODULES_XBDM_TABLE_H_
|
#ifndef XENIA_KERNEL_MODULES_XAM_INFO_H_
|
||||||
#define XENIA_KERNEL_MODULES_XBDM_TABLE_H_
|
#define XENIA_KERNEL_MODULES_XAM_INFO_H_
|
||||||
|
|
||||||
#include <xenia/kernel/export.h>
|
#include "kernel/modules/xam/xam_state.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xbdm {
|
namespace xam {
|
||||||
|
|
||||||
|
|
||||||
#define FLAG(t) kXEKernelExportFlag##t
|
void RegisterInfoExports(ExportResolver* export_resolver, XamState* state);
|
||||||
|
|
||||||
|
|
||||||
static KernelExport xbdm_export_table[] = {
|
} // namespace xam
|
||||||
{ 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#undef FLAG
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace xbdm
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_MODULES_XBDM_TABLE_H_
|
#endif // XENIA_KERNEL_MODULES_XAM_INFO_H_
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include "kernel/modules/xam/xam_module.h"
|
#include "kernel/modules/xam/xam_module.h"
|
||||||
|
|
||||||
|
#include "kernel/modules/xam/xam_info.h"
|
||||||
|
|
||||||
#include "kernel/modules/xam/xam_table.h"
|
#include "kernel/modules/xam/xam_table.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +24,12 @@ XamModule::XamModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||||
KernelModule(pal, memory, resolver) {
|
KernelModule(pal, memory, resolver) {
|
||||||
resolver->RegisterTable(
|
resolver->RegisterTable(
|
||||||
"xam.xex", xam_export_table, XECOUNT(xam_export_table));
|
"xam.xex", xam_export_table, XECOUNT(xam_export_table));
|
||||||
|
|
||||||
|
// Setup the xam state instance.
|
||||||
|
xam_state = auto_ptr<XamState>(new XamState(pal, memory, resolver));
|
||||||
|
|
||||||
|
// Register all exported functions.
|
||||||
|
RegisterInfoExports(resolver.get(), xam_state.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
XamModule::~XamModule() {
|
XamModule::~XamModule() {
|
||||||
|
|
|
@ -21,12 +21,17 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xam {
|
namespace xam {
|
||||||
|
|
||||||
|
class XamState;
|
||||||
|
|
||||||
|
|
||||||
class XamModule : public KernelModule {
|
class XamModule : public KernelModule {
|
||||||
public:
|
public:
|
||||||
XamModule(xe_pal_ref pal, xe_memory_ref memory,
|
XamModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||||
shared_ptr<ExportResolver> resolver);
|
shared_ptr<ExportResolver> resolver);
|
||||||
virtual ~XamModule();
|
virtual ~XamModule();
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto_ptr<XamState> xam_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,22 +7,27 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/modules/xbdm/xbdm_module.h"
|
#include "kernel/modules/xam/xam_state.h"
|
||||||
|
|
||||||
#include "kernel/modules/xbdm/xbdm_table.h"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
using namespace xe::kernel::xbdm;
|
using namespace xe::kernel::xam;
|
||||||
|
|
||||||
|
|
||||||
XbdmModule::XbdmModule(xe_pal_ref pal, xe_memory_ref memory,
|
namespace {
|
||||||
shared_ptr<ExportResolver> resolver) :
|
|
||||||
KernelModule(pal, memory, resolver) {
|
|
||||||
resolver->RegisterTable(
|
|
||||||
"xbdm.exe", xbdm_export_table, XECOUNT(xbdm_export_table));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XbdmModule::~XbdmModule() {
|
|
||||||
|
XamState::XamState(xe_pal_ref pal, xe_memory_ref memory,
|
||||||
|
shared_ptr<ExportResolver> export_resolver) {
|
||||||
|
this->pal = xe_pal_retain(pal);
|
||||||
|
this->memory = xe_memory_retain(memory);
|
||||||
|
export_resolver_ = export_resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
XamState::~XamState() {
|
||||||
|
xe_memory_release(memory);
|
||||||
|
xe_pal_release(pal);
|
||||||
}
|
}
|
|
@ -7,8 +7,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_KERNEL_MODULES_XBDM_MODULE_H_
|
#ifndef XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
|
||||||
#define XENIA_KERNEL_MODULES_XBDM_MODULE_H_
|
#define XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
|
||||||
|
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
@ -19,20 +19,26 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xbdm {
|
namespace xam {
|
||||||
|
|
||||||
|
|
||||||
class XbdmModule : public KernelModule {
|
class XamState {
|
||||||
public:
|
public:
|
||||||
XbdmModule(xe_pal_ref pal, xe_memory_ref memory,
|
XamState(xe_pal_ref pal, xe_memory_ref memory,
|
||||||
shared_ptr<ExportResolver> resolver);
|
shared_ptr<ExportResolver> export_resolver);
|
||||||
virtual ~XbdmModule();
|
~XamState();
|
||||||
|
|
||||||
|
xe_pal_ref pal;
|
||||||
|
xe_memory_ref memory;
|
||||||
|
|
||||||
|
private:
|
||||||
|
shared_ptr<ExportResolver> export_resolver_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace xbdm
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_MODULES_XBDM_MODULE_H_
|
#endif // XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
|
|
@ -1,6 +0,0 @@
|
||||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
|
||||||
{
|
|
||||||
'sources': [
|
|
||||||
'xbdm_module.cc',
|
|
||||||
],
|
|
||||||
}
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* 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/module.h"
|
||||||
|
|
||||||
|
#include "kernel/modules/xboxkrnl/kernel_state.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/xboxkrnl_hal.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/xboxkrnl_memory.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/xboxkrnl_module.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/xboxkrnl_rtl.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/xboxkrnl_threading.h"
|
||||||
|
|
||||||
|
#include "kernel/modules/xboxkrnl/xboxkrnl_table.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::kernel;
|
||||||
|
using namespace xe::kernel::xboxkrnl;
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
// Setup the kernel state instance.
|
||||||
|
// This is where all kernel objects are kept while running.
|
||||||
|
kernel_state = auto_ptr<KernelState>(new KernelState(pal, memory, resolver));
|
||||||
|
|
||||||
|
// Register all exported functions.
|
||||||
|
RegisterHalExports(resolver.get(), kernel_state.get());
|
||||||
|
RegisterMemoryExports(resolver.get(), kernel_state.get());
|
||||||
|
RegisterModuleExports(resolver.get(), kernel_state.get());
|
||||||
|
RegisterRtlExports(resolver.get(), kernel_state.get());
|
||||||
|
RegisterThreadingExports(resolver.get(), kernel_state.get());
|
||||||
|
|
||||||
|
// TODO(benvanik): alloc heap memory somewhere in user space
|
||||||
|
// TODO(benvanik): tools for reading/writing to heap memory
|
||||||
|
|
||||||
|
uint8_t* mem = xe_memory_addr(memory, 0);
|
||||||
|
|
||||||
|
// KeDebugMonitorData (?*)
|
||||||
|
// I'm not sure what this is for, but games make sure it's not null and
|
||||||
|
// exit if it is.
|
||||||
|
resolver->SetVariableMapping(
|
||||||
|
"xboxkrnl.exe", 0x00000059,
|
||||||
|
0x80102100);
|
||||||
|
XESETUINT32BE(mem + 0x80102100, 0x1);
|
||||||
|
|
||||||
|
// XboxHardwareInfo (XboxHardwareInfo_t, 16b)
|
||||||
|
// flags cpu# ? ? ? ? ? ?
|
||||||
|
// 0x00000000, 0x06, 0x00, 0x00, 0x00, 0x00000000, 0x0000, 0x0000
|
||||||
|
// Games seem to check if bit 26 (0x20) is set, which at least for xbox1
|
||||||
|
// was whether an HDD was present. Not sure what the other flags are.
|
||||||
|
resolver->SetVariableMapping(
|
||||||
|
"xboxkrnl.exe", 0x00000156,
|
||||||
|
0x80100FED);
|
||||||
|
XESETUINT32BE(mem + 0x80100FED, 0x00000000); // flags
|
||||||
|
XESETUINT8BE(mem + 0x80100FEE, 0x06); // cpu count
|
||||||
|
// Remaining 11b are zeroes?
|
||||||
|
|
||||||
|
// XexExecutableModuleHandle (?**)
|
||||||
|
// Games try to dereference this to get a pointer to some module struct.
|
||||||
|
// So far it seems like it's just in loader code, and only used to look up
|
||||||
|
// the XexHeaderBase for use by RtlImageXexHeaderField.
|
||||||
|
// We fake it so that the address passed to that looks legit.
|
||||||
|
// 0x80100FFC <- pointer to structure
|
||||||
|
// 0x80101000 <- our module structure
|
||||||
|
// 0x80101058 <- pointer to xex header
|
||||||
|
// 0x80101100 <- xex header base
|
||||||
|
resolver->SetVariableMapping(
|
||||||
|
"xboxkrnl.exe", 0x00000193,
|
||||||
|
0x80100FFC);
|
||||||
|
XESETUINT32BE(mem + 0x80100FFC, 0x80101000);
|
||||||
|
XESETUINT32BE(mem + 0x80101058, 0x80101100);
|
||||||
|
|
||||||
|
// ExLoadedCommandLine (char*)
|
||||||
|
// The name of the xex. Not sure this is ever really used on real devices.
|
||||||
|
// Perhaps it's how swap disc/etc data is sent?
|
||||||
|
// Always set to "default.xex" (with quotes) for now.
|
||||||
|
resolver->SetVariableMapping(
|
||||||
|
"xboxkrnl.exe", 0x000001AE,
|
||||||
|
0x80102000);
|
||||||
|
char command_line[] = "\"default.xex\"";
|
||||||
|
xe_copy_memory(mem + 0x80102000, 1024,
|
||||||
|
command_line, XECOUNT(command_line) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XboxkrnlModule::~XboxkrnlModule() {
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* 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. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace kernel {
|
||||||
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
class KernelState;
|
||||||
|
|
||||||
|
|
||||||
|
class XboxkrnlModule : public KernelModule {
|
||||||
|
public:
|
||||||
|
XboxkrnlModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||||
|
shared_ptr<ExportResolver> resolver);
|
||||||
|
virtual ~XboxkrnlModule();
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto_ptr<KernelState> kernel_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xboxkrnl
|
||||||
|
} // namespace kernel
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
|
@ -2,6 +2,7 @@
|
||||||
{
|
{
|
||||||
'sources': [
|
'sources': [
|
||||||
'kernel_state.cc',
|
'kernel_state.cc',
|
||||||
|
'module.cc',
|
||||||
'xboxkrnl_hal.cc',
|
'xboxkrnl_hal.cc',
|
||||||
'xboxkrnl_memory.cc',
|
'xboxkrnl_memory.cc',
|
||||||
'xboxkrnl_module.cc',
|
'xboxkrnl_module.cc',
|
||||||
|
|
|
@ -75,6 +75,10 @@ typedef uint32_t X_HANDLE;
|
||||||
#define X_PROCTYPE_SYSTEM 2
|
#define X_PROCTYPE_SYSTEM 2
|
||||||
|
|
||||||
|
|
||||||
|
// TLS specials.
|
||||||
|
#define X_TLS_OUT_OF_INDEXES UINT32_MAX // (-1)
|
||||||
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -9,13 +9,10 @@
|
||||||
|
|
||||||
#include "kernel/modules/xboxkrnl/xboxkrnl_module.h"
|
#include "kernel/modules/xboxkrnl/xboxkrnl_module.h"
|
||||||
|
|
||||||
#include "kernel/modules/xboxkrnl/kernel_state.h"
|
#include <xenia/kernel/xex2.h>
|
||||||
#include "kernel/modules/xboxkrnl/xboxkrnl_hal.h"
|
|
||||||
#include "kernel/modules/xboxkrnl/xboxkrnl_memory.h"
|
|
||||||
#include "kernel/modules/xboxkrnl/xboxkrnl_rtl.h"
|
|
||||||
#include "kernel/modules/xboxkrnl/xboxkrnl_threading.h"
|
|
||||||
|
|
||||||
#include "kernel/modules/xboxkrnl/xboxkrnl_table.h"
|
#include "kernel/shim_utils.h"
|
||||||
|
#include "kernel/modules/xboxkrnl/xboxkrnl.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
|
@ -25,76 +22,87 @@ using namespace xe::kernel::xboxkrnl;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
// void ExGetXConfigSetting_shim(
|
||||||
|
// xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// // ?
|
||||||
|
// SHIM_SET_RETURN(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
void XexCheckExecutablePrivilege_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// BOOL
|
||||||
|
// DWORD Privilege
|
||||||
|
|
||||||
|
uint32_t privilege = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("XexCheckExecutablePrivilege(%.8X)"),
|
||||||
|
privilege);
|
||||||
|
|
||||||
|
// Privilege is bit position in xe_xex2_system_flags enum - so:
|
||||||
|
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
||||||
|
uint32_t mask = 1 << privilege;
|
||||||
|
|
||||||
|
// TODO(benvanik): pull from xex header:
|
||||||
|
// XEKernelModuleRef module = XEKernelGetExecutableModule(XEGetKernel());
|
||||||
|
// const XEXHeader* xexhdr = XEKernelModuleGetXEXHeader(module);
|
||||||
|
// return xexhdr->systemFlags & mask;
|
||||||
|
|
||||||
|
if (mask == XEX_SYSTEM_PAL50_INCOMPATIBLE) {
|
||||||
|
// Only one we've seen.
|
||||||
|
} else {
|
||||||
|
XELOGW(XT("XexCheckExecutablePrivilege: %.8X is NOT IMPLEMENTED"),
|
||||||
|
privilege);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XboxkrnlModule::XboxkrnlModule(xe_pal_ref pal, xe_memory_ref memory,
|
void XexGetModuleHandle_shim(
|
||||||
shared_ptr<ExportResolver> resolver) :
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
KernelModule(pal, memory, resolver) {
|
// BOOL
|
||||||
resolver->RegisterTable(
|
// LPCSZ ModuleName
|
||||||
"xboxkrnl.exe", xboxkrnl_export_table, XECOUNT(xboxkrnl_export_table));
|
// LPHMODULE ModuleHandle
|
||||||
|
|
||||||
// Setup the kernel state instance.
|
uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
|
||||||
// This is where all kernel objects are kept while running.
|
const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
|
||||||
kernel_state = auto_ptr<KernelState>(new KernelState(pal, memory, resolver));
|
uint32_t module_handle_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
// Register all exported functions.
|
XELOGD(
|
||||||
RegisterHalExports(resolver.get(), kernel_state.get());
|
XT("XexGetModuleHandle(%s, %.8X)"),
|
||||||
RegisterMemoryExports(resolver.get(), kernel_state.get());
|
module_name, module_handle_ptr);
|
||||||
RegisterRtlExports(resolver.get(), kernel_state.get());
|
|
||||||
RegisterThreadingExports(resolver.get(), kernel_state.get());
|
|
||||||
|
|
||||||
// TODO(benvanik): alloc heap memory somewhere in user space
|
XEASSERTALWAYS();
|
||||||
// TODO(benvanik): tools for reading/writing to heap memory
|
|
||||||
|
|
||||||
uint8_t* mem = xe_memory_addr(memory, 0);
|
// TODO(benvanik): get module
|
||||||
|
// XEKernelModuleRef module = XEKernelGetModuleByName(XEGetKernel(), ModuleName);
|
||||||
|
// if (!module) {
|
||||||
|
SHIM_SET_RETURN(0);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
// KeDebugMonitorData (?*)
|
// SHIM_SET_MEM_32(module_handle_ptr, module->handle());
|
||||||
// I'm not sure what this is for, but games make sure it's not null and
|
// SHIM_SET_RETURN(1);
|
||||||
// exit if it is.
|
|
||||||
resolver->SetVariableMapping(
|
|
||||||
"xboxkrnl.exe", 0x00000059,
|
|
||||||
0x80102100);
|
|
||||||
XESETUINT32BE(mem + 0x80102100, 0x1);
|
|
||||||
|
|
||||||
// XboxHardwareInfo (XboxHardwareInfo_t, 16b)
|
|
||||||
// flags cpu# ? ? ? ? ? ?
|
|
||||||
// 0x00000000, 0x06, 0x00, 0x00, 0x00, 0x00000000, 0x0000, 0x0000
|
|
||||||
// Games seem to check if bit 26 (0x20) is set, which at least for xbox1
|
|
||||||
// was whether an HDD was present. Not sure what the other flags are.
|
|
||||||
resolver->SetVariableMapping(
|
|
||||||
"xboxkrnl.exe", 0x00000156,
|
|
||||||
0x80100FED);
|
|
||||||
XESETUINT32BE(mem + 0x80100FED, 0x00000000); // flags
|
|
||||||
XESETUINT8BE(mem + 0x80100FEE, 0x06); // cpu count
|
|
||||||
// Remaining 11b are zeroes?
|
|
||||||
|
|
||||||
// XexExecutableModuleHandle (?**)
|
|
||||||
// Games try to dereference this to get a pointer to some module struct.
|
|
||||||
// So far it seems like it's just in loader code, and only used to look up
|
|
||||||
// the XexHeaderBase for use by RtlImageXexHeaderField.
|
|
||||||
// We fake it so that the address passed to that looks legit.
|
|
||||||
// 0x80100FFC <- pointer to structure
|
|
||||||
// 0x80101000 <- our module structure
|
|
||||||
// 0x80101058 <- pointer to xex header
|
|
||||||
// 0x80101100 <- xex header base
|
|
||||||
resolver->SetVariableMapping(
|
|
||||||
"xboxkrnl.exe", 0x00000193,
|
|
||||||
0x80100FFC);
|
|
||||||
XESETUINT32BE(mem + 0x80100FFC, 0x80101000);
|
|
||||||
XESETUINT32BE(mem + 0x80101058, 0x80101100);
|
|
||||||
|
|
||||||
// ExLoadedCommandLine (char*)
|
|
||||||
// The name of the xex. Not sure this is ever really used on real devices.
|
|
||||||
// Perhaps it's how swap disc/etc data is sent?
|
|
||||||
// Always set to "default.xex" (with quotes) for now.
|
|
||||||
resolver->SetVariableMapping(
|
|
||||||
"xboxkrnl.exe", 0x000001AE,
|
|
||||||
0x80102000);
|
|
||||||
char command_line[] = "\"default.xex\"";
|
|
||||||
xe_copy_memory(mem + 0x80102000, 1024,
|
|
||||||
command_line, XECOUNT(command_line) + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XboxkrnlModule::~XboxkrnlModule() {
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xe::kernel::xboxkrnl::RegisterModuleExports(
|
||||||
|
ExportResolver* export_resolver, KernelState* state) {
|
||||||
|
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||||
|
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||||
|
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||||
|
|
||||||
|
//SHIM_SET_MAPPING(0x00000010, ExGetXConfigSetting_shim, NULL);
|
||||||
|
|
||||||
|
SHIM_SET_MAPPING(0x00000194, XexCheckExecutablePrivilege_shim, NULL);
|
||||||
|
|
||||||
|
SHIM_SET_MAPPING(0x00000195, XexGetModuleHandle_shim, NULL);
|
||||||
|
|
||||||
|
#undef SET_MAPPING
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,36 +7,23 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_IMPL_H_
|
||||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
#define XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_IMPL_H_
|
||||||
|
|
||||||
#include <xenia/common.h>
|
#include "kernel/modules/xboxkrnl/kernel_state.h"
|
||||||
#include <xenia/core.h>
|
|
||||||
|
|
||||||
#include <xenia/kernel/export.h>
|
|
||||||
#include <xenia/kernel/kernel_module.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
class KernelState;
|
|
||||||
|
|
||||||
|
void RegisterModuleExports(ExportResolver* export_resolver, KernelState* state);
|
||||||
class XboxkrnlModule : public KernelModule {
|
|
||||||
public:
|
|
||||||
XboxkrnlModule(xe_pal_ref pal, xe_memory_ref memory,
|
|
||||||
shared_ptr<ExportResolver> resolver);
|
|
||||||
virtual ~XboxkrnlModule();
|
|
||||||
|
|
||||||
private:
|
|
||||||
auto_ptr<KernelState> kernel_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
|
||||||
|
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_IMPL_H_
|
||||||
|
|
|
@ -49,6 +49,15 @@ void RtlImageXexHeaderField_shim(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(benvanik): pull from xex header
|
||||||
|
// module = GetExecutableModule() || (user defined one)
|
||||||
|
// header = module->xex_header()
|
||||||
|
// for (n = 0; n < header->header_count; n++) {
|
||||||
|
// if (header->headers[n].key == ImageField) {
|
||||||
|
// return value? or offset?
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
uint32_t return_value = 0;
|
uint32_t return_value = 0;
|
||||||
switch (image_field) {
|
switch (image_field) {
|
||||||
case XEX_HEADER_DEFAULT_HEAP_SIZE:
|
case XEX_HEADER_DEFAULT_HEAP_SIZE:
|
||||||
|
@ -68,6 +77,107 @@ void RtlImageXexHeaderField_shim(
|
||||||
SHIM_SET_RETURN(return_value);
|
SHIM_SET_RETURN(return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ff561778
|
||||||
|
void RtlCompareMemory_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// SIZE_T
|
||||||
|
// _In_ const VOID *Source1,
|
||||||
|
// _In_ const VOID *Source2,
|
||||||
|
// _In_ SIZE_T Length
|
||||||
|
|
||||||
|
uint32_t source1 = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t source2 = SHIM_GET_ARG_32(1);
|
||||||
|
uint32_t length = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("RtlCompareMemory(%.8X, %.8X, %d)"),
|
||||||
|
source1, source2, length);
|
||||||
|
|
||||||
|
uint8_t* p1 = SHIM_MEM_ADDR(source1);
|
||||||
|
uint8_t* p2 = SHIM_MEM_ADDR(source2);
|
||||||
|
|
||||||
|
// Note that the return value is the number of bytes that match, so it's best
|
||||||
|
// we just do this ourselves vs. using memcmp.
|
||||||
|
// On Windows we could use the builtin function.
|
||||||
|
|
||||||
|
uint32_t c = 0;
|
||||||
|
for (uint32_t n = 0; n < length; n++, p1++, p2++) {
|
||||||
|
if (*p1 == *p2) {
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ff552123
|
||||||
|
void RtlCompareMemoryUlong_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// SIZE_T
|
||||||
|
// _In_ PVOID Source,
|
||||||
|
// _In_ SIZE_T Length,
|
||||||
|
// _In_ ULONG Pattern
|
||||||
|
|
||||||
|
uint32_t source = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t length = SHIM_GET_ARG_32(1);
|
||||||
|
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("RtlCompareMemoryUlong(%.8X, %d, %.8X)"),
|
||||||
|
source, length, pattern);
|
||||||
|
|
||||||
|
if ((source % 4) || (length % 4)) {
|
||||||
|
SHIM_SET_RETURN(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* p = SHIM_MEM_ADDR(source);
|
||||||
|
|
||||||
|
// Swap pattern.
|
||||||
|
// TODO(benvanik): ensure byte order of pattern is correct.
|
||||||
|
// Since we are doing byte-by-byte comparison we may not want to swap.
|
||||||
|
// GET_ARG swaps, so this is a swap back. Ugly.
|
||||||
|
const uint32_t pb32 = XESWAP32BE(pattern);
|
||||||
|
const uint8_t* pb = (uint8_t*)&pb32;
|
||||||
|
|
||||||
|
uint32_t c = 0;
|
||||||
|
for (uint32_t n = 0; n < length; n++, p++) {
|
||||||
|
if (*p == pb[n % 4]) {
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ff552263
|
||||||
|
void RtlFillMemoryUlong_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// VOID
|
||||||
|
// _Out_ PVOID Destination,
|
||||||
|
// _In_ SIZE_T Length,
|
||||||
|
// _In_ ULONG Pattern
|
||||||
|
|
||||||
|
uint32_t destination = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t length = SHIM_GET_ARG_32(1);
|
||||||
|
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("RtlFillMemoryUlong(%.8X, %d, %.8X)"),
|
||||||
|
destination, length, pattern);
|
||||||
|
|
||||||
|
// NOTE: length must be % 4, so we can work on uint32s.
|
||||||
|
uint32_t* p = (uint32_t*)SHIM_MEM_ADDR(destination);
|
||||||
|
|
||||||
|
// TODO(benvanik): ensure byte order is correct - we're writing back the
|
||||||
|
// swapped arg value.
|
||||||
|
|
||||||
|
for (uint32_t n = 0; n < length / 4; n++, p++) {
|
||||||
|
*p = pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//RtlInitializeCriticalSection
|
//RtlInitializeCriticalSection
|
||||||
//RtlEnterCriticalSection
|
//RtlEnterCriticalSection
|
||||||
|
@ -82,6 +192,10 @@ void xe::kernel::xboxkrnl::RegisterRtlExports(
|
||||||
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||||
|
|
||||||
|
SHIM_SET_MAPPING(0x0000011A, RtlCompareMemory_shim, NULL);
|
||||||
|
SHIM_SET_MAPPING(0x0000011B, RtlCompareMemoryUlong_shim, NULL);
|
||||||
|
SHIM_SET_MAPPING(0x00000126, RtlFillMemoryUlong_shim, NULL);
|
||||||
|
|
||||||
SHIM_SET_MAPPING(0x0000012B, RtlImageXexHeaderField_shim, NULL);
|
SHIM_SET_MAPPING(0x0000012B, RtlImageXexHeaderField_shim, NULL);
|
||||||
|
|
||||||
#undef SET_MAPPING
|
#undef SET_MAPPING
|
||||||
|
|
|
@ -21,6 +21,55 @@ using namespace xe::kernel::xboxkrnl;
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
// r13 + 0x100: pointer to thread local state
|
||||||
|
// Thread local state:
|
||||||
|
// 0x14C: thread id
|
||||||
|
// 0x150: if >0 then error states don't get set
|
||||||
|
// 0x160: last error
|
||||||
|
|
||||||
|
// GetCurrentThreadId:
|
||||||
|
// lwz r11, 0x100(r13)
|
||||||
|
// lwz r3, 0x14C(r11)
|
||||||
|
|
||||||
|
// RtlGetLastError:
|
||||||
|
// lwz r11, 0x150(r13)
|
||||||
|
// if (r11 != 0) {
|
||||||
|
// lwz r11, 0x100(r13)
|
||||||
|
// stw r3, 0x160(r11)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// RtlSetLastError:
|
||||||
|
// lwz r11, 0x150(r13)
|
||||||
|
// if (r11 != 0) {
|
||||||
|
// lwz r11, 0x100(r13)
|
||||||
|
// stw r3, 0x160(r11)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// RtlSetLastNTError:
|
||||||
|
// r3 = RtlNtStatusToDosError(r3)
|
||||||
|
// lwz r11, 0x150(r13)
|
||||||
|
// if (r11 != 0) {
|
||||||
|
// lwz r11, 0x100(r13)
|
||||||
|
// stw r3, 0x160(r11)
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
void ExCreateThread() {
|
||||||
|
// launch native thread
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ExCreateThread_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("ExCreateThread()"));
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void KeGetCurrentProcessType_shim(
|
void KeGetCurrentProcessType_shim(
|
||||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
// DWORD
|
// DWORD
|
||||||
|
@ -32,6 +81,121 @@ void KeGetCurrentProcessType_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The TLS system used here is a bit hacky, but seems to work.
|
||||||
|
// Both Win32 and pthreads use unsigned longs as TLS indices, so we can map
|
||||||
|
// right into the system for these calls. We're just round tripping the IDs and
|
||||||
|
// hoping for the best.
|
||||||
|
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ms686801
|
||||||
|
void KeTlsAlloc_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// DWORD
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("KeTlsAlloc()"));
|
||||||
|
|
||||||
|
uint32_t tls_index;
|
||||||
|
|
||||||
|
#if XE_PLATFORM(WIN32)
|
||||||
|
tls_index = TlsAlloc();
|
||||||
|
#else
|
||||||
|
pthread_key_t key;
|
||||||
|
if (pthread_key_create(&key, NULL)) {
|
||||||
|
tls_index = X_TLS_OUT_OF_INDEXES;
|
||||||
|
} else {
|
||||||
|
tls_index = (uint32_t)key;
|
||||||
|
}
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(tls_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ms686804
|
||||||
|
void KeTlsFree_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// BOOL
|
||||||
|
// _In_ DWORD dwTlsIndex
|
||||||
|
|
||||||
|
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("KeTlsFree(%.8X)"),
|
||||||
|
tls_index);
|
||||||
|
|
||||||
|
if (tls_index == X_TLS_OUT_OF_INDEXES) {
|
||||||
|
SHIM_SET_RETURN(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result_code = 0;
|
||||||
|
|
||||||
|
#if XE_PLATFORM(WIN32)
|
||||||
|
result_code = TlsFree(tls_index);
|
||||||
|
#else
|
||||||
|
result_code = pthread_key_delete(tls_index) == 0;
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ms686812
|
||||||
|
void KeTlsGetValue_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// LPVOID
|
||||||
|
// _In_ DWORD dwTlsIndex
|
||||||
|
|
||||||
|
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("KeTlsGetValue(%.8X)"),
|
||||||
|
tls_index);
|
||||||
|
|
||||||
|
uint32_t value = 0;
|
||||||
|
|
||||||
|
#if XE_PLATFORM(WIN32)
|
||||||
|
value = (uint32_t)((uint64_t)TlsGetValue(tls_index));
|
||||||
|
#else
|
||||||
|
value = (uint32_t)((uint64_t)pthread_getspecific(tls_index));
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
XELOGW(XT("KeTlsGetValue should SetLastError if result is NULL"));
|
||||||
|
// TODO(benvanik): SetLastError
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ms686818
|
||||||
|
void KeTlsSetValue_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
// BOOL
|
||||||
|
// _In_ DWORD dwTlsIndex,
|
||||||
|
// _In_opt_ LPVOID lpTlsValue
|
||||||
|
|
||||||
|
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t tls_value = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
XT("KeTlsSetValue(%.8X, %.8X)"),
|
||||||
|
tls_index, tls_value);
|
||||||
|
|
||||||
|
int result_code = 0;
|
||||||
|
|
||||||
|
#if XE_PLATFORM(WIN32)
|
||||||
|
result_code = TlsSetValue(tls_index, tls_value);
|
||||||
|
#else
|
||||||
|
result_code = pthread_setspecific(tls_index, (void*)tls_value) == 0;
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +205,14 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports(
|
||||||
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||||
|
|
||||||
|
SHIM_SET_MAPPING(0x0000000D, ExCreateThread_shim, ExCreateThread);
|
||||||
|
|
||||||
SHIM_SET_MAPPING(0x00000066, KeGetCurrentProcessType_shim, NULL);
|
SHIM_SET_MAPPING(0x00000066, KeGetCurrentProcessType_shim, NULL);
|
||||||
|
|
||||||
|
SHIM_SET_MAPPING(0x00000152, KeTlsAlloc_shim, NULL);
|
||||||
|
SHIM_SET_MAPPING(0x00000153, KeTlsFree_shim, NULL);
|
||||||
|
SHIM_SET_MAPPING(0x00000154, KeTlsGetValue_shim, NULL);
|
||||||
|
SHIM_SET_MAPPING(0x00000155, KeTlsSetValue_shim, NULL);
|
||||||
|
|
||||||
#undef SET_MAPPING
|
#undef SET_MAPPING
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,6 @@ Runtime::Runtime(xe_pal_ref pal, shared_ptr<cpu::Processor> processor,
|
||||||
|
|
||||||
kernel_modules_.push_back(
|
kernel_modules_.push_back(
|
||||||
new xboxkrnl::XboxkrnlModule(pal_, memory_, export_resolver_));
|
new xboxkrnl::XboxkrnlModule(pal_, memory_, export_resolver_));
|
||||||
kernel_modules_.push_back(
|
|
||||||
new xbdm::XbdmModule(pal_, memory_, export_resolver_));
|
|
||||||
kernel_modules_.push_back(
|
kernel_modules_.push_back(
|
||||||
new xam::XamModule(pal_, memory_, export_resolver_));
|
new xam::XamModule(pal_, memory_, export_resolver_));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue