Get the "MemTools" and backpatching code to build on linux. Not yet activated.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1532 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
f3eda7d85a
commit
7eefb7743b
|
@ -16,12 +16,19 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
|
||||||
// TODO: create a working OS-neutral version of this file and put it in Common.
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/ucontext.h> // Look in here for the context definition.
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
@ -35,6 +42,8 @@
|
||||||
namespace EMM
|
namespace EMM
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
||||||
{
|
{
|
||||||
switch (pPtrs->ExceptionRecord->ExceptionCode)
|
switch (pPtrs->ExceptionRecord->ExceptionCode)
|
||||||
|
@ -69,7 +78,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u64 memspaceTop = memspaceBottom + 0x100000000ULL;
|
u64 memspaceTop = memspaceBottom + 0x100000000ULL;
|
||||||
#else
|
#else
|
||||||
u64 memspaceTop = memspaceBottom + 0x40000000;
|
u64 memspaceTop = memspaceBottom + 0x40000000;
|
||||||
#endif
|
#endif
|
||||||
if (badAddress < memspaceBottom || badAddress >= memspaceTop) {
|
if (badAddress < memspaceBottom || badAddress >= memspaceTop) {
|
||||||
PanicAlert("Exception handler - access outside memory space. %08x%08x",
|
PanicAlert("Exception handler - access outside memory space. %08x%08x",
|
||||||
|
@ -136,15 +145,12 @@ void InstallExceptionHandler()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
#else // _WIN32)
|
||||||
#else
|
|
||||||
|
|
||||||
namespace EMM {
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//
|
//
|
||||||
// backtrace useful function
|
// backtrace useful function
|
||||||
//
|
//
|
||||||
|
|
||||||
void print_trace(const char * msg)
|
void print_trace(const char * msg)
|
||||||
{
|
{
|
||||||
void *array[100];
|
void *array[100];
|
||||||
|
@ -160,41 +166,63 @@ void print_trace(const char * msg)
|
||||||
free(strings);
|
free(strings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sigsegv_handler(int signal, int siginfo_t *info, void *raw_context)
|
void sigsegv_handler(int signal, siginfo_t *info, void *raw_context)
|
||||||
{
|
{
|
||||||
if (signal != SIGSEGV)
|
if (signal != SIGSEGV)
|
||||||
{
|
{
|
||||||
// We are not interested in other signals - handle it as usual.
|
// We are not interested in other signals - handle it as usual.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ucontext_t *context = (ucontext_t)raw_context;
|
ucontext_t *context = (ucontext_t *)raw_context;
|
||||||
int si_code = info->si_code;
|
int si_code = info->si_code;
|
||||||
if (si_code != SEGV_MAPERR)
|
if (si_code != SEGV_MAPERR && si_code != SEGV_ACCERR)
|
||||||
{
|
{
|
||||||
// Huh? Return.
|
// Huh? Return.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mcontext_t *ctx = &context->uc_mcontext;
|
|
||||||
void *fault_memory_ptr = (void *)info->si_addr;
|
void *fault_memory_ptr = (void *)info->si_addr;
|
||||||
void *fault_instruction_ptr = (void *)ctx->mc_rip;
|
|
||||||
|
|
||||||
if (!Jit64::IsInJitCode(fault_instruction_ptr)) {
|
// Get all the information we can out of the context.
|
||||||
|
mcontext_t *ctx = &context->uc_mcontext;
|
||||||
|
u8 *fault_instruction_ptr = (u8 *)ctx->gregs[REG_RIP];
|
||||||
|
|
||||||
|
if (!Jit64::IsInJitCode((const u8 *)fault_instruction_ptr)) {
|
||||||
// Let's not prevent debugging.
|
// Let's not prevent debugging.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 memspaceBottom = (u64)Memory::base;
|
u64 bad_address = (u64)fault_memory_ptr;
|
||||||
if (badAddress < memspaceBottom) {
|
u64 memspace_bottom = (u64)Memory::base;
|
||||||
|
if (bad_address < memspace_bottom) {
|
||||||
PanicAlert("Exception handler - access below memory space. %08x%08x",
|
PanicAlert("Exception handler - access below memory space. %08x%08x",
|
||||||
badAddress >> 32, badAddress);
|
bad_address >> 32, bad_address);
|
||||||
}
|
}
|
||||||
u32 emAddress = (u32)(badAddress - memspaceBottom);
|
u32 em_address = (u32)(bad_address - memspace_bottom);
|
||||||
|
|
||||||
// Backpatch time.
|
// Backpatch time.
|
||||||
Jit64::BackPatch(fault_instruction_ptr, accessType, emAddress);
|
// Seems we'll need to disassemble to get access_type - that work is probably
|
||||||
}
|
// best done and debugged on the Windows side.
|
||||||
|
int access_type = 0;
|
||||||
|
|
||||||
|
CONTEXT fake_ctx;
|
||||||
|
#ifdef _M_X64
|
||||||
|
fake_ctx.Rax = ctx->gregs[REG_RAX];
|
||||||
|
fake_ctx.Rip = ctx->gregs[REG_RIP];
|
||||||
|
#else
|
||||||
|
fake_ctx.Eax = ctx->gregs[REG_EAX];
|
||||||
|
fake_ctx.Eip = ctx->gregs[REG_EIP];
|
||||||
#endif
|
#endif
|
||||||
|
u8 *new_rip = Jit64::BackPatch(fault_instruction_ptr, access_type, em_address, &fake_ctx);
|
||||||
|
if (new_rip) {
|
||||||
|
#ifdef _M_X64
|
||||||
|
ctx->gregs[REG_RAX] = fake_ctx.Rax;
|
||||||
|
ctx->gregs[REG_RIP] = (u64)new_rip;
|
||||||
|
#else
|
||||||
|
ctx->gregs[REG_EAX] = fake_ctx.Rax;
|
||||||
|
ctx->gregs[REG_EIP] = (u32)new_rip;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InstallExceptionHandler()
|
void InstallExceptionHandler()
|
||||||
{
|
{
|
||||||
|
@ -203,22 +231,14 @@ void InstallExceptionHandler()
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
sighandler_t old_signal_handler = signal(SIGSEGV , sigsegv_handler);
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
memset(&sa, 0, sizeof(sa));
|
sa.sa_handler = 0;
|
||||||
sa.sa_handler = sigsegv_handler;
|
sa.sa_sigaction = &sigsegv_handler;
|
||||||
sa.sa_flags = SA_SIGINFO;
|
sa.sa_flags = SA_SIGINFO;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sigaction(SIGSEGV, &sa, NULL);
|
sigaction(SIGSEGV, &sa, NULL);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* signal(xyz);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
|
@ -43,11 +43,10 @@ void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) {
|
||||||
char disbuf[256];
|
char disbuf[256];
|
||||||
memset(disbuf, 0, 256);
|
memset(disbuf, 0, 256);
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
disasm.disasm32
|
disasm.disasm32(0, code_addr, codePtr, disbuf);
|
||||||
#else
|
#else
|
||||||
disasm.disasm64
|
disasm.disasm64(0, code_addr, codePtr, disbuf);
|
||||||
#endif
|
#endif
|
||||||
(0, code_addr, codePtr, disbuf);
|
|
||||||
PanicAlert("%s\n\n"
|
PanicAlert("%s\n\n"
|
||||||
"Error encountered accessing emulated address %08x.\n"
|
"Error encountered accessing emulated address %08x.\n"
|
||||||
"Culprit instruction: \n%s\nat %08x%08x",
|
"Culprit instruction: \n%s\nat %08x%08x",
|
||||||
|
@ -84,7 +83,7 @@ u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx)
|
||||||
if (info.operandSize != 4) {
|
if (info.operandSize != 4) {
|
||||||
BackPatchError(StringFromFormat("BackPatch - no support for operand size %i", info.operandSize), codePtr, emAddress);
|
BackPatchError(StringFromFormat("BackPatch - no support for operand size %i", info.operandSize), codePtr, emAddress);
|
||||||
}
|
}
|
||||||
u64 code_addr = (u64)codePtr;
|
|
||||||
X64Reg addrReg = (X64Reg)info.scaledReg;
|
X64Reg addrReg = (X64Reg)info.scaledReg;
|
||||||
X64Reg dataReg = (X64Reg)info.regOperandReg;
|
X64Reg dataReg = (X64Reg)info.regOperandReg;
|
||||||
if (info.otherReg != RBX)
|
if (info.otherReg != RBX)
|
||||||
|
@ -185,7 +184,7 @@ u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx)
|
||||||
SetCodePtr(oldCodePtr);
|
SetCodePtr(oldCodePtr);
|
||||||
|
|
||||||
// We entered here with a BSWAP-ed EAX. We'll have to swap it back.
|
// We entered here with a BSWAP-ed EAX. We'll have to swap it back.
|
||||||
ctx->Rax = _byteswap_ulong(ctx->Rax);
|
ctx->Rax = Common::swap32(ctx->Rax);
|
||||||
|
|
||||||
return codePtr - 2;
|
return codePtr - 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,24 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// A bit of a hack to get things building under linux. We manually fill in this structure as needed
|
||||||
|
// from the real context.
|
||||||
|
struct CONTEXT
|
||||||
|
{
|
||||||
|
#ifdef _M_X64
|
||||||
|
u64 Rip;
|
||||||
|
u64 Rax;
|
||||||
|
#else
|
||||||
|
u32 Eip;
|
||||||
|
u32 Eax;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Jit64 {
|
namespace Jit64 {
|
||||||
|
|
|
@ -80,6 +80,7 @@ files = ["Console.cpp",
|
||||||
"PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp",
|
"PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp",
|
||||||
"PowerPC/Interpreter/Interpreter_SystemRegisters.cpp",
|
"PowerPC/Interpreter/Interpreter_SystemRegisters.cpp",
|
||||||
"PowerPC/Jit64/Jit.cpp",
|
"PowerPC/Jit64/Jit.cpp",
|
||||||
|
"PowerPC/Jit64/JitBackpatch.cpp",
|
||||||
"PowerPC/Jit64/JitCore.cpp",
|
"PowerPC/Jit64/JitCore.cpp",
|
||||||
"PowerPC/Jit64/JitCache.cpp",
|
"PowerPC/Jit64/JitCache.cpp",
|
||||||
"PowerPC/Jit64/JitRegCache.cpp",
|
"PowerPC/Jit64/JitRegCache.cpp",
|
||||||
|
|
Loading…
Reference in New Issue