replace the VHD/diskpart disk image pipeline with a directory-based vvfat root, we'll see when it breaks, fix /O2, add an all_tests, generalize the fat32 driver into a fat 16+32 driver, change policy on volume drivers, collapse KCPU's fields into a single atomic KE_CPU_STATE state machine, move scheduler ticking to per-CPU LAPIC timers, gate verbose SMP topology logging behind selftest diagnostics and add SMP pool-checkpoint validation around AP admission, add checked intrusive list helpers behind a new KE_DEBUG_LIST_CHECKS flag, add ObInitializeObjectHeader/ObTryReferenceObject, add waitable display clock objects and a SYS_OPEN_DISPLAY_CLOCK syscall for vsync-style waits, refactor kernel input into a per-queue KE_INPUT_CONTEXT with its own key/mouse ring buffers and DPC-driven key repeat, add KeInputQueuePeekEvent/ReadEvent/WaitKey and a SYS_QUERY_GLOBAL_INPUT_STATE syscall, split the kernel pool allocator out of mm_virt, new video files!
This commit is contained in:
1 parent
485a6bbfe7
commit
8b254f84f4
74 files changed
+4488
-2503
No files matched your search
+110
-30
@@ -28,6 +28,8 @@ static const HAL_API* gDebugHal;
|
||||
#define KE_DEBUG_LOG_BUFFER_SIZE (50u * 1024u)
|
||||
#define KE_DEBUG_LOG_LINE_SIZE 1024u
|
||||
#define KE_FATAL_OUTPUT_LINE_SIZE 2048u
|
||||
#define KE_STACK_DUMP_SLOT_COUNT 12u
|
||||
#define KE_RBP_CALL_STACK_DEPTH 16u
|
||||
|
||||
static SPINLOCK gDebugPrintLock = SPINLOCK_INIT;
|
||||
static char* gDebugLogBuffer;
|
||||
@@ -412,6 +414,22 @@ static void KiPrintAddress(PROCESS* proc, const char* label, uintptr_t addr) {
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a resolved address without ending the current line.
|
||||
static void KiPrintAddressValue(PROCESS* proc, uintptr_t addr) {
|
||||
uintptr_t base = 0;
|
||||
size_t size = 0;
|
||||
const char* mod = KiResolveModuleEx(proc, addr, &base, &size);
|
||||
|
||||
if (base) {
|
||||
KiFaultPrintf("%016llx <%s+0x%016llX>",
|
||||
(unsigned long long)addr,
|
||||
mod,
|
||||
(unsigned long long)(addr - base));
|
||||
} else {
|
||||
KiFaultPrintf("%016llx", (unsigned long long)addr);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks whether a kernel virtual range is mapped before diagnostic reads.
|
||||
static int KiKernelRangeReadable(uintptr_t addr, size_t size) {
|
||||
if (!addr || size == 0) return 0;
|
||||
@@ -562,44 +580,103 @@ static void KiDumpModules(PROCESS* proc) {
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps user Stack.
|
||||
static void KiDumpUserStack(PROCESS* proc, uintptr_t rsp) {
|
||||
KiFaultPrintf("User stack @ %016llx:\n", (unsigned long long)rsp);
|
||||
#if 0
|
||||
// Returns whether a range is inside the current kernel stack.
|
||||
static int KiKernelStackContains(const THREAD* thread, uintptr_t addr, size_t size) {
|
||||
if (!thread || !thread->KernelStackBase || !thread->KernelStackTop || !addr || size == 0)
|
||||
return 0;
|
||||
if (size - 1u > (size_t)(UINTPTR_MAX - addr))
|
||||
return 0;
|
||||
|
||||
uintptr_t base = (uintptr_t)thread->KernelStackBase;
|
||||
uintptr_t top = thread->KernelStackTop;
|
||||
uintptr_t end = addr + size;
|
||||
return addr >= base && end <= top;
|
||||
}
|
||||
|
||||
// Returns whether the fault frame is using the current kernel stack.
|
||||
static int KiFaultFrameOnKernelStack(const THREAD* thread, const KFAULT_FRAME* f) {
|
||||
if (!f || !thread)
|
||||
return 0;
|
||||
return KiKernelStackContains(thread, (uintptr_t)f->Rsp, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
#endif
|
||||
// Dumps stack words near RSP.
|
||||
static void KiDumpStack(PROCESS* proc, uintptr_t rsp) {
|
||||
KiFaultPrintf("Stack @ %016llx:\n", (unsigned long long)rsp);
|
||||
if (!rsp) {
|
||||
KiFaultPrintf(" <no user RSP captured>\n");
|
||||
KiFaultPrintf(" <no RSP captured>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
uintptr_t slot = rsp + (uintptr_t)i * 8u;
|
||||
for (uint32_t i = 0; i < KE_STACK_DUMP_SLOT_COUNT; i++) {
|
||||
uintptr_t slot = rsp + (uintptr_t)i * sizeof(uint64_t);
|
||||
uint64_t value = 0;
|
||||
KiFaultPrintf(" [%02u] %016llx : ",
|
||||
(unsigned)i,
|
||||
(unsigned long long)slot);
|
||||
if (KiUserReadU64(slot, &value)) {
|
||||
uintptr_t base = 0;
|
||||
size_t size = 0;
|
||||
const char* mod = KiResolveModuleEx(proc, (uintptr_t)value, &base, &size);
|
||||
if (base) {
|
||||
KiFaultPrintf(" [%02d] %016llx : %016llx <%s+0x%016llX>\n",
|
||||
i,
|
||||
(unsigned long long)slot,
|
||||
(unsigned long long)value,
|
||||
mod,
|
||||
(unsigned long long)((uintptr_t)value - base));
|
||||
} else {
|
||||
KiFaultPrintf(" [%02d] %016llx : %016llx\n",
|
||||
i,
|
||||
(unsigned long long)slot,
|
||||
(unsigned long long)value);
|
||||
}
|
||||
KiPrintAddressValue(proc, (uintptr_t)value);
|
||||
KiFaultPrintf("\n");
|
||||
} else {
|
||||
KiFaultPrintf(" [%02d] %016llx : <unreadable>\n",
|
||||
i,
|
||||
(unsigned long long)slot);
|
||||
KiFaultPrintf("<unreadable>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps fault Frame.
|
||||
static void KiDumpFaultFrame(PROCESS* proc, const KFAULT_FRAME* f) {
|
||||
#if 0
|
||||
// Dumps a best-effort frame-pointer call stack.
|
||||
static void KiDumpRbpCallStack(PROCESS* proc, THREAD* thread, const KFAULT_FRAME* f) {
|
||||
uintptr_t rbp = f ? (uintptr_t)f->Rbp : 0;
|
||||
KiFaultPrintf("RBP call stack @ %016llx:\n", (unsigned long long)rbp);
|
||||
if (!rbp) {
|
||||
KiFaultPrintf(" <no RBP captured>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int kernelStack = KiFaultFrameOnKernelStack(thread, f);
|
||||
for (uint32_t depth = 0; depth < KE_RBP_CALL_STACK_DEPTH; depth++) {
|
||||
if (rbp & (sizeof(uint64_t) - 1u)) {
|
||||
KiFaultPrintf(" stop: unaligned RBP %016llx\n",
|
||||
(unsigned long long)rbp);
|
||||
return;
|
||||
}
|
||||
if (kernelStack && !KiKernelStackContains(thread, rbp, sizeof(uint64_t) * 2u)) {
|
||||
KiFaultPrintf(" stop: RBP outside kernel stack %016llx\n",
|
||||
(unsigned long long)rbp);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t next = 0;
|
||||
uint64_t ret = 0;
|
||||
if (!KiUserReadU64(rbp, &next) || !KiUserReadU64(rbp + sizeof(uint64_t), &ret)) {
|
||||
KiFaultPrintf(" stop: frame unreadable at %016llx\n",
|
||||
(unsigned long long)rbp);
|
||||
return;
|
||||
}
|
||||
|
||||
KiFaultPrintf(" #%02u rbp=%016llx ret=",
|
||||
(unsigned)depth,
|
||||
(unsigned long long)rbp);
|
||||
KiPrintAddressValue(proc, (uintptr_t)ret);
|
||||
KiFaultPrintf(" next=%016llx\n", (unsigned long long)next);
|
||||
|
||||
if (!next)
|
||||
return;
|
||||
if ((uintptr_t)next <= rbp) {
|
||||
KiFaultPrintf(" stop: non-forward RBP chain %016llx -> %016llx\n",
|
||||
(unsigned long long)rbp,
|
||||
(unsigned long long)next);
|
||||
return;
|
||||
}
|
||||
rbp = (uintptr_t)next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// Dumps a fault frame.
|
||||
static void KiDumpFaultFrame(PROCESS* proc, THREAD* thread, const KFAULT_FRAME* f) {
|
||||
if (!f) return;
|
||||
|
||||
KiFaultPrintf("Regs:\n");
|
||||
@@ -634,7 +711,10 @@ static void KiDumpFaultFrame(PROCESS* proc, const KFAULT_FRAME* f) {
|
||||
KiDumpBytes(proc, "Bytes near RIP", (uintptr_t)f->Rip);
|
||||
}
|
||||
|
||||
KiDumpUserStack(proc, (uintptr_t)f->Rsp);
|
||||
KiDumpStack(proc, (uintptr_t)f->Rsp);
|
||||
#if 0
|
||||
KiDumpRbpCallStack(proc, thread, f);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void KiPrintCrashHeader(PROCESS* proc, int vector, uintptr_t rip,
|
||||
@@ -710,7 +790,7 @@ static _Noreturn void KiPanicKernelFault(PROCESS* proc, THREAD* thread, const KF
|
||||
thread,
|
||||
proc ? proc->ProcessId : 0,
|
||||
proc ? proc->Name : "<none>");
|
||||
KiDumpFaultFrame(proc, frame);
|
||||
KiDumpFaultFrame(proc, thread, frame);
|
||||
if (vector == 14) {
|
||||
MmDebugDescribeAddress((uintptr_t)frame->Cr2);
|
||||
if (frame->Rip) MmDebugDescribeAddress((uintptr_t)frame->Rip);
|
||||
@@ -755,7 +835,7 @@ static _Noreturn void KiTerminateUserFault(PROCESS* proc, THREAD* thread, const
|
||||
(uintptr_t)frame->Rip,
|
||||
(uintptr_t)frame->ErrorCode,
|
||||
(uintptr_t)frame->Cr2);
|
||||
KiDumpFaultFrame(proc, frame);
|
||||
KiDumpFaultFrame(proc, thread, frame);
|
||||
KiDumpModules(proc);
|
||||
|
||||
KiFinishFaultedProcess(proc, thread, KeExceptionProcessExitStatus((uint32_t)frame->Vector));
|
||||
|
||||
Reference in new issue
Block a user