Merge branch 'master' into d3d12

This commit is contained in:
Triang3l 2018-11-18 12:13:26 +03:00
commit 251ce2af6b
4 changed files with 93 additions and 77 deletions

View File

@ -29,9 +29,69 @@ namespace cpu {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
// http://msdn.microsoft.com/en-us/library/ssa62fwe.aspx
typedef enum _UNWIND_OP_CODES {
UWOP_PUSH_NONVOL = 0, /* info == register number */
UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */
UWOP_ALLOC_SMALL, /* info == size of allocation / 8 - 1 */
UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */
UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */
UWOP_SAVE_XMM128, /* info == XMM reg number, offset in next slot */
UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */
UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */
} UNWIND_CODE_OPS;
class UNWIND_REGISTER {
public:
enum _ {
RAX = 0,
RCX = 1,
RDX = 2,
RBX = 3,
RSP = 4,
RBP = 5,
RSI = 6,
RDI = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
R13 = 13,
R14 = 14,
R15 = 15,
};
};
typedef union _UNWIND_CODE {
struct {
uint8_t CodeOffset;
uint8_t UnwindOp : 4;
uint8_t OpInfo : 4;
};
USHORT FrameOffset;
} UNWIND_CODE, *PUNWIND_CODE;
typedef struct _UNWIND_INFO {
uint8_t Version : 3;
uint8_t Flags : 5;
uint8_t SizeOfProlog;
uint8_t CountOfCodes;
uint8_t FrameRegister : 4;
uint8_t FrameOffset : 4;
UNWIND_CODE UnwindCode[1];
/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
* union {
* OPTIONAL ULONG ExceptionHandler;
* OPTIONAL ULONG FunctionEntry;
* };
* OPTIONAL ULONG ExceptionData[]; */
} UNWIND_INFO, *PUNWIND_INFO;
// Size of unwind info per function. // Size of unwind info per function.
// TODO(benvanik): move this to emitter. // TODO(benvanik): move this to emitter.
static const uint32_t kUnwindInfoSize = 4 + (2 * 1 + 2 + 2); static const uint32_t kUnwindInfoSize =
sizeof(UNWIND_INFO) + (sizeof(UNWIND_CODE) * (6 - 1));
class Win32X64CodeCache : public X64CodeCache { class Win32X64CodeCache : public X64CodeCache {
public: public:
@ -106,10 +166,10 @@ bool Win32X64CodeCache::Initialize() {
if (!RtlInstallFunctionTableCallback( if (!RtlInstallFunctionTableCallback(
reinterpret_cast<DWORD64>(generated_code_base_) | 0x3, reinterpret_cast<DWORD64>(generated_code_base_) | 0x3,
reinterpret_cast<DWORD64>(generated_code_base_), kGeneratedCodeSize, reinterpret_cast<DWORD64>(generated_code_base_), kGeneratedCodeSize,
[](uintptr_t control_pc, void* context) { [](DWORD64 control_pc, PVOID context) {
auto code_cache = reinterpret_cast<X64CodeCache*>(context); auto code_cache = reinterpret_cast<Win32X64CodeCache*>(context);
return reinterpret_cast<PRUNTIME_FUNCTION>( return reinterpret_cast<PRUNTIME_FUNCTION>(
code_cache->LookupUnwindEntry(control_pc)); code_cache->LookupUnwindInfo(control_pc));
}, },
this, nullptr)) { this, nullptr)) {
XELOGE("Unable to install function table callback"); XELOGE("Unable to install function table callback");
@ -150,71 +210,13 @@ void Win32X64CodeCache::PlaceCode(uint32_t guest_address, void* machine_code,
FlushInstructionCache(GetCurrentProcess(), code_address, code_size); FlushInstructionCache(GetCurrentProcess(), code_address, code_size);
} }
// http://msdn.microsoft.com/en-us/library/ssa62fwe.aspx
typedef enum _UNWIND_OP_CODES {
UWOP_PUSH_NONVOL = 0, /* info == register number */
UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */
UWOP_ALLOC_SMALL, /* info == size of allocation / 8 - 1 */
UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */
UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */
UWOP_SAVE_XMM128, /* info == XMM reg number, offset in next slot */
UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */
UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */
} UNWIND_CODE_OPS;
class UNWIND_REGISTER {
public:
enum _ {
RAX = 0,
RCX = 1,
RDX = 2,
RBX = 3,
RSP = 4,
RBP = 5,
RSI = 6,
RDI = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
R13 = 13,
R14 = 14,
R15 = 15,
};
};
typedef union _UNWIND_CODE {
struct {
uint8_t CodeOffset;
uint8_t UnwindOp : 4;
uint8_t OpInfo : 4;
};
USHORT FrameOffset;
} UNWIND_CODE, *PUNWIND_CODE;
typedef struct _UNWIND_INFO {
uint8_t Version : 3;
uint8_t Flags : 5;
uint8_t SizeOfProlog;
uint8_t CountOfCodes;
uint8_t FrameRegister : 4;
uint8_t FrameOffset : 4;
UNWIND_CODE UnwindCode[1];
/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
* union {
* OPTIONAL ULONG ExceptionHandler;
* OPTIONAL ULONG FunctionEntry;
* };
* OPTIONAL ULONG ExceptionData[]; */
} UNWIND_INFO, *PUNWIND_INFO;
void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address, void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
size_t unwind_table_slot, size_t unwind_table_slot,
void* code_address, void* code_address,
size_t code_size, size_t code_size,
size_t stack_size) { size_t stack_size) {
auto unwind_info = reinterpret_cast<UNWIND_INFO*>(unwind_entry_address); auto unwind_info = reinterpret_cast<UNWIND_INFO*>(unwind_entry_address);
UNWIND_CODE* unwind_code = nullptr;
if (!stack_size) { if (!stack_size) {
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
@ -231,17 +233,16 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
unwind_info->Version = 1; unwind_info->Version = 1;
unwind_info->Flags = 0; unwind_info->Flags = 0;
unwind_info->SizeOfProlog = prolog_size; unwind_info->SizeOfProlog = prolog_size;
unwind_info->CountOfCodes = 1; unwind_info->CountOfCodes = 0;
unwind_info->FrameRegister = 0; unwind_info->FrameRegister = 0;
unwind_info->FrameOffset = 0; unwind_info->FrameOffset = 0;
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx // http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
size_t co = 0; unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
auto& unwind_code = unwind_info->UnwindCode[co++]; unwind_code->CodeOffset =
unwind_code.CodeOffset =
14; // end of instruction + 1 == offset of next instruction 14; // end of instruction + 1 == offset of next instruction
unwind_code.UnwindOp = UWOP_ALLOC_SMALL; unwind_code->UnwindOp = UWOP_ALLOC_SMALL;
unwind_code.OpInfo = stack_size / 8 - 1; unwind_code->OpInfo = stack_size / 8 - 1;
} else { } else {
// TODO(benvanik): take as parameters? // TODO(benvanik): take as parameters?
uint8_t prolog_size = 7; uint8_t prolog_size = 7;
@ -250,21 +251,26 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
unwind_info->Version = 1; unwind_info->Version = 1;
unwind_info->Flags = 0; unwind_info->Flags = 0;
unwind_info->SizeOfProlog = prolog_size; unwind_info->SizeOfProlog = prolog_size;
unwind_info->CountOfCodes = 2; unwind_info->CountOfCodes = 0;
unwind_info->FrameRegister = 0; unwind_info->FrameRegister = 0;
unwind_info->FrameOffset = 0; unwind_info->FrameOffset = 0;
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx // http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
size_t co = 0; unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
auto& unwind_code = unwind_info->UnwindCode[co++]; unwind_code->CodeOffset =
unwind_code.CodeOffset =
7; // end of instruction + 1 == offset of next instruction 7; // end of instruction + 1 == offset of next instruction
unwind_code.UnwindOp = UWOP_ALLOC_LARGE; unwind_code->UnwindOp = UWOP_ALLOC_LARGE;
unwind_code.OpInfo = 0; unwind_code->OpInfo = 0; // One slot for size
assert_true((stack_size / 8) < 65536u); assert_true((stack_size / 8) < 65536u);
unwind_code = unwind_info->UnwindCode[co++]; unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
unwind_code.FrameOffset = (USHORT)(stack_size) / 8; unwind_code->FrameOffset = (USHORT)(stack_size) / 8;
}
if (unwind_info->CountOfCodes % 1) {
// Count of unwind codes must always be even.
std::memset(&unwind_info->UnwindCode[unwind_info->CountOfCodes + 1], 0,
sizeof(UNWIND_CODE));
} }
// Add entry. // Add entry.

View File

@ -92,6 +92,8 @@ class StackWalker {
// populated. // populated.
virtual bool ResolveStack(uint64_t* frame_host_pcs, StackFrame* frames, virtual bool ResolveStack(uint64_t* frame_host_pcs, StackFrame* frames,
size_t frame_count) = 0; size_t frame_count) = 0;
virtual ~StackWalker() = default;
}; };
} // namespace cpu } // namespace cpu

View File

@ -35,6 +35,8 @@ class App {
virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
uint32_t buffer_length) = 0; uint32_t buffer_length) = 0;
virtual ~App() = default;
protected: protected:
App(KernelState* kernel_state, uint32_t app_id); App(KernelState* kernel_state, uint32_t app_id);

View File

@ -42,6 +42,12 @@ void RtlRaiseException(pointer_t<X_EXCEPTION_RECORD> record) {
reinterpret_cast<X_THREADNAME_INFO*>(&record->exception_information[0]); reinterpret_cast<X_THREADNAME_INFO*>(&record->exception_information[0]);
assert_true(thread_info->type == 0x1000); assert_true(thread_info->type == 0x1000);
if (!thread_info->name_ptr) {
XELOGD("SetThreadName called with null name_ptr");
return;
}
auto name = auto name =
kernel_memory()->TranslateVirtual<const char*>(thread_info->name_ptr); kernel_memory()->TranslateVirtual<const char*>(thread_info->name_ptr);