[Audit] handle-lifecycle XELOGKERNEL probes (cvar-gated)
New cvar `audit_handle_lifecycle` (Auditing group, default false). When enabled, emits one-line XELOGKERNEL traces tagged AUDIT-HLC at: NtCreateEvent return, NtSetEvent entry, KeSetEvent entry, NtWaitForSingleObjectEx entry + completion, EmulateCPInterruptDPC entry. Observation-only: zero-overhead when cvar off (single branch + flag read). Intended for handle disambiguation between xenia-rs and canary under the Wine cross-build oracle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,3 +14,7 @@ DEFINE_bool(headless, false,
|
|||||||
"UI");
|
"UI");
|
||||||
DEFINE_bool(log_high_frequency_kernel_calls, false,
|
DEFINE_bool(log_high_frequency_kernel_calls, false,
|
||||||
"Log kernel calls with the kHighFrequency tag.", "Logging");
|
"Log kernel calls with the kHighFrequency tag.", "Logging");
|
||||||
|
DEFINE_bool(audit_handle_lifecycle, false,
|
||||||
|
"Emit XELOGKERNEL on Event/Semaphore/Wait lifecycle "
|
||||||
|
"(create/set/wait/complete). Audit oracle probe — off by default.",
|
||||||
|
"Auditing");
|
||||||
|
|||||||
@@ -13,5 +13,6 @@
|
|||||||
|
|
||||||
DECLARE_bool(headless);
|
DECLARE_bool(headless);
|
||||||
DECLARE_bool(log_high_frequency_kernel_calls);
|
DECLARE_bool(log_high_frequency_kernel_calls);
|
||||||
|
DECLARE_bool(audit_handle_lifecycle);
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_KERNEL_FLAGS_H_
|
#endif // XENIA_KERNEL_KERNEL_FLAGS_H_
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/hid/input_system.h"
|
#include "xenia/hid/input_system.h"
|
||||||
|
#include "xenia/kernel/kernel_flags.h"
|
||||||
#include "xenia/kernel/user_module.h"
|
#include "xenia/kernel/user_module.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_memory.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_memory.h"
|
||||||
@@ -1372,6 +1373,13 @@ void KernelState::EmulateCPInterruptDPC(uint32_t interrupt_callback,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cvars::audit_handle_lifecycle) {
|
||||||
|
XELOGKERNEL(
|
||||||
|
"AUDIT-HLC EmulateCPInterruptDPC callback={:08X} data={:08X} source={} "
|
||||||
|
"cpu={}",
|
||||||
|
interrupt_callback, interrupt_callback_data, source, cpu);
|
||||||
|
}
|
||||||
|
|
||||||
auto thread = kernel::XThread::GetCurrentThread();
|
auto thread = kernel::XThread::GetCurrentThread();
|
||||||
assert_not_null(thread);
|
assert_not_null(thread);
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
|
#include "xenia/kernel/kernel_flags.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||||
#include "xenia/kernel/xsemaphore.h"
|
#include "xenia/kernel/xsemaphore.h"
|
||||||
@@ -582,6 +583,10 @@ uint32_t xeKeSetEvent(X_KEVENT* event_ptr, uint32_t increment, uint32_t wait) {
|
|||||||
|
|
||||||
dword_result_t KeSetEvent_entry(pointer_t<X_KEVENT> event_ptr,
|
dword_result_t KeSetEvent_entry(pointer_t<X_KEVENT> event_ptr,
|
||||||
dword_t increment, dword_t wait) {
|
dword_t increment, dword_t wait) {
|
||||||
|
if (cvars::audit_handle_lifecycle) {
|
||||||
|
XELOGKERNEL("AUDIT-HLC KeSetEvent guest_ptr={:08X}",
|
||||||
|
uint32_t(event_ptr.guest_address()));
|
||||||
|
}
|
||||||
return xeKeSetEvent(event_ptr, increment, wait);
|
return xeKeSetEvent(event_ptr, increment, wait);
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT2(KeSetEvent, kThreading, kImplemented, kHighFrequency);
|
DECLARE_XBOXKRNL_EXPORT2(KeSetEvent, kThreading, kImplemented, kHighFrequency);
|
||||||
@@ -639,6 +644,11 @@ dword_result_t NtCreateEvent_entry(
|
|||||||
if (handle_ptr) {
|
if (handle_ptr) {
|
||||||
*handle_ptr = ev->handle();
|
*handle_ptr = ev->handle();
|
||||||
}
|
}
|
||||||
|
if (cvars::audit_handle_lifecycle) {
|
||||||
|
XELOGKERNEL("AUDIT-HLC NtCreateEvent handle={:08X} type={} initial_state={}",
|
||||||
|
handle_ptr ? uint32_t(*handle_ptr) : 0u,
|
||||||
|
uint32_t(event_type), uint32_t(initial_state));
|
||||||
|
}
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT1(NtCreateEvent, kThreading, kImplemented);
|
DECLARE_XBOXKRNL_EXPORT1(NtCreateEvent, kThreading, kImplemented);
|
||||||
@@ -664,6 +674,9 @@ uint32_t xeNtSetEvent(uint32_t handle, xe::be<uint32_t>* previous_state_ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dword_result_t NtSetEvent_entry(dword_t handle, lpdword_t previous_state_ptr) {
|
dword_result_t NtSetEvent_entry(dword_t handle, lpdword_t previous_state_ptr) {
|
||||||
|
if (cvars::audit_handle_lifecycle) {
|
||||||
|
XELOGKERNEL("AUDIT-HLC NtSetEvent handle={:08X}", uint32_t(handle));
|
||||||
|
}
|
||||||
return xeNtSetEvent(handle, previous_state_ptr);
|
return xeNtSetEvent(handle, previous_state_ptr);
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT2(NtSetEvent, kThreading, kImplemented, kHighFrequency);
|
DECLARE_XBOXKRNL_EXPORT2(NtSetEvent, kThreading, kImplemented, kHighFrequency);
|
||||||
@@ -1038,9 +1051,19 @@ dword_result_t NtWaitForSingleObjectEx_entry(dword_t object_handle,
|
|||||||
dword_t wait_mode,
|
dword_t wait_mode,
|
||||||
dword_t alertable,
|
dword_t alertable,
|
||||||
lpqword_t timeout_ptr) {
|
lpqword_t timeout_ptr) {
|
||||||
|
if (cvars::audit_handle_lifecycle) {
|
||||||
|
XELOGKERNEL("AUDIT-HLC NtWaitForSingleObjectEx handle={:08X} alertable={}",
|
||||||
|
uint32_t(object_handle), uint32_t(alertable));
|
||||||
|
}
|
||||||
uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u;
|
uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u;
|
||||||
return NtWaitForSingleObjectEx(object_handle, wait_mode, alertable,
|
uint32_t result = NtWaitForSingleObjectEx(object_handle, wait_mode, alertable,
|
||||||
timeout_ptr ? &timeout : nullptr);
|
timeout_ptr ? &timeout : nullptr);
|
||||||
|
if (cvars::audit_handle_lifecycle) {
|
||||||
|
XELOGKERNEL(
|
||||||
|
"AUDIT-HLC NtWaitForSingleObjectEx_done handle={:08X} result={:08X}",
|
||||||
|
uint32_t(object_handle), result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT3(NtWaitForSingleObjectEx, kThreading, kImplemented,
|
DECLARE_XBOXKRNL_EXPORT3(NtWaitForSingleObjectEx, kThreading, kImplemented,
|
||||||
kBlocking, kHighFrequency);
|
kBlocking, kHighFrequency);
|
||||||
|
|||||||
Reference in New Issue
Block a user