Fix building on OS X 10.10

This commit is contained in:
Robert Xu 2015-02-10 23:17:39 -05:00
parent 73d63c508a
commit 00e637645c
6 changed files with 145 additions and 10 deletions

View File

@ -263,6 +263,30 @@ namespace fmt
} }
}; };
template<>
struct get_fmt<unsigned long>
{
static std::string text(const char* fmt, size_t len, unsigned long arg)
{
if (fmt[len - 1] == 'x')
{
return to_hex(arg, get_fmt_precision(fmt, len));
}
else if (fmt[len - 1] == 'X')
{
return fmt::toupper(to_hex(arg, get_fmt_precision(fmt, len)));
}
else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u')
{
return to_udec(arg);
}
else
{
throw "Invalid formatting (unsigned long): " + std::string(fmt, len);
}
}
};
template<> template<>
struct get_fmt<u64> struct get_fmt<u64>
{ {
@ -359,6 +383,30 @@ namespace fmt
} }
}; };
template<>
struct get_fmt<long>
{
static std::string text(const char* fmt, size_t len, long arg)
{
if (fmt[len - 1] == 'x')
{
return to_hex((u64)arg, get_fmt_precision(fmt, len));
}
else if (fmt[len - 1] == 'X')
{
return fmt::toupper(to_hex((u64)arg, get_fmt_precision(fmt, len)));
}
else if (fmt[len - 1] == 'd')
{
return to_sdec(arg);
}
else
{
throw "Invalid formatting (long): " + std::string(fmt, len);
}
}
};
template<> template<>
struct get_fmt<s64> struct get_fmt<s64>
{ {

View File

@ -9,6 +9,8 @@
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
#define _XOPEN_SOURCE
#define __USE_GNU
#include <signal.h> #include <signal.h>
#include <ucontext.h> #include <ucontext.h>
#endif #endif
@ -195,21 +197,72 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_
typedef CONTEXT x64_context; typedef CONTEXT x64_context;
#define RIP 16 #define RIP 16
#define X64REG(context, reg) ((&context->Rax)[reg]) #define X64REG(context, reg) (&(&context->Rax)[reg])
#else #else
typedef ucontext_t x64_context; typedef ucontext_t x64_context;
typedef decltype(REG_RIP) reg_table_t;
#define RIP 16 #define RIP 16
#ifdef __APPLE__
#define X64REG(context, reg) (darwin_x64reg(context, reg))
uint64_t* darwin_x64reg(x64_context *context, int reg)
{
auto *state = &context->uc_mcontext->__ss;
switch(reg)
{
case 0: // RAX
return &state->__rax;
case 1: // RCX
return &state->__rcx;
case 2: // RDX
return &state->__rdx;
case 3: // RBX
return &state->__rbx;
case 4: // RSP
return &state->__rsp;
case 5: // RBP
return &state->__rbp;
case 6: // RSI
return &state->__rsi;
case 7: // RDI
return &state->__rdi;
case 8: // R8
return &state->__r8;
case 9: // R9
return &state->__r9;
case 10: // R10
return &state->__r10;
case 11: // R11
return &state->__r11;
case 12: // R12
return &state->__r12;
case 13: // R13
return &state->__r13;
case 14: // R14
return &state->__r14;
case 15: // R15
return &state->__r15;
case 16: // RIP
return &state->__rip;
default: // FAIL
assert(0);
}
}
#else
typedef decltype(REG_RIP) reg_table_t;
static const reg_table_t reg_table[17] = static const reg_table_t reg_table[17] =
{ {
REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI,
REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP
}; };
#define X64REG(context, reg) (context->uc_mcontext.gregs[reg_table[reg]]) #define X64REG(context, reg) (&context->uc_mcontext.gregs[reg_table[reg]])
#endif // __APPLE__
#endif #endif
@ -222,19 +275,19 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte
x64_op_t op; x64_op_t op;
x64_reg_t reg; x64_reg_t reg;
size_t size; size_t size;
decode_x64_reg_op((const u8*)X64REG(context, RIP), op, reg, size); decode_x64_reg_op((const u8*)(*X64REG(context, RIP)), op, reg, size);
// get x64 reg value (for store operations) // get x64 reg value (for store operations)
u64 reg_value; u64 reg_value;
if (reg - X64R32 < 16) if (reg - X64R32 < 16)
{ {
// load the value from x64 register // load the value from x64 register
reg_value = (u32)X64REG(context, reg - X64R32); reg_value = (u32)*X64REG(context, reg - X64R32);
} }
else if (reg == X64_IMM32) else if (reg == X64_IMM32)
{ {
// load the immediate value (assuming it's at the end of the instruction) // load the immediate value (assuming it's at the end of the instruction)
reg_value = *(u32*)(X64REG(context, RIP) + size - 4); reg_value = *(u32*)(*X64REG(context, RIP) + size - 4);
} }
else else
{ {
@ -265,7 +318,7 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte
if (reg - X64R32 < 16) if (reg - X64R32 < 16)
{ {
// store the value into x64 register // store the value into x64 register
X64REG(context, reg - X64R32) = (u32)reg_value; *X64REG(context, reg - X64R32) = (u32)reg_value;
} }
else else
{ {
@ -274,7 +327,7 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte
} }
// skip decoded instruction // skip decoded instruction
X64REG(context, RIP) += size; *X64REG(context, RIP) += size;
return true; return true;
} }
@ -324,7 +377,12 @@ const PVOID exception_handler = (atexit([]{ RemoveVectoredExceptionHandler(excep
void signal_handler(int sig, siginfo_t* info, void* uct) void signal_handler(int sig, siginfo_t* info, void* uct)
{ {
const u64 addr64 = (u64)info->si_addr - (u64)vm::g_base_addr; const u64 addr64 = (u64)info->si_addr - (u64)vm::g_base_addr;
#ifdef __APPLE__
const bool is_writing = ((ucontext_t*)uct)->uc_mcontext->__es.__err & 0x2;
#else
const bool is_writing = ((ucontext_t*)uct)->uc_mcontext.gregs[REG_ERR] & 0x2; const bool is_writing = ((ucontext_t*)uct)->uc_mcontext.gregs[REG_ERR] & 0x2;
#endif
if ((u32)addr64 == addr64 && GetCurrentNamedThread()) if ((u32)addr64 == addr64 && GetCurrentNamedThread())
{ {

View File

@ -887,6 +887,20 @@ struct cast_ppu_gpr<u32, false>
} }
}; };
template<>
struct cast_ppu_gpr<unsigned long, false>
{
__forceinline static u64 to_gpr(const unsigned long& value)
{
return value;
}
__forceinline static unsigned long from_gpr(const u64 reg)
{
return static_cast<unsigned long>(reg);
}
};
template<> template<>
struct cast_ppu_gpr<u64, false> struct cast_ppu_gpr<u64, false>
{ {

View File

@ -61,7 +61,7 @@ struct VFS
struct links_sorter struct links_sorter
{ {
bool operator()(const std::vector<std::string>& a, const std::vector<std::string>& b) bool operator()(const std::vector<std::string>& a, const std::vector<std::string>& b) const
{ {
return b.size() < a.size(); return b.size() < a.size();
} }

View File

@ -252,7 +252,7 @@ public:
else else
{ {
assert(!"Invalid ID type"); assert(!"Invalid ID type");
return{}; return std::set<u32>{};
} }
} }
}; };

View File

@ -84,6 +84,21 @@ namespace vm
} }
}; };
template<>
struct cast_ptr<unsigned long>
{
__forceinline static u32 cast(const unsigned long addr, const char* func)
{
const u32 res = static_cast<u32>(addr);
if (res != addr)
{
vm::error(addr, func);
}
return res;
}
};
template<> template<>
struct cast_ptr<u32> struct cast_ptr<u32>
{ {