Real modules and threads (mostly).

Need events/waiting to get proper launch thread behavior.
This commit is contained in:
Ben Vanik
2013-01-30 22:44:32 -08:00
parent 2ecacedaa6
commit 49af0dbc85
51 changed files with 1335 additions and 657 deletions

View File

@@ -15,6 +15,7 @@
#include <xenia/core/file.h>
#include <xenia/core/memory.h>
#include <xenia/core/mmap.h>
#include <xenia/core/mutex.h>
#include <xenia/core/pal.h>
#include <xenia/core/ref.h>

View File

@@ -0,0 +1,27 @@
/**
******************************************************************************
* 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_CORE_MUTEX_H_
#define XENIA_CORE_MUTEX_H_
#include <xenia/common.h>
typedef struct xe_mutex xe_mutex_t;
xe_mutex_t* xe_mutex_alloc(uint32_t spin_count);
void xe_mutex_free(xe_mutex_t* mutex);
int xe_mutex_lock(xe_mutex_t* mutex);
int xe_mutex_trylock(xe_mutex_t* mutex);
int xe_mutex_unlock(xe_mutex_t* mutex);
#endif // XENIA_CORE_MUTEX_H_

View File

@@ -16,7 +16,6 @@
#include <xenia/cpu/sdb.h>
#include <xenia/core/memory.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/user_module.h>
namespace llvm {

View File

@@ -15,7 +15,7 @@
#include <xenia/cpu/sdb.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/user_module.h>
#include <xenia/kernel/xex2.h>
namespace llvm {
@@ -49,7 +49,7 @@ public:
shared_ptr<llvm::ExecutionEngine>& engine);
~ExecModule();
int PrepareUserModule(kernel::UserModule* user_module);
int PrepareXex(xe_xex2_ref xex);
int PrepareRawBinary(uint32_t start_address, uint32_t end_address);
void AddFunctionsToMap(FunctionMap& map);

View File

@@ -17,7 +17,7 @@
#include <xenia/cpu/exec_module.h>
#include <xenia/cpu/thread_state.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/user_module.h>
#include <xenia/kernel/xex2.h>
namespace llvm {
@@ -40,17 +40,18 @@ public:
int Setup();
int PrepareModule(const char* module_name, const char* module_path,
uint32_t start_address, uint32_t end_address,
shared_ptr<kernel::ExportResolver> export_resolver);
int PrepareModule(kernel::UserModule* user_module,
int LoadBinary(const xechar_t* path, uint32_t start_address,
shared_ptr<kernel::ExportResolver> export_resolver);
int PrepareModule(const char* name, const char* path, xe_xex2_ref xex,
shared_ptr<kernel::ExportResolver> export_resolver);
uint32_t CreateCallback(void (*callback)(void* data), void* data);
ThreadState* AllocThread(uint32_t stack_address, uint32_t stack_size);
ThreadState* AllocThread(uint32_t stack_size, uint32_t thread_state_address);
void DeallocThread(ThreadState* thread_state);
int Execute(ThreadState* thread_state, uint32_t address);
uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t arg0);
private:
llvm::Function* GetFunction(uint32_t address);

View File

@@ -17,7 +17,7 @@
#include <vector>
#include <xenia/kernel/export.h>
#include <xenia/kernel/user_module.h>
#include <xenia/kernel/xex2.h>
namespace xe {
@@ -205,7 +205,7 @@ class XexSymbolDatabase : public SymbolDatabase {
public:
XexSymbolDatabase(xe_memory_ref memory,
kernel::ExportResolver* export_resolver,
kernel::UserModule* module);
xe_xex2_ref xex);
virtual ~XexSymbolDatabase();
virtual int Analyze();
@@ -218,7 +218,7 @@ private:
virtual uint32_t GetEntryPoint();
virtual bool IsValueInTextRange(uint32_t value);
kernel::UserModule* module_;
xe_xex2_ref xex_;
};

View File

@@ -25,16 +25,19 @@ class Processor;
class ThreadState {
public:
ThreadState(Processor* processor,
uint32_t stack_address, uint32_t stack_size);
uint32_t stack_size, uint32_t thread_state_address);
~ThreadState();
xe_ppc_state_t* ppc_state();
private:
uint32_t stack_address_;
uint32_t stack_size_;
uint32_t thread_state_address;
xe_memory_ref memory_;
uint32_t stack_address_;
uint32_t thread_state_address_;
xe_ppc_state_t ppc_state_;
};

View File

@@ -14,30 +14,36 @@
#include <xenia/core.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/runtime.h>
namespace xe {
namespace kernel {
class Runtime;
class KernelModule {
public:
KernelModule(xe_pal_ref pal, xe_memory_ref memory,
shared_ptr<ExportResolver> resolver) {
pal_ = xe_pal_retain(pal);
memory_ = xe_memory_retain(memory);
resolver_ = resolver;
KernelModule(Runtime* runtime) {
runtime_ = runtime;
pal_ = runtime->pal();
memory_ = runtime->memory();
export_resolver_ = runtime->export_resolver();
}
virtual ~KernelModule() {
export_resolver_.reset();
xe_memory_release(memory_);
xe_pal_release(pal_);
}
protected:
xe_pal_ref pal_;
xe_memory_ref memory_;
shared_ptr<ExportResolver> resolver_;
Runtime* runtime_;
xe_pal_ref pal_;
xe_memory_ref memory_;
shared_ptr<ExportResolver> export_resolver_;
};

View File

@@ -15,7 +15,6 @@
#include <xenia/cpu.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/user_module.h>
#include <xenia/kernel/xex2.h>
@@ -23,6 +22,14 @@ namespace xe {
namespace cpu {
class Processor;
}
namespace kernel {
namespace xboxkrnl {
class XboxkrnlModule;
}
namespace xam {
class XamModule;
}
}
}
@@ -44,12 +51,7 @@ public:
shared_ptr<ExportResolver> export_resolver();
const xechar_t* command_line();
int LoadBinaryModule(const xechar_t* path, uint32_t start_address);
int LoadModule(const xechar_t* path);
void LaunchModule(UserModule* user_module);
UserModule* GetModule(const xechar_t* path);
void UnloadModule(UserModule* user_module);
int LaunchModule(const xechar_t* path);
private:
xe_pal_ref pal_;
@@ -58,8 +60,8 @@ private:
xechar_t command_line_[2048];
shared_ptr<ExportResolver> export_resolver_;
std::vector<KernelModule*> kernel_modules_;
std::map<const xechar_t*, UserModule*> user_modules_;
auto_ptr<xboxkrnl::XboxkrnlModule> xboxkrnl_;
auto_ptr<xam::XamModule> xam_;
};

View File

@@ -1,89 +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. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_USER_MODULE_H_
#define XENIA_KERNEL_USER_MODULE_H_
#include <xenia/core.h>
#include <vector>
#include <xenia/kernel/export.h>
#include <xenia/kernel/xex2.h>
namespace xe {
namespace kernel {
#define kXEPESectionContainsCode 0x00000020
#define kXEPESectionContainsDataInit 0x00000040
#define kXEPESectionContainsDataUninit 0x00000080
#define kXEPESectionMemoryExecute 0x20000000
#define kXEPESectionMemoryRead 0x40000000
#define kXEPESectionMemoryWrite 0x80000000
class PESection {
public:
char name[9]; // 8 + 1 for \0
uint32_t raw_address;
size_t raw_size;
uint32_t address;
size_t size;
uint32_t flags; // kXEPESection*
};
class PEMethodInfo {
public:
uint32_t address;
size_t total_length; // in bytes
size_t prolog_length; // in bytes
};
class UserModule {
public:
UserModule(xe_memory_ref memory);
~UserModule();
int Load(const void* addr, const size_t length, const xechar_t* path);
const xechar_t* path();
const xechar_t* name();
uint32_t handle();
xe_xex2_ref xex();
const xe_xex2_header_t* xex_header();
void* GetProcAddress(const uint32_t ordinal);
PESection* GetSection(const char* name);
int GetMethodHints(PEMethodInfo** out_method_infos,
size_t* out_method_info_count);
void Dump(ExportResolver* export_resolver);
private:
int LoadPE();
xe_memory_ref memory_;
xechar_t path_[2048];
xechar_t name_[256];
uint32_t handle_;
xe_xex2_ref xex_;
std::vector<PESection*> sections_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_USER_MODULE_H_

View File

@@ -0,0 +1,92 @@
/**
******************************************************************************
* 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_XBOX_H_
#define XENIA_KERNEL_XBOX_H_
#include <xenia/common.h>
#include <xenia/core.h>
namespace xe {
namespace kernel {
typedef uint32_t X_HANDLE;
#define X_INVALID_HANDLE_VALUE ((X_HANDLE)-1)
// NT_STATUS (STATUS_*)
// http://msdn.microsoft.com/en-us/library/cc704588.aspx
// Adding as needed.
typedef uint32_t X_STATUS;
#define XFAILED(s) (s & X_STATUS_UNSUCCESSFUL)
#define XSUCCEEDED(s) !XFAILED(s)
#define X_STATUS_SUCCESS ((uint32_t)0x00000000L)
#define X_STATUS_UNSUCCESSFUL ((uint32_t)0xC0000001L)
#define X_STATUS_NOT_IMPLEMENTED ((uint32_t)0xC0000002L)
#define X_STATUS_ACCESS_VIOLATION ((uint32_t)0xC0000005L)
#define X_STATUS_INVALID_HANDLE ((uint32_t)0xC0000008L)
#define X_STATUS_INVALID_PARAMETER ((uint32_t)0xC000000DL)
#define X_STATUS_NO_MEMORY ((uint32_t)0xC0000017L)
#define X_STATUS_ALREADY_COMMITTED ((uint32_t)0xC0000021L)
#define X_STATUS_ACCESS_DENIED ((uint32_t)0xC0000022L)
#define X_STATUS_BUFFER_TOO_SMALL ((uint32_t)0xC0000023L)
#define X_STATUS_OBJECT_TYPE_MISMATCH ((uint32_t)0xC0000024L)
#define X_STATUS_INVALID_PAGE_PROTECTION ((uint32_t)0xC0000045L)
// MEM_*, used by NtAllocateVirtualMemory
#define X_MEM_COMMIT 0x00001000
#define X_MEM_RESERVE 0x00002000
#define X_MEM_DECOMMIT 0x00004000
#define X_MEM_RELEASE 0x00008000
#define X_MEM_FREE 0x00010000
#define X_MEM_PRIVATE 0x00020000
#define X_MEM_RESET 0x00080000
#define X_MEM_TOP_DOWN 0x00100000
#define X_MEM_NOZERO 0x00800000
#define X_MEM_LARGE_PAGES 0x20000000
#define X_MEM_HEAP 0x40000000
#define X_MEM_16MB_PAGES 0x80000000 // from Valve SDK
// PAGE_*, used by NtAllocateVirtualMemory
#define X_PAGE_NOACCESS 0x00000001
#define X_PAGE_READONLY 0x00000002
#define X_PAGE_READWRITE 0x00000004
#define X_PAGE_WRITECOPY 0x00000008
#define X_PAGE_EXECUTE 0x00000010
#define X_PAGE_EXECUTE_READ 0x00000020
#define X_PAGE_EXECUTE_READWRITE 0x00000040
#define X_PAGE_EXECUTE_WRITECOPY 0x00000080
#define X_PAGE_GUARD 0x00000100
#define X_PAGE_NOCACHE 0x00000200
#define X_PAGE_WRITECOMBINE 0x00000400
// (?), used by KeGetCurrentProcessType
#define X_PROCTYPE_IDLE 0
#define X_PROCTYPE_USER 1
#define X_PROCTYPE_SYSTEM 2
// Thread enums.
#define X_CREATE_SUSPENDED 0x00000004
// TLS specials.
#define X_TLS_OUT_OF_INDEXES UINT32_MAX // (-1)
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XBOX_H_

View File

@@ -27,6 +27,24 @@ typedef struct {
uint32_t thunk_address; // NULL or address of thunk
} xe_xex2_import_info_t;
enum xe_pe_section_flags_e {
kXEPESectionContainsCode = 0x00000020,
kXEPESectionContainsDataInit = 0x00000040,
kXEPESectionContainsDataUninit = 0x00000080,
kXEPESectionMemoryExecute = 0x20000000,
kXEPESectionMemoryRead = 0x40000000,
kXEPESectionMemoryWrite = 0x80000000,
};
class PESection {
public:
char name[9]; // 8 + 1 for \0
uint32_t raw_address;
size_t raw_size;
uint32_t address;
size_t size;
uint32_t flags; // kXEPESection*
};
xe_xex2_ref xe_xex2_load(xe_memory_ref memory,
const void* addr, const size_t length,
@@ -36,6 +54,7 @@ void xe_xex2_release(xe_xex2_ref xex);
const xechar_t *xe_xex2_get_name(xe_xex2_ref xex);
const xe_xex2_header_t *xe_xex2_get_header(xe_xex2_ref xex);
const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name);
int xe_xex2_get_import_infos(xe_xex2_ref xex,
const xe_xex2_import_library_t *library,