summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2008-12-14 17:29:13 +0000
committerhrydgard <hrydgard@gmail.com>2008-12-14 17:29:13 +0000
commit7eefb7743bc4fa94ed5315a55b622bcef1da47b2 (patch)
tree8da6601bd032a52df5610e61e7832d21145d5da8 /Source/Core
parentf3eda7d85ad47ba61491e8879c186725b10f054d (diff)
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
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/MemTools.cpp86
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp9
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h17
-rw-r--r--Source/Core/Core/Src/SConscript1
4 files changed, 75 insertions, 38 deletions
diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp
index f810de1b15..d3fadaf39e 100644
--- a/Source/Core/Core/Src/MemTools.cpp
+++ b/Source/Core/Core/Src/MemTools.cpp
@@ -16,12 +16,19 @@
// http://code.google.com/p/dolphin-emu/
-// TODO: create a working OS-neutral version of this file and put it in Common.
-
-
#ifdef _WIN32
#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 "Common.h"
@@ -35,6 +42,8 @@
namespace EMM
{
+#ifdef _WIN32
+
LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
{
switch (pPtrs->ExceptionRecord->ExceptionCode)
@@ -69,7 +78,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
#ifdef _M_X64
u64 memspaceTop = memspaceBottom + 0x100000000ULL;
#else
- u64 memspaceTop = memspaceBottom + 0x40000000;
+ u64 memspaceTop = memspaceBottom + 0x40000000;
#endif
if (badAddress < memspaceBottom || badAddress >= memspaceTop) {
PanicAlert("Exception handler - access outside memory space. %08x%08x",
@@ -136,15 +145,12 @@ void InstallExceptionHandler()
#endif
}
-}
-#else
+#else // _WIN32)
-namespace EMM {
-
-#if 0
//
// backtrace useful function
//
+
void print_trace(const char * msg)
{
void *array[100];
@@ -160,41 +166,63 @@ void print_trace(const char * msg)
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)
{
// We are not interested in other signals - handle it as usual.
return;
}
- ucontext_t *context = (ucontext_t)raw_context;
+ ucontext_t *context = (ucontext_t *)raw_context;
int si_code = info->si_code;
- if (si_code != SEGV_MAPERR)
+ if (si_code != SEGV_MAPERR && si_code != SEGV_ACCERR)
{
// Huh? Return.
return;
}
- mcontext_t *ctx = &context->uc_mcontext;
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.
return;
}
-
- u64 memspaceBottom = (u64)Memory::base;
- if (badAddress < memspaceBottom) {
+
+ u64 bad_address = (u64)fault_memory_ptr;
+ u64 memspace_bottom = (u64)Memory::base;
+ if (bad_address < memspace_bottom) {
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.
- 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
+ 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()
{
@@ -203,22 +231,14 @@ void InstallExceptionHandler()
return;
#endif
-#if 0
- sighandler_t old_signal_handler = signal(SIGSEGV , sigsegv_handler);
struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = sigsegv_handler;
+ sa.sa_handler = 0;
+ sa.sa_sigaction = &sigsegv_handler;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(SIGSEGV, &sa, NULL);
-#endif
-
- /*
- * signal(xyz);
- */
-}
-
}
#endif
+} // namespace
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
index ae1efb1a8e..87c7f2ef17 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
@@ -43,11 +43,10 @@ void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) {
char disbuf[256];
memset(disbuf, 0, 256);
#ifdef _M_IX86
- disasm.disasm32
+ disasm.disasm32(0, code_addr, codePtr, disbuf);
#else
- disasm.disasm64
+ disasm.disasm64(0, code_addr, codePtr, disbuf);
#endif
- (0, code_addr, codePtr, disbuf);
PanicAlert("%s\n\n"
"Error encountered accessing emulated address %08x.\n"
"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) {
BackPatchError(StringFromFormat("BackPatch - no support for operand size %i", info.operandSize), codePtr, emAddress);
}
- u64 code_addr = (u64)codePtr;
+
X64Reg addrReg = (X64Reg)info.scaledReg;
X64Reg dataReg = (X64Reg)info.regOperandReg;
if (info.otherReg != RBX)
@@ -185,7 +184,7 @@ u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx)
SetCodePtr(oldCodePtr);
// 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;
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h
index f30836fc79..f3e923e97e 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h
@@ -21,7 +21,24 @@
#include "Common.h"
#ifdef _WIN32
+
#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
namespace Jit64 {
diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript
index 50efeea214..415650e100 100644
--- a/Source/Core/Core/Src/SConscript
+++ b/Source/Core/Core/Src/SConscript
@@ -80,6 +80,7 @@ files = ["Console.cpp",
"PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp",
"PowerPC/Interpreter/Interpreter_SystemRegisters.cpp",
"PowerPC/Jit64/Jit.cpp",
+ "PowerPC/Jit64/JitBackpatch.cpp",
"PowerPC/Jit64/JitCore.cpp",
"PowerPC/Jit64/JitCache.cpp",
"PowerPC/Jit64/JitRegCache.cpp",