diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc index 460978fe2..7df32bfbe 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc @@ -162,6 +162,30 @@ dword_result_t ExCreateThread_entry(lpdword_t handle_ptr, dword_t stack_size, lpvoid_t start_address, lpvoid_t start_context, dword_t creation_flags) { + if (cvars::audit_handle_lifecycle) { + auto* ctx = cpu::ThreadState::Get()->context(); + uint32_t lr = static_cast(ctx->lr); + // Walk one PPC stack frame up from the shim's frame to recover the GUEST + // caller's LR (lr_enter is just the kernel-internal shim's return + // address; we want the function that called *it*). Same convention as + // the NtWaitForSingleObjectEx probe above. + uint32_t guest_lr = 0; + uint32_t sp = static_cast(ctx->r[1]); + uint32_t back1 = xe::load_and_swap(ctx->TranslateVirtual(sp)); + if (back1) { + uint32_t back2 = + xe::load_and_swap(ctx->TranslateVirtual(back1)); + if (back2) { + guest_lr = + xe::load_and_swap(ctx->TranslateVirtual(back2 - 8)); + } + } + XELOGKERNEL( + "AUDIT-HLC ExCreateThread entry={:08X} start_ctx={:08X} xapi={:08X} " + "flags={:08X} lr={:08X} guest_lr={:08X}", + uint32_t(start_address), uint32_t(start_context), + uint32_t(xapi_thread_startup), uint32_t(creation_flags), lr, guest_lr); + } return ExCreateThread(handle_ptr, stack_size, thread_id_ptr, xapi_thread_startup, start_address, start_context, creation_flags); diff --git a/src/xenia/kernel/xthread.cc b/src/xenia/kernel/xthread.cc index 33610bfb3..e2c4ecedc 100644 --- a/src/xenia/kernel/xthread.cc +++ b/src/xenia/kernel/xthread.cc @@ -21,6 +21,7 @@ #include "xenia/base/threading.h" #include "xenia/cpu/processor.h" #include "xenia/emulator.h" +#include "xenia/kernel/kernel_flags.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/user_module.h" #include "xenia/kernel/xboxkrnl/xboxkrnl_threading.h" @@ -544,6 +545,13 @@ X_STATUS XThread::Terminate(int exit_code) { void XThread::Execute() { XELOGKERNEL("XThread::Execute thid {} (handle={:08X}, '{}', native={:08X})", thread_id_, handle(), thread_name_, thread_->system_id()); + if (cvars::audit_handle_lifecycle) { + XELOGKERNEL( + "AUDIT-HLC XThread::Execute tid={} start_address={:08X} " + "start_context={:08X} xapi={:08X}", + thread_id_, creation_params_.start_address, + creation_params_.start_context, creation_params_.xapi_thread_startup); + } // Let the kernel know we are starting. kernel_state()->OnThreadExecute(this);