diff --git a/Core/Crash/CrashDetails.cpp b/Core/Crash/CrashDetails.cpp new file mode 100644 index 0000000..491abb3 --- /dev/null +++ b/Core/Crash/CrashDetails.cpp @@ -0,0 +1,119 @@ +#include "../crashhandler.hpp" +#include "chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(__amd64__) +#include "../../Architecture/amd64/cpu/gdt.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +#include "../../kernel.h" + +static const char *PagefaultDescriptions[8] = { + "Supervisory process tried to read a non-present page entry\n", + "Supervisory process tried to read a page and caused a protection fault\n", + "Supervisory process tried to write to a non-present page entry\n", + "Supervisory process tried to write a page and caused a protection fault\n", + "User process tried to read a non-present page entry\n", + "User process tried to read a page and caused a protection fault\n", + "User process tried to write to a non-present page entry\n", + "User process tried to write a page and caused a protection fault\n"}; + +__no_stack_protector void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame) +{ + fixme("Divide by zero exception\n"); +} +__no_stack_protector void DebugExceptionHandler(CHArchTrapFrame *Frame) +{ + CrashHandler::EHPrint("\eDD2920System crashed!\n"); + CrashHandler::EHPrint("Kernel triggered debug exception.\n"); +} +__no_stack_protector void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); } +__no_stack_protector void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); } +__no_stack_protector void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); } +__no_stack_protector void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); } +__no_stack_protector void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame) +{ + CrashHandler::EHPrint("\eDD2920System crashed!\n"); + CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n"); +} +__no_stack_protector void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); } +__no_stack_protector void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); } +__no_stack_protector void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); } +__no_stack_protector void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); } +__no_stack_protector void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); } +__no_stack_protector void StackFaultExceptionHandler(CHArchTrapFrame *Frame) +{ + CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; + CrashHandler::EHPrint("\eDD2920System crashed!\n"); + CrashHandler::EHPrint("More info about the exception:\n"); + CrashHandler::EHPrint("Stack segment fault at address %#lx\n", Frame->rip); + CrashHandler::EHPrint("External: %d\n", SelCode.External); + CrashHandler::EHPrint("Table: %d\n", SelCode.Table); + CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); + CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode); +} +__no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame) +{ + // staticbuffer(descbuf); + // staticbuffer(desc_ext); + // staticbuffer(desc_table); + // staticbuffer(desc_idx); + // staticbuffer(desc_tmp); + CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; + // switch (SelCode.Table) + // { + // case CPU::x64::0b00: + // memcpy(desc_tmp, "GDT", 3); + // break; + // case CPU::x64::0b01: + // memcpy(desc_tmp, "IDT", 3); + // break; + // case CPU::x64::0b10: + // memcpy(desc_tmp, "LDT", 3); + // break; + // case CPU::x64::0b11: + // memcpy(desc_tmp, "IDT", 3); + // break; + // default: + // memcpy(desc_tmp, "Unknown", 7); + // break; + // } + CrashHandler::EHPrint("\eDD2920System crashed!\n"); + CrashHandler::EHPrint("Kernel performed an illegal operation.\n"); + CrashHandler::EHPrint("More info about the exception:\n"); + CrashHandler::EHPrint("External: %d\n", SelCode.External); + CrashHandler::EHPrint("Table: %d\n", SelCode.Table); + CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); +} +__no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame) +{ + CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; + CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF"); + CrashHandler::EHPrint("An exception occurred at %#lx by %#lx\n", CPU::x64::readcr2().PFLA, Frame->rip); + CrashHandler::EHPrint("Page: %s\n", params.P ? "Present" : "Not Present"); + CrashHandler::EHPrint("Write Operation: %s\n", params.W ? "Read-Only" : "Read-Write"); + CrashHandler::EHPrint("Processor Mode: %s\n", params.U ? "User-Mode" : "Kernel-Mode"); + CrashHandler::EHPrint("CPU Reserved Bits: %s\n", params.R ? "Reserved" : "Unreserved"); + CrashHandler::EHPrint("Caused By An Instruction Fetch: %s\n", params.I ? "Yes" : "No"); + CrashHandler::EHPrint("Caused By A Protection-Key Violation: %s\n", params.PK ? "Yes" : "No"); + CrashHandler::EHPrint("Caused By A Shadow Stack Access: %s\n", params.SS ? "Yes" : "No"); + CrashHandler::EHPrint("Caused By An SGX Violation: %s\n", params.SGX ? "Yes" : "No"); + if (Frame->ErrorCode & 0x00000008) + CrashHandler::EHPrint("One or more page directory entries contain reserved bits which are set to 1.\n"); + else + CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]); +} +__no_stack_protector void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); } +__no_stack_protector void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); } +__no_stack_protector void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); } +__no_stack_protector void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); } +__no_stack_protector void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); } +__no_stack_protector void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); } +__no_stack_protector void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); } diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index d7067fd..3e6688e 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -15,15 +16,19 @@ #include "../../kernel.h" +NewLock(UserInputLock); + namespace CrashHandler { - __attribute__((no_stack_protector)) void printfWrapper(char c, void *unused) + static bool ExceptionOccurred = false; + int SBIdx = 255; + __no_stack_protector void printfWrapper(char c, void *unused) { - Display->Print(c, 255, true); + Display->Print(c, SBIdx, true); UNUSED(unused); } - __attribute__((no_stack_protector)) void EHPrint(const char *Format, ...) + __no_stack_protector void EHPrint(const char *Format, ...) { va_list args; va_start(args, Format); @@ -31,17 +36,227 @@ namespace CrashHandler va_end(args); } - __attribute__((no_stack_protector)) void Handle(void *Data) + CRData crashdata = {}; + + __no_stack_protector void DisplayTopOverlay() + { + Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); + Video::Font *f = Display->GetCurrentFont(); + Video::FontInfo fi = f->GetInfo(); + + for (uint32_t i = 0; i < sb->Width; i++) + for (uint32_t j = 0; j < fi.Height + 8; j++) + Display->SetPixel(i, j, 0x282828, SBIdx); + + Display->SetBufferCursor(SBIdx, 8, (fi.Height + 8) / 6); + switch (SBIdx) + { + case 255: + { + EHPrint("\eAAAAAAMAIN \e606060DETAILS \e606060FRAMES \e606060TASKS \e606060CONSOLE"); + break; + } + case 254: + { + EHPrint("\e606060MAIN \eAAAAAADETAILS \e606060FRAMES \e606060TASKS \e606060CONSOLE"); + break; + } + case 253: + { + EHPrint("\e606060MAIN \e606060DETAILS \eAAAAAAFRAMES \e606060TASKS \e606060CONSOLE"); + break; + } + case 252: + { + EHPrint("\e606060MAIN \e606060DETAILS \e606060FRAMES \eAAAAAATASKS \e606060CONSOLE"); + break; + } + case 251: + { + EHPrint("\e606060MAIN \e606060DETAILS \e606060FRAMES \e606060TASKS \eAAAAAACONSOLE"); + break; + } + default: + { + EHPrint("\e606060MAIN \e606060DETAILS \e606060FRAMES \e606060TASKS \e606060CONSOLE"); + break; + } + } + EHPrint(" \e00AAFF%ldMB / %ldMB (%ldMB Reserved)", + TO_MB(KernelAllocator.GetUsedMemory()), + TO_MB(KernelAllocator.GetTotalMemory()), + TO_MB(KernelAllocator.GetReservedMemory())); + EHPrint(" \eAA0F0F%s", CPU::Hypervisor()); + EHPrint(" \eAAF00F%s", CPU::Vendor()); + EHPrint(" \eAA00FF%s", CPU::Name()); + Display->SetBufferCursor(SBIdx, 0, fi.Height + 10); + } + + __no_stack_protector void DisplayBottomOverlay() + { + Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); + Video::Font *f = Display->GetCurrentFont(); + Video::FontInfo fi = f->GetInfo(); + + for (uint32_t i = 0; i < sb->Width; i++) + for (uint32_t j = sb->Height - fi.Height - 8; j < sb->Height; j++) + Display->SetPixel(i, j, 0x282828, SBIdx); + + Display->SetBufferCursor(SBIdx, 8, sb->Height - fi.Height - 4); + EHPrint("\eAAAAAA> \eFAFAFA"); + } + + __no_stack_protector void ArrowInput(uint8_t key) + { + switch (key) + { + case KEY_D_UP: + if (SBIdx < 255) + SBIdx++; + else + return; + break; + case KEY_D_LEFT: + if (SBIdx < 255) + SBIdx++; + else + return; + break; + case KEY_D_RIGHT: + if (SBIdx > 250) + SBIdx--; + else + return; + break; + case KEY_D_DOWN: + if (SBIdx > 250) + SBIdx--; + else + return; + break; + default: + break; + } + Display->ClearBuffer(SBIdx); + DisplayTopOverlay(); + EHPrint("\eFAFAFA"); + + switch (SBIdx) + { + case 255: + { + DisplayMainScreen(crashdata); + break; + } + case 254: + { + DisplayDetailsScreen(crashdata); + break; + } + case 253: + { + DisplayStackFrameScreen(crashdata); + break; + } + case 252: + { + DisplayTasksScreen(crashdata); + break; + } + case 251: + { + DisplayConsoleScreen(crashdata); + break; + } + default: + { + break; + } + } + DisplayBottomOverlay(); + Display->SetBuffer(SBIdx); + } + + __no_stack_protector void UserInput(char *Input) + { + SmartCriticalSection(UserInputLock); + Display->ClearBuffer(SBIdx); + DisplayTopOverlay(); + EHPrint("\eFAFAFA"); + + if (strcmp(Input, "help") == 0) + { + EHPrint("Available commands are: exit, main, details, frames, tasks, console\n"); + EHPrint("Also, you can use the arrow keys to navigate the menu.\n"); + EHPrint("=========================================================================\n"); + EHPrint("Kernel Compiled at: %s %s with C++ Standard: %d\n", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD); + EHPrint("C++ Language Version (__cplusplus): %ld\n", __cplusplus); + } + else if (strcmp(Input, "exit") == 0) + { + PowerManager->Shutdown(); + EHPrint("\eFFFFFFNow it's safe to turn off your computer."); + CPU::Stop(); + } + else if (strcmp(Input, "main") == 0) + { + SBIdx = 255; + DisplayTopOverlay(); + DisplayMainScreen(crashdata); + Display->SetBuffer(SBIdx); + } + else if (strcmp(Input, "details") == 0) + { + SBIdx = 254; + DisplayTopOverlay(); + DisplayDetailsScreen(crashdata); + Display->SetBuffer(SBIdx); + } + else if (strcmp(Input, "frames") == 0) + { + SBIdx = 253; + DisplayTopOverlay(); + DisplayStackFrameScreen(crashdata); + Display->SetBuffer(SBIdx); + } + else if (strcmp(Input, "tasks") == 0) + { + SBIdx = 252; + DisplayTopOverlay(); + DisplayTasksScreen(crashdata); + Display->SetBuffer(SBIdx); + } + else if (strcmp(Input, "console") == 0) + { + SBIdx = 251; + DisplayTopOverlay(); + DisplayConsoleScreen(crashdata); + Display->SetBuffer(SBIdx); + } + else + { + if (strlen(Input) > 0) + EHPrint("Unknown command: %s", Input); + } + DisplayBottomOverlay(); + Display->SetBuffer(SBIdx); + } + + __no_stack_protector void Handle(void *Data) { CPU::Interrupts(CPU::Disable); -#if defined(__amd64__) + error("An exception occurred!"); + if (TaskManager) + TaskManager->Panic(); + SBIdx = 255; CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data; +#if defined(__amd64__) error("Exception: %#llx", Frame->InterruptNumber); if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA) { debug("Exception in kernel mode"); - Display->CreateBuffer(0, 0, 255); + Display->CreateBuffer(0, 0, SBIdx); } else { @@ -49,6 +264,7 @@ namespace CrashHandler CPUData *data = GetCurrentCPU(); if (!data) { + Display->CreateBuffer(0, 0, SBIdx); EHPrint("\eFF0000Cannot get CPU data! This results in a kernel crash!"); error("Cannot get CPU data! This results in a kernel crash!"); error("This should never happen!"); @@ -67,152 +283,94 @@ namespace CrashHandler } else { + Display->CreateBuffer(0, 0, SBIdx); EHPrint("\eFF0000Init process crashed!"); } } } } + if (ExceptionOccurred) + { + SBIdx = 255; + Display->ClearBuffer(SBIdx); + Display->SetBufferCursor(SBIdx, 0, 0); + + CPU::x64::CR0 cr0 = CPU::x64::readcr0(); + CPU::x64::CR2 cr2 = CPU::x64::readcr2(); + CPU::x64::CR3 cr3 = CPU::x64::readcr3(); + CPU::x64::CR4 cr4 = CPU::x64::readcr4(); + CPU::x64::CR8 cr8 = CPU::x64::readcr8(); + CPU::x64::EFER efer; + efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER); + + EHPrint("\eFF0000FS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx\n", + CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), + Frame->ss, Frame->cs, Frame->ds); + EHPrint("R8=%#llx R9=%#llx R10=%#llx R11=%#llx\n", Frame->r8, Frame->r9, Frame->r10, Frame->r11); + EHPrint("R12=%#llx R13=%#llx R14=%#llx R15=%#llx\n", Frame->r12, Frame->r13, Frame->r14, Frame->r15); + EHPrint("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx\n", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); + EHPrint("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx\n", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); + EHPrint("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx\n", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); + EHPrint("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx\n", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); + EHPrint("CR0: PE:%s MP:%s EM:%s TS:%s\n ET:%s NE:%s WP:%s AM:%s\n NW:%s CD:%s PG:%s\n R0:%#x R1:%#x R2:%#x\n", + cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False", + cr0.ET ? "True " : "False", cr0.NE ? "True " : "False", cr0.WP ? "True " : "False", cr0.AM ? "True " : "False", + cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False", + cr0.Reserved0, cr0.Reserved1, cr0.Reserved2); + EHPrint("CR2: PFLA: %#llx\n", + cr2.PFLA); + EHPrint("CR3: PWT:%s PCD:%s PDBR:%#llx\n", + cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); + EHPrint("CR4: VME:%s PVI:%s TSD:%s DE:%s\n PSE:%s PAE:%s MCE:%s PGE:%s\n PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s\n LA57:%s VMXE:%s SMXE:%s PCIDE:%s\n OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s\n R0:%#x R1:%#x R2:%#x\n", + cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", + cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", + cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", + cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", + cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", + cr4.Reserved0, cr4.Reserved1, cr4.Reserved2); + EHPrint("CR8: TPL:%d\n", cr8.TPL); + EHPrint("RFL: CF:%s PF:%s AF:%s ZF:%s\n SF:%s TF:%s IF:%s DF:%s\n OF:%s IOPL:%s NT:%s RF:%s\n VM:%s AC:%s VIF:%s VIP:%s\n ID:%s AlwaysOne:%d\n R0:%#x R1:%#x R2:%#x R3:%#x\n", + Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", + Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", + Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False", + Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", + Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, + Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); + EHPrint("EFER: SCE:%s LME:%s LMA:%s NXE:%s\n SVME:%s LMSLE:%s FFXSR:%s TCE:%s\n R0:%#x R1:%#x R2:%#x\n", + efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", + efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", + efer.Reserved0, efer.Reserved1, efer.Reserved2); + + EHPrint("\nException occurred while handling exception! HALTED!"); + Display->SetBuffer(SBIdx); + CPU::Stop(); + } + + ExceptionOccurred = true; + debug("Reading control registers..."); - CPU::x64::CR0 cr0 = CPU::x64::readcr0(); - CPU::x64::CR2 cr2 = CPU::x64::readcr2(); - CPU::x64::CR3 cr3 = CPU::x64::readcr3(); - CPU::x64::CR4 cr4 = CPU::x64::readcr4(); - CPU::x64::CR8 cr8 = CPU::x64::readcr8(); - CPU::x64::EFER efer; - efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER); + crashdata.Frame = Frame; + crashdata.cr0 = CPU::x64::readcr0(); + crashdata.cr2 = CPU::x64::readcr2(); + crashdata.cr3 = CPU::x64::readcr3(); + crashdata.cr4 = CPU::x64::readcr4(); + crashdata.cr8 = CPU::x64::readcr8(); + crashdata.efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER); - uint64_t dr0, dr1, dr2, dr3, dr6; - CPU::x64::DR7 dr7; - - // store debug registers - debug("Reading debug registers..."); + // Get debug registers asmv("movq %%dr0, %0" - : "=r"(dr0)); + : "=r"(crashdata.dr0)); asmv("movq %%dr1, %0" - : "=r"(dr1)); + : "=r"(crashdata.dr1)); asmv("movq %%dr2, %0" - : "=r"(dr2)); + : "=r"(crashdata.dr2)); asmv("movq %%dr3, %0" - : "=r"(dr3)); + : "=r"(crashdata.dr3)); asmv("movq %%dr6, %0" - : "=r"(dr6)); + : "=r"(crashdata.dr6)); asmv("movq %%dr7, %0" - : "=r"(dr7)); - - switch (Frame->InterruptNumber) - { - case CPU::x64::DivideByZero: - { - DivideByZeroExceptionHandler(Frame); - break; - } - case CPU::x64::Debug: - { - DebugExceptionHandler(Frame); - break; - } - case CPU::x64::NonMaskableInterrupt: - { - NonMaskableInterruptExceptionHandler(Frame); - break; - } - case CPU::x64::Breakpoint: - { - BreakpointExceptionHandler(Frame); - break; - } - case CPU::x64::Overflow: - { - OverflowExceptionHandler(Frame); - break; - } - case CPU::x64::BoundRange: - { - BoundRangeExceptionHandler(Frame); - break; - } - case CPU::x64::InvalidOpcode: - { - InvalidOpcodeExceptionHandler(Frame); - break; - } - case CPU::x64::DeviceNotAvailable: - { - DeviceNotAvailableExceptionHandler(Frame); - break; - } - case CPU::x64::DoubleFault: - { - DoubleFaultExceptionHandler(Frame); - break; - } - case CPU::x64::CoprocessorSegmentOverrun: - { - CoprocessorSegmentOverrunExceptionHandler(Frame); - break; - } - case CPU::x64::InvalidTSS: - { - InvalidTSSExceptionHandler(Frame); - break; - } - case CPU::x64::SegmentNotPresent: - { - SegmentNotPresentExceptionHandler(Frame); - break; - } - case CPU::x64::StackSegmentFault: - { - StackFaultExceptionHandler(Frame); - break; - } - case CPU::x64::GeneralProtectionFault: - { - GeneralProtectionExceptionHandler(Frame); - break; - } - case CPU::x64::PageFault: - { - PageFaultExceptionHandler(Frame); - break; - } - case CPU::x64::x87FloatingPoint: - { - x87FloatingPointExceptionHandler(Frame); - break; - } - case CPU::x64::AlignmentCheck: - { - AlignmentCheckExceptionHandler(Frame); - break; - } - case CPU::x64::MachineCheck: - { - MachineCheckExceptionHandler(Frame); - break; - } - case CPU::x64::SIMDFloatingPoint: - { - SIMDFloatingPointExceptionHandler(Frame); - break; - } - case CPU::x64::Virtualization: - { - VirtualizationExceptionHandler(Frame); - break; - } - case CPU::x64::Security: - { - SecurityExceptionHandler(Frame); - break; - } - default: - { - UnknownExceptionHandler(Frame); - break; - } - } + : "=r"(crashdata.dr7)); CPUData *cpudata = GetCurrentCPU(); @@ -234,93 +392,78 @@ namespace CrashHandler } if (cpudata != nullptr) - EHPrint("\e7981FCTechnical Informations on CPU %lld:\n", cpudata->ID); + { + crashdata.ID = cpudata->ID; + error("Technical Informations on CPU %lld:", cpudata->ID); + } if (TaskManager && cpudata != nullptr) { - EHPrint("\e7981FCCurrent Process: %s(%ld)\n", - cpudata->CurrentProcess->Name, - cpudata->CurrentProcess->ID); - EHPrint("\e7981FCCurrent Thread: %s(%ld)\n", - cpudata->CurrentThread->Name, - cpudata->CurrentThread->ID); + crashdata.Process = cpudata->CurrentProcess; + crashdata.Thread = cpudata->CurrentThread; + + error("Current Process: %s(%ld)\n", + cpudata->CurrentProcess->Name, + cpudata->CurrentProcess->ID); + error("Current Thread: %s(%ld)\n", + cpudata->CurrentThread->Name, + cpudata->CurrentThread->ID); } - EHPrint("\e7981FCFS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx\n", - CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), - Frame->ss, Frame->cs, Frame->ds); - EHPrint("R8=%#llx R9=%#llx R10=%#llx R11=%#llx\n", Frame->r8, Frame->r9, Frame->r10, Frame->r11); - EHPrint("R12=%#llx R13=%#llx R14=%#llx R15=%#llx\n", Frame->r12, Frame->r13, Frame->r14, Frame->r15); - EHPrint("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx\n", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); - EHPrint("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx\n", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); - EHPrint("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx\n", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); - EHPrint("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx\n", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); - EHPrint("DR0=%#llx DR1=%#llx DR2=%#llx DR3=%#llx DR6=%#llx DR7=%#llx\n", dr0, dr1, dr2, dr3, dr6, dr7.raw); + { + error("FS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx", + CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), + Frame->ss, Frame->cs, Frame->ds); + error("R8=%#llx R9=%#llx R10=%#llx R11=%#llx", Frame->r8, Frame->r9, Frame->r10, Frame->r11); + error("R12=%#llx R13=%#llx R14=%#llx R15=%#llx", Frame->r12, Frame->r13, Frame->r14, Frame->r15); + error("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); + error("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); + error("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, crashdata.efer.raw); + error("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx", crashdata.cr0.raw, crashdata.cr2.raw, crashdata.cr3.raw, crashdata.cr4.raw, crashdata.cr8.raw); + error("DR0=%#llx DR1=%#llx DR2=%#llx DR3=%#llx DR6=%#llx DR7=%#llx", crashdata.dr0, crashdata.dr1, crashdata.dr2, crashdata.dr3, crashdata.dr6, crashdata.dr7.raw); - EHPrint("\eFC797BCR0: PE:%s MP:%s EM:%s TS:%s\n ET:%s NE:%s WP:%s AM:%s\n NW:%s CD:%s PG:%s\n R0:%#x R1:%#x R2:%#x\n", - cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False", - cr0.ET ? "True " : "False", cr0.NE ? "True " : "False", cr0.WP ? "True " : "False", cr0.AM ? "True " : "False", - cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False", - cr0.Reserved0, cr0.Reserved1, cr0.Reserved2); + error("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x", + crashdata.cr0.PE ? "True " : "False", crashdata.cr0.MP ? "True " : "False", crashdata.cr0.EM ? "True " : "False", crashdata.cr0.TS ? "True " : "False", + crashdata.cr0.ET ? "True " : "False", crashdata.cr0.NE ? "True " : "False", crashdata.cr0.WP ? "True " : "False", crashdata.cr0.AM ? "True " : "False", + crashdata.cr0.NW ? "True " : "False", crashdata.cr0.CD ? "True " : "False", crashdata.cr0.PG ? "True " : "False", + crashdata.cr0.Reserved0, crashdata.cr0.Reserved1, crashdata.cr0.Reserved2); - EHPrint("\eFCBD79CR2: PFLA: %#llx\n", - cr2.PFLA); + error("CR2: PFLA: %#llx", + crashdata.cr2.PFLA); - EHPrint("\e79FC84CR3: PWT:%s PCD:%s PDBR:%#llx\n", - cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); + error("CR3: PWT:%s PCD:%s PDBR:%#llx", + crashdata.cr3.PWT ? "True " : "False", crashdata.cr3.PCD ? "True " : "False", crashdata.cr3.PDBR); - EHPrint("\eBD79FCCR4: VME:%s PVI:%s TSD:%s DE:%s\n PSE:%s PAE:%s MCE:%s PGE:%s\n PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s\n LA57:%s VMXE:%s SMXE:%s PCIDE:%s\n OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s\n R0:%#x R1:%#x R2:%#x\n", - cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", - cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", - cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", - cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", - cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", - cr4.Reserved0, cr4.Reserved1, cr4.Reserved2); + error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x", + crashdata.cr4.VME ? "True " : "False", crashdata.cr4.PVI ? "True " : "False", crashdata.cr4.TSD ? "True " : "False", crashdata.cr4.DE ? "True " : "False", + crashdata.cr4.PSE ? "True " : "False", crashdata.cr4.PAE ? "True " : "False", crashdata.cr4.MCE ? "True " : "False", crashdata.cr4.PGE ? "True " : "False", + crashdata.cr4.PCE ? "True " : "False", crashdata.cr4.UMIP ? "True " : "False", crashdata.cr4.OSFXSR ? "True " : "False", crashdata.cr4.OSXMMEXCPT ? "True " : "False", + crashdata.cr4.LA57 ? "True " : "False", crashdata.cr4.VMXE ? "True " : "False", crashdata.cr4.SMXE ? "True " : "False", crashdata.cr4.PCIDE ? "True " : "False", + crashdata.cr4.OSXSAVE ? "True " : "False", crashdata.cr4.SMEP ? "True " : "False", crashdata.cr4.SMAP ? "True " : "False", crashdata.cr4.PKE ? "True " : "False", + crashdata.cr4.Reserved0, crashdata.cr4.Reserved1, crashdata.cr4.Reserved2); - EHPrint("\e79FCF5CR8: TPL:%d\n", cr8.TPL); + error("CR8: TPL:%d", crashdata.cr8.TPL); - EHPrint("\eFCFC02RFL: CF:%s PF:%s AF:%s ZF:%s\n SF:%s TF:%s IF:%s DF:%s\n OF:%s IOPL:%s NT:%s RF:%s\n VM:%s AC:%s VIF:%s VIP:%s\n ID:%s AlwaysOne:%d\n R0:%#x R1:%#x R2:%#x R3:%#x\n", - Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", - Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", - Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False", - Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", - Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, - Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); + error("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x", + Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", + Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", + Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False", + Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", + Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, + Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); - EHPrint("\eA0F0F0DR7: LDR0:%s GDR0:%s LDR1:%s GDR1:%s\n LDR2:%s GDR2:%s LDR3:%s GDR3:%s\n CDR0:%s SDR0:%s CDR1:%s SDR1:%s\n CDR2:%s SDR2:%s CDR3:%s SDR3:%s\n R:%#x\n", - dr7.LocalDR0 ? "True " : "False", dr7.GlobalDR0 ? "True " : "False", dr7.LocalDR1 ? "True " : "False", dr7.GlobalDR1 ? "True " : "False", - dr7.LocalDR2 ? "True " : "False", dr7.GlobalDR2 ? "True " : "False", dr7.LocalDR3 ? "True " : "False", dr7.GlobalDR3 ? "True " : "False", - dr7.ConditionsDR0 ? "True " : "False", dr7.SizeDR0 ? "True " : "False", dr7.ConditionsDR1 ? "True " : "False", dr7.SizeDR1 ? "True " : "False", - dr7.ConditionsDR2 ? "True " : "False", dr7.SizeDR2 ? "True " : "False", dr7.ConditionsDR3 ? "True " : "False", dr7.SizeDR3 ? "True " : "False", - dr7.Reserved); + error("DR7: LDR0:%s GDR0:%s LDR1:%s GDR1:%s LDR2:%s GDR2:%s LDR3:%s GDR3:%s CDR0:%s SDR0:%s CDR1:%s SDR1:%s CDR2:%s SDR2:%s CDR3:%s SDR3:%s R:%#x", + crashdata.dr7.LocalDR0 ? "True " : "False", crashdata.dr7.GlobalDR0 ? "True " : "False", crashdata.dr7.LocalDR1 ? "True " : "False", crashdata.dr7.GlobalDR1 ? "True " : "False", + crashdata.dr7.LocalDR2 ? "True " : "False", crashdata.dr7.GlobalDR2 ? "True " : "False", crashdata.dr7.LocalDR3 ? "True " : "False", crashdata.dr7.GlobalDR3 ? "True " : "False", + crashdata.dr7.ConditionsDR0 ? "True " : "False", crashdata.dr7.SizeDR0 ? "True " : "False", crashdata.dr7.ConditionsDR1 ? "True " : "False", crashdata.dr7.SizeDR1 ? "True " : "False", + crashdata.dr7.ConditionsDR2 ? "True " : "False", crashdata.dr7.SizeDR2 ? "True " : "False", crashdata.dr7.ConditionsDR3 ? "True " : "False", crashdata.dr7.SizeDR3 ? "True " : "False", + crashdata.dr7.Reserved); - EHPrint("\e009FF0EFER: SCE:%s LME:%s LMA:%s NXE:%s\n SVME:%s LMSLE:%s FFXSR:%s TCE:%s\n R0:%#x R1:%#x R2:%#x\n", - efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", - efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", - efer.Reserved0, efer.Reserved1, efer.Reserved2); - - // restore debug registers - debug("Restoring debug registers..."); - asmv("movq %0, %%dr0" - : - : "r"(dr0)); - asmv("movq %0, %%dr1" - : - : "r"(dr1)); - asmv("movq %0, %%dr2" - : - : "r"(dr2)); - asmv("movq %0, %%dr3" - : - : "r"(dr3)); - asmv("movq %0, %%dr6" - : - : "r"(dr6)); - asmv("movq %0, %%dr7" - : - : "r"(dr7)); - - TraceFrames(Frame, 20); + error("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x", + crashdata.efer.SCE ? "True " : "False", crashdata.efer.LME ? "True " : "False", crashdata.efer.LMA ? "True " : "False", crashdata.efer.NXE ? "True " : "False", + crashdata.efer.SVME ? "True " : "False", crashdata.efer.LMSLE ? "True " : "False", crashdata.efer.FFXSR ? "True " : "False", crashdata.efer.TCE ? "True " : "False", + crashdata.efer.Reserved0, crashdata.efer.Reserved1, crashdata.efer.Reserved2); + } goto CrashEnd; #elif defined(__i386__) @@ -330,288 +473,31 @@ namespace CrashHandler #endif CrashEnd: - Display->SetBuffer(255); - CPU::Stop(); - } -} + if (Config.InterruptsOnCrash) + { + // 255 // Main + Display->CreateBuffer(0, 0, 254); // Details + Display->CreateBuffer(0, 0, 253); // Frames + Display->CreateBuffer(0, 0, 252); // Tasks + Display->CreateBuffer(0, 0, 251); // Console + Display->CreateBuffer(0, 0, 250); // Empty -#if defined(__amd64__) || defined(__i386__) -static const char *PagefaultDescriptions[8] = { - "Supervisory process tried to read a non-present page entry\n", - "Supervisory process tried to read a page and caused a protection fault\n", - "Supervisory process tried to write to a non-present page entry\n", - "Supervisory process tried to write a page and caused a protection fault\n", - "User process tried to read a non-present page entry\n", - "User process tried to read a page and caused a protection fault\n", - "User process tried to write to a non-present page entry\n", - "User process tried to write a page and caused a protection fault\n"}; -#endif - -#if defined(__amd64__) -__attribute__((no_stack_protector)) void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame) -{ - fixme("Divide by zero exception\n"); -} -__attribute__((no_stack_protector)) void DebugExceptionHandler(CHArchTrapFrame *Frame) -{ - CrashHandler::EHPrint("\eDD2920System crashed!\n"); - CrashHandler::EHPrint("Kernel triggered debug exception.\n"); -} -__attribute__((no_stack_protector)) void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); } -__attribute__((no_stack_protector)) void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); } -__attribute__((no_stack_protector)) void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); } -__attribute__((no_stack_protector)) void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); } -__attribute__((no_stack_protector)) void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame) -{ - CrashHandler::EHPrint("\eDD2920System crashed!\n"); - CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n"); -} -__attribute__((no_stack_protector)) void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); } -__attribute__((no_stack_protector)) void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); } -__attribute__((no_stack_protector)) void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); } -__attribute__((no_stack_protector)) void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); } -__attribute__((no_stack_protector)) void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); } -__attribute__((no_stack_protector)) void StackFaultExceptionHandler(CHArchTrapFrame *Frame) -{ - CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; - CrashHandler::EHPrint("\eDD2920System crashed!\n"); - CrashHandler::EHPrint("More info about the exception:\n"); - CrashHandler::EHPrint("Stack segment fault at address %#lx\n", Frame->rip); - CrashHandler::EHPrint("External: %d\n", SelCode.External); - CrashHandler::EHPrint("Table: %d\n", SelCode.Table); - CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); - CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode); -} -__attribute__((no_stack_protector)) void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame) -{ - // staticbuffer(descbuf); - // staticbuffer(desc_ext); - // staticbuffer(desc_table); - // staticbuffer(desc_idx); - // staticbuffer(desc_tmp); - CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; - // switch (SelCode.Table) - // { - // case CPU::x64::0b00: - // memcpy(desc_tmp, "GDT", 3); - // break; - // case CPU::x64::0b01: - // memcpy(desc_tmp, "IDT", 3); - // break; - // case CPU::x64::0b10: - // memcpy(desc_tmp, "LDT", 3); - // break; - // case CPU::x64::0b11: - // memcpy(desc_tmp, "IDT", 3); - // break; - // default: - // memcpy(desc_tmp, "Unknown", 7); - // break; - // } - CrashHandler::EHPrint("\eDD2920System crashed!\n"); - CrashHandler::EHPrint("Kernel performed an illegal operation.\n"); - CrashHandler::EHPrint("More info about the exception:\n"); - CrashHandler::EHPrint("External: %d\n", SelCode.External); - CrashHandler::EHPrint("Table: %d\n", SelCode.Table); - CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); -} -__attribute__((no_stack_protector)) void PageFaultExceptionHandler(CHArchTrapFrame *Frame) -{ - CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; - CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF"); - CrashHandler::EHPrint("An exception occurred at %#lx by %#lx\n", CPU::x64::readcr2().PFLA, Frame->rip); - CrashHandler::EHPrint("Page: %s\n", params.P ? "Present" : "Not Present"); - CrashHandler::EHPrint("Write Operation: %s\n", params.W ? "Read-Only" : "Read-Write"); - CrashHandler::EHPrint("Processor Mode: %s\n", params.U ? "User-Mode" : "Kernel-Mode"); - CrashHandler::EHPrint("CPU Reserved Bits: %s\n", params.R ? "Reserved" : "Unreserved"); - CrashHandler::EHPrint("Caused By An Instruction Fetch: %s\n", params.I ? "Yes" : "No"); - CrashHandler::EHPrint("Caused By A Protection-Key Violation: %s\n", params.PK ? "Yes" : "No"); - CrashHandler::EHPrint("Caused By A Shadow Stack Access: %s\n", params.SS ? "Yes" : "No"); - CrashHandler::EHPrint("Caused By An SGX Violation: %s\n", params.SGX ? "Yes" : "No"); - if (Frame->ErrorCode & 0x00000008) - CrashHandler::EHPrint("One or more page directory entries contain reserved bits which are set to 1.\n"); - else - CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]); -} -__attribute__((no_stack_protector)) void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); } -__attribute__((no_stack_protector)) void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); } -__attribute__((no_stack_protector)) void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); } -__attribute__((no_stack_protector)) void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); } -__attribute__((no_stack_protector)) void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); } -__attribute__((no_stack_protector)) void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); } -__attribute__((no_stack_protector)) void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); } - -__attribute__((no_stack_protector)) void UserModeExceptionHandler(CHArchTrapFrame *Frame) -{ - CriticalSection cs; - debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No"); - fixme("Handling user mode exception"); - TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Terminated; - - { - CPU::x64::CR0 cr0 = CPU::x64::readcr0(); - CPU::x64::CR2 cr2 = CPU::x64::readcr2(); - CPU::x64::CR3 cr3 = CPU::x64::readcr3(); - CPU::x64::CR4 cr4 = CPU::x64::readcr4(); - CPU::x64::CR8 cr8 = CPU::x64::readcr8(); - CPU::x64::EFER efer; - efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER); - - error("Technical Informations on CPU %lld:", GetCurrentCPU()->ID); - error("FS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx", - CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), - Frame->ss, Frame->cs, Frame->ds); - error("R8=%#llx R9=%#llx R10=%#llx R11=%#llx", Frame->r8, Frame->r9, Frame->r10, Frame->r11); - error("R12=%#llx R13=%#llx R14=%#llx R15=%#llx", Frame->r12, Frame->r13, Frame->r14, Frame->r15); - error("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); - error("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); - error("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); - error("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); - - error("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x", - cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False", - cr0.ET ? "True " : "False", cr0.NE ? "True " : "False", cr0.WP ? "True " : "False", cr0.AM ? "True " : "False", - cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False", - cr0.Reserved0, cr0.Reserved1, cr0.Reserved2); - - error("CR2: PFLA: %#llx", - cr2.PFLA); - - error("CR3: PWT:%s PCD:%s PDBR:%#llx", - cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); - - error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x", - cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", - cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", - cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", - cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", - cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", - cr4.Reserved0, cr4.Reserved1, cr4.Reserved2); - - error("CR8: TPL:%d", cr8.TPL); - - error("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x", - Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", - Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", - Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False", - Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", - Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, - Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); - - error("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x", - efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", - efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", - efer.Reserved0, efer.Reserved1, efer.Reserved2); - } - - switch (Frame->InterruptNumber) - { - case CPU::x64::DivideByZero: - { - break; - } - case CPU::x64::Debug: - { - break; - } - case CPU::x64::NonMaskableInterrupt: - { - break; - } - case CPU::x64::Breakpoint: - { - break; - } - case CPU::x64::Overflow: - { - break; - } - case CPU::x64::BoundRange: - { - break; - } - case CPU::x64::InvalidOpcode: - { - break; - } - case CPU::x64::DeviceNotAvailable: - { - break; - } - case CPU::x64::DoubleFault: - { - break; - } - case CPU::x64::CoprocessorSegmentOverrun: - { - break; - } - case CPU::x64::InvalidTSS: - { - break; - } - case CPU::x64::SegmentNotPresent: - { - break; - } - case CPU::x64::StackSegmentFault: - { - break; - } - case CPU::x64::GeneralProtectionFault: - { - break; - } - case CPU::x64::PageFault: - { - CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; - error("An exception occurred at %#lx by %#lx", CPU::x64::readcr2().PFLA, Frame->rip); - error("Page: %s", params.P ? "Present" : "Not Present"); - error("Write Operation: %s", params.W ? "Read-Only" : "Read-Write"); - error("Processor Mode: %s", params.U ? "User-Mode" : "Kernel-Mode"); - error("CPU Reserved Bits: %s", params.R ? "Reserved" : "Unreserved"); - error("Caused By An Instruction Fetch: %s", params.I ? "Yes" : "No"); - error("Caused By A Protection-Key Violation: %s", params.PK ? "Yes" : "No"); - error("Caused By A Shadow Stack Access: %s", params.SS ? "Yes" : "No"); - error("Caused By An SGX Violation: %s", params.SGX ? "Yes" : "No"); - if (Frame->ErrorCode & 0x00000008) - error("One or more page directory entries contain reserved bits which are set to 1."); + DisplayTopOverlay(); + DisplayMainScreen(crashdata); + DisplayBottomOverlay(); + Display->SetBuffer(255); + debug("Interrupts are enabled, waiting for user input"); + CPU::Interrupts(CPU::Enable); + HookKeyboard(); + } else - error(PagefaultDescriptions[Frame->ErrorCode & 0b111]); - break; + { + /* + TODO: Stuff that should be done when IOC is disabled. + */ + Display->SetBuffer(255); + } + + CPU::Halt(true); } - case CPU::x64::x87FloatingPoint: - { - break; - } - case CPU::x64::AlignmentCheck: - { - break; - } - case CPU::x64::MachineCheck: - { - break; - } - case CPU::x64::SIMDFloatingPoint: - { - break; - } - case CPU::x64::Virtualization: - { - break; - } - case CPU::x64::Security: - { - break; - } - default: - { - break; - } - } - error("End of report."); - CPU::Interrupts(CPU::Enable); - debug("Interrupts enabled back."); - return; } -#endif diff --git a/Core/Crash/KBDrv.cpp b/Core/Crash/KBDrv.cpp new file mode 100644 index 0000000..ba2ce6a --- /dev/null +++ b/Core/Crash/KBDrv.cpp @@ -0,0 +1,176 @@ +#include "../crashhandler.hpp" +#include "chfcts.hpp" + +#include +#include +#include +#include +#include +#include + +#if defined(__amd64__) +#include "../../Architecture/amd64/cpu/gdt.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +#include "../../kernel.h" + +const char sc_ascii_low[] = {'?', '?', '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '?', '?', 'q', 'w', 'e', 'r', 't', 'y', + 'u', 'i', 'o', 'p', '[', ']', '?', '?', 'a', 's', 'd', 'f', 'g', + 'h', 'j', 'k', 'l', ';', '\'', '`', '?', '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', '?', '?', '?', ' '}; + +const char sc_ascii_high[] = {'?', '?', '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y', + 'U', 'I', 'O', 'P', '{', '}', '?', '?', 'A', 'S', 'D', 'F', 'G', + 'H', 'J', 'K', 'L', ';', '\"', '~', '?', '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?', '?', '?', '?', ' '}; + +static int LowerCase = true; + +static inline int GetLetterFromScanCode(uint8_t ScanCode) +{ + if (ScanCode & 0x80) + { + switch (ScanCode) + { + case KEY_U_LSHIFT: + LowerCase = true; + return KEY_INVALID; + case KEY_U_RSHIFT: + LowerCase = true; + return KEY_INVALID; + default: + return KEY_INVALID; + } + } + else + { + switch (ScanCode) + { + case KEY_D_RETURN: + return '\n'; + case KEY_D_LSHIFT: + LowerCase = false; + return KEY_INVALID; + case KEY_D_RSHIFT: + LowerCase = false; + return KEY_INVALID; + case KEY_D_BACKSPACE: + return ScanCode; + default: + { + if (ScanCode > 0x39) + break; + if (LowerCase) + return sc_ascii_low[ScanCode]; + else + return sc_ascii_high[ScanCode]; + } + } + } + return KEY_INVALID; +} + +static inline void backspace(char s[]) +{ + int len = strlen(s); + s[len - 1] = '\0'; +} + +static inline void append(char s[], char n) +{ + int len = strlen(s); + s[len] = n; + s[len + 1] = '\0'; +} + +namespace CrashHandler +{ + CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(CPU::x64::IRQ1) + { + while (inb(0x64) & 0x1) + inb(0x60); + + outb(0x64, 0xAE); + outb(0x64, 0x20); + uint8_t ret = (inb(0x60) | 1) & ~0x10; + outb(0x64, 0x60); + outb(0x60, ret); + outb(0x60, 0xF4); + + outb(0x21, 0xFD); + outb(0xA1, 0xFF); + CPU::Interrupts(CPU::Enable); // Just to be sure. + } + + CrashKeyboardDriver::~CrashKeyboardDriver() + { + error("CrashKeyboardDriver::~CrashKeyboardDriver() called!"); + } + + int BackSpaceLimit = 0; + static char UserInputBuffer[1024]; + +#if defined(__amd64__) + __no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame) +#elif defined(__i386__) + __no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame) +#elif defined(__aarch64__) + __no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame) +#endif + { + uint8_t scanCode = inb(0x60); + if (scanCode == KEY_D_TAB || + scanCode == KEY_D_LCTRL || + scanCode == KEY_D_LALT || + scanCode == KEY_U_LCTRL || + scanCode == KEY_U_LALT) + return; + + switch (scanCode) + { + case KEY_D_UP: + case KEY_D_LEFT: + case KEY_D_RIGHT: + case KEY_D_DOWN: + ArrowInput(scanCode); + } + + int key = GetLetterFromScanCode(scanCode); + if (key != KEY_INVALID) + { + if (key == KEY_D_BACKSPACE) + { + if (BackSpaceLimit > 0) + { + Display->Print('\b', SBIdx); + backspace(UserInputBuffer); + BackSpaceLimit--; + } + } + else if (key == '\n') + { + UserInput(UserInputBuffer); + BackSpaceLimit = 0; + UserInputBuffer[0] = '\0'; + } + else + { + append(UserInputBuffer, key); + Display->Print(key, SBIdx); + BackSpaceLimit++; + } + Display->SetBuffer(SBIdx); // Update as we type. + } + } + + __no_stack_protector void HookKeyboard() + { + CrashKeyboardDriver kbd; // We don't want to allocate memory. + asmv("Loop: nop; jmp Loop;"); + // CPU::Halt(true); // This is an infinite loop. + } +} diff --git a/Core/Crash/SFrame.cpp b/Core/Crash/SFrame.cpp index 2912593..ea012bf 100644 --- a/Core/Crash/SFrame.cpp +++ b/Core/Crash/SFrame.cpp @@ -23,7 +23,7 @@ namespace CrashHandler uint64_t rip; }; - __attribute__((no_stack_protector)) void TraceFrames(CHArchTrapFrame *Frame, int Count) + __no_stack_protector void TraceFrames(CHArchTrapFrame *Frame, int Count) { struct StackFrame *frames = (struct StackFrame *)Frame->rbp; // (struct StackFrame *)__builtin_frame_address(0); debug("Stack tracing..."); @@ -62,4 +62,4 @@ namespace CrashHandler } } } -} \ No newline at end of file +} diff --git a/Core/Crash/Screens/Console.cpp b/Core/Crash/Screens/Console.cpp new file mode 100644 index 0000000..1e97810 --- /dev/null +++ b/Core/Crash/Screens/Console.cpp @@ -0,0 +1,24 @@ +#include "../../crashhandler.hpp" +#include "../chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(__amd64__) +#include "../../../Architecture/amd64/cpu/gdt.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +#include "../../../kernel.h" + +namespace CrashHandler +{ + __no_stack_protector void DisplayConsoleScreen(CRData data) + { + EHPrint("TODO"); + } +} \ No newline at end of file diff --git a/Core/Crash/Screens/Details.cpp b/Core/Crash/Screens/Details.cpp new file mode 100644 index 0000000..90f110b --- /dev/null +++ b/Core/Crash/Screens/Details.cpp @@ -0,0 +1,198 @@ +#include "../../crashhandler.hpp" +#include "../chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(__amd64__) +#include "../../../Architecture/amd64/cpu/gdt.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +#include "../../../kernel.h" + +namespace CrashHandler +{ + __no_stack_protector void DisplayDetailsScreen(CRData data) + { + if (data.Process) + EHPrint("\e7981FCCurrent Process: %s(%ld)\n", + data.Process->Name, + data.Process->ID); + if (data.Thread) + EHPrint("\e7981FCCurrent Thread: %s(%ld)\n", + data.Thread->Name, + data.Thread->ID); + EHPrint("\e7981FCTechnical Informations on CPU %lld:\n", data.ID); + EHPrint("\e7981FCFS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx\n", + CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), + data.Frame->ss, data.Frame->cs, data.Frame->ds); + EHPrint("R8=%#llx R9=%#llx R10=%#llx R11=%#llx\n", data.Frame->r8, data.Frame->r9, data.Frame->r10, data.Frame->r11); + EHPrint("R12=%#llx R13=%#llx R14=%#llx R15=%#llx\n", data.Frame->r12, data.Frame->r13, data.Frame->r14, data.Frame->r15); + EHPrint("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx\n", data.Frame->rax, data.Frame->rbx, data.Frame->rcx, data.Frame->rdx); + EHPrint("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx\n", data.Frame->rsi, data.Frame->rdi, data.Frame->rbp, data.Frame->rsp); + EHPrint("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx\n", data.Frame->rip, data.Frame->rflags.raw, data.Frame->InterruptNumber, data.Frame->ErrorCode, data.efer.raw); + EHPrint("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx\n", data.cr0.raw, data.cr2.raw, data.cr3.raw, data.cr4.raw, data.cr8.raw); + EHPrint("DR0=%#llx DR1=%#llx DR2=%#llx DR3=%#llx DR6=%#llx DR7=%#llx\n", data.dr0, data.dr1, data.dr2, data.dr3, data.dr6, data.dr7.raw); + + EHPrint("\eFC797BCR0: PE:%s MP:%s EM:%s TS:%s\n ET:%s NE:%s WP:%s AM:%s\n NW:%s CD:%s PG:%s\n R0:%#x R1:%#x R2:%#x\n", + data.cr0.PE ? "True " : "False", data.cr0.MP ? "True " : "False", data.cr0.EM ? "True " : "False", data.cr0.TS ? "True " : "False", + data.cr0.ET ? "True " : "False", data.cr0.NE ? "True " : "False", data.cr0.WP ? "True " : "False", data.cr0.AM ? "True " : "False", + data.cr0.NW ? "True " : "False", data.cr0.CD ? "True " : "False", data.cr0.PG ? "True " : "False", + data.cr0.Reserved0, data.cr0.Reserved1, data.cr0.Reserved2); + + EHPrint("\eFCBD79CR2: PFLA: %#llx\n", + data.cr2.PFLA); + + EHPrint("\e79FC84CR3: PWT:%s PCD:%s PDBR:%#llx\n", + data.cr3.PWT ? "True " : "False", data.cr3.PCD ? "True " : "False", data.cr3.PDBR); + + EHPrint("\eBD79FCCR4: VME:%s PVI:%s TSD:%s DE:%s\n PSE:%s PAE:%s MCE:%s PGE:%s\n PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s\n LA57:%s VMXE:%s SMXE:%s PCIDE:%s\n OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s\n R0:%#x R1:%#x R2:%#x\n", + data.cr4.VME ? "True " : "False", data.cr4.PVI ? "True " : "False", data.cr4.TSD ? "True " : "False", data.cr4.DE ? "True " : "False", + data.cr4.PSE ? "True " : "False", data.cr4.PAE ? "True " : "False", data.cr4.MCE ? "True " : "False", data.cr4.PGE ? "True " : "False", + data.cr4.PCE ? "True " : "False", data.cr4.UMIP ? "True " : "False", data.cr4.OSFXSR ? "True " : "False", data.cr4.OSXMMEXCPT ? "True " : "False", + data.cr4.LA57 ? "True " : "False", data.cr4.VMXE ? "True " : "False", data.cr4.SMXE ? "True " : "False", data.cr4.PCIDE ? "True " : "False", + data.cr4.OSXSAVE ? "True " : "False", data.cr4.SMEP ? "True " : "False", data.cr4.SMAP ? "True " : "False", data.cr4.PKE ? "True " : "False", + data.cr4.Reserved0, data.cr4.Reserved1, data.cr4.Reserved2); + + EHPrint("\e79FCF5CR8: TPL:%d\n", data.cr8.TPL); + + EHPrint("\eFCFC02RFL: CF:%s PF:%s AF:%s ZF:%s\n SF:%s TF:%s IF:%s DF:%s\n OF:%s IOPL:%s NT:%s RF:%s\n VM:%s AC:%s VIF:%s VIP:%s\n ID:%s AlwaysOne:%d\n R0:%#x R1:%#x R2:%#x R3:%#x\n", + data.Frame->rflags.CF ? "True " : "False", data.Frame->rflags.PF ? "True " : "False", data.Frame->rflags.AF ? "True " : "False", data.Frame->rflags.ZF ? "True " : "False", + data.Frame->rflags.SF ? "True " : "False", data.Frame->rflags.TF ? "True " : "False", data.Frame->rflags.IF ? "True " : "False", data.Frame->rflags.DF ? "True " : "False", + data.Frame->rflags.OF ? "True " : "False", data.Frame->rflags.IOPL ? "True " : "False", data.Frame->rflags.NT ? "True " : "False", data.Frame->rflags.RF ? "True " : "False", + data.Frame->rflags.VM ? "True " : "False", data.Frame->rflags.AC ? "True " : "False", data.Frame->rflags.VIF ? "True " : "False", data.Frame->rflags.VIP ? "True " : "False", + data.Frame->rflags.ID ? "True " : "False", data.Frame->rflags.AlwaysOne, + data.Frame->rflags.Reserved0, data.Frame->rflags.Reserved1, data.Frame->rflags.Reserved2, data.Frame->rflags.Reserved3); + + EHPrint("\eA0F0F0DR7: LDR0:%s GDR0:%s LDR1:%s GDR1:%s\n LDR2:%s GDR2:%s LDR3:%s GDR3:%s\n CDR0:%s SDR0:%s CDR1:%s SDR1:%s\n CDR2:%s SDR2:%s CDR3:%s SDR3:%s\n R:%#x\n", + data.dr7.LocalDR0 ? "True " : "False", data.dr7.GlobalDR0 ? "True " : "False", data.dr7.LocalDR1 ? "True " : "False", data.dr7.GlobalDR1 ? "True " : "False", + data.dr7.LocalDR2 ? "True " : "False", data.dr7.GlobalDR2 ? "True " : "False", data.dr7.LocalDR3 ? "True " : "False", data.dr7.GlobalDR3 ? "True " : "False", + data.dr7.ConditionsDR0 ? "True " : "False", data.dr7.SizeDR0 ? "True " : "False", data.dr7.ConditionsDR1 ? "True " : "False", data.dr7.SizeDR1 ? "True " : "False", + data.dr7.ConditionsDR2 ? "True " : "False", data.dr7.SizeDR2 ? "True " : "False", data.dr7.ConditionsDR3 ? "True " : "False", data.dr7.SizeDR3 ? "True " : "False", + data.dr7.Reserved); + + EHPrint("\e009FF0EFER: SCE:%s LME:%s LMA:%s NXE:%s\n SVME:%s LMSLE:%s FFXSR:%s TCE:%s\n R0:%#x R1:%#x R2:%#x\n", + data.efer.SCE ? "True " : "False", data.efer.LME ? "True " : "False", data.efer.LMA ? "True " : "False", data.efer.NXE ? "True " : "False", + data.efer.SVME ? "True " : "False", data.efer.LMSLE ? "True " : "False", data.efer.FFXSR ? "True " : "False", data.efer.TCE ? "True " : "False", + data.efer.Reserved0, data.efer.Reserved1, data.efer.Reserved2); + + switch (data.Frame->InterruptNumber) + { + case CPU::x64::DivideByZero: + { + DivideByZeroExceptionHandler(data.Frame); + break; + } + case CPU::x64::Debug: + { + DebugExceptionHandler(data.Frame); + break; + } + case CPU::x64::NonMaskableInterrupt: + { + NonMaskableInterruptExceptionHandler(data.Frame); + break; + } + case CPU::x64::Breakpoint: + { + BreakpointExceptionHandler(data.Frame); + break; + } + case CPU::x64::Overflow: + { + OverflowExceptionHandler(data.Frame); + break; + } + case CPU::x64::BoundRange: + { + BoundRangeExceptionHandler(data.Frame); + break; + } + case CPU::x64::InvalidOpcode: + { + InvalidOpcodeExceptionHandler(data.Frame); + break; + } + case CPU::x64::DeviceNotAvailable: + { + DeviceNotAvailableExceptionHandler(data.Frame); + break; + } + case CPU::x64::DoubleFault: + { + DoubleFaultExceptionHandler(data.Frame); + break; + } + case CPU::x64::CoprocessorSegmentOverrun: + { + CoprocessorSegmentOverrunExceptionHandler(data.Frame); + break; + } + case CPU::x64::InvalidTSS: + { + InvalidTSSExceptionHandler(data.Frame); + break; + } + case CPU::x64::SegmentNotPresent: + { + SegmentNotPresentExceptionHandler(data.Frame); + break; + } + case CPU::x64::StackSegmentFault: + { + StackFaultExceptionHandler(data.Frame); + break; + } + case CPU::x64::GeneralProtectionFault: + { + GeneralProtectionExceptionHandler(data.Frame); + break; + } + case CPU::x64::PageFault: + { + PageFaultExceptionHandler(data.Frame); + break; + } + case CPU::x64::x87FloatingPoint: + { + x87FloatingPointExceptionHandler(data.Frame); + break; + } + case CPU::x64::AlignmentCheck: + { + AlignmentCheckExceptionHandler(data.Frame); + break; + } + case CPU::x64::MachineCheck: + { + MachineCheckExceptionHandler(data.Frame); + break; + } + case CPU::x64::SIMDFloatingPoint: + { + SIMDFloatingPointExceptionHandler(data.Frame); + break; + } + case CPU::x64::Virtualization: + { + VirtualizationExceptionHandler(data.Frame); + break; + } + case CPU::x64::Security: + { + SecurityExceptionHandler(data.Frame); + break; + } + default: + { + UnknownExceptionHandler(data.Frame); + break; + } + } + } +} diff --git a/Core/Crash/Screens/Main.cpp b/Core/Crash/Screens/Main.cpp new file mode 100644 index 0000000..8363cd9 --- /dev/null +++ b/Core/Crash/Screens/Main.cpp @@ -0,0 +1,335 @@ +#include "../../crashhandler.hpp" +#include "../chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(__amd64__) +#include "../../../Architecture/amd64/cpu/gdt.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +#include "../../../kernel.h" + +static const char *PagefaultDescriptions[8] = { + "Supervisory process tried to read a non-present page entry\n", + "Supervisory process tried to read a page and caused a protection fault\n", + "Supervisory process tried to write to a non-present page entry\n", + "Supervisory process tried to write a page and caused a protection fault\n", + "User process tried to read a non-present page entry\n", + "User process tried to read a page and caused a protection fault\n", + "User process tried to write to a non-present page entry\n", + "User process tried to write a page and caused a protection fault\n"}; + +namespace CrashHandler +{ + __no_stack_protector void DisplayMainScreen(CRData data) + { + CHArchTrapFrame *Frame = data.Frame; + + /* + _______ ___ ___ _______ _______ _______ _______ ______ ______ _______ _______ _______ _______ _____ +| __| | | __|_ _| ___| | | | | __ \ _ | __| | | ___| \ +|__ |\ /|__ | | | | ___| | | ---| < |__ | | ___| -- | +|_______| |___| |_______| |___| |_______|__|_|__| |______|___|__|___|___|_______|___|___|_______|_____/ + */ + EHPrint("\eFF5500 _______ ___ ___ _______ _______ _______ _______ ______ ______ _______ _______ _______ _______ _____ \n"); + EHPrint("| __| | | __|_ _| ___| | | | | __ \\ _ | __| | | ___| \\ \n"); + EHPrint("|__ |\\ /|__ | | | | ___| | | ---| < |__ | | ___| -- |\n"); + EHPrint("|_______| |___| |_______| |___| |_______|__|_|__| |______|___|__|___|___|_______|___|___|_______|_____/ \n\eFAFAFA"); + + switch (Frame->InterruptNumber) + { + case CPU::x64::DivideByZero: + { + EHPrint("Exception: Divide By Zero\n"); + EHPrint("The processor attempted to divide a number by zero.\n"); + break; + } + case CPU::x64::Debug: + { + EHPrint("Exception: Debug\n"); + EHPrint("A debug exception has occurred.\n"); + break; + } + case CPU::x64::NonMaskableInterrupt: + { + EHPrint("Exception: Non-Maskable Interrupt\n"); + EHPrint("A non-maskable interrupt was received.\n"); + break; + } + case CPU::x64::Breakpoint: + { + EHPrint("Exception: Breakpoint\n"); + EHPrint("The processor encountered a breakpoint.\n"); + break; + } + case CPU::x64::Overflow: + { + EHPrint("Exception: Overflow\n"); + EHPrint("The processor attempted to add a number to a number that was too large.\n"); + break; + } + case CPU::x64::BoundRange: + { + EHPrint("Exception: Bound Range\n"); + EHPrint("The processor attempted to access an array element that is out of bounds.\n"); + break; + } + case CPU::x64::InvalidOpcode: + { + EHPrint("Exception: Invalid Opcode\n"); + EHPrint("The processor attempted to execute an invalid opcode.\n"); + break; + } + case CPU::x64::DeviceNotAvailable: + { + EHPrint("Exception: Device Not Available\n"); + EHPrint("The processor attempted to use a device that is not available.\n"); + break; + } + case CPU::x64::DoubleFault: + { + EHPrint("Exception: Double Fault\n"); + EHPrint("The processor encountered a double fault.\n"); + break; + } + case CPU::x64::CoprocessorSegmentOverrun: + { + EHPrint("Exception: Coprocessor Segment Overrun\n"); + EHPrint("The processor attempted to access a segment that is not available.\n"); + break; + } + case CPU::x64::InvalidTSS: + { + EHPrint("Exception: Invalid TSS\n"); + EHPrint("The processor attempted to access a task state segment that is not available or valid.\n"); + CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; + EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); + EHPrint("GDT IDT LDT IDT\n"); + switch (SelCode.Table) + { + case 0b00: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b01: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b10: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b11: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + } + break; + } + case CPU::x64::SegmentNotPresent: + { + EHPrint("Exception: Segment Not Present\n"); + EHPrint("The processor attempted to access a segment that is not present.\n"); + CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; + EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); + EHPrint("GDT IDT LDT IDT\n"); + switch (SelCode.Table) + { + case 0b00: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b01: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b10: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b11: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + } + break; + } + case CPU::x64::StackSegmentFault: + { + EHPrint("Exception: Stack Segment Fault\n"); + CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; + EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); + EHPrint("GDT IDT LDT IDT\n"); + switch (SelCode.Table) + { + case 0b00: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b01: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b10: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b11: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + } + break; + } + case CPU::x64::GeneralProtectionFault: + { + EHPrint("Exception: General Protection Fault\n"); + EHPrint("Kernel performed an illegal operation.\n"); + CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; + EHPrint("External? %s\n", SelCode.External ? "Yes" : "No"); + EHPrint("GDT IDT LDT IDT\n"); + switch (SelCode.Table) + { + case 0b00: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b01: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b10: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + case 0b11: + { + EHPrint(" ^ \n"); + EHPrint(" | \n"); + EHPrint(" %ld\n", SelCode.Idx); + break; + } + } + break; + } + case CPU::x64::PageFault: + { + EHPrint("Exception: Page Fault\n"); + EHPrint("The processor attempted to access a page that is not present.\n"); + + CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; + EHPrint("At \e8888FF%#lx \eFAFAFAby \e8888FF%#lx\eFAFAFA\n", CPU::x64::readcr2().PFLA, Frame->rip); + EHPrint("Page: %s\eFAFAFA\n", params.P ? "\e058C19Present" : "\eE85230Not Present"); + EHPrint("Write Operation: \e8888FF%s\eFAFAFA\n", params.W ? "Read-Only" : "Read-Write"); + EHPrint("Processor Mode: \e8888FF%s\eFAFAFA\n", params.U ? "User-Mode" : "Kernel-Mode"); + EHPrint("CPU Reserved Bits: %s\eFAFAFA\n", params.R ? "\eE85230Reserved" : "\e058C19Unreserved"); + EHPrint("Caused By An Instruction Fetch: %s\eFAFAFA\n", params.I ? "\eE85230Yes" : "\e058C19No"); + EHPrint("Caused By A Protection-Key Violation: %s\eFAFAFA\n", params.PK ? "\eE85230Yes" : "\e058C19No"); + EHPrint("Caused By A Shadow Stack Access: %s\eFAFAFA\n", params.SS ? "\eE85230Yes" : "\e058C19No"); + EHPrint("Caused By An SGX Violation: %s\eFAFAFA\n", params.SGX ? "\eE85230Yes" : "\e058C19No"); + EHPrint("More Info: \e8888FF"); + if (Frame->ErrorCode & 0x00000008) + EHPrint("One or more page directory entries contain reserved bits which are set to 1.\n"); + else + EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]); + EHPrint("\eFAFAFA"); + break; + } + case CPU::x64::x87FloatingPoint: + { + EHPrint("Exception: x87 Floating Point\n"); + EHPrint("The x87 FPU generated an error.\n"); + break; + } + case CPU::x64::AlignmentCheck: + { + EHPrint("Exception: Alignment Check\n"); + EHPrint("The CPU detected an unaligned memory access.\n"); + break; + } + case CPU::x64::MachineCheck: + { + EHPrint("Exception: Machine Check\n"); + EHPrint("The CPU detected a hardware error.\n"); + break; + } + case CPU::x64::SIMDFloatingPoint: + { + EHPrint("Exception: SIMD Floating Point\n"); + EHPrint("The CPU detected an error in the SIMD unit.\n"); + break; + } + case CPU::x64::Virtualization: + { + EHPrint("Exception: Virtualization\n"); + EHPrint("The CPU detected a virtualization error.\n"); + break; + } + case CPU::x64::Security: + { + EHPrint("Exception: Security\n"); + EHPrint("The CPU detected a security violation.\n"); + break; + } + default: + { + EHPrint("Exception: Unknown\n"); + EHPrint("The CPU generated an unknown exception.\n"); + break; + } + } + + EHPrint("The exception happened at \e8888FF%#lx\eFAFAFA\n", Frame->rip); + } +} diff --git a/Core/Crash/Screens/StackFrame.cpp b/Core/Crash/Screens/StackFrame.cpp new file mode 100644 index 0000000..14d4b5f --- /dev/null +++ b/Core/Crash/Screens/StackFrame.cpp @@ -0,0 +1,25 @@ +#include "../../crashhandler.hpp" +#include "../chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(__amd64__) +#include "../../../Architecture/amd64/cpu/gdt.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +#include "../../../kernel.h" + +namespace CrashHandler +{ + __no_stack_protector void DisplayStackFrameScreen(CRData data) + { + EHPrint("\eFAFAFATracing 40 frames...\n"); + TraceFrames(data.Frame, 40); + } +} diff --git a/Core/Crash/Screens/Tasks.cpp b/Core/Crash/Screens/Tasks.cpp new file mode 100644 index 0000000..679ce05 --- /dev/null +++ b/Core/Crash/Screens/Tasks.cpp @@ -0,0 +1,63 @@ +#include "../../crashhandler.hpp" +#include "../chfcts.hpp" + +#include +#include +#include +#include +#include + +#if defined(__amd64__) +#include "../../../Architecture/amd64/cpu/gdt.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +#include "../../../kernel.h" + +namespace CrashHandler +{ + __no_stack_protector void DisplayTasksScreen(CRData data) + { + const char *StatusColor[7] = { + "FF0000", // Unknown + "AAFF00", // Ready + "00AA00", // Running + "FFAA00", // Sleeping + "FFAA00", // Waiting + "FF0088", // Stopped + "FF0000", // Terminated + }; + + const char *StatusString[7] = { + "Unknown", // Unknown + "Ready", // Ready + "Running", // Running + "Sleeping", // Sleeping + "Waiting", // Waiting + "Stopped", // Stopped + "Terminated", // Terminated + }; + + Vector Plist = TaskManager->GetProcessList(); + + if (TaskManager) + { + if (data.Thread) + EHPrint("\eFAFAFACrash occured in thread \eAA0F0F%s\eFAFAFA(%ld)\n", data.Thread->Name, data.Thread->ID); + + EHPrint("\eFAFAFAProcess list (%ld):\n", Plist.size()); + foreach (auto Process in Plist) + { + EHPrint("\e%s-> \eFAFAFA%s\eCCCCCC(%ld) \e00AAAA%s\n", + StatusColor[Process->Status], Process->Name, Process->ID, StatusString[Process->Status]); + + foreach (auto Thread in Process->Threads) + EHPrint("\e%s -> \eFAFAFA%s\eCCCCCC(%ld) \e00AAAA%s\n", + StatusColor[Thread->Status], Thread->Name, Thread->ID, StatusString[Thread->Status]); + } + } + else + EHPrint("\eFAFAFATaskManager is not initialized!\n"); + } +} diff --git a/Core/Crash/UserHandler.cpp b/Core/Crash/UserHandler.cpp index 8954224..06bc748 100644 --- a/Core/Crash/UserHandler.cpp +++ b/Core/Crash/UserHandler.cpp @@ -15,3 +15,186 @@ #include "../../kernel.h" +static const char *PagefaultDescriptions[8] = { + "Supervisory process tried to read a non-present page entry\n", + "Supervisory process tried to read a page and caused a protection fault\n", + "Supervisory process tried to write to a non-present page entry\n", + "Supervisory process tried to write a page and caused a protection fault\n", + "User process tried to read a non-present page entry\n", + "User process tried to read a page and caused a protection fault\n", + "User process tried to write to a non-present page entry\n", + "User process tried to write a page and caused a protection fault\n"}; + +__no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame) +{ + CriticalSection cs; + debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No"); + fixme("Handling user mode exception"); + TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Terminated; + + { + CPU::x64::CR0 cr0 = CPU::x64::readcr0(); + CPU::x64::CR2 cr2 = CPU::x64::readcr2(); + CPU::x64::CR3 cr3 = CPU::x64::readcr3(); + CPU::x64::CR4 cr4 = CPU::x64::readcr4(); + CPU::x64::CR8 cr8 = CPU::x64::readcr8(); + CPU::x64::EFER efer; + efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER); + + error("Technical Informations on CPU %lld:", GetCurrentCPU()->ID); + error("FS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx", + CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), + Frame->ss, Frame->cs, Frame->ds); + error("R8=%#llx R9=%#llx R10=%#llx R11=%#llx", Frame->r8, Frame->r9, Frame->r10, Frame->r11); + error("R12=%#llx R13=%#llx R14=%#llx R15=%#llx", Frame->r12, Frame->r13, Frame->r14, Frame->r15); + error("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); + error("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); + error("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); + error("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); + + error("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x", + cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False", + cr0.ET ? "True " : "False", cr0.NE ? "True " : "False", cr0.WP ? "True " : "False", cr0.AM ? "True " : "False", + cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False", + cr0.Reserved0, cr0.Reserved1, cr0.Reserved2); + + error("CR2: PFLA: %#llx", + cr2.PFLA); + + error("CR3: PWT:%s PCD:%s PDBR:%#llx", + cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); + + error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x", + cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", + cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", + cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", + cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False", + cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", + cr4.Reserved0, cr4.Reserved1, cr4.Reserved2); + + error("CR8: TPL:%d", cr8.TPL); + + error("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x", + Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", + Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", + Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False", + Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", + Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, + Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); + + error("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x", + efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", + efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", + efer.Reserved0, efer.Reserved1, efer.Reserved2); + } + + switch (Frame->InterruptNumber) + { + case CPU::x64::DivideByZero: + { + break; + } + case CPU::x64::Debug: + { + break; + } + case CPU::x64::NonMaskableInterrupt: + { + break; + } + case CPU::x64::Breakpoint: + { + break; + } + case CPU::x64::Overflow: + { + break; + } + case CPU::x64::BoundRange: + { + break; + } + case CPU::x64::InvalidOpcode: + { + break; + } + case CPU::x64::DeviceNotAvailable: + { + break; + } + case CPU::x64::DoubleFault: + { + break; + } + case CPU::x64::CoprocessorSegmentOverrun: + { + break; + } + case CPU::x64::InvalidTSS: + { + break; + } + case CPU::x64::SegmentNotPresent: + { + break; + } + case CPU::x64::StackSegmentFault: + { + break; + } + case CPU::x64::GeneralProtectionFault: + { + break; + } + case CPU::x64::PageFault: + { + CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; + error("An exception occurred at %#lx by %#lx", CPU::x64::readcr2().PFLA, Frame->rip); + error("Page: %s", params.P ? "Present" : "Not Present"); + error("Write Operation: %s", params.W ? "Read-Only" : "Read-Write"); + error("Processor Mode: %s", params.U ? "User-Mode" : "Kernel-Mode"); + error("CPU Reserved Bits: %s", params.R ? "Reserved" : "Unreserved"); + error("Caused By An Instruction Fetch: %s", params.I ? "Yes" : "No"); + error("Caused By A Protection-Key Violation: %s", params.PK ? "Yes" : "No"); + error("Caused By A Shadow Stack Access: %s", params.SS ? "Yes" : "No"); + error("Caused By An SGX Violation: %s", params.SGX ? "Yes" : "No"); + if (Frame->ErrorCode & 0x00000008) + error("One or more page directory entries contain reserved bits which are set to 1."); + else + error(PagefaultDescriptions[Frame->ErrorCode & 0b111]); + break; + } + case CPU::x64::x87FloatingPoint: + { + break; + } + case CPU::x64::AlignmentCheck: + { + break; + } + case CPU::x64::MachineCheck: + { + break; + } + case CPU::x64::SIMDFloatingPoint: + { + break; + } + case CPU::x64::Virtualization: + { + break; + } + case CPU::x64::Security: + { + break; + } + default: + { + break; + } + } + error("End of report."); + CPU::Interrupts(CPU::Enable); + debug("Interrupts enabled back."); + return; +} diff --git a/Core/Crash/chfcts.hpp b/Core/Crash/chfcts.hpp index 26389ac..dfc3b53 100644 --- a/Core/Crash/chfcts.hpp +++ b/Core/Crash/chfcts.hpp @@ -2,19 +2,252 @@ #define __FENNIX_KERNEL_CRASH_HANDLERS_FUNCTIONS_H__ #include + +#include +#include #include #if defined(__amd64__) typedef struct CPU::x64::TrapFrame CHArchTrapFrame; + +struct CRData +{ + CHArchTrapFrame *Frame; + + CPU::x64::CR0 cr0; + CPU::x64::CR2 cr2; + CPU::x64::CR3 cr3; + CPU::x64::CR4 cr4; + CPU::x64::CR8 cr8; + CPU::x64::EFER efer; + uint64_t dr0, dr1, dr2, dr3, dr6; + CPU::x64::DR7 dr7; + + long ID; + Tasking::PCB *Process; + Tasking::TCB *Thread; +}; + #elif defined(__i386__) typedef struct CPU::x86::TrapFrame CHArchTrapFrame; #elif defined(__aarch64__) typedef struct CPU::aarch64::TrapFrame CHArchTrapFrame; #endif +enum Keys +{ + KEY_INVALID = 0x0, + KEY_D_ESCAPE = 0x1, + KEY_D_1 = 0x2, + KEY_D_2 = 0x3, + KEY_D_3 = 0x4, + KEY_D_4 = 0x5, + KEY_D_5 = 0x6, + KEY_D_6 = 0x7, + KEY_D_7 = 0x8, + KEY_D_8 = 0x9, + KEY_D_9 = 0xa, + KEY_D_0 = 0xb, + KEY_D_MINUS = 0xc, + KEY_D_EQUALS = 0xd, + KEY_D_BACKSPACE = 0xe, + KEY_D_TAB = 0xf, + KEY_D_Q = 0x10, + KEY_D_W = 0x11, + KEY_D_E = 0x12, + KEY_D_R = 0x13, + KEY_D_T = 0x14, + KEY_D_Y = 0x15, + KEY_D_U = 0x16, + KEY_D_I = 0x17, + KEY_D_O = 0x18, + KEY_D_P = 0x19, + KEY_D_LBRACKET = 0x1a, + KEY_D_RBRACKET = 0x1b, + KEY_D_RETURN = 0x1c, + KEY_D_LCTRL = 0x1d, + KEY_D_A = 0x1e, + KEY_D_S = 0x1f, + KEY_D_D = 0x20, + KEY_D_F = 0x21, + KEY_D_G = 0x22, + KEY_D_H = 0x23, + KEY_D_J = 0x24, + KEY_D_K = 0x25, + KEY_D_L = 0x26, + KEY_D_SEMICOLON = 0x27, + KEY_D_APOSTROPHE = 0x28, + KEY_D_GRAVE = 0x29, + KEY_D_LSHIFT = 0x2a, + KEY_D_BACKSLASH = 0x2b, + KEY_D_Z = 0x2c, + KEY_D_X = 0x2d, + KEY_D_C = 0x2e, + KEY_D_V = 0x2f, + KEY_D_B = 0x30, + KEY_D_N = 0x31, + KEY_D_M = 0x32, + KEY_D_COMMA = 0x33, + KEY_D_PERIOD = 0x34, + KEY_D_SLASH = 0x35, + KEY_D_RSHIFT = 0x36, + KEY_D_PRTSC = 0x37, + KEY_D_LALT = 0x38, + KEY_D_SPACE = 0x39, + KEY_D_CAPSLOCK = 0x3a, + KEY_D_NUMLOCK = 0x45, + KEY_D_SCROLLLOCK = 0x46, + + KEY_D_KP_MULTIPLY = 0x37, + KEY_D_KP_7 = 0x47, + KEY_D_KP_8 = 0x48, + KEY_D_KP_9 = 0x49, + KEY_D_KP_MINUS = 0x4a, + KEY_D_KP_4 = 0x4b, + KEY_D_KP_5 = 0x4c, + KEY_D_KP_6 = 0x4d, + KEY_D_KP_PLUS = 0x4e, + KEY_D_KP_1 = 0x4f, + KEY_D_KP_2 = 0x50, + KEY_D_KP_3 = 0x51, + KEY_D_KP_0 = 0x52, + KEY_D_KP_PERIOD = 0x53, + + KEY_D_F1 = 0x3b, + KEY_D_F2 = 0x3c, + KEY_D_F3 = 0x3d, + KEY_D_F4 = 0x3e, + KEY_D_F5 = 0x3f, + KEY_D_F6 = 0x40, + KEY_D_F7 = 0x41, + KEY_D_F8 = 0x42, + KEY_D_F9 = 0x43, + KEY_D_F10 = 0x44, + KEY_D_F11 = 0x57, + KEY_D_F12 = 0x58, + + KEY_D_UP = 0x48, + KEY_D_LEFT = 0x4b, + KEY_D_RIGHT = 0x4d, + KEY_D_DOWN = 0x50, + + KEY_U_ESCAPE = 0x81, + KEY_U_1 = 0x82, + KEY_U_2 = 0x83, + KEY_U_3 = 0x84, + KEY_U_4 = 0x85, + KEY_U_5 = 0x86, + KEY_U_6 = 0x87, + KEY_U_7 = 0x88, + KEY_U_8 = 0x89, + KEY_U_9 = 0x8a, + KEY_U_0 = 0x8b, + KEY_U_MINUS = 0x8c, + KEY_U_EQUALS = 0x8d, + KEY_U_BACKSPACE = 0x8e, + KEY_U_TAB = 0x8f, + KEY_U_Q = 0x90, + KEY_U_W = 0x91, + KEY_U_E = 0x92, + KEY_U_R = 0x93, + KEY_U_T = 0x94, + KEY_U_Y = 0x95, + KEY_U_U = 0x96, + KEY_U_I = 0x97, + KEY_U_O = 0x98, + KEY_U_P = 0x99, + KEY_U_LBRACKET = 0x9a, + KEY_U_RBRACKET = 0x9b, + KEY_U_RETURN = 0x9c, + KEY_U_LCTRL = 0x9d, + KEY_U_A = 0x9e, + KEY_U_S = 0x9f, + KEY_U_D = 0xa0, + KEY_U_F = 0xa1, + KEY_U_G = 0xa2, + KEY_U_H = 0xa3, + KEY_U_J = 0xa4, + KEY_U_K = 0xa5, + KEY_U_L = 0xa6, + KEY_U_SEMICOLON = 0xa7, + KEY_U_APOSTROPHE = 0xa8, + KEY_U_GRAVE = 0xa9, + KEY_U_LSHIFT = 0xaa, + KEY_U_BACKSLASH = 0xab, + KEY_U_Z = 0xac, + KEY_U_X = 0xad, + KEY_U_C = 0xae, + KEY_U_V = 0xaf, + KEY_U_B = 0xb0, + KEY_U_N = 0xb1, + KEY_U_M = 0xb2, + KEY_U_COMMA = 0xb3, + KEY_U_PERIOD = 0xb4, + KEY_U_SLASH = 0xb5, + KEY_U_RSHIFT = 0xb6, + KEY_U_KP_MULTIPLY = 0xb7, + KEY_U_LALT = 0xb8, + KEY_U_SPACE = 0xb9, + KEY_U_CAPSLOCK = 0xba, + KEY_U_F1 = 0xbb, + KEY_U_F2 = 0xbc, + KEY_U_F3 = 0xbd, + KEY_U_F4 = 0xbe, + KEY_U_F5 = 0xbf, + KEY_U_F6 = 0xc0, + KEY_U_F7 = 0xc1, + KEY_U_F8 = 0xc2, + KEY_U_F9 = 0xc3, + KEY_U_F10 = 0xc4, + KEY_U_NUMLOCK = 0xc5, + KEY_U_SCROLLLOCK = 0xc6, + KEY_U_KP_7 = 0xc7, + KEY_U_KP_8 = 0xc8, + KEY_U_KP_9 = 0xc9, + KEY_U_KP_MINUS = 0xca, + KEY_U_KP_4 = 0xcb, + KEY_U_KP_5 = 0xcc, + KEY_U_KP_6 = 0xcd, + KEY_U_KP_PLUS = 0xce, + KEY_U_KP_1 = 0xcf, + KEY_U_KP_2 = 0xd0, + KEY_U_KP_3 = 0xd1, + KEY_U_KP_0 = 0xd2, + KEY_U_KP_PERIOD = 0xd3, + KEY_U_F11 = 0xd7, + KEY_U_F12 = 0xd8, +}; + namespace CrashHandler { + extern int SBIdx; + + class CrashKeyboardDriver : public Interrupts::Handler + { + private: +#if defined(__amd64__) + void OnInterruptReceived(CPU::x64::TrapFrame *Frame); +#elif defined(__i386__) + void OnInterruptReceived(void *Frame); +#elif defined(__aarch64__) + void OnInterruptReceived(void *Frame); +#endif + public: + CrashKeyboardDriver(); + ~CrashKeyboardDriver(); + }; + void TraceFrames(CHArchTrapFrame *Frame, int Count); + + void ArrowInput(uint8_t key); + void UserInput(char *Input); + void HookKeyboard(); + + void DisplayMainScreen(CRData data); + void DisplayDetailsScreen(CRData data); + void DisplayStackFrameScreen(CRData data); + void DisplayTasksScreen(CRData data); + void DisplayConsoleScreen(CRData data); } void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame); diff --git a/Core/Interrupts/IntManager.cpp b/Core/Interrupts/IntManager.cpp index 877e06d..b22fa9f 100644 --- a/Core/Interrupts/IntManager.cpp +++ b/Core/Interrupts/IntManager.cpp @@ -19,7 +19,7 @@ #include "../crashhandler.hpp" #include "../kernel.h" -extern "C" __attribute__((no_stack_protector)) void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); } +extern "C" __no_stack_protector void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); } namespace Interrupts { @@ -118,7 +118,7 @@ namespace Interrupts if (apic[Core]) { ((APIC::APIC *)Interrupts::apic[Core])->EOI(); - // apic->IPI(CurrentCPU->ID, SchedulerInterrupt); ?????? + // TODO: Handle PIC too return; } // TODO: PIC @@ -127,6 +127,7 @@ namespace Interrupts #elif defined(__aarch64__) void *Frame = Data; #endif + error("HALT HALT HALT HALT HALT HALT HALT HALT HALT"); CPU::Stop(); } diff --git a/Core/Video/Display.cpp b/Core/Video/Display.cpp index 0d756aa..51946f4 100644 --- a/Core/Video/Display.cpp +++ b/Core/Video/Display.cpp @@ -53,8 +53,32 @@ namespace Video } case '\b': { + switch (this->CurrentFont->GetInfo().Type) + { + case FontType::PCScreenFont1: + { + fixme("PCScreenFont1"); + break; + } + case FontType::PCScreenFont2: + { + uint32_t fonthdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width; + uint32_t fonthdrHeight = this->CurrentFont->GetInfo().PSF2Font->Header->height; + + for (unsigned long Y = this->Buffers[Index]->CursorY; Y < this->Buffers[Index]->CursorY + fonthdrHeight; Y++) + for (unsigned long X = this->Buffers[Index]->CursorX - fonthdrWidth; X < this->Buffers[Index]->CursorX; X++) + *(uint32_t *)((uint64_t)this->Buffers[Index]->Buffer + + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8)) = 0; + break; + } + default: + warn("Unsupported font type"); + break; + } + if (this->Buffers[Index]->CursorX > 0) this->Buffers[Index]->CursorX -= this->GetCurrentFont()->GetInfo().Width; + return Char; } case '\t': diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 597995e..b1a6ca2 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -27,7 +27,7 @@ NewLock(SchedulerLock); namespace Tasking { - extern "C" __attribute__((no_stack_protector)) void OneShot(int TimeSlice) + extern "C" __no_stack_protector void OneShot(int TimeSlice) { if (TimeSlice == 0) TimeSlice = 10; @@ -53,7 +53,7 @@ namespace Tasking #endif } - __attribute__((no_stack_protector)) void Task::RemoveThread(TCB *Thread) + __no_stack_protector void Task::RemoveThread(TCB *Thread) { for (uint64_t i = 0; i < Thread->Parent->Threads.size(); i++) if (Thread->Parent->Threads[i] == Thread) @@ -70,7 +70,7 @@ namespace Tasking } } - __attribute__((no_stack_protector)) void Task::RemoveProcess(PCB *Process) + __no_stack_protector void Task::RemoveProcess(PCB *Process) { if (Process == nullptr) return; @@ -107,7 +107,7 @@ namespace Tasking } } - __attribute__((no_stack_protector)) void Task::UpdateInfo(TaskInfo *Info, int Core) + __no_stack_protector void Task::UpdateInfo(TaskInfo *Info, int Core) { if (Info->Affinity[Core] == true) { @@ -135,7 +135,7 @@ namespace Tasking } #if defined(__amd64__) - __attribute__((no_stack_protector)) bool Task::FindNewProcess(void *CPUDataPointer) + __no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; schedbg("%d processes", ListProcess.size()); @@ -184,7 +184,7 @@ namespace Tasking return false; } - __attribute__((no_stack_protector)) bool Task::GetNextAvailableThread(void *CPUDataPointer) + __no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -224,7 +224,7 @@ namespace Tasking return false; } - __attribute__((no_stack_protector)) bool Task::GetNextAvailableProcess(void *CPUDataPointer) + __no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -267,7 +267,7 @@ namespace Tasking return false; } - __attribute__((no_stack_protector)) void Task::SchedulerCleanupProcesses() + __no_stack_protector void Task::SchedulerCleanupProcesses() { foreach (PCB *pcb in ListProcess) { @@ -277,7 +277,7 @@ namespace Tasking } } - __attribute__((no_stack_protector)) bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) + __no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -305,9 +305,14 @@ namespace Tasking return false; } - __attribute__((no_stack_protector)) void Task::Schedule(CPU::x64::TrapFrame *Frame) + __no_stack_protector void Task::Schedule(CPU::x64::TrapFrame *Frame) { SmartCriticalSection(SchedulerLock); + if (StopSheduler) + { + warn("Scheduler stopped."); + return; + } CPUData *CurrentCPU = GetCurrentCPU(); schedbg("Scheduler called on CPU %d.", CurrentCPU->ID); schedbg("%d: %ld%%", CurrentCPU->ID, GetUsage(CurrentCPU->ID)); @@ -488,71 +493,71 @@ namespace Tasking } } - __attribute__((no_stack_protector)) void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); } + __no_stack_protector void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); } #elif defined(__i386__) - __attribute__((no_stack_protector)) bool Task::FindNewProcess(void *CPUDataPointer) + __no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) bool Task::GetNextAvailableThread(void *CPUDataPointer) + __no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) bool Task::GetNextAvailableProcess(void *CPUDataPointer) + __no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) void Task::SchedulerCleanupProcesses() + __no_stack_protector void Task::SchedulerCleanupProcesses() { fixme("unimplemented"); } - __attribute__((no_stack_protector)) bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) + __no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) void Task::Schedule(void *Frame) + __no_stack_protector void Task::Schedule(void *Frame) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } + __no_stack_protector void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } #elif defined(__aarch64__) - __attribute__((no_stack_protector)) bool Task::FindNewProcess(void *CPUDataPointer) + __no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) bool Task::GetNextAvailableThread(void *CPUDataPointer) + __no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) bool Task::GetNextAvailableProcess(void *CPUDataPointer) + __no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) void Task::SchedulerCleanupProcesses() + __no_stack_protector void Task::SchedulerCleanupProcesses() { fixme("unimplemented"); } - __attribute__((no_stack_protector)) bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) + __no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) void Task::Schedule(void *Frame) + __no_stack_protector void Task::Schedule(void *Frame) { fixme("unimplemented"); } - __attribute__((no_stack_protector)) void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } + __no_stack_protector void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } #endif void ThreadDoExit() diff --git a/include/cpu.hpp b/include/cpu.hpp index 1dd40d9..c4bd090 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -143,7 +143,7 @@ namespace CPU /** * @brief Pause the CPU */ - __attribute__((no_stack_protector)) static inline void Pause(bool Loop = false) + __no_stack_protector static inline void Pause(bool Loop = false) { do { @@ -158,7 +158,7 @@ namespace CPU /** * @brief Stop the CPU (infinite loop) */ - __attribute__((no_stack_protector)) static inline void Stop() + __no_stack_protector static inline void Stop() { while (1) { @@ -177,7 +177,7 @@ namespace CPU /** * @brief Halt the CPU */ - __attribute__((no_stack_protector)) static inline void Halt(bool Loop = false) + __no_stack_protector static inline void Halt(bool Loop = false) { do { @@ -213,7 +213,7 @@ namespace CPU namespace MemBar { - __attribute__((no_stack_protector)) static inline void Barrier() + __no_stack_protector static inline void Barrier() { #if defined(__amd64__) || defined(__i386__) asmv("" :: @@ -224,7 +224,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void Fence() + __no_stack_protector static inline void Fence() { #if defined(__amd64__) || defined(__i386__) asmv("mfence" :: @@ -235,7 +235,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void StoreFence() + __no_stack_protector static inline void StoreFence() { #if defined(__amd64__) || defined(__i386__) asmv("sfence" :: @@ -246,7 +246,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void LoadFence() + __no_stack_protector static inline void LoadFence() { #if defined(__amd64__) || defined(__i386__) asmv("lfence" :: @@ -1390,7 +1390,7 @@ namespace CPU uint64_t raw; } SelectorErrorCode; - __attribute__((no_stack_protector)) static inline void lgdt(void *gdt) + __no_stack_protector static inline void lgdt(void *gdt) { #if defined(__amd64__) asmv("lgdt (%0)" @@ -1399,7 +1399,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void lidt(void *idt) + __no_stack_protector static inline void lidt(void *idt) { #if defined(__amd64__) asmv("lidt (%0)" @@ -1408,7 +1408,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void ltr(uint16_t Segment) + __no_stack_protector static inline void ltr(uint16_t Segment) { #if defined(__amd64__) asmv("ltr %0" @@ -1417,7 +1417,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void invlpg(void *Address) + __no_stack_protector static inline void invlpg(void *Address) { #if defined(__amd64__) asmv("invlpg (%0)" @@ -1436,7 +1436,7 @@ namespace CPU * @param ecx ECX * @param edx EDX */ - __attribute__((no_stack_protector)) static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) + __no_stack_protector static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { #if defined(__amd64__) asmv("cpuid" @@ -1452,14 +1452,14 @@ namespace CPU * * @return uint32_t */ - __attribute__((no_stack_protector)) static inline uint32_t GetHighestLeaf() + __no_stack_protector static inline uint32_t GetHighestLeaf() { uint32_t eax, ebx, ecx, edx; cpuid(0x0, &eax, &ebx, &ecx, &edx); return eax; } - __attribute__((no_stack_protector)) static inline uint64_t rdmsr(uint32_t msr) + __no_stack_protector static inline uint64_t rdmsr(uint32_t msr) { uint32_t Low, High; #if defined(__amd64__) @@ -1471,7 +1471,7 @@ namespace CPU return ((uint64_t)Low) | (((uint64_t)High) << 32); } - __attribute__((no_stack_protector)) static inline void wrmsr(uint32_t msr, uint64_t Value) + __no_stack_protector static inline void wrmsr(uint32_t msr, uint64_t Value) { uint32_t Low = Value, High = Value >> 32; #if defined(__amd64__) @@ -1482,7 +1482,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline CR0 readcr0() + __no_stack_protector static inline CR0 readcr0() { uint64_t Result; #if defined(__amd64__) @@ -1492,7 +1492,7 @@ namespace CPU return (CR0){.raw = Result}; } - __attribute__((no_stack_protector)) static inline CR2 readcr2() + __no_stack_protector static inline CR2 readcr2() { uint64_t Result; #if defined(__amd64__) @@ -1502,7 +1502,7 @@ namespace CPU return (CR2){.raw = Result}; } - __attribute__((no_stack_protector)) static inline CR3 readcr3() + __no_stack_protector static inline CR3 readcr3() { uint64_t Result; #if defined(__amd64__) @@ -1512,7 +1512,7 @@ namespace CPU return (CR3){.raw = Result}; } - __attribute__((no_stack_protector)) static inline CR4 readcr4() + __no_stack_protector static inline CR4 readcr4() { uint64_t Result; #if defined(__amd64__) @@ -1522,7 +1522,7 @@ namespace CPU return (CR4){.raw = Result}; } - __attribute__((no_stack_protector)) static inline CR8 readcr8() + __no_stack_protector static inline CR8 readcr8() { uint64_t Result; #if defined(__amd64__) @@ -1532,7 +1532,7 @@ namespace CPU return (CR8){.raw = Result}; } - __attribute__((no_stack_protector)) static inline void writecr0(CR0 ControlRegister) + __no_stack_protector static inline void writecr0(CR0 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr0" @@ -1542,7 +1542,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void writecr2(CR2 ControlRegister) + __no_stack_protector static inline void writecr2(CR2 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr2" @@ -1552,7 +1552,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void writecr3(CR3 ControlRegister) + __no_stack_protector static inline void writecr3(CR3 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr3" @@ -1562,7 +1562,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void writecr4(CR4 ControlRegister) + __no_stack_protector static inline void writecr4(CR4 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr4" @@ -1572,7 +1572,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void writecr8(CR8 ControlRegister) + __no_stack_protector static inline void writecr8(CR8 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr8" @@ -1582,7 +1582,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void fxsave(char *FXSaveArea) + __no_stack_protector static inline void fxsave(char *FXSaveArea) { #if defined(__amd64__) if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000) @@ -1596,7 +1596,7 @@ namespace CPU #endif } - __attribute__((no_stack_protector)) static inline void fxrstor(char *FXRstorArea) + __no_stack_protector static inline void fxrstor(char *FXRstorArea) { #if defined(__amd64__) if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000) diff --git a/include/task.hpp b/include/task.hpp index 5abc26f..2103cfd 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -172,7 +172,7 @@ namespace Tasking PCB *IdleProcess = nullptr; TCB *IdleThread = nullptr; - __attribute__((no_stack_protector)) bool InvalidPCB(PCB *pcb) + __no_stack_protector bool InvalidPCB(PCB *pcb) { if (pcb >= (PCB *)0xfffffffffffff000) return true; @@ -181,7 +181,7 @@ namespace Tasking return false; } - __attribute__((no_stack_protector)) bool InvalidTCB(TCB *tcb) + __no_stack_protector bool InvalidTCB(TCB *tcb) { if (tcb >= (TCB *)0xfffffffffffff000) return true; @@ -211,8 +211,11 @@ namespace Tasking void Schedule(void *Frame); void OnInterruptReceived(void *Frame); #endif + bool StopSheduler = false; public: + Vector GetProcessList() { return ListProcess; } + void Panic() { StopSheduler = true; } void Schedule(); long GetUsage(int Core) { return 100 - IdleProcess->Info.Usage[Core]; } void KillThread(TCB *tcb, int Code) diff --git a/include/types.h b/include/types.h index d757b48..d23a010 100644 --- a/include/types.h +++ b/include/types.h @@ -240,5 +240,17 @@ typedef __SIZE_TYPE__ size_t; #define __constructor __attribute__((constructor)) #define __destructor __attribute__((destructor)) #define __cleanup(x) __attribute__((cleanup(x))) +#define __fallthrough __attribute__((fallthrough)) +#define __nonnull(x) __attribute__((nonnull x)) +#define __nonnull_all __attribute__((nonnull)) +#define __returns_nonnull __attribute__((returns_nonnull)) +#define __sentinel __attribute__((sentinel)) +#define __sentinel_all __attribute__((sentinel(0))) +#define __format(x, y, z) __attribute__((format(x, y, z))) +#define __format_arg(x) __attribute__((format_arg(x))) +#define __nonnull_params(x) __attribute__((nonnull x)) +#define __nonnull_all __attribute__((nonnull)) +#define __warn_unused_result __attribute__((warn_unused_result)) +#define __no_stack_protector __attribute__((no_stack_protector)) #endif // !__FENNIX_KERNEL_TYPES_H__