diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index 3abc3c5c7..fc050507e 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -212,34 +212,51 @@ SHIM_CALL DbgBreakPoint_shim(PPCContext* ppc_state, KernelState* state) { DebugBreak(); } +// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +typedef struct { + xe::be type; + xe::be name_ptr; + xe::be thread_id; + xe::be flags; +} X_THREADNAME_INFO; +static_assert_size(X_THREADNAME_INFO, 0x10); + +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082.aspx +typedef struct { + xe::be exception_code; + xe::be exception_flags; + xe::be exception_record; + xe::be exception_address; + xe::be number_parameters; + xe::be exception_information[15]; +} X_EXCEPTION_RECORD; +static_assert_size(X_EXCEPTION_RECORD, 0x50); + SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) { uint32_t record_ptr = SHIM_GET_ARG_32(0); - uint32_t code = SHIM_MEM_32(record_ptr + 0); - uint32_t flags = SHIM_MEM_32(record_ptr + 4); - // ... - uint32_t param_count = SHIM_MEM_32(record_ptr + 16); + auto record = reinterpret_cast(SHIM_MEM_ADDR(record_ptr)); - XELOGD("RtlRaiseException(%.8X(%.8X))", record_ptr, code); + XELOGD("RtlRaiseException(%.8X(%.8X))", record_ptr, record->exception_code); - if (code == 0x406D1388) { + if (record->exception_code == 0x406D1388) { // SetThreadName. FFS. - uint32_t thread_info_ptr = record_ptr + 20; - uint32_t type = SHIM_MEM_32(thread_info_ptr + 0); - assert_true(type == 0x1000); - uint32_t name_ptr = SHIM_MEM_32(thread_info_ptr + 4); - uint32_t thread_id = SHIM_MEM_32(thread_info_ptr + 8); + // https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx - const char* name = (const char*)SHIM_MEM_ADDR(name_ptr); + // TODO: check record->number_parameters to make sure it's a correct size + auto thread_info = reinterpret_cast(&record->exception_information[0]); + + assert_true(thread_info->type == 0x1000); + const char* name = (const char*)SHIM_MEM_ADDR(thread_info->name_ptr); XThread* thread = NULL; - if (thread_id == -1) { + if (thread_info->thread_id == -1) { // Current thread. thread = XThread::GetCurrentThread(); thread->Retain(); } else { // Lookup thread by ID. - thread = state->GetThreadByID(thread_id); + thread = state->GetThreadByID(thread_info->thread_id); } if (thread) { @@ -252,6 +269,13 @@ SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) { return; } + if (record->exception_code == 0xE06D7363) { + // C++ exception. + // http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx + DebugBreak(); + return; + } + // TODO(benvanik): unwinding. // This is going to suck. DebugBreak();