Kernel calls and variables now working and tracing better.
This commit is contained in:
@@ -31,6 +31,7 @@ void ExportResolver::RegisterTable(
|
||||
for (size_t n = 0; n < count; n++) {
|
||||
exports[n].is_implemented = false;
|
||||
exports[n].variable_ptr = 0;
|
||||
exports[n].function_data.shim_data = NULL;
|
||||
exports[n].function_data.shim = NULL;
|
||||
exports[n].function_data.impl = NULL;
|
||||
}
|
||||
@@ -69,13 +70,14 @@ void ExportResolver::SetVariableMapping(const char* library_name,
|
||||
kernel_export->variable_ptr = value;
|
||||
}
|
||||
|
||||
void ExportResolver::SetFunctionMapping(const char* library_name,
|
||||
const uint32_t ordinal,
|
||||
xe_kernel_export_shim_fn shim,
|
||||
xe_kernel_export_impl_fn impl) {
|
||||
void ExportResolver::SetFunctionMapping(
|
||||
const char* library_name, const uint32_t ordinal,
|
||||
void* shim_data, xe_kernel_export_shim_fn shim,
|
||||
xe_kernel_export_impl_fn impl) {
|
||||
KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal);
|
||||
XEASSERTNOTNULL(kernel_export);
|
||||
kernel_export->is_implemented = true;
|
||||
kernel_export->function_data.shim_data = shim_data;
|
||||
kernel_export->function_data.shim = shim;
|
||||
kernel_export->function_data.impl = impl;
|
||||
}
|
||||
|
||||
33
src/kernel/modules/xboxkrnl/kernel_state.cc
Normal file
33
src/kernel/modules/xboxkrnl/kernel_state.cc
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/kernel_state.h"
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
KernelState::KernelState(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> export_resolver) {
|
||||
pal = xe_pal_retain(pal);
|
||||
memory = xe_memory_retain(memory);
|
||||
export_resolver_ = export_resolver;
|
||||
}
|
||||
|
||||
KernelState::~KernelState() {
|
||||
xe_memory_release(memory);
|
||||
xe_pal_release(pal);
|
||||
}
|
||||
44
src/kernel/modules/xboxkrnl/kernel_state.h
Normal file
44
src/kernel/modules/xboxkrnl/kernel_state.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_KERNEL_STATE_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_KERNEL_STATE_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 {
|
||||
public:
|
||||
KernelState(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> export_resolver);
|
||||
~KernelState();
|
||||
|
||||
xe_pal_ref pal;
|
||||
xe_memory_ref memory;
|
||||
|
||||
private:
|
||||
shared_ptr<ExportResolver> export_resolver_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_KERNEL_STATE_H_
|
||||
@@ -1,6 +1,9 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'kernel_state.cc',
|
||||
'xboxkrnl_hal.cc',
|
||||
'xboxkrnl_memory.cc',
|
||||
'xboxkrnl_module.cc',
|
||||
],
|
||||
}
|
||||
|
||||
54
src/kernel/modules/xboxkrnl/xboxkrnl_hal.cc
Normal file
54
src/kernel/modules/xboxkrnl/xboxkrnl_hal.cc
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_hal.h"
|
||||
|
||||
#include "kernel/shim_utils.h"
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
void HalReturnToFirmware_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// void
|
||||
// IN FIRMWARE_REENTRY Routine
|
||||
|
||||
// Routine must be 1 'HalRebootRoutine'
|
||||
uint32_t routine = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
XT("HalReturnToFirmware(%d)"),
|
||||
routine);
|
||||
|
||||
// TODO(benvank): diediedie much more gracefully
|
||||
// Not sure how to blast back up the stack in LLVM without exceptions, though.
|
||||
XELOGE(XT("Game requested shutdown via HalReturnToFirmware"));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterHalExports(
|
||||
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(0x00000028, HalReturnToFirmware_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
29
src/kernel/modules/xboxkrnl/xboxkrnl_hal.h
Normal file
29
src/kernel/modules/xboxkrnl/xboxkrnl_hal.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_HAL_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_HAL_H_
|
||||
|
||||
#include "kernel/modules/xboxkrnl/kernel_state.h"
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
void RegisterHalExports(ExportResolver* export_resolver, KernelState* state);
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_HAL_H_
|
||||
112
src/kernel/modules/xboxkrnl/xboxkrnl_memory.cc
Normal file
112
src/kernel/modules/xboxkrnl/xboxkrnl_memory.cc
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_memory.h"
|
||||
|
||||
#include "kernel/shim_utils.h"
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
void NtAllocateVirtualMemory_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// NTSTATUS
|
||||
// _Inout_ PVOID *BaseAddress,
|
||||
// _In_ ULONG_PTR ZeroBits,
|
||||
// _Inout_ PSIZE_T RegionSize,
|
||||
// _In_ ULONG AllocationType,
|
||||
// _In_ ULONG Protect
|
||||
// ? handle?
|
||||
|
||||
uint32_t base_addr_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr);
|
||||
uint32_t region_size_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t region_size_value = SHIM_MEM_32(region_size_ptr);
|
||||
// MEM_COMMIT | MEM_PHYSICAL | MEM_RESERVE | MEM_RESET | MEM_TOP_DOWN
|
||||
uint32_t allocation_type = SHIM_GET_ARG_32(2);
|
||||
// PAGE_NOACCESS | PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE |
|
||||
// PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_GUARD | PAGE_NOCACHE |
|
||||
// PAGE_WRITECOMBINE
|
||||
uint32_t protect_bits = SHIM_GET_ARG_32(3);
|
||||
uint32_t unknown = SHIM_GET_ARG_32(4);
|
||||
|
||||
XELOGD(
|
||||
XT("NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)"),
|
||||
base_addr_ptr, base_addr_value,
|
||||
region_size_ptr, region_size_value,
|
||||
allocation_type, protect_bits, unknown);
|
||||
|
||||
// TODO(benvanik): alloc memory
|
||||
|
||||
// Possible return codes:
|
||||
// STATUS_ACCESS_DENIED
|
||||
// STATUS_ALREADY_COMMITTED
|
||||
// STATUS_COMMITMENT_LIMIT
|
||||
// STATUS_CONFLICTING_ADDRESSES
|
||||
// STATUS_INSUFFICIENT_RESOURCES
|
||||
// STATUS_INVALID_HANDLE
|
||||
// STATUS_INVALID_PAGE_PROTECTION
|
||||
// STATUS_NO_MEMORY
|
||||
// STATUS_OBJECT_TYPE_MISMATCH
|
||||
// STATUS_PROCESS_IS_TERMINATING
|
||||
SHIM_SET_RETURN(0xC0000017);
|
||||
}
|
||||
|
||||
void NtFreeVirtualMemory_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// NTSTATUS
|
||||
// _Inout_ PVOID *BaseAddress,
|
||||
// _Inout_ PSIZE_T RegionSize,
|
||||
// _In_ ULONG FreeType
|
||||
// ? handle?
|
||||
|
||||
uint32_t base_addr_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr);
|
||||
uint32_t region_size_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t region_size_value = SHIM_MEM_32(region_size_ptr);
|
||||
// MEM_DECOMMIT | MEM_RELEASE
|
||||
uint32_t free_type = SHIM_GET_ARG_32(2);
|
||||
uint32_t unknown = SHIM_GET_ARG_32(3);
|
||||
|
||||
XELOGD(
|
||||
XT("NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)"),
|
||||
base_addr_ptr, base_addr_value,
|
||||
region_size_ptr, region_size_value,
|
||||
free_type, unknown);
|
||||
|
||||
// TODO(benvanik): free memory
|
||||
|
||||
// Possible return codes:
|
||||
// STATUS_ACCESS_DENIED
|
||||
// STATUS_INVALID_HANDLE
|
||||
// STATUS_OBJECT_TYPE_MISMATCH
|
||||
SHIM_SET_RETURN(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterMemoryExports(
|
||||
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(0x000000CC, NtAllocateVirtualMemory_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x000000DC, NtFreeVirtualMemory_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
29
src/kernel/modules/xboxkrnl/xboxkrnl_memory.h
Normal file
29
src/kernel/modules/xboxkrnl/xboxkrnl_memory.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MEMORY_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_MEMORY_H_
|
||||
|
||||
#include "kernel/modules/xboxkrnl/kernel_state.h"
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
void RegisterMemoryExports(ExportResolver* export_resolver, KernelState* state);
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MEMORY_H_
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include "kernel/modules/xboxkrnl/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_table.h"
|
||||
|
||||
|
||||
@@ -48,6 +51,14 @@ XboxkrnlModule::XboxkrnlModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
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());
|
||||
|
||||
// TODO(benvanik): alloc heap memory somewhere in user space
|
||||
// TODO(benvanik): tools for reading/writing to heap memory
|
||||
|
||||
@@ -55,15 +66,15 @@ XboxkrnlModule::XboxkrnlModule(xe_pal_ref pal, xe_memory_ref memory,
|
||||
// KeDebugMonitorData
|
||||
resolver->SetVariableMapping(
|
||||
"xboxkrnl.exe", 0x00000059,
|
||||
0);
|
||||
0x40001000);
|
||||
// XboxHardwareInfo
|
||||
resolver->SetVariableMapping(
|
||||
"xboxkrnl.exe", 0x00000156,
|
||||
0);
|
||||
0x40002000);
|
||||
// XexExecutableModuleHandle
|
||||
resolver->SetVariableMapping(
|
||||
"xboxkrnl.exe", 0x00000193,
|
||||
0);
|
||||
0x40000000);
|
||||
|
||||
// 0x0000012B, RtlImageXexHeaderField
|
||||
}
|
||||
|
||||
@@ -21,12 +21,17 @@ 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -34,5 +39,4 @@ public:
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
||||
|
||||
43
src/kernel/shim_utils.h
Normal file
43
src/kernel/shim_utils.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_SHIM_UTILS_H_
|
||||
#define XENIA_KERNEL_SHIM_UTILS_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/cpu/ppc.h>
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
#define SHIM_MEM_ADDR(a) (ppc_state->membase + a)
|
||||
|
||||
#define SHIM_MEM_32(a) (uint32_t)XEGETUINT32BE(SHIM_MEM_ADDR(a));
|
||||
#define SHIM_SET_MEM_32(a, v) (*(uint32_t*)SHIM_MEM_ADDR(a)) = XESWAP32(v)
|
||||
|
||||
#define SHIM_GPR_32(n) (uint32_t)(ppc_state->r[n])
|
||||
#define SHIM_SET_GPR_32(n, v) ppc_state->r[n] = (uint64_t)((v) & UINT32_MAX)
|
||||
#define SHIM_GPR_64(n) ppc_state->r[n]
|
||||
#define SHIM_SET_GPR_64(n, v) ppc_state->r[n] = (uint64_t)(v)
|
||||
|
||||
#define SHIM_GET_ARG_32(n) SHIM_GPR_32(3 + n)
|
||||
#define SHIM_GET_ARG_64(n) SHIM_GPR_64(3 + n)
|
||||
#define SHIM_SET_RETURN(v) SHIM_SET_GPR_64(3, v)
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_SHIM_UTILS_H_
|
||||
Reference in New Issue
Block a user