summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorcomex <comexk@gmail.com>2013-09-24 01:38:27 -0400
committercomex <comexk@gmail.com>2013-09-24 01:38:27 -0400
commit29dc253fde386b7d1186f85ca43569cc73795b6e (patch)
tree1e520fe2cc5424e8c67f864df0730287d97d758e /Source/Core
parent4cdce55615f5863d1df2fef9169fa2b8ff25cb47 (diff)
Improve context structure handling on non-Windows.
Instead of copying data into and out of a fake CONTEXT structure with only a few entries, use the platform specific structure directly with a typedef and macros. This is needed because fastmem writes need to be able to access any register from BackPatch. It adds a fair number of repetitive defines, but it's better than the alternative.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/ArmMemTools.cpp6
-rw-r--r--Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp10
-rw-r--r--Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp4
-rw-r--r--Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h236
-rw-r--r--Source/Core/Core/Src/x64MemTools.cpp69
5 files changed, 224 insertions, 101 deletions
diff --git a/Source/Core/Core/Src/ArmMemTools.cpp b/Source/Core/Core/Src/ArmMemTools.cpp
index 01e63a6a42..d2c003060f 100644
--- a/Source/Core/Core/Src/ArmMemTools.cpp
+++ b/Source/Core/Core/Src/ArmMemTools.cpp
@@ -81,11 +81,9 @@ void sigsegv_handler(int signal, siginfo_t *info, void *raw_context)
u32 em_address = (u32)(bad_address - memspace_bottom);
- CONTEXT fake_ctx;
- fake_ctx.reg_pc = ctx->arm_pc;
- const u8 *new_rip = jit->BackPatch(fault_instruction_ptr, em_address, &fake_ctx);
+ const u8 *new_rip = jit->BackPatch(fault_instruction_ptr, em_address, ctx);
if (new_rip) {
- ctx->arm_pc = fake_ctx.reg_pc;
+ ctx->arm_pc = (u32) new_rip;
}
}
diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp
index d051dae726..465e1fac1e 100644
--- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp
+++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp
@@ -80,7 +80,7 @@ bool DisamLoadStore(const u32 inst, ARMReg &rD, u8 &accessSize, bool &Store)
const u8 *JitArm::BackPatch(u8 *codePtr, u32, void *ctx_void)
{
// TODO: This ctx needs to be filled with our information
- CONTEXT *ctx = (CONTEXT *)ctx_void;
+ SContext *ctx = (SContext *)ctx_void;
// We need to get the destination register before we start
u32 Value = *(u32*)codePtr;
@@ -90,7 +90,7 @@ const u8 *JitArm::BackPatch(u8 *codePtr, u32, void *ctx_void)
if (!DisamLoadStore(Value, rD, accessSize, Store))
{
- printf("Invalid backpatch at location 0x%08x(0x%08x)\n", ctx->reg_pc, Value);
+ printf("Invalid backpatch at location 0x%08x(0x%08x)\n", ctx->CTX_PC, Value);
exit(0);
}
@@ -117,8 +117,8 @@ const u8 *JitArm::BackPatch(u8 *codePtr, u32, void *ctx_void)
emitter.MOV(R1, R10); // Addr- 5
emitter.BL(R14); // 6
emitter.POP(4, R0, R1, R2, R3); // 7
- u32 newPC = ctx->reg_pc - (ARMREGOFFSET + 4 * 4);
- ctx->reg_pc = newPC;
+ u32 newPC = ctx->CTX_PC - (ARMREGOFFSET + 4 * 4);
+ ctx->CTX_PC = newPC;
emitter.FlushIcache();
return codePtr;
}
@@ -144,7 +144,7 @@ const u8 *JitArm::BackPatch(u8 *codePtr, u32, void *ctx_void)
emitter.MOV(R14, R0); // 6
emitter.POP(4, R0, R1, R2, R3); // 7
emitter.MOV(rD, R14); // 8
- ctx->reg_pc -= ARMREGOFFSET + (4 * 4);
+ ctx->CTX_PC -= ARMREGOFFSET + (4 * 4);
emitter.FlushIcache();
return codePtr;
}
diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp
index 506435284e..57a2f002ff 100644
--- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp
+++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp
@@ -163,7 +163,7 @@ const u8 *TrampolineCache::GetWriteTrampoline(const InstructionInfo &info)
const u8 *Jitx86Base::BackPatch(u8 *codePtr, u32 emAddress, void *ctx_void)
{
#ifdef _M_X64
- CONTEXT *ctx = (CONTEXT *)ctx_void;
+ SContext *ctx = (SContext *)ctx_void;
if (!jit->IsInCodeSpace(codePtr))
return 0; // this will become a regular crash real soon after this
@@ -206,7 +206,7 @@ const u8 *Jitx86Base::BackPatch(u8 *codePtr, u32 emAddress, void *ctx_void)
if (info.instructionSize < 3)
PanicAlert("Instruction too small");
// We entered here with a BSWAP-ed EAX. We'll have to swap it back.
- ctx->Rax = Common::swap32((u32)ctx->Rax);
+ ctx->CTX_RAX = Common::swap32((u32)ctx->CTX_RAX);
return codePtr - 2;
}
return 0;
diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h
index a8f204b1e1..5c44f844a9 100644
--- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h
+++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h
@@ -10,38 +10,220 @@
#include "x64Analyzer.h"
#include "Thunk.h"
-// Declarations and definitions
-// ----------
-
-// void Jit(u32 em_address);
-
-#ifndef _WIN32
-
- // 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_ARM
- u32 reg_pc;
+// meh.
+#if defined(_WIN32)
+ #include <windows.h>
+ typedef CONTEXT SContext;
+ #if defined(_M_X64)
+ #define CTX_RAX Rax
+ #define CTX_RBX Rbx
+ #define CTX_RCX Rcx
+ #define CTX_RDX Rdx
+ #define CTX_RDI Rdi
+ #define CTX_RSI Rsi
+ #define CTX_RBP Rbp
+ #define CTX_RSP Rsp
+ #define CTX_R8 R8
+ #define CTX_R9 R9
+ #define CTX_R10 R10
+ #define CTX_R11 R11
+ #define CTX_R12 R12
+ #define CTX_R13 R13
+ #define CTX_R14 R14
+ #define CTX_R15 R15
+ #define CTX_RIP Rip
+ #elif defined(_M_IX86)
+ #define CTX_EAX Eax
+ #define CTX_EBX Ebx
+ #define CTX_ECX Ecx
+ #define CTX_EDX Edx
+ #define CTX_EDI Edi
+ #define CTX_ESI Esi
+ #define CTX_EBP Ebp
+ #define CTX_ESP Esp
+ #define CTX_EIP Eip
#else
- #ifdef _M_X64
- u64 Rip;
- u64 Rax;
+ #error No context definition for OS
+ #endif
+#elif defined(__APPLE__)
+ #include <mach/mach.h>
+ #include <mach/message.h>
+ #if defined(_M_X64)
+ typedef x86_thread_state64_t SContext;
+ #define CTX_RAX __rax
+ #define CTX_RBX __rbx
+ #define CTX_RCX __rcx
+ #define CTX_RDX __rdx
+ #define CTX_RDI __rdi
+ #define CTX_RSI __rsi
+ #define CTX_RBP __rbp
+ #define CTX_RSP __rsp
+ #define CTX_R8 __r8
+ #define CTX_R9 __r9
+ #define CTX_R10 __r10
+ #define CTX_R11 __r11
+ #define CTX_R12 __r12
+ #define CTX_R13 __r13
+ #define CTX_R14 __r14
+ #define CTX_R15 __r15
+ #define CTX_RIP __rip
+ #elif defined(_M_IX86)
+ typedef x86_thread_state_t SContext;
+ #define CTX_EAX __eax
+ #define CTX_EBX __ebx
+ #define CTX_ECX __ecx
+ #define CTX_EDX __edx
+ #define CTX_EDI __edi
+ #define CTX_ESI __esi
+ #define CTX_EBP __ebp
+ #define CTX_ESP __esp
+ #define CTX_EIP __eip
+ #elif defined(_M_ARM)
+ typedef arm_thread_state_t SContext;
+ // Add others if required.
+ #define CTX_PC __pc
#else
- u32 Eip;
- u32 Eax;
- #endif
+ #error No context definition for OS
+ #endif
+#elif defined(__linux__)
+ #include <signal.h>
+ #if defined(_M_X64)
+ #include <ucontext.h>
+ typedef mcontext_t SContext;
+ #define CTX_RAX gregs[REG_RAX]
+ #define CTX_RBX gregs[REG_RBX]
+ #define CTX_RCX gregs[REG_RCX]
+ #define CTX_RDX gregs[REG_RDX]
+ #define CTX_RDI gregs[REG_RDI]
+ #define CTX_RSI gregs[REG_RSI]
+ #define CTX_RBP gregs[REG_RBP]
+ #define CTX_RSP gregs[REG_RSP]
+ #define CTX_R8 gregs[REG_R8]
+ #define CTX_R9 gregs[REG_R9]
+ #define CTX_R10 gregs[REG_R10]
+ #define CTX_R11 gregs[REG_R11]
+ #define CTX_R12 gregs[REG_R12]
+ #define CTX_R13 gregs[REG_R13]
+ #define CTX_R14 gregs[REG_R14]
+ #define CTX_R15 gregs[REG_R15]
+ #define CTX_RIP gregs[REG_RIP]
+ #elif defined(_M_IX86)
+ #include <ucontext.h>
+ typedef mcontext_t SContext;
+ #define CTX_EAX gregs[REG_EAX]
+ #define CTX_EBX gregs[REG_EBX]
+ #define CTX_ECX gregs[REG_ECX]
+ #define CTX_EDX gregs[REG_EDX]
+ #define CTX_EDI gregs[REG_EDI]
+ #define CTX_ESI gregs[REG_ESI]
+ #define CTX_EBP gregs[REG_EBP]
+ #define CTX_ESP gregs[REG_ESP]
+ #define CTX_EIP gregs[REG_EIP]
+ #elif defined(ANDROID)
+ // Add others if required.
+ typedef struct sigcontext SContext;
+ #define CTX_PC arm_pc
+ #else
+ #error No context definition for OS
+ #endif
+#elif defined(__NetBSD__)
+ #include <ucontext.h>
+ typedef mcontext_t SContext;
+ #if defined(_M_X64)
+ #define CTX_RAX __gregs[_REG_RAX]
+ #define CTX_RBX __gregs[_REG_RBX]
+ #define CTX_RCX __gregs[_REG_RCX]
+ #define CTX_RDX __gregs[_REG_RDX]
+ #define CTX_RDI __gregs[_REG_RDI]
+ #define CTX_RSI __gregs[_REG_RSI]
+ #define CTX_RBP __gregs[_REG_RBP]
+ #define CTX_RSP __gregs[_REG_RSP]
+ #define CTX_R8 __gregs[_REG_R8]
+ #define CTX_R9 __gregs[_REG_R9]
+ #define CTX_R10 __gregs[_REG_R10]
+ #define CTX_R11 __gregs[_REG_R11]
+ #define CTX_R12 __gregs[_REG_R12]
+ #define CTX_R13 __gregs[_REG_R13]
+ #define CTX_R14 __gregs[_REG_R14]
+ #define CTX_R15 __gregs[_REG_R15]
+ #define CTX_RIP __gregs[_REG_RIP]
+ #elif defined(_M_IX86)
+ #define CTX_EAX __gregs[__REG_EAX]
+ #define CTX_EBX __gregs[__REG_EBX]
+ #define CTX_ECX __gregs[__REG_ECX]
+ #define CTX_EDX __gregs[__REG_EDX]
+ #define CTX_EDI __gregs[__REG_EDI]
+ #define CTX_ESI __gregs[__REG_ESI]
+ #define CTX_EBP __gregs[__REG_EBP]
+ #define CTX_ESP __gregs[__REG_ESP]
+ #define CTX_EIP __gregs[__REG_EIP]
+ #else
+ #error No context definition for OS
+ #endif
+#elif defined(__FreeBSD__)
+ #include <ucontext.h>
+ typedef mcontext_t SContext;
+ #if defined(_M_X64)
+ #define CTX_RAX mc_rax
+ #define CTX_RBX mc_rbx
+ #define CTX_RCX mc_rcx
+ #define CTX_RDX mc_rdx
+ #define CTX_RDI mc_rdi
+ #define CTX_RSI mc_rsi
+ #define CTX_RBP mc_rbp
+ #define CTX_RSP mc_rsp
+ #define CTX_R8 mc_r8
+ #define CTX_R9 mc_r9
+ #define CTX_R10 mc_r10
+ #define CTX_R11 mc_r11
+ #define CTX_R12 mc_r12
+ #define CTX_R13 mc_r13
+ #define CTX_R14 mc_r14
+ #define CTX_R15 mc_r15
+ #define CTX_RIP mc_rip
+ #elif defined(_M_IX86)
+ #define CTX_EAX mc_eax
+ #define CTX_EBX mc_ebx
+ #define CTX_ECX mc_ecx
+ #define CTX_EDX mc_edx
+ #define CTX_EDI mc_edi
+ #define CTX_ESI mc_esi
+ #define CTX_EBP mc_ebp
+ #define CTX_ESP mc_esp
+ #define CTX_EIP mc_eip
+ #else
+ #error No context definition for OS
#endif
- };
-
#endif
-#if defined(_M_ARM)
-#define CONTEXT_PC(ctx) ((ctx)->reg_pc)
-#elif defined(_M_X64)
-#define CONTEXT_PC(ctx) ((ctx)->Rip)
-#else
-#define CONTEXT_PC(ctx) ((ctx)->Eip)
+#if defined(_M_X64)
+#define CTX_PC CTX_RIP
+#include <stddef.h>
+static inline u64 *ContextRN(SContext* ctx, int n)
+{
+ static const u8 offsets[] =
+ {
+ offsetof(SContext, CTX_RAX),
+ offsetof(SContext, CTX_RCX),
+ offsetof(SContext, CTX_RDX),
+ offsetof(SContext, CTX_RBX),
+ offsetof(SContext, CTX_RSP),
+ offsetof(SContext, CTX_RBP),
+ offsetof(SContext, CTX_RSI),
+ offsetof(SContext, CTX_RDI),
+ offsetof(SContext, CTX_R8),
+ offsetof(SContext, CTX_R9),
+ offsetof(SContext, CTX_R10),
+ offsetof(SContext, CTX_R11),
+ offsetof(SContext, CTX_R12),
+ offsetof(SContext, CTX_R13),
+ offsetof(SContext, CTX_R14),
+ offsetof(SContext, CTX_R15)
+ };
+ return (u64 *) ((char *) ctx + offsets[n]);
+}
+#elif defined(_M_IX86)
+#define CTX_PC CTX_EIP
#endif
class TrampolineCache : public Gen::XCodeBlock
diff --git a/Source/Core/Core/Src/x64MemTools.cpp b/Source/Core/Core/Src/x64MemTools.cpp
index 9d854238d5..a0c79aaed5 100644
--- a/Source/Core/Core/Src/x64MemTools.cpp
+++ b/Source/Core/Core/Src/x64MemTools.cpp
@@ -2,44 +2,11 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
-#ifdef _WIN32
-#include <windows.h>
-#else
#include <stdio.h>
-#include <signal.h>
-#ifndef ANDROID
-#include <sys/ucontext.h> // Look in here for the context definition.
-#endif
-#endif
-
#ifdef __APPLE__
-#include <mach/mach.h>
-#include <mach/message.h>
#include "Thread.h"
#endif
-#ifdef __APPLE__
-#define CREG_RAX(ctx) (*(ctx))->__ss.__rax
-#define CREG_RIP(ctx) (*(ctx))->__ss.__rip
-#define CREG_EAX(ctx) (*(ctx))->__ss.__eax
-#define CREG_EIP(ctx) (*(ctx))->__ss.__eip
-#elif defined __FreeBSD__
-#define CREG_RAX(ctx) (ctx)->mc_rax
-#define CREG_RIP(ctx) (ctx)->mc_rip
-#define CREG_EAX(ctx) (ctx)->mc_eax
-#define CREG_EIP(ctx) (ctx)->mc_eip
-#elif defined __linux__
-#define CREG_RAX(ctx) (ctx)->gregs[REG_RAX]
-#define CREG_RIP(ctx) (ctx)->gregs[REG_RIP]
-#define CREG_EAX(ctx) (ctx)->gregs[REG_EAX]
-#define CREG_EIP(ctx) (ctx)->gregs[REG_EIP]
-#elif defined __NetBSD__
-#define CREG_RAX(ctx) (ctx)->__gregs[_REG_RAX]
-#define CREG_RIP(ctx) (ctx)->__gregs[_REG_RIP]
-#define CREG_EAX(ctx) (ctx)->__gregs[_REG_EAX]
-#define CREG_EIP(ctx) (ctx)->__gregs[_REG_EIP]
-#endif
-
#include <vector>
#include "Common.h"
@@ -73,9 +40,9 @@ void print_trace(const char * msg)
}
#endif
-bool DoFault(u64 bad_address, CONTEXT *ctx)
+bool DoFault(u64 bad_address, SContext *ctx)
{
- if (!JitInterface::IsInCodeSpace((u8*) CONTEXT_PC(ctx)))
+ if (!JitInterface::IsInCodeSpace((u8*) ctx->CTX_PC))
{
// Let's not prevent debugging.
return false;
@@ -93,10 +60,10 @@ bool DoFault(u64 bad_address, CONTEXT *ctx)
return false;
}
u32 em_address = (u32)(bad_address - memspace_bottom);
- const u8 *new_pc = jit->BackPatch((u8*) CONTEXT_PC(ctx), em_address, ctx);
+ const u8 *new_pc = jit->BackPatch((u8*) ctx->CTX_PC, em_address, ctx);
if (new_pc)
{
- CONTEXT_PC(ctx) = (u64) new_pc;
+ ctx->CTX_PC = (u64) new_pc;
}
return true;
@@ -244,14 +211,8 @@ void ExceptionThread(mach_port_t port)
}
x86_thread_state64_t *state = (x86_thread_state64_t *) msg_in.old_state;
- CONTEXT fake_ctx;
- fake_ctx.Rax = state->__rax;
- fake_ctx.Rip = state->__rip;
-
- bool ok = DoFault(msg_in.code[1], &fake_ctx);
- state->__rax = fake_ctx.Rax;
- state->__rip = fake_ctx.Rip;
+ bool ok = DoFault(msg_in.code[1], state);
// Set up the reply.
msg_out.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg_in.Head.msgh_bits), 0);
@@ -324,26 +285,8 @@ void sigsegv_handler(int sig, siginfo_t *info, void *raw_context)
// Get all the information we can out of the context.
mcontext_t *ctx = &context->uc_mcontext;
- CONTEXT fake_ctx;
-#ifdef _M_X64
- fake_ctx.Rax = CREG_RAX(ctx);
- fake_ctx.Rip = CREG_RIP(ctx);
-#else
- fake_ctx.Eax = CREG_EAX(ctx);
- fake_ctx.Eip = CREG_EIP(ctx);
-#endif
// assume it's not a write
- if (DoFault(bad_address, &fake_ctx))
- {
-#ifdef _M_X64
- CREG_RAX(ctx) = fake_ctx.Rax;
- CREG_RIP(ctx) = fake_ctx.Rip;
-#else
- CREG_EAX(ctx) = fake_ctx.Eax;
- CREG_EIP(ctx) = fake_ctx.Eip;
-#endif
- }
- else
+ if (!DoFault(bad_address, ctx))
{
// retry and crash
signal(SIGSEGV, SIG_DFL);