From 02890549002eef7602dee5ed0b0a9f0f54653c54 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 28 Nov 2022 08:25:37 +0200 Subject: [PATCH] Changed a lot of files. Summary: profiler support; "SafeFunction"; UnlockDeadLock kernel config; Code optimization & more --- .gitignore | 3 + .vscode/c_cpp_properties.json | 3 +- Architecture/amd64/Limine.c | 22 +- .../amd64/cpu/GlobalDescriptorTable.cpp | 4 +- Architecture/amd64/linker.ld | 18 ++ Architecture/i686/Multiboot2.cpp | 15 +- Core/Crash/CrashDetails.cpp | 44 ++-- Core/Crash/CrashHandler.cpp | 89 +++++-- Core/Crash/KBDrv.cpp | 10 +- Core/Crash/SFrame.cpp | 2 +- Core/Crash/Screens/Console.cpp | 2 +- Core/Crash/Screens/Details.cpp | 2 +- Core/Crash/Screens/Main.cpp | 2 +- Core/Crash/Screens/StackFrame.cpp | 23 +- Core/Crash/Screens/Tasks.cpp | 2 +- Core/Crash/UserHandler.cpp | 2 +- Core/Debugger.cpp | 12 +- Core/{ => Driver}/Driver.cpp | 242 ++++++++--------- Core/Driver/DriverAPI.cpp | 131 ++++++++++ Core/Driver/api.hpp | 10 + Core/Interrupts/IntManager.cpp | 44 +++- Core/Lock.cpp | 9 + Core/Memory/HeapAllocators/Xalloc.cpp | 80 ++++++ Core/Memory/Memory.cpp | 97 ++++--- Core/Memory/PhysicalMemoryManager.cpp | 2 +- Core/Power.cpp | 4 + Core/StackGuard.c | 24 +- Core/Symbols.cpp | 2 +- Core/UndefinedBehaviorSanitization.c | 40 ++- ...iversalAsynchronousReceiverTransmitter.cpp | 59 +++-- Core/crashhandler.hpp | 4 + DAPI.hpp | 25 +- Fex.hpp | 6 + FileSystem/FS/ustar.cpp | 2 +- FileSystem/Filesystem.cpp | 52 ++-- KConfig.cpp | 22 +- KThread.cpp | 64 ++--- Kernel.cpp | 34 ++- Library/Convert.c | 246 +++++++++++++++++- Library/md5.c | 4 + Library/printf.c | 62 ++--- Makefile | 16 +- Profiling/cyg.cpp | 87 +++++++ Profiling/gcov.cpp | 67 +++++ Profiling/gprof.cpp | 19 ++ Recovery/RecoveryMain.cpp | 2 + Tasking/InterProcessCommunication.cpp | 14 - Tasking/Task.cpp | 83 +++--- dump.sh | 1 + include/convert.h | 39 ++- include/cpu.hpp | 56 ++-- include/display.hpp | 6 +- include/filesystem.hpp | 8 +- include/filesystem/mounts.hpp | 8 +- include/interrupts.hpp | 13 +- include/kconfig.hpp | 1 + include/recovery.hpp | 11 + include/task.hpp | 11 +- include/types.h | 11 +- include/uart.hpp | 2 +- include/vector.hpp | 44 ++-- kernel.h | 1 + 62 files changed, 1462 insertions(+), 558 deletions(-) rename Core/{ => Driver}/Driver.cpp (74%) create mode 100644 Core/Driver/DriverAPI.cpp create mode 100644 Core/Driver/api.hpp create mode 100644 Profiling/cyg.cpp create mode 100644 Profiling/gcov.cpp create mode 100644 Profiling/gprof.cpp create mode 100644 Recovery/RecoveryMain.cpp create mode 100755 dump.sh create mode 100644 include/recovery.hpp diff --git a/.gitignore b/.gitignore index 9852334..c528893 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ *.o +*.su +*.gcno *.map *.fsys *.log Files/*.psf +.dccache diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index ed46d89..9e3c90f 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -40,7 +40,8 @@ "-Wl,-static,--no-dynamic-linker,-ztext", "-shared", "-zmax-page-size=0x1000", - "-nostdinc++" + "-nostdinc++", + "-fsanitize=undefined" ] } ], diff --git a/Architecture/amd64/Limine.c b/Architecture/amd64/Limine.c index acb4b6b..bfcb8d5 100644 --- a/Architecture/amd64/Limine.c +++ b/Architecture/amd64/Limine.c @@ -42,7 +42,7 @@ static volatile struct limine_smbios_request SmbiosRequest = { .id = LIMINE_SMBIOS_REQUEST, .revision = 0}; -void init_limine() +SafeFunction __no_instrument_function void init_limine() { struct BootInfo binfo; struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response; @@ -211,8 +211,12 @@ void init_limine() } binfo.Modules[i].Address = (void *)((uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000); - strcpy(binfo.Modules[i].Path, ModuleResponse->modules[i]->path); - strcpy(binfo.Modules[i].CommandLine, ModuleResponse->modules[i]->cmdline); + strncpy(binfo.Modules[i].Path, + ModuleResponse->modules[i]->path, + strlen(ModuleResponse->modules[i]->path) + 1); + strncpy(binfo.Modules[i].CommandLine, + ModuleResponse->modules[i]->cmdline, + strlen(ModuleResponse->modules[i]->cmdline) + 1); binfo.Modules[i].Size = ModuleResponse->modules[i]->size; debug("Module %d:\nAddress: %p\nPath: %s\nCommand Line: %s\nSize: %ld", i, (uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000, ModuleResponse->modules[i]->path, @@ -234,13 +238,19 @@ void init_limine() binfo.Kernel.PhysicalBase = (void *)KernelAddressResponse->physical_base; binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base; binfo.Kernel.FileBase = KernelFileResponse->kernel_file->address; - strcpy(binfo.Kernel.CommandLine, KernelFileResponse->kernel_file->cmdline); + strncpy(binfo.Kernel.CommandLine, + KernelFileResponse->kernel_file->cmdline, + strlen(KernelFileResponse->kernel_file->cmdline) + 1); binfo.Kernel.Size = KernelFileResponse->kernel_file->size; trace("Kernel physical address: %p", KernelAddressResponse->physical_base); trace("Kernel virtual address: %p", KernelAddressResponse->virtual_base); - strcpy(binfo.Bootloader.Name, BootloaderInfoResponse->name); - strcpy(binfo.Bootloader.Version, BootloaderInfoResponse->version); + strncpy(binfo.Bootloader.Name, + BootloaderInfoResponse->name, + strlen(BootloaderInfoResponse->name) + 1); + strncpy(binfo.Bootloader.Version, + BootloaderInfoResponse->version, + strlen(BootloaderInfoResponse->version) + 1); // Call kernel entry point Entry(&binfo); diff --git a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp index 67fc010..aec13bb 100644 --- a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp +++ b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp @@ -89,7 +89,7 @@ namespace GlobalDescriptorTable void *CPUStackPointer[MAX_CPU]; - __no_stack_protector void Init(int Core) + SafeFunction void Init(int Core) { memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries)); gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]}; @@ -143,7 +143,7 @@ namespace GlobalDescriptorTable trace("Global Descriptor Table initialized"); } - __no_stack_protector void SetKernelStack(void *Stack) + SafeFunction void SetKernelStack(void *Stack) { if (Stack) tss[GetCurrentCPU()->ID].StackPointer[0] = (uint64_t)Stack; diff --git a/Architecture/amd64/linker.ld b/Architecture/amd64/linker.ld index 1b993ed..1046b98 100644 --- a/Architecture/amd64/linker.ld +++ b/Architecture/amd64/linker.ld @@ -29,6 +29,24 @@ SECTIONS _kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE)); . += CONSTANT(MAXPAGESIZE); + .init_array : + { + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(.init_array .ctors)) + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + PROVIDE_HIDDEN (__init_array_end = .); + } + + .fini_array : + { + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP(*(.fini_array .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + . += CONSTANT(MAXPAGESIZE); + + .bss : { *(COMMON) diff --git a/Architecture/i686/Multiboot2.cpp b/Architecture/i686/Multiboot2.cpp index 066c09f..a6ad5c0 100644 --- a/Architecture/i686/Multiboot2.cpp +++ b/Architecture/i686/Multiboot2.cpp @@ -92,12 +92,16 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic) { case MULTIBOOT_TAG_TYPE_CMDLINE: { - strcpy(binfo.Kernel.CommandLine, ((multiboot_tag_string *)Tag)->string); + strncpy(binfo.Kernel.CommandLine, + ((multiboot_tag_string *)Tag)->string, + strlen(((multiboot_tag_string *)Tag)->string)); break; } case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: { - strcpy(binfo.Bootloader.Name, ((multiboot_tag_string *)Tag)->string); + strncpy(binfo.Bootloader.Name, + ((multiboot_tag_string *)Tag)->string, + strlen(((multiboot_tag_string *)Tag)->string)); break; } case MULTIBOOT_TAG_TYPE_MODULE: @@ -106,8 +110,9 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic) static int module_count = 0; binfo.Modules[module_count++].Address = (void *)module->mod_start; binfo.Modules[module_count++].Size = module->size; - strcpy(binfo.Modules[module_count++].Path, "(null)"); - strcpy(binfo.Modules[module_count++].CommandLine, module->cmdline); + strncpy(binfo.Modules[module_count++].Path, "(null)", 6); + strncpy(binfo.Modules[module_count++].CommandLine, module->cmdline, + strlen(module->cmdline)); break; } case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: @@ -332,7 +337,7 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic) vm[12] = 0x0579; vm[13] = 0x0565; vm[14] = 0x0574; - + CPU::Stop(); // Entry(&binfo); } diff --git a/Core/Crash/CrashDetails.cpp b/Core/Crash/CrashDetails.cpp index aa71fba..16ea021 100644 --- a/Core/Crash/CrashDetails.cpp +++ b/Core/Crash/CrashDetails.cpp @@ -25,30 +25,30 @@ static const char *PagefaultDescriptions[8] = { "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) +SafeFunction void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame) { fixme("Divide by zero exception\n"); } -__no_stack_protector void DebugExceptionHandler(CHArchTrapFrame *Frame) +SafeFunction 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) +SafeFunction void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); } +SafeFunction void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); } +SafeFunction void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); } +SafeFunction void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); } +SafeFunction 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) +SafeFunction void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); } +SafeFunction void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); } +SafeFunction void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); } +SafeFunction void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); } +SafeFunction void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); } +SafeFunction void StackFaultExceptionHandler(CHArchTrapFrame *Frame) { CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; CrashHandler::EHPrint("\eDD2920System crashed!\n"); @@ -64,7 +64,7 @@ __no_stack_protector void StackFaultExceptionHandler(CHArchTrapFrame *Frame) CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode); } -__no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame) +SafeFunction void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame) { // staticbuffer(descbuf); // staticbuffer(desc_ext); @@ -97,7 +97,7 @@ __no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Fra CrashHandler::EHPrint("Table: %d\n", SelCode.Table); CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); } -__no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame) +SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame) { CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF"); @@ -120,10 +120,10 @@ __no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame) 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"); } +SafeFunction void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); } +SafeFunction void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); } +SafeFunction void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); } +SafeFunction void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); } +SafeFunction void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); } +SafeFunction void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); } +SafeFunction void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); } diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index 2dcc192..ba0b186 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -22,15 +22,16 @@ NewLock(UserInputLock); namespace CrashHandler { + void *EHIntFrames[INT_FRAMES_MAX]; static bool ExceptionOccurred = false; int SBIdx = 255; - __no_stack_protector void printfWrapper(char c, void *unused) + SafeFunction void printfWrapper(char c, void *unused) { Display->Print(c, SBIdx, true); UNUSED(unused); } - __no_stack_protector void EHPrint(const char *Format, ...) + SafeFunction void EHPrint(const char *Format, ...) { va_list args; va_start(args, Format); @@ -38,7 +39,7 @@ namespace CrashHandler va_end(args); } - __no_stack_protector char *trimwhitespace(char *str) + SafeFunction char *TrimWhiteSpace(char *str) { char *end; while (*str == ' ') @@ -54,7 +55,7 @@ namespace CrashHandler CRData crashdata = {}; - __no_stack_protector void DisplayTopOverlay() + SafeFunction void DisplayTopOverlay() { Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); Video::Font *f = Display->GetCurrentFont(); @@ -108,7 +109,7 @@ namespace CrashHandler Display->SetBufferCursor(SBIdx, 0, fi.Height + 10); } - __no_stack_protector void DisplayBottomOverlay() + SafeFunction void DisplayBottomOverlay() { Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); Video::Font *f = Display->GetCurrentFont(); @@ -122,7 +123,7 @@ namespace CrashHandler EHPrint("\eAAAAAA> \eFAFAFA"); } - __no_stack_protector void ArrowInput(uint8_t key) + SafeFunction void ArrowInput(uint8_t key) { switch (key) { @@ -193,7 +194,7 @@ namespace CrashHandler Display->SetBuffer(SBIdx); } - __no_stack_protector void UserInput(char *Input) + SafeFunction void UserInput(char *Input) { SmartCriticalSection(UserInputLock); Display->ClearBuffer(SBIdx); @@ -209,6 +210,7 @@ namespace CrashHandler EHPrint("showbuf - Display the contents of a screen buffer.\n"); EHPrint(" - A sleep timer will be enabled. This will cause the OS to sleep for an unknown amount of time.\n"); EHPrint(" - \eFF4400WARNING: This can crash the system if a wrong buffer is selected.\eFAFAFA\n"); + EHPrint("ifr - Show interrupt frames.\n"); EHPrint("main - Show the main screen.\n"); EHPrint("details - Show the details screen.\n"); EHPrint("frames - Show the stack frame screen.\n"); @@ -223,25 +225,66 @@ namespace CrashHandler { PowerManager->Shutdown(); EHPrint("\eFFFFFFNow it's safe to turn off your computer."); + Display->SetBuffer(SBIdx); CPU::Stop(); } else if (strcmp(Input, "reboot") == 0) { PowerManager->Reboot(); EHPrint("\eFFFFFFNow it's safe to reboot your computer."); + Display->SetBuffer(SBIdx); CPU::Stop(); } else if (strncmp(Input, "showbuf", 7) == 0) { - char *arg = trimwhitespace(Input + 7); + char *arg = TrimWhiteSpace(Input + 7); int tmpidx = SBIdx; SBIdx = atoi(arg); Display->SetBuffer(SBIdx); - for (int i = 0; i < 1000000; i++) + for (int i = 0; i < 5000000; i++) inb(0x80); SBIdx = tmpidx; Display->SetBuffer(SBIdx); } + else if (strncmp(Input, "ifr", 3) == 0) + { + char *arg = TrimWhiteSpace(Input + 3); + uint64_t CountI = atoi(arg); + uint64_t TotalCount = sizeof(EHIntFrames) / sizeof(EHIntFrames[0]); + + debug("Printing %ld interrupt frames.", CountI); + + if (CountI > TotalCount) + { + EHPrint("eFF4400Count too big! Maximum allowed is %ld\eFAFAFA\n", TotalCount); + Display->SetBuffer(SBIdx); + } + else + { + for (uint64_t i = 0; i < CountI; i++) + { + if (EHIntFrames[i]) + { + if (!Memory::Virtual().Check(EHIntFrames[i])) + continue; + EHPrint("\n\e2565CC%p", EHIntFrames[i]); + EHPrint("\e7925CC-"); +#if defined(__amd64__) + if ((uint64_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end) +#elif defined(__i386__) + if ((uint64_t)EHIntFrames[i] >= 0xC0000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end) +#elif defined(__aarch64__) +#endif + EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uint64_t)EHIntFrames[i])); + else + EHPrint("\eFF4CA9Outside Kernel"); + for (int i = 0; i < 20000; i++) + inb(0x80); + Display->SetBuffer(SBIdx); + } + } + } + } else if (strcmp(Input, "main") == 0) { SBIdx = 255; @@ -286,11 +329,14 @@ namespace CrashHandler Display->SetBuffer(SBIdx); } - __no_stack_protector void Handle(void *Data) + SafeFunction void Handle(void *Data) { // TODO: SUPPORT SMP CPU::Interrupts(CPU::Disable); error("An exception occurred!"); + for (size_t i = 0; i < INT_FRAMES_MAX; i++) + EHIntFrames[i] = Interrupts::InterruptFrames[i]; + SBIdx = 255; CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data; #if defined(__amd64__) @@ -299,27 +345,11 @@ namespace CrashHandler if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA) { debug("Exception in kernel mode"); - if (Frame->InterruptNumber == CPU::x64::PageFault) - { - CPUData *data = GetCurrentCPU(); - if (data) - { - if (data->CurrentThread->Stack->Expand(CPU::x64::readcr2().raw)) - { - debug("Stack expanded"); - CPU::Interrupts(CPU::Enable); - return; - } - else - { - error("Stack expansion failed"); - } - } - } - if (TaskManager) TaskManager->Panic(); + debug("ePanicSchedStop"); Display->CreateBuffer(0, 0, SBIdx); + debug("e0"); } else { @@ -348,7 +378,9 @@ namespace CrashHandler { SBIdx = 255; Display->ClearBuffer(SBIdx); + debug("e0-1"); Display->SetBufferCursor(SBIdx, 0, 0); + debug("e0-2"); CPU::x64::CR0 cr0 = CPU::x64::readcr0(); CPU::x64::CR2 cr2 = CPU::x64::readcr2(); @@ -405,6 +437,7 @@ namespace CrashHandler } ExceptionOccurred = true; + Interrupts::RemoveAll(); debug("Reading control registers..."); crashdata.Frame = Frame; diff --git a/Core/Crash/KBDrv.cpp b/Core/Crash/KBDrv.cpp index 54b1eee..ad0c6e9 100644 --- a/Core/Crash/KBDrv.cpp +++ b/Core/Crash/KBDrv.cpp @@ -103,11 +103,11 @@ namespace CrashHandler static char UserInputBuffer[1024]; #if defined(__amd64__) - __no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame) + SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame) #elif defined(__i386__) - __no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame) + SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame) #elif defined(__aarch64__) - __no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame) + SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame) #endif { uint8_t scanCode = inb(0x60); @@ -155,10 +155,10 @@ namespace CrashHandler } } - __no_stack_protector void HookKeyboard() + SafeFunction void HookKeyboard() { CrashKeyboardDriver kbd; // We don't want to allocate memory. - asmv("Loop: nop; jmp Loop;"); + asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;"); // CPU::Halt(true); // This is an infinite loop. } } diff --git a/Core/Crash/SFrame.cpp b/Core/Crash/SFrame.cpp index d5226c3..ad0b51a 100644 --- a/Core/Crash/SFrame.cpp +++ b/Core/Crash/SFrame.cpp @@ -23,7 +23,7 @@ namespace CrashHandler uint64_t rip; }; - __no_stack_protector void TraceFrames(CHArchTrapFrame *Frame, int Count) + SafeFunction void TraceFrames(CHArchTrapFrame *Frame, int Count) { #if defined(__amd64__) diff --git a/Core/Crash/Screens/Console.cpp b/Core/Crash/Screens/Console.cpp index 1e97810..af3df4e 100644 --- a/Core/Crash/Screens/Console.cpp +++ b/Core/Crash/Screens/Console.cpp @@ -17,7 +17,7 @@ namespace CrashHandler { - __no_stack_protector void DisplayConsoleScreen(CRData data) + SafeFunction void DisplayConsoleScreen(CRData data) { EHPrint("TODO"); } diff --git a/Core/Crash/Screens/Details.cpp b/Core/Crash/Screens/Details.cpp index 13e9ca4..20b4a74 100644 --- a/Core/Crash/Screens/Details.cpp +++ b/Core/Crash/Screens/Details.cpp @@ -17,7 +17,7 @@ namespace CrashHandler { - __no_stack_protector void DisplayDetailsScreen(CRData data) + SafeFunction void DisplayDetailsScreen(CRData data) { if (data.Process) EHPrint("\e7981FCCurrent Process: %s(%ld)\n", diff --git a/Core/Crash/Screens/Main.cpp b/Core/Crash/Screens/Main.cpp index f095806..be3f643 100644 --- a/Core/Crash/Screens/Main.cpp +++ b/Core/Crash/Screens/Main.cpp @@ -27,7 +27,7 @@ static const char *PagefaultDescriptions[8] = { namespace CrashHandler { - __no_stack_protector void DisplayMainScreen(CRData data) + SafeFunction void DisplayMainScreen(CRData data) { CHArchTrapFrame *Frame = data.Frame; diff --git a/Core/Crash/Screens/StackFrame.cpp b/Core/Crash/Screens/StackFrame.cpp index 14d4b5f..23c0a8e 100644 --- a/Core/Crash/Screens/StackFrame.cpp +++ b/Core/Crash/Screens/StackFrame.cpp @@ -1,6 +1,7 @@ #include "../../crashhandler.hpp" #include "../chfcts.hpp" +#include #include #include #include @@ -17,9 +18,29 @@ namespace CrashHandler { - __no_stack_protector void DisplayStackFrameScreen(CRData data) + SafeFunction void DisplayStackFrameScreen(CRData data) { EHPrint("\eFAFAFATracing 40 frames...\n"); TraceFrames(data.Frame, 40); + EHPrint("\n\n\eFAFAFATracing interrupt frames...\n"); + for (uint64_t i = 0; i < 8; i++) + { + if (EHIntFrames[i]) + { + if (!Memory::Virtual().Check(EHIntFrames[i])) + continue; + EHPrint("\n\e2565CC%p", EHIntFrames[i]); + EHPrint("\e7925CC-"); +#if defined(__amd64__) + if ((uint64_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end) +#elif defined(__i386__) + if ((uint64_t)EHIntFrames[i] >= 0xC0000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end) +#elif defined(__aarch64__) +#endif + EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uint64_t)EHIntFrames[i])); + else + EHPrint("\eFF4CA9Outside Kernel"); + } + } } } diff --git a/Core/Crash/Screens/Tasks.cpp b/Core/Crash/Screens/Tasks.cpp index 14fcb27..2936667 100644 --- a/Core/Crash/Screens/Tasks.cpp +++ b/Core/Crash/Screens/Tasks.cpp @@ -17,7 +17,7 @@ namespace CrashHandler { - __no_stack_protector void DisplayTasksScreen(CRData data) + SafeFunction void DisplayTasksScreen(CRData data) { const char *StatusColor[7] = { "FF0000", // Unknown diff --git a/Core/Crash/UserHandler.cpp b/Core/Crash/UserHandler.cpp index 68c53cd..b117868 100644 --- a/Core/Crash/UserHandler.cpp +++ b/Core/Crash/UserHandler.cpp @@ -25,7 +25,7 @@ static const char *PagefaultDescriptions[8] = { "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) +SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) { CriticalSection cs; debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No"); diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index e84ef78..fad3c04 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -8,13 +8,13 @@ NewLock(DebuggerLock); using namespace UniversalAsynchronousReceiverTransmitter; -static inline void uart_wrapper(char c, void *unused) +static inline __no_instrument_function void uart_wrapper(char c, void *unused) { UART(COM1).Write(c); (void)unused; } -static inline void WritePrefix(DebugLevel Level, const char *File, int Line, const char *Function) +static inline __no_instrument_function void WritePrefix(DebugLevel Level, const char *File, int Line, const char *Function) { const char *DbgLvlString; switch (Level) @@ -52,7 +52,7 @@ static inline void WritePrefix(DebugLevel Level, const char *File, int Line, con namespace SysDbg { - void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) + __no_instrument_function void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) { WritePrefix(Level, File, Line, Function); va_list args; @@ -61,7 +61,7 @@ namespace SysDbg va_end(args); } - void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) + __no_instrument_function void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) { // SmartLock(DebuggerLock); WritePrefix(Level, File, Line, Function); @@ -74,7 +74,7 @@ namespace SysDbg } // C compatibility -extern "C" void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) +extern "C" __no_instrument_function void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) { WritePrefix(Level, File, Line, Function); va_list args; @@ -84,7 +84,7 @@ extern "C" void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, c } // C compatibility -extern "C" void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) +extern "C" __no_instrument_function void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) { WritePrefix(Level, File, Line, Function); va_list args; diff --git a/Core/Driver.cpp b/Core/Driver/Driver.cpp similarity index 74% rename from Core/Driver.cpp rename to Core/Driver/Driver.cpp index ea49996..9015c29 100644 --- a/Core/Driver.cpp +++ b/Core/Driver/Driver.cpp @@ -2,19 +2,19 @@ #include #include -#include #include #include #include #include #include -#include "../kernel.h" -#include "../DAPI.hpp" -#include "../Fex.hpp" +#include "../../kernel.h" +#include "../../DAPI.hpp" +#include "../../Fex.hpp" +#include "api.hpp" NewLock(DriverInitLock); -NewLock(DriverDisplayPrintLock); +NewLock(DriverInterruptLock); namespace Driver { @@ -28,127 +28,6 @@ namespace Driver "Input", "Audio"}; - void DriverDebugPrint(char *String, unsigned long DriverUID) - { - SmartLock(DriverDisplayPrintLock); - trace("[%ld] %s", DriverUID, String); - } - - void DriverDisplayPrint(char *String) - { - SmartLock(DriverDisplayPrintLock); - for (unsigned long i = 0; i < strlen(String); i++) - Display->Print(String[i], 0, true); - } - - void *RequestPage(unsigned long Size) - { - SmartLock(DriverDisplayPrintLock); - debug("Requesting %ld pages from the kernel...", Size); - void *ret = KernelAllocator.RequestPages(Size); - debug("Got %#lx", ret); - return ret; - } - - void FreePage(void *Page, unsigned long Size) - { - SmartLock(DriverDisplayPrintLock); - debug("Freeing %ld pages from the address %#lx...", Size, (unsigned long)Page); - KernelAllocator.FreePages(Page, Size); - } - - void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags) - { - SmartLock(DriverDisplayPrintLock); - debug("Mapping %#lx to %#lx with flags %#lx...", (unsigned long)VirtualAddress, (unsigned long)PhysicalAddress, Flags); - Memory::Virtual().Map(VirtualAddress, PhysicalAddress, Flags); - } - - void UnmapMemory(void *VirtualAddress) - { - SmartLock(DriverDisplayPrintLock); - debug("Unmapping %#lx...", (unsigned long)VirtualAddress); - Memory::Virtual().Unmap(VirtualAddress); - } - - void *Drivermemcpy(void *Destination, void *Source, unsigned long Size) - { - SmartLock(DriverDisplayPrintLock); - debug("Copying %ld bytes from %#lx to %#lx...", Size, (unsigned long)Source, (unsigned long)Destination); - return memcpy(Destination, Source, Size); - } - - void *Drivermemset(void *Destination, int Value, unsigned long Size) - { - SmartLock(DriverDisplayPrintLock); - debug("Setting %ld bytes from %#lx to %#x...", Size, (unsigned long)Destination, Value); - return memset(Destination, Value, Size); - } - - void DriverNetSend(unsigned int DriverID, unsigned char *Data, unsigned short Size) - { - DumpData("DriverNetSend", Data, Size); - } - - void DriverNetReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size) - { - DumpData("DriverNetReceive", Data, Size); - } - - void DriverAHCIDiskRead(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port) - { - DumpData("DriverDiskRead", Data, SectorCount * 512); - } - - void DriverAHCIDiskWrite(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port) - { - DumpData("DriverDiskWrite", Data, SectorCount * 512); - } - - char *DriverPCIGetDeviceName(unsigned int VendorID, unsigned int DeviceID) - { - return (char *)"Unknown"; - } - - KernelAPI KAPI = { - .Version = { - .Major = 0, - .Minor = 0, - .Patch = 1}, - .Info = { - .Offset = 0, - .DriverUID = 0, - }, - .Memory = { - .PageSize = PAGE_SIZE, - .RequestPage = RequestPage, - .FreePage = FreePage, - .Map = MapMemory, - .Unmap = UnmapMemory, - }, - .PCI = { - .GetDeviceName = DriverPCIGetDeviceName, - }, - .Util = { - .DebugPrint = DriverDebugPrint, - .DisplayPrint = DriverDisplayPrint, - .memcpy = Drivermemcpy, - .memset = Drivermemset, - }, - .Commmand = { - .Network = { - .SendPacket = DriverNetSend, - .ReceivePacket = DriverNetReceive, - }, - .Disk = { - .AHCI = { - .ReadSector = DriverAHCIDiskRead, - .WriteSector = DriverAHCIDiskWrite, - }, - }, - }, - }; - int Driver::IOCB(unsigned long DUID, void *KCB) { foreach (auto var in Drivers) @@ -411,7 +290,48 @@ namespace Driver } case FexDriverType::FexDriverType_Input: { - fixme("Input driver: %s", fexExtended->Driver.Name); + DriverInterruptHook *InterruptHook = nullptr; + if (DrvExtHdr->Driver.Bind.Interrupt.Vector[0] != 0) + InterruptHook = new DriverInterruptHook(DrvExtHdr->Driver.Bind.Interrupt.Vector[0] + 32, // x86 + (void *)((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex), + KCallback); + + for (unsigned long i = 0; i < sizeof(DrvExtHdr->Driver.Bind.Interrupt.Vector) / sizeof(DrvExtHdr->Driver.Bind.Interrupt.Vector[0]); i++) + { + if (DrvExtHdr->Driver.Bind.Interrupt.Vector[i] == 0) + break; + // InterruptHook = new DriverInterruptHook(DrvExtHdr->Driver.Bind.Interrupt.Vector[i] + 32, // x86 + // (void *)((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex), + // KCallback); + fixme("TODO: MULTIPLE BIND INTERRUPT VECTORS %d", DrvExtHdr->Driver.Bind.Interrupt.Vector[i]); + } + + KCallback->RawPtr = nullptr; + KCallback->Reason = CallbackReason::ConfigurationReason; + int callbackret = ((int (*)(KernelCallback *))((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex))(KCallback); + if (callbackret == DriverReturnCode::NOT_IMPLEMENTED) + { + KernelAllocator.FreePages(fex, TO_PAGES(Size)); + KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback))); + error("Driver %s does not implement the configuration callback", fexExtended->Driver.Name); + break; + } + else if (callbackret != DriverReturnCode::OK) + { + KernelAllocator.FreePages(fex, TO_PAGES(Size)); + KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback))); + error("Driver %s returned error %d", fexExtended->Driver.Name, callbackret); + break; + } + + memset(KCallback, 0, sizeof(KernelCallback)); + KCallback->Reason = CallbackReason::InterruptReason; + + DriverFile *drvfile = new DriverFile; + drvfile->DriverUID = KAPI.Info.DriverUID; + drvfile->Address = (void *)fex; + drvfile->InterruptHook[0] = InterruptHook; + Drivers.push_back(drvfile); break; } case FexDriverType::FexDriverType_Audio: @@ -430,6 +350,68 @@ namespace Driver { fixme("Process driver: %s", DrvExtHdr->Driver.Name); } + else if (DrvExtHdr->Driver.Bind.Type == DriverBindType::BIND_INPUT) + { + Fex *fex = (Fex *)KernelAllocator.RequestPages(TO_PAGES(Size)); + memcpy(fex, (void *)DriverAddress, Size); + FexExtended *fexExtended = (FexExtended *)((uint64_t)fex + EXTENDED_SECTION_ADDRESS); +#ifdef DEBUG + uint8_t *result = md5File((uint8_t *)fex, Size); + debug("MD5: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], + result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]); + kfree(result); +#endif + if (CallDriverEntryPoint(fex) != DriverCode::OK) + { + KernelAllocator.FreePages(fex, TO_PAGES(Size)); + return DriverCode::DRIVER_RETURNED_ERROR; + } + debug("Starting driver %s (offset: %#lx)", fexExtended->Driver.Name, fex); + + KernelCallback *KCallback = (KernelCallback *)KernelAllocator.RequestPages(TO_PAGES(sizeof(KernelCallback))); + + switch (fexExtended->Driver.Type) + { + case FexDriverType::FexDriverType_Input: + { + fixme("Input driver: %s", fexExtended->Driver.Name); + KCallback->RawPtr = nullptr; + break; + KCallback->Reason = CallbackReason::ConfigurationReason; + int callbackret = ((int (*)(KernelCallback *))((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex))(KCallback); + if (callbackret == DriverReturnCode::NOT_IMPLEMENTED) + { + KernelAllocator.FreePages(fex, TO_PAGES(Size)); + KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback))); + error("Driver %s does not implement the configuration callback", fexExtended->Driver.Name); + break; + } + else if (callbackret != DriverReturnCode::OK) + { + KernelAllocator.FreePages(fex, TO_PAGES(Size)); + KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback))); + error("Driver %s returned error %d", fexExtended->Driver.Name, callbackret); + break; + } + + KernelAllocator.FreePages(fex, TO_PAGES(Size)); + KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback))); + + DriverFile *drvfile = new DriverFile; + drvfile->DriverUID = KAPI.Info.DriverUID; + drvfile->Address = (void *)fex; + drvfile->InterruptHook[0] = nullptr; + Drivers.push_back(drvfile); + break; + } + default: + { + warn("Unknown driver type: %d", fexExtended->Driver.Type); + break; + } + } + } else { error("Unknown driver bind type: %d", DrvExtHdr->Driver.Bind.Type); @@ -454,9 +436,9 @@ namespace Driver if (!strcmp(extension, ".fex")) { uint64_t ret = this->LoadDriver(driver->Address, driver->Length); - char retstring[64]; + char retstring[128]; if (ret == DriverCode::OK) - strcpy(retstring, "\e058C19OK"); + strncpy(retstring, "\e058C19OK", 64); else sprintf_(retstring, "\eE85230FAILED (%#lx)", ret); KPrint("%s %s", driver->Name, retstring); @@ -477,7 +459,7 @@ namespace Driver void DriverInterruptHook::OnInterruptReceived(void *Frame) #endif { - CriticalSection cs; // or SmartCriticalSection(DriverInitLock); ? + SmartCriticalSection(DriverInterruptLock); ((int (*)(void *))(Handle))(Data); } diff --git a/Core/Driver/DriverAPI.cpp b/Core/Driver/DriverAPI.cpp new file mode 100644 index 0000000..6bba26f --- /dev/null +++ b/Core/Driver/DriverAPI.cpp @@ -0,0 +1,131 @@ +#include + +#include +#include + +#include "../../kernel.h" +#include "../../Fex.hpp" +#include "api.hpp" + +NewLock(DriverDisplayPrintLock); + +void DriverDebugPrint(char *String, unsigned long DriverUID) +{ + SmartLock(DriverDisplayPrintLock); + trace("[%ld] %s", DriverUID, String); +} + +void DriverDisplayPrint(char *String) +{ + SmartLock(DriverDisplayPrintLock); + for (unsigned long i = 0; i < strlen(String); i++) + Display->Print(String[i], 0, true); +} + +void *RequestPage(unsigned long Size) +{ + SmartLock(DriverDisplayPrintLock); + // debug("Requesting %ld pages from the kernel...", Size); + void *ret = KernelAllocator.RequestPages(Size); + // debug("Got %#lx", ret); + return ret; +} + +void FreePage(void *Page, unsigned long Size) +{ + SmartLock(DriverDisplayPrintLock); + debug("Freeing %ld pages from the address %#lx...", Size, (unsigned long)Page); + KernelAllocator.FreePages(Page, Size); +} + +void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags) +{ + SmartLock(DriverDisplayPrintLock); + debug("Mapping %#lx to %#lx with flags %#lx...", (unsigned long)VirtualAddress, (unsigned long)PhysicalAddress, Flags); + Memory::Virtual().Map(VirtualAddress, PhysicalAddress, Flags); +} + +void UnmapMemory(void *VirtualAddress) +{ + SmartLock(DriverDisplayPrintLock); + debug("Unmapping %#lx...", (unsigned long)VirtualAddress); + Memory::Virtual().Unmap(VirtualAddress); +} + +void *Drivermemcpy(void *Destination, void *Source, unsigned long Size) +{ + SmartLock(DriverDisplayPrintLock); + // debug("Copying %ld bytes from %#lx to %#lx...", Size, (unsigned long)Source, (unsigned long)Destination); + return memcpy(Destination, Source, Size); +} + +void *Drivermemset(void *Destination, int Value, unsigned long Size) +{ + SmartLock(DriverDisplayPrintLock); + // debug("Setting %ld bytes from %#lx to %#x...", Size, (unsigned long)Destination, Value); + return memset(Destination, Value, Size); +} + +void DriverNetSend(unsigned int DriverID, unsigned char *Data, unsigned short Size) +{ + DumpData("DriverNetSend", Data, Size); +} + +void DriverNetReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size) +{ + DumpData("DriverNetReceive", Data, Size); +} + +void DriverAHCIDiskRead(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port) +{ + DumpData("DriverDiskRead", Data, SectorCount * 512); +} + +void DriverAHCIDiskWrite(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port) +{ + DumpData("DriverDiskWrite", Data, SectorCount * 512); +} + +char *DriverPCIGetDeviceName(unsigned int VendorID, unsigned int DeviceID) +{ + return (char *)"Unknown"; +} + +KernelAPI KAPI = { + .Version = { + .Major = 0, + .Minor = 0, + .Patch = 1}, + .Info = { + .Offset = 0, + .DriverUID = 0, + }, + .Memory = { + .PageSize = PAGE_SIZE, + .RequestPage = RequestPage, + .FreePage = FreePage, + .Map = MapMemory, + .Unmap = UnmapMemory, + }, + .PCI = { + .GetDeviceName = DriverPCIGetDeviceName, + }, + .Util = { + .DebugPrint = DriverDebugPrint, + .DisplayPrint = DriverDisplayPrint, + .memcpy = Drivermemcpy, + .memset = Drivermemset, + }, + .Command = { + .Network = { + .SendPacket = DriverNetSend, + .ReceivePacket = DriverNetReceive, + }, + .Disk = { + .AHCI = { + .ReadSector = DriverAHCIDiskRead, + .WriteSector = DriverAHCIDiskWrite, + }, + }, + }, +}; diff --git a/Core/Driver/api.hpp b/Core/Driver/api.hpp new file mode 100644 index 0000000..7f4a768 --- /dev/null +++ b/Core/Driver/api.hpp @@ -0,0 +1,10 @@ +#ifndef __FENNIX_KERNEL_DRIVER_API_H__ +#define __FENNIX_KERNEL_DRIVER_API_H__ + +#include + +#include "../../DAPI.hpp" + +extern KernelAPI KAPI; + +#endif // !__FENNIX_KERNEL_DRIVER_API_H__ diff --git a/Core/Interrupts/IntManager.cpp b/Core/Interrupts/IntManager.cpp index b22fa9f..83af544 100644 --- a/Core/Interrupts/IntManager.cpp +++ b/Core/Interrupts/IntManager.cpp @@ -19,7 +19,7 @@ #include "../crashhandler.hpp" #include "../kernel.h" -extern "C" __no_stack_protector void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); } +extern "C" SafeFunction void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); } namespace Interrupts { @@ -32,6 +32,7 @@ namespace Interrupts /* APIC::APIC */ void *apic[MAX_CPU]; #elif defined(__aarch64__) #endif + void *InterruptFrames[INT_FRAMES_MAX]; void Initialize(int Core) { @@ -103,25 +104,42 @@ namespace Interrupts #endif } - extern "C" void MainInterruptHandler(void *Data) + void RemoveAll() + { + for (int i = 0; i < CPU::x64::IRQ223; i++) + RegisteredEvents->DeleteNode(i); + } + + extern "C" SafeFunction void MainInterruptHandler(void *Data) { #if defined(__amd64__) CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data; - int Core = GetCurrentCPU()->ID; - Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber); - if (handler != (Handler *)0xdeadbeef) - handler->OnInterruptReceived(Frame); - else - error("Unhandled IRQ%d on CPU %d.", Frame->InterruptNumber - 32, Core); + memmove(InterruptFrames + 1, InterruptFrames, sizeof(InterruptFrames) - sizeof(InterruptFrames[0])); + InterruptFrames[0] = (void *)Frame->rip; + + CPUData *CoreData = GetCurrentCPU(); + int Core = 0; + if (likely(CoreData != nullptr)) + Core = CoreData->ID; - if (apic[Core]) + // If this is false, we have a big problem. + if (likely(Frame->InterruptNumber < CPU::x64::IRQ223 && Frame->InterruptNumber > CPU::x64::ISR0)) { - ((APIC::APIC *)Interrupts::apic[Core])->EOI(); - // TODO: Handle PIC too - return; + Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber); + if (likely(handler != (Handler *)0xdeadbeef)) + handler->OnInterruptReceived(Frame); + else + error("Unhandled IRQ%ld on CPU %d.", Frame->InterruptNumber - 32, Core); + + if (likely(apic[Core])) + { + ((APIC::APIC *)Interrupts::apic[Core])->EOI(); + // TODO: Handle PIC too + return; + } + // TODO: PIC } - // TODO: PIC #elif defined(__i386__) void *Frame = Data; #elif defined(__aarch64__) diff --git a/Core/Lock.cpp b/Core/Lock.cpp index 8165425..e485a74 100644 --- a/Core/Lock.cpp +++ b/Core/Lock.cpp @@ -20,6 +20,15 @@ void LockClass::DeadLock(SpinLockData Lock) this->DeadLocks++; + if (Config.UnlockDeadLock && this->DeadLocks > 10) + { + warn("Unlocking lock '%s' held by '%s'! %ld locks in queue. Core %ld is being held by %ld.", + Lock.AttemptingToGet, Lock.CurrentHolder, + Lock.Count, CCore, Lock.Core); + this->DeadLocks = 0; + this->Unlock(); + } + if (TaskManager) TaskManager->Schedule(); } diff --git a/Core/Memory/HeapAllocators/Xalloc.cpp b/Core/Memory/HeapAllocators/Xalloc.cpp index 1a065a8..4202dac 100644 --- a/Core/Memory/HeapAllocators/Xalloc.cpp +++ b/Core/Memory/HeapAllocators/Xalloc.cpp @@ -2,6 +2,72 @@ namespace Xalloc { + class XLockClass + { + struct SpinLockData + { + uint64_t LockData = 0x0; + const char *CurrentHolder = "(nul)"; + const char *AttemptingToGet = "(nul)"; + uint64_t Count = 0; + }; + + void DeadLock(SpinLockData Lock) + { + Xalloc_warn("Potential deadlock in lock '%s' held by '%s'! %ld locks in queue.", Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count); + } + + private: + SpinLockData LockData; + bool IsLocked = false; + + public: + int Lock(const char *FunctionName) + { + LockData.AttemptingToGet = FunctionName; + Retry: + unsigned int i = 0; + while (__atomic_exchange_n(&IsLocked, true, __ATOMIC_ACQUIRE) && ++i < 0x10000000) + ; + if (i >= 0x10000000) + { + DeadLock(LockData); + goto Retry; + } + LockData.Count++; + LockData.CurrentHolder = FunctionName; + __sync_synchronize(); + return 0; + } + + int Unlock() + { + __sync_synchronize(); + __atomic_store_n(&IsLocked, false, __ATOMIC_RELEASE); + LockData.Count--; + IsLocked = false; + return 0; + } + }; + + class XSmartLock + { + private: + XLockClass *LockPointer = nullptr; + + public: + XSmartLock(XLockClass &Lock, const char *FunctionName) + { + this->LockPointer = &Lock; + this->LockPointer->Lock(FunctionName); + } + ~XSmartLock() { this->LockPointer->Unlock(); } + }; + + XLockClass XLock; + +#define XSL XSmartLock CONCAT(lock##_, __COUNTER__)(XLock, __FUNCTION__) + class SmartSMAPClass { private: @@ -20,6 +86,7 @@ namespace Xalloc AllocatorV1::AllocatorV1(void *Address, bool UserMode, bool SMAPEnabled) { SmartSMAP; + XSL; void *Position = Address; UserMapping = UserMode; SMAPUsed = SMAPEnabled; @@ -47,6 +114,7 @@ namespace Xalloc AllocatorV1::~AllocatorV1() { SmartSMAP; + XSL; Xalloc_trace("Destructor not implemented yet."); } @@ -81,6 +149,7 @@ namespace Xalloc void *AllocatorV1::Malloc(Xuint64_t Size) { SmartSMAP; + XSL; if (this->HeapStart == nullptr) { Xalloc_err("Memory allocation not initialized yet!"); @@ -136,12 +205,14 @@ namespace Xalloc CurrentSegment = CurrentSegment->Next; } ExpandHeap(Size); + XLock.Unlock(); return this->Malloc(Size); } void AllocatorV1::Free(void *Address) { SmartSMAP; + XSL; if (this->HeapStart == nullptr) { Xalloc_err("Memory allocation not initialized yet!"); @@ -156,6 +227,7 @@ namespace Xalloc void *AllocatorV1::Calloc(Xuint64_t NumberOfBlocks, Xuint64_t Size) { SmartSMAP; + XSL; if (this->HeapStart == nullptr) { Xalloc_err("Memory allocation not initialized yet!"); @@ -168,7 +240,10 @@ namespace Xalloc Size = 0x10; } + XLock.Unlock(); void *Block = this->Malloc(NumberOfBlocks * Size); + XLock.Lock(__FUNCTION__); + if (Block) Xmemset(Block, 0, NumberOfBlocks * Size); return Block; @@ -177,6 +252,7 @@ namespace Xalloc void *AllocatorV1::Realloc(void *Address, Xuint64_t Size) { SmartSMAP; + XSL; if (this->HeapStart == nullptr) { Xalloc_err("Memory allocation not initialized yet!"); @@ -184,11 +260,13 @@ namespace Xalloc } if (!Address && Size == 0) { + XLock.Unlock(); this->Free(Address); return nullptr; } else if (!Address) { + XLock.Unlock(); return this->Calloc(Size, sizeof(char)); } @@ -198,7 +276,9 @@ namespace Xalloc Size = 0x10; } + XLock.Unlock(); void *newAddress = this->Calloc(Size, sizeof(char)); + XLock.Lock(__FUNCTION__); Xmemcpy(newAddress, Address, Size); return newAddress; } diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index 967b379..9670a95 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -16,7 +16,7 @@ static MemoryAllocatorType AllocatorType = MemoryAllocatorType::None; Xalloc::AllocatorV1 *XallocV1Allocator = nullptr; #ifdef DEBUG -void tracepagetable(PageTable *pt) +__no_instrument_function void tracepagetable(PageTable *pt) { for (int i = 0; i < 512; i++) { @@ -37,11 +37,12 @@ void tracepagetable(PageTable *pt) } #endif -void MapFromZero(PageTable *PT, BootInfo *Info) +__no_instrument_function void MapFromZero(PageTable *PT, BootInfo *Info) { Virtual va = Virtual(PT); uint64_t VirtualOffsetNormalVMA = NORMAL_VMA_OFFSET; - for (uint64_t t = 0; t < Info->Memory.Size; t += PAGE_SIZE) + uint64_t MemSize = Info->Memory.Size; + for (uint64_t t = 0; t < MemSize; t += PAGE_SIZE) { va.Map((void *)t, (void *)t, PTFlag::RW); va.Map((void *)VirtualOffsetNormalVMA, (void *)t, PTFlag::RW); @@ -49,7 +50,7 @@ void MapFromZero(PageTable *PT, BootInfo *Info) } } -void MapFramebuffer(PageTable *PT, BootInfo *Info) +__no_instrument_function void MapFramebuffer(PageTable *PT, BootInfo *Info) { Virtual va = Virtual(PT); int itrfb = 0; @@ -66,7 +67,7 @@ void MapFramebuffer(PageTable *PT, BootInfo *Info) } } -void MapKernel(PageTable *PT, BootInfo *Info) +__no_instrument_function void MapKernel(PageTable *PT, BootInfo *Info) { /* KernelStart KernelTextEnd KernelRoDataEnd KernelEnd Kernel Start & Text Start ------ Text End ------ Kernel Rodata End ------ Kernel Data End & Kernel End @@ -79,28 +80,30 @@ void MapKernel(PageTable *PT, BootInfo *Info) uint64_t KernelEnd = (uint64_t)&_kernel_end; uint64_t BaseKernelMapAddress = (uint64_t)Info->Kernel.PhysicalBase; - for (uint64_t k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE) + uint64_t k; + + for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW); KernelAllocator.LockPage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } - for (uint64_t k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE) + for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW); KernelAllocator.LockPage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } - for (uint64_t k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE) + for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::P); KernelAllocator.LockPage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } - for (uint64_t k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE) + for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW); KernelAllocator.LockPage((void *)BaseKernelMapAddress); @@ -111,8 +114,9 @@ void MapKernel(PageTable *PT, BootInfo *Info) KernelStart, KernelTextEnd, KernelRoDataEnd, KernelEnd, Info->Kernel.PhysicalBase, BaseKernelMapAddress - PAGE_SIZE); } -void InitializeMemoryManagement(BootInfo *Info) +__no_instrument_function void InitializeMemoryManagement(BootInfo *Info) { +#ifdef DEBUG for (uint64_t i = 0; i < Info->Memory.Entries; i++) { uint64_t Base = reinterpret_cast(Info->Memory.Entry[i].BaseAddress); @@ -122,7 +126,7 @@ void InitializeMemoryManagement(BootInfo *Info) switch (Info->Memory.Entry[i].Type) { - case Usable: + case likely(Usable): Type = "Usable"; break; case Reserved: @@ -150,12 +154,13 @@ void InitializeMemoryManagement(BootInfo *Info) break; } - trace("%lld: %#016llx-%#016llx %s", + debug("%lld: %#016llx-%#016llx %s", i, Base, End, Type); } +#endif trace("Initializing Physical Memory Manager"); KernelAllocator = Physical(); @@ -177,7 +182,8 @@ void InitializeMemoryManagement(BootInfo *Info) debug("Mapping from 0x0 to %#llx", Info->Memory.Size); MapFromZero(KernelPageTable, Info); debug("Mapping from 0x0 %#llx for Userspace Page Table", Info->Memory.Size); - MapFromZero(UserspaceKernelOnlyPageTable, Info); + UserspaceKernelOnlyPageTable[0] = KernelPageTable[0]; // TODO: This is a hack to speed up the boot process + // MapFromZero(UserspaceKernelOnlyPageTable, Info); /* Mapping Framebuffer address */ debug("Mapping Framebuffer"); @@ -219,10 +225,14 @@ void *HeapMalloc(uint64_t Size) { switch (AllocatorType) { - case MemoryAllocatorType::Pages: + case unlikely(MemoryAllocatorType::Pages): return KernelAllocator.RequestPages(TO_PAGES(Size)); case MemoryAllocatorType::XallocV1: - return XallocV1Allocator->Malloc(Size); + { + void *ret = XallocV1Allocator->Malloc(Size); + memset(ret, 0, Size); + return ret; + } case MemoryAllocatorType::liballoc11: { void *ret = PREFIX(malloc)(Size); @@ -238,10 +248,14 @@ void *HeapCalloc(uint64_t n, uint64_t Size) { switch (AllocatorType) { - case MemoryAllocatorType::Pages: + case unlikely(MemoryAllocatorType::Pages): return KernelAllocator.RequestPages(TO_PAGES(n * Size)); case MemoryAllocatorType::XallocV1: - return XallocV1Allocator->Calloc(n, Size); + { + void *ret = XallocV1Allocator->Calloc(n, Size); + memset(ret, 0, n * Size); + return ret; + } case MemoryAllocatorType::liballoc11: { void *ret = PREFIX(calloc)(n, Size); @@ -257,10 +271,14 @@ void *HeapRealloc(void *Address, uint64_t Size) { switch (AllocatorType) { - case MemoryAllocatorType::Pages: + case unlikely(MemoryAllocatorType::Pages): return KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak case MemoryAllocatorType::XallocV1: - return XallocV1Allocator->Realloc(Address, Size); + { + void *ret = XallocV1Allocator->Realloc(Address, Size); + memset(ret, 0, Size); + return ret; + } case MemoryAllocatorType::liballoc11: { void *ret = PREFIX(realloc)(Address, Size); @@ -276,11 +294,12 @@ void HeapFree(void *Address) { switch (AllocatorType) { - case MemoryAllocatorType::Pages: + case unlikely(MemoryAllocatorType::Pages): KernelAllocator.FreePage(Address); // WARNING: Potential memory leak break; case MemoryAllocatorType::XallocV1: - XallocV1Allocator->Free(Address); + if (XallocV1Allocator) + XallocV1Allocator->Free(Address); break; case MemoryAllocatorType::liballoc11: PREFIX(free) @@ -291,20 +310,32 @@ void HeapFree(void *Address) } } -void *operator new(size_t Size) { - return HeapMalloc(Size); } -void *operator new[](size_t Size) { - return HeapMalloc(Size); } +void *operator new(size_t Size) +{ + return HeapMalloc(Size); +} +void *operator new[](size_t Size) +{ + return HeapMalloc(Size); +} void *operator new(unsigned long Size, std::align_val_t Alignment) { fixme("operator new with alignment(%#lx) is not implemented", Alignment); return HeapMalloc(Size); } -void operator delete(void *Pointer) { - HeapFree(Pointer); } -void operator delete[](void *Pointer) { - HeapFree(Pointer); } -void operator delete(void *Pointer, long unsigned int Size) { - HeapFree(Pointer); } -void operator delete[](void *Pointer, long unsigned int Size) { - HeapFree(Pointer); } +void operator delete(void *Pointer) +{ + HeapFree(Pointer); +} +void operator delete[](void *Pointer) +{ + HeapFree(Pointer); +} +void operator delete(void *Pointer, long unsigned int Size) +{ + HeapFree(Pointer); +} +void operator delete[](void *Pointer, long unsigned int Size) +{ + HeapFree(Pointer); +} diff --git a/Core/Memory/PhysicalMemoryManager.cpp b/Core/Memory/PhysicalMemoryManager.cpp index fd009bf..f33beab 100644 --- a/Core/Memory/PhysicalMemoryManager.cpp +++ b/Core/Memory/PhysicalMemoryManager.cpp @@ -265,7 +265,7 @@ namespace Memory trace("Reserving pages..."); this->ReservePages(0, MemorySize / PAGE_SIZE + 1); - trace("Unreserving usable pages..."); + trace("Unreserve usable pages..."); for (uint64_t i = 0; i < Info->Memory.Entries; i++) if (Info->Memory.Entry[i].Type == Usable) this->UnreservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1); diff --git a/Core/Power.cpp b/Core/Power.cpp index 60dba25..96a5721 100644 --- a/Core/Power.cpp +++ b/Core/Power.cpp @@ -14,6 +14,8 @@ namespace Power { void Power::Reboot() { + BeforeShutdown(); + if (((ACPI::ACPI *)this->acpi)->FADT) if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported) ((ACPI::DSDT *)this->dsdt)->Reboot(); @@ -42,6 +44,8 @@ namespace Power void Power::Shutdown() { + BeforeShutdown(); + if (((ACPI::ACPI *)this->acpi)->FADT) if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported) ((ACPI::DSDT *)this->dsdt)->Shutdown(); diff --git a/Core/StackGuard.c b/Core/StackGuard.c index a3cbb4b..5bc2a27 100644 --- a/Core/StackGuard.c +++ b/Core/StackGuard.c @@ -5,37 +5,32 @@ #ifndef STACK_CHK_GUARD_VALUE #if UINTPTR_MAX == UINT32_MAX -#define STACK_CHK_GUARD_VALUE 0x25F6CC8D +#define STACK_CHK_GUARD_VALUE 0xDEAD57AC #else -#define STACK_CHK_GUARD_VALUE 0xBADFE2EC255A8572 +#define STACK_CHK_GUARD_VALUE 0xDEAD57AC00000000 #endif #endif __attribute__((weak)) uintptr_t __stack_chk_guard = 0; -__attribute__((weak)) uintptr_t __stack_chk_guard_init(void) +__attribute__((weak, no_stack_protector)) uintptr_t __stack_chk_guard_init(void) { return STACK_CHK_GUARD_VALUE; } -static void __attribute__((constructor, no_stack_protector)) __construct_stk_chk_guard() +extern __attribute__((constructor, no_stack_protector)) void __guard_setup(void) { + debug("StackGuard: __guard_setup"); if (__stack_chk_guard == 0) __stack_chk_guard = __stack_chk_guard_init(); } -// https://opensource.apple.com/source/xnu/xnu-1504.7.4/libkern/stack_protector.c.auto.html -// static void __guard_setup(void) __attribute__((constructor)); - -// static void __guard_setup(void) -// { -// read_random(__stack_chk_guard, sizeof(__stack_chk_guard)); -// } - __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void) { TaskingPanic(); - error("Stack smashing detected!"); + for (short i = 0; i < 10; i++) + error("Stack smashing detected!"); + debug("%#lx", __stack_chk_guard); KPrint("\eFF0000Stack smashing detected!"); #if defined(__amd64__) || defined(__i386__) while (1) @@ -49,7 +44,8 @@ __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void) __attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void) { TaskingPanic(); - error("Buffer overflow detected!"); + for (short i = 0; i < 10; i++) + error("Buffer overflow detected!"); KPrint("\eFF0000Buffer overflow detected!"); #if defined(__amd64__) || defined(__i386__) while (1) diff --git a/Core/Symbols.cpp b/Core/Symbols.cpp index de38f6c..526ee48 100644 --- a/Core/Symbols.cpp +++ b/Core/Symbols.cpp @@ -123,7 +123,7 @@ namespace SymbolResolver Symbols::~Symbols() {} - const char *Symbols::GetSymbolFromAddress(uint64_t Address) + const __no_instrument_function char *Symbols::GetSymbolFromAddress(uint64_t Address) { Symbols::SymbolTable Result{0, (char *)""}; for (size_t i = 0; i < TotalEntries; i++) diff --git a/Core/UndefinedBehaviorSanitization.c b/Core/UndefinedBehaviorSanitization.c index 47c2fc5..62530c4 100644 --- a/Core/UndefinedBehaviorSanitization.c +++ b/Core/UndefinedBehaviorSanitization.c @@ -115,27 +115,41 @@ const char *Type_Check_Kinds[] = { "Cast to virtual base of", }; -// Prevent huge spam from ubsan bool UBSANMsg(const char *file, uint32_t line, uint32_t column) { // blacklist - if (strstr(file, "liballoc") || strstr(file, "cwalk")) + // if (strstr(file, "liballoc") || + // strstr(file, "cwalk") || + // strstr(file, "AdvancedConfigurationandPowerInterface") || + // strstr(file, "SystemManagementBIOS")) + // return false; + + if (strstr(file, "AdvancedConfigurationandPowerInterface.cpp") && + (line == 17 && column == 47)) return false; - static char *onceFile[512] = {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}; - static uint32_t onceLine[512] = {0}; - static uint32_t onceColumn[512] = {0}; - static uint32_t onceCount = 0; + if (strstr(file, "SystemManagementBIOS.cpp") && + ((line == 30 && column == 21) || + (line == 27 && column == 49) || + (line == 45 && column == 26))) + return false; - for (uint32_t i = 0; i < onceCount; i++) - if ((!strcmp(onceFile[i], file)) && onceLine[i] == line && onceColumn[i] == column) - return false; + if (strstr(file, "cwalk.c") && + ((line == 1047 && column == 15))) + return false; + + if (strstr(file, "liballoc_1_1.c")) + return false; + + if (strstr(file, "display.hpp") && + ((line == 113 && column == 43))) + return false; + + if (strstr(file, "Xalloc.hpp") && + (line == 48 && column == 28)) + return false; - onceFile[onceCount] = (char *)file; - onceLine[onceCount] = line; - onceColumn[onceCount] = column; ubsan("\t\tIn File: %s:%i:%i", file, line, column); - onceCount++; return true; } diff --git a/Core/UniversalAsynchronousReceiverTransmitter.cpp b/Core/UniversalAsynchronousReceiverTransmitter.cpp index cd6c163..88cdb2b 100644 --- a/Core/UniversalAsynchronousReceiverTransmitter.cpp +++ b/Core/UniversalAsynchronousReceiverTransmitter.cpp @@ -2,11 +2,28 @@ #include #include -#include volatile bool serialports[8] = {false, false, false, false, false, false, false, false}; Vector RegisteredEvents; +#if defined(__amd64__) || defined(__i386__) +__no_instrument_function uint8_t NoProfiler_inportb(uint16_t Port) +{ + uint8_t Result; + asm("in %%dx, %%al" + : "=a"(Result) + : "d"(Port)); + return Result; +} + +__no_instrument_function void NoProfiler_outportb(uint16_t Port, uint8_t Data) +{ + asmv("out %%al, %%dx" + : + : "a"(Data), "d"(Port)); +} +#endif + namespace UniversalAsynchronousReceiverTransmitter { #define SERIAL_ENABLE_DLAB 0x80 @@ -14,7 +31,7 @@ namespace UniversalAsynchronousReceiverTransmitter #define SERIAL_RATE_38400_HI 0x00 #define SERIAL_BUFFER_EMPTY 0x20 - UART::UART(SerialPorts Port) + SafeFunction __no_instrument_function UART::UART(SerialPorts Port) { #if defined(__amd64__) || defined(__i386__) if (Port == COMNULL) @@ -57,16 +74,16 @@ namespace UniversalAsynchronousReceiverTransmitter return; // Initialize the serial port - outb(Port + 1, 0x00); // Disable all interrupts - outb(Port + 3, SERIAL_ENABLE_DLAB); // Enable DLAB (set baud rate divisor) - outb(Port + 0, SERIAL_RATE_38400_LO); // Set divisor to 3 (lo byte) 38400 baud - outb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte) - outb(Port + 3, 0x03); // 8 bits, no parity, one stop bit - outb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - outb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set + NoProfiler_outportb(Port + 1, 0x00); // Disable all interrupts + NoProfiler_outportb(Port + 3, SERIAL_ENABLE_DLAB); // Enable DLAB (set baud rate divisor) + NoProfiler_outportb(Port + 0, SERIAL_RATE_38400_LO); // Set divisor to 3 (lo byte) 38400 baud + NoProfiler_outportb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte) + NoProfiler_outportb(Port + 3, 0x03); // 8 bits, no parity, one stop bit + NoProfiler_outportb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + NoProfiler_outportb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set // Check if the serial port is faulty. - if (inb(Port + 0) != 0xAE) + if (NoProfiler_inportb(Port + 0) != 0xAE) { static int once = 0; if (!once++) @@ -76,50 +93,50 @@ namespace UniversalAsynchronousReceiverTransmitter } // Set to normal operation mode. - outb(Port + 4, 0x0F); + NoProfiler_outportb(Port + 4, 0x0F); serialports[PortNumber] = true; #endif } - UART::~UART() {} + SafeFunction __no_instrument_function UART::~UART() {} - void UART::Write(uint8_t Char) + SafeFunction __no_instrument_function void UART::Write(uint8_t Char) { #if defined(__amd64__) || defined(__i386__) - while ((inb(Port + 5) & SERIAL_BUFFER_EMPTY) == 0) + while ((NoProfiler_inportb(Port + 5) & SERIAL_BUFFER_EMPTY) == 0) ; - outb(Port, Char); + NoProfiler_outportb(Port, Char); #endif foreach (auto e in RegisteredEvents) if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL) e->OnSent(Char); } - uint8_t UART::Read() + SafeFunction __no_instrument_function uint8_t UART::Read() { #if defined(__amd64__) || defined(__i386__) - while ((inb(Port + 5) & 1) == 0) + while ((NoProfiler_inportb(Port + 5) & 1) == 0) ; - return inb(Port); + return NoProfiler_inportb(Port); #endif foreach (auto e in RegisteredEvents) { if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL) { #if defined(__amd64__) || defined(__i386__) - e->OnReceived(inb(Port)); + e->OnReceived(NoProfiler_inportb(Port)); #endif } } } - Events::Events(SerialPorts Port) + SafeFunction __no_instrument_function Events::Events(SerialPorts Port) { this->Port = Port; RegisteredEvents.push_back(this); } - Events::~Events() + SafeFunction __no_instrument_function Events::~Events() { for (uint64_t i = 0; i < RegisteredEvents.size(); i++) if (RegisteredEvents[i] == this) diff --git a/Core/crashhandler.hpp b/Core/crashhandler.hpp index cb35514..6742c4d 100644 --- a/Core/crashhandler.hpp +++ b/Core/crashhandler.hpp @@ -2,10 +2,14 @@ #define __FENNIX_KERNEL_CRASH_HANDELR_H__ #include + +#include #include namespace CrashHandler { + extern void *EHIntFrames[INT_FRAMES_MAX]; + void EHPrint(const char *Format, ...); void Handle(void *Data); } diff --git a/DAPI.hpp b/DAPI.hpp index 1eab8d3..42a1d7a 100644 --- a/DAPI.hpp +++ b/DAPI.hpp @@ -14,6 +14,7 @@ enum DriverReturnCode NOT_ACCEPTED, INVALID_KERNEL_API, DEVICE_NOT_SUPPORTED, + SYSTEM_NOT_SUPPORTED, KERNEL_API_VERSION_NOT_SUPPORTED }; @@ -22,7 +23,8 @@ enum DriverBindType BIND_NULL, BIND_INTERRUPT, BIND_PROCESS, - BIND_PCI + BIND_PCI, + BIND_INPUT }; struct KernelAPI @@ -80,7 +82,7 @@ struct KernelAPI void (*WriteSector)(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port); } AHCI; } Disk; - } Commmand; + } Command; } __attribute__((packed)); @@ -95,7 +97,8 @@ enum CallbackReason BindReason, UnbindReason, InterruptReason, - ProcessReason + ProcessReason, + InputReason, }; struct KernelCallback @@ -130,6 +133,22 @@ struct KernelCallback } Fetch; } DiskCallback; + struct + { + struct + { + unsigned long X; + unsigned long Y; + unsigned long Z; + struct + { + bool Left; + bool Right; + bool Middle; + } Buttons; + } Mouse; + } InputCallback; + struct { unsigned char Vector; diff --git a/Fex.hpp b/Fex.hpp index 02dfb2c..9c867d9 100644 --- a/Fex.hpp +++ b/Fex.hpp @@ -87,6 +87,12 @@ struct FexExtended unsigned short SubClass; unsigned short ProgIF; } PCI; + + struct + { + bool AttachToMouse; + bool AttachToKeyboard; + } Input; } Bind; } Driver; } __attribute__((packed)); diff --git a/FileSystem/FS/ustar.cpp b/FileSystem/FS/ustar.cpp index 6a9ff98..9e3f081 100644 --- a/FileSystem/FS/ustar.cpp +++ b/FileSystem/FS/ustar.cpp @@ -19,7 +19,7 @@ namespace FileSystem return Size; } - FileSystemOpeations ustar = { + FileSystemOperations ustar = { .Name = "ustar", .Read = USTAR_Read, }; diff --git a/FileSystem/Filesystem.cpp b/FileSystem/Filesystem.cpp index 8eaa50d..aff318a 100644 --- a/FileSystem/Filesystem.cpp +++ b/FileSystem/Filesystem.cpp @@ -60,7 +60,7 @@ namespace FileSystem if (strcmp(Parent->Name, Path)) { cwk_segment segment; - if (!cwk_path_get_first_segment(Path, &segment)) + if (unlikely(!cwk_path_get_first_segment(Path, &segment))) { error("Path doesn't have any segments."); return nullptr; @@ -104,13 +104,13 @@ namespace FileSystem vfsdbg("AddNewChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name); FileSystemNode *newNode = new FileSystemNode; newNode->Parent = Parent; - strcpy(newNode->Name, Name); - if (Parent) + strncpy(newNode->Name, Name, FILENAME_LENGTH); + if (likely(Parent)) newNode->Operator = Parent->Operator; else newNode->Operator = nullptr; - if (Parent) + if (likely(Parent)) Parent->Children.push_back(newNode); vfsdbg("AddNewChild()->\"%s\"", newNode->Name); return newNode; @@ -119,7 +119,7 @@ namespace FileSystem FileSystemNode *GetChild(FileSystemNode *Parent, const char *Name) { vfsdbg("GetChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name); - if (Parent) + if (likely(Parent)) foreach (auto var in Parent->Children) if (strcmp(var->Name, Name) == 0) { @@ -181,7 +181,7 @@ namespace FileSystem char *NormalizedPath = NormalizePath(Parent, Path); FileSystemNode *Node = GetNodeFromPath(Parent, NormalizedPath); - if (Node == nullptr) + if (!Node) { vfsdbg("FileExists()->NOT_FOUND"); return FileStatus::NOT_FOUND; @@ -204,7 +204,7 @@ namespace FileSystem FileSystemNode *CurrentParent = nullptr; - if (Parent == nullptr) + if (!Parent) { if (FileSystemRoot->Children.size() >= 1) { @@ -270,27 +270,27 @@ namespace FileSystem return nullptr; } - FileSystemNode *Virtual::CreateRoot(FileSystemOpeations *Operator, const char *RootName) + FileSystemNode *Virtual::CreateRoot(FileSystemOperations *Operator, const char *RootName) { if (Operator == nullptr) return nullptr; vfsdbg("Setting root to %s", RootName); FileSystemNode *newNode = new FileSystemNode; - strcpy(newNode->Name, RootName); + strncpy(newNode->Name, RootName, FILENAME_LENGTH); newNode->Flags = NodeFlags::FS_DIRECTORY; newNode->Operator = Operator; FileSystemRoot->Children.push_back(newNode); return newNode; } - FILE *Virtual::Mount(FileSystemOpeations *Operator, const char *Path) + FILE *Virtual::Mount(FileSystemOperations *Operator, const char *Path) { SmartLock(VFSLock); - if (Operator == nullptr) + if (unlikely(!Operator)) return nullptr; - if (isempty((char *)Path)) + if (unlikely(isempty((char *)Path))) return nullptr; vfsdbg("Mounting %s", Path); @@ -306,7 +306,7 @@ namespace FileSystem FileStatus Virtual::Unmount(FILE *File) { SmartLock(VFSLock); - if (File == nullptr) + if (unlikely(File)) return FileStatus::INVALID_PARAMETER; vfsdbg("Unmounting %s", File->Name); return FileStatus::OK; @@ -322,7 +322,7 @@ namespace FileSystem FILE *file = new FILE; FileStatus filestatus = FileStatus::OK; file->Node = Parent; - if (file->Node == nullptr) + if (unlikely(!file->Node)) file->Status = FileStatus::NOT_FOUND; const char *basename; cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr); @@ -338,7 +338,7 @@ namespace FileSystem FILE *file = new FILE; FileStatus filestatus = FileStatus::OK; file->Node = Parent; - if (file->Node == nullptr) + if (!file->Node) file->Status = FileStatus::NOT_FOUND; const char *basename; cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr); @@ -388,7 +388,7 @@ namespace FileSystem } file->Node = GetNodeFromPath(FileSystemRoot->Children[0], CleanPath); - if (file->Node != nullptr) + if (file->Node) { const char *basename; cwk_path_get_basename(GetPathFromNode(file->Node), &basename, nullptr); @@ -403,7 +403,7 @@ namespace FileSystem else { file->Node = GetNodeFromPath(Parent, CleanPath); - if (file->Node == nullptr) + if (unlikely(!file->Node)) file->Status = FileStatus::NOT_FOUND; const char *basename; cwk_path_get_basename(CleanPath, &basename, nullptr); @@ -417,18 +417,18 @@ namespace FileSystem uint64_t Virtual::Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size) { SmartLock(VFSLock); - if (File == nullptr) + if (unlikely(!File)) return 0; File->Status = FileStatus::OK; - if (File->Node == nullptr) + if (unlikely(!File->Node)) { File->Status = FileStatus::INVALID_PARAMETER; return 0; } - if (File->Node->Operator == nullptr) + if (unlikely(!File->Node->Operator)) { File->Status = FileStatus::INVALID_PARAMETER; return 0; @@ -440,18 +440,18 @@ namespace FileSystem uint64_t Virtual::Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size) { SmartLock(VFSLock); - if (File == nullptr) + if (unlikely(!File)) return 0; File->Status = FileStatus::OK; - if (File->Node == nullptr) + if (unlikely(!File->Node)) { File->Status = FileStatus::INVALID_PARAMETER; return 0; } - if (File->Node->Operator == nullptr) + if (unlikely(!File->Node->Operator)) { File->Status = FileStatus::INVALID_PARAMETER; return 0; @@ -463,7 +463,7 @@ namespace FileSystem FileStatus Virtual::Close(FILE *File) { SmartLock(VFSLock); - if (File == nullptr) + if (unlikely(!File)) return FileStatus::INVALID_HANDLE; vfsdbg("Closing %s", File->Name); delete File; @@ -477,12 +477,12 @@ namespace FileSystem FileSystemRoot->Flags = NodeFlags::FS_MOUNTPOINT; FileSystemRoot->Operator = nullptr; FileSystemRoot->Parent = nullptr; - strcpy(FileSystemRoot->Name, "root"); + strncpy(FileSystemRoot->Name, "root", 4); cwk_path_set_style(CWK_STYLE_UNIX); } Virtual::~Virtual() { - warn("Tried to uninitialize Virtual File System!"); + warn("Tried to deinitialize Virtual File System!"); } } diff --git a/KConfig.cpp b/KConfig.cpp index 775d1ca..bd61490 100644 --- a/KConfig.cpp +++ b/KConfig.cpp @@ -49,11 +49,17 @@ static struct cag_option ConfigOptions[] = { .value_name = "PATH", .description = "Path to init program"}, + {.identifier = 'l', + .access_letters = NULL, + .access_name = "udl", + .value_name = "BOOL", + .description = "Unlock the deadlock after 10 retries"}, + {.identifier = 'o', .access_letters = NULL, .access_name = "ioc", .value_name = "BOOL", - .description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash."}, + .description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash"}, {.identifier = 'h', .access_letters = "h", @@ -71,7 +77,8 @@ KernelConfig ParseConfig(char *Config) {'/', 's', 'y', 's', 't', 'e', 'm', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'}, {'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'}, false, - 0}; + 0, + false}; if (Config == NULL) { @@ -331,14 +338,14 @@ ParseSuccess: case 'd': { value = cag_option_get_value(&context); - strcpy(config.DriverDirectory, value); + strncpy(config.DriverDirectory, value, strlen(value)); KPrint("\eAAFFAAUsing %s as driver directory", value); break; } case 'i': { value = cag_option_get_value(&context); - strcpy(config.InitPath, value); + strncpy(config.InitPath, value, strlen(value)); KPrint("\eAAFFAAUsing %s as init program", value); break; } @@ -349,6 +356,13 @@ ParseSuccess: KPrint("\eAAFFAAInterrupts on crash: %s", value); break; } + case 'l': + { + value = cag_option_get_value(&context); + strcmp(value, "true") ? config.UnlockDeadLock = false : config.UnlockDeadLock = true; + KPrint("\eAAFFAAUnlocking the deadlock after 10 retires"); + break; + } case 'h': { KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration."); diff --git a/KThread.cpp b/KThread.cpp index 6df4fb5..b0c0cb5 100644 --- a/KThread.cpp +++ b/KThread.cpp @@ -14,65 +14,33 @@ Driver::Driver *DriverManager = nullptr; Disk::Manager *DiskManager = nullptr; -void StartFilesystem() -{ - KPrint("Initializing Filesystem..."); - vfs = new FileSystem::Virtual; - new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd - KPrint("Initializing Disk Manager..."); - DiskManager = new Disk::Manager; - /* ... */ - TEXIT(0); -} - -void LoadDrivers() -{ - KPrint("Loading Drivers..."); - DriverManager = new Driver::Driver; - TEXIT(0); -} - -void FetchDisks() -{ - KPrint("Fetching Disks..."); - foreach (auto Driver in DriverManager->GetDrivers()) - { - FexExtended *DrvExtHdr = (FexExtended *)((uint64_t)Driver->Address + EXTENDED_SECTION_ADDRESS); - - if (DrvExtHdr->Driver.Type == FexDriverType::FexDriverType_Storage) - DiskManager->FetchDisks(Driver->DriverUID); - } - TEXIT(0); -} - void KernelMainThread() { TaskManager->InitIPC(); + TaskManager->GetCurrentThread()->SetPriority(100); Vector auxv; Tasking::TCB *CurrentWorker = nullptr; KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD); KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus); - TaskManager->GetCurrentThread()->SetPriority(1); - CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem, nullptr, nullptr, auxv); - CurrentWorker->Rename("Filesystems"); - CurrentWorker->SetPriority(100); - TaskManager->WaitForThread(CurrentWorker); + KPrint("Initializing Filesystem..."); + vfs = new FileSystem::Virtual; + new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd + KPrint("Initializing Disk Manager..."); + DiskManager = new Disk::Manager; - CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)LoadDrivers, nullptr, nullptr, auxv); - CurrentWorker->Rename("Drivers"); - CurrentWorker->SetPriority(100); - TaskManager->WaitForThread(CurrentWorker); + KPrint("Loading Drivers..."); + DriverManager = new Driver::Driver; - CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks, nullptr, nullptr, auxv); - CurrentWorker->Rename("Disks"); - CurrentWorker->SetPriority(100); - TaskManager->WaitForThread(CurrentWorker); + KPrint("Fetching Disks..."); + foreach (auto Driver in DriverManager->GetDrivers()) + if (((FexExtended *)((uint64_t)Driver->Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Storage) + DiskManager->FetchDisks(Driver->DriverUID); KPrint("Setting up userspace..."); - const char *envp[] = { + const char *envp[9] = { "PATH=/system:/system/bin", "TERM=tty", "HOME=/", @@ -83,12 +51,11 @@ void KernelMainThread() "TZ=UTC", nullptr}; - const char *argv[] = { + const char *argv[3] = { "--init", "--critical", nullptr}; - // TODO: Untested! bool ien = CPU::Interrupts(CPU::Check); CPU::Interrupts(CPU::Disable); Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argv, envp); @@ -100,9 +67,12 @@ void KernelMainThread() goto Exit; } ret.Thread->SetCritical(true); + debug("%s interrupts", ien ? "Enabling" : "Disabling"); if (ien) CPU::Interrupts(CPU::Enable); + debug("After interrupts boolean"); KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath); + TaskManager->GetCurrentThread()->SetPriority(1); TaskManager->WaitForThread(ret.Thread); KPrint("\eE85230Userspace process exited with code %d", ret.Thread->GetExitCode()); error("Userspace process exited with code %d (%#x)", ret.Thread->GetExitCode(), ret.Thread->GetExitCode()); diff --git a/Kernel.cpp b/Kernel.cpp index 3f822d2..138b73a 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -27,6 +27,8 @@ FileSystem::Virtual *vfs = nullptr; KernelConfig Config; Time::Clock BootClock; +extern bool EnableProfiler; + // For the Display class. Printing on first buffer as default. EXTERNC void putchar(char c) { Display->Print(c, 0); } @@ -43,10 +45,8 @@ EXTERNC void KPrint(const char *Format, ...) Display->SetBuffer(0); } -EXTERNC void Entry(BootInfo *Info) +EXTERNC __no_instrument_function void PostEntry(BootInfo *Info) { - trace("Hello, World!"); - InitializeMemoryManagement(Info); BootClock = Time::ReadClock(); bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo))); memcpy(bInfo, Info, sizeof(BootInfo)); @@ -167,6 +167,34 @@ EXTERNC void Entry(BootInfo *Info) CPU::Halt(true); } +EXTERNC void __guard_setup(void); + +typedef void (*CallPtr)(void); +extern CallPtr __init_array_start[0], __init_array_end[0]; +extern CallPtr __fini_array_start[0], __fini_array_end[0]; + +EXTERNC __no_stack_protector __no_instrument_function void Entry(BootInfo *Info) +{ + trace("Hello, World!"); + + // https://wiki.osdev.org/Calling_Global_Constructors + for (CallPtr *func = __init_array_start; func != __init_array_end; func++) + (*func)(); + + InitializeMemoryManagement(Info); + EnableProfiler = true; + PostEntry(Info); +} + +EXTERNC __no_stack_protector __no_instrument_function void BeforeShutdown() +{ + // https://wiki.osdev.org/Calling_Global_Constructors + debug("Calling destructors..."); + for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++) + (*func)(); + debug("Done."); +} + EXTERNC void TaskingPanic() { if (TaskManager) diff --git a/Library/Convert.c b/Library/Convert.c index 46d1374..c59edbc 100644 --- a/Library/Convert.c +++ b/Library/Convert.c @@ -1,6 +1,7 @@ #include -#include + #include +#include // TODO: Replace mem* with assembly code @@ -29,7 +30,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -void *memcpy(void *dest, const void *src, size_t n) +void *memcpy_unsafe(void *dest, const void *src, size_t n) { unsigned char *d = dest; const unsigned char *s = src; @@ -193,7 +194,7 @@ void *memcpy(void *dest, const void *src, size_t n) return dest; } -void *memset(void *dest, int c, size_t n) +void *memset_unsafe(void *dest, int c, size_t n) { unsigned char *s = dest; size_t k; @@ -264,7 +265,7 @@ void *memset(void *dest, int c, size_t n) return dest; } -void *memmove(void *dest, const void *src, size_t n) +void *memmove_unsafe(void *dest, const void *src, size_t n) { #ifdef __GNUC__ typedef __attribute__((__may_alias__)) size_t WT; @@ -362,9 +363,9 @@ long unsigned strlen(const char s[]) return i; } -char *strcat(char *destination, const char *source) +char *strcat_unsafe(char *destination, const char *source) { - if ((destination == NULL) && (source == NULL)) + if ((destination == NULL) || (source == NULL)) return NULL; char *start = destination; while (*start != '\0') @@ -379,7 +380,7 @@ char *strcat(char *destination, const char *source) return destination; } -char *strcpy(char *destination, const char *source) +char *strcpy_unsafe(char *destination, const char *source) { if (destination == NULL) return NULL; @@ -446,7 +447,7 @@ char *strchr(const char *String, int Char) char *strdup(const char *String) { char *OutBuffer = kmalloc(strlen((char *)String) + 1); - strcpy(OutBuffer, String); + strncpy(OutBuffer, String, strlen(String) + 1); return OutBuffer; } @@ -611,3 +612,232 @@ char *itoa(int Value, char *Buffer, int Base) Buffer[i] = '\0'; return reverse(Buffer, 0, i - 1); } + +char *ltoa(long Value, char *Buffer, int Base) +{ + if (Base < 2 || Base > 32) + return Buffer; + + long n = abs(Value); + int i = 0; + + while (n) + { + int r = n % Base; + if (r >= 10) + Buffer[i++] = 65 + (r - 10); + else + Buffer[i++] = 48 + r; + n = n / Base; + } + + if (i == 0) + Buffer[i++] = '0'; + + if (Value < 0 && Base == 10) + Buffer[i++] = '-'; + + Buffer[i] = '\0'; + return reverse(Buffer, 0, i - 1); +} + +char *ultoa(unsigned long Value, char *Buffer, int Base) +{ + if (Base < 2 || Base > 32) + return Buffer; + + unsigned long n = Value; + int i = 0; + + while (n) + { + int r = n % Base; + if (r >= 10) + Buffer[i++] = 65 + (r - 10); + else + Buffer[i++] = 48 + r; + n = n / Base; + } + + if (i == 0) + Buffer[i++] = '0'; + + Buffer[i] = '\0'; + return reverse(Buffer, 0, i - 1); +} + +extern void __chk_fail(void) __attribute__((__noreturn__)); + +// #define DBG_CHK 1 + +__no_stack_protector void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen) +{ +#ifdef DBG_CHK + debug("( dest:%#lx src:%#lx len:%llu slen:%llu )", dest, src, len, slen); +#endif + if (unlikely(dest == NULL)) + { + error("dest is NULL"); + while (1) + ; + } + + if (unlikely(src == NULL)) + { + error("src is NULL"); + while (1) + ; + } + + if (unlikely(len == 0)) + { + error("len is 0"); + while (1) + ; + } + + if (unlikely(slen == 0)) + { + error("slen is 0"); + while (1) + ; + } + + if (unlikely(len > slen)) + __chk_fail(); + return memcpy_unsafe(dest, src, len); +} + +__no_stack_protector void *__memset_chk(void *dest, int val, size_t len, size_t slen) +{ +#ifdef DBG_CHK + debug("( dest:%#lx val:%#x len:%llu slen:%llu )", dest, val, len, slen); +#endif + if (unlikely(dest == NULL)) + { + error("dest is NULL"); + while (1) + ; + } + + if (unlikely(len == 0)) + { + error("len is 0"); + while (1) + ; + } + + if (unlikely(slen == 0)) + { + error("slen is 0"); + while (1) + ; + } + + if (unlikely(len > slen)) + __chk_fail(); + return memset_unsafe(dest, val, len); +} + +__no_stack_protector void *__memmove_chk(void *dest, const void *src, size_t len, size_t slen) +{ +#ifdef DBG_CHK + debug("( dest:%#lx src:%#lx len:%llu slen:%llu )", dest, src, len, slen); +#endif + if (unlikely(dest == NULL)) + { + error("dest is NULL"); + while (1) + ; + } + + if (unlikely(src == NULL)) + { + error("src is NULL"); + while (1) + ; + } + + if (unlikely(len == 0)) + { + error("len is 0"); + while (1) + ; + } + + if (unlikely(slen == 0)) + { + error("slen is 0"); + while (1) + ; + } + + if (unlikely(len > slen)) + __chk_fail(); + return memmove_unsafe(dest, src, len); +} + +__no_stack_protector char *__strcat_chk(char *dest, const char *src, size_t slen) +{ +#ifdef DBG_CHK + debug("( dest:%#lx src:%#lx slen:%llu )", dest, src, slen); +#endif + if (unlikely(dest == NULL)) + { + error("dest is NULL"); + while (1) + ; + } + + if (unlikely(src == NULL)) + { + error("src is NULL"); + while (1) + ; + } + + if (unlikely(slen == 0)) + { + error("slen is 0"); + while (1) + ; + } + + size_t dest_len = strlen(dest); + if (unlikely(dest_len + strlen(src) + 1 > slen)) + __chk_fail(); + return strcat_unsafe(dest, src); +} + +__no_stack_protector char *__strcpy_chk(char *dest, const char *src, size_t slen) +{ +#ifdef DBG_CHK + debug("( dest:%#lx src:%#lx slen:%llu )", dest, src, slen); +#endif + if (unlikely(dest == NULL)) + { + error("dest is NULL"); + while (1) + ; + } + + if (unlikely(src == NULL)) + { + error("src is NULL"); + while (1) + ; + } + + if (unlikely(slen == 0)) + { + error("slen is 0"); + while (1) + ; + } + + size_t len = strlen(src); + + if (unlikely(len >= slen)) + __chk_fail(); + return strcpy_unsafe(dest, src); +} diff --git a/Library/md5.c b/Library/md5.c index e02547b..dee7059 100644 --- a/Library/md5.c +++ b/Library/md5.c @@ -208,6 +208,8 @@ uint8_t *md5String(char *input) md5Finalize(&ctx); uint8_t *result = kmalloc(16); + if (result == NULL) + return (uint8_t *)"error"; memcpy(result, ctx.digest, 16); return result; } @@ -236,6 +238,8 @@ uint8_t *md5File(uint8_t *buffer, size_t input_len) md5Finalize(&ctx); uint8_t *result = kmalloc(16); + if (result == NULL) + return (uint8_t *)"error"; memcpy(result, ctx.digest, 16); return result; } diff --git a/Library/printf.c b/Library/printf.c index 73c3c9e..e61d33f 100644 --- a/Library/printf.c +++ b/Library/printf.c @@ -266,14 +266,14 @@ typedef union // 1. Some compilers are finicky about this; // 2. Some people may want to convert this to C89; // 3. If you try to use it as C++, only C++20 supports compound literals -static inline double_with_bit_access get_bit_access(double x) +static inline __no_instrument_function double_with_bit_access get_bit_access(double x) { double_with_bit_access dwba; dwba.F = x; return dwba; } -static inline int get_sign_bit(double x) +static inline __no_instrument_function int get_sign_bit(double x) { // The sign is stored in the highest bit return (int)(get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1)); @@ -317,7 +317,7 @@ typedef struct // or alternatively, that '\0' can be passed to the function in the output // gadget. The former assumption holds within the printf library. It also // assumes that the output gadget has been properly initialized. -static inline void putchar_via_gadget(output_gadget_t *gadget, char c) +static inline __no_instrument_function void putchar_via_gadget(output_gadget_t *gadget, char c) { printf_size_t write_pos = gadget->pos++; // We're _always_ increasing pos, so as to count how may characters @@ -340,7 +340,7 @@ static inline void putchar_via_gadget(output_gadget_t *gadget, char c) } // Possibly-write the string-terminating '\0' character -static inline void append_termination_with_gadget(output_gadget_t *gadget) +static inline __no_instrument_function void append_termination_with_gadget(output_gadget_t *gadget) { if (gadget->function != NULL || gadget->max_chars == 0) { @@ -356,13 +356,13 @@ static inline void append_termination_with_gadget(output_gadget_t *gadget) // We can't use putchar_ as is, since our output gadget // only takes pointers to functions with an extra argument -static inline void putchar_wrapper(char c, void *unused) +static inline __no_instrument_function void putchar_wrapper(char c, void *unused) { (void)unused; putchar(c); } -static inline output_gadget_t discarding_gadget(void) +static inline __no_instrument_function output_gadget_t discarding_gadget(void) { output_gadget_t gadget; gadget.function = NULL; @@ -373,7 +373,7 @@ static inline output_gadget_t discarding_gadget(void) return gadget; } -static inline output_gadget_t buffer_gadget(char *buffer, size_t buffer_size) +static inline __no_instrument_function output_gadget_t buffer_gadget(char *buffer, size_t buffer_size) { printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ? PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t)buffer_size; output_gadget_t result = discarding_gadget(); @@ -385,7 +385,7 @@ static inline output_gadget_t buffer_gadget(char *buffer, size_t buffer_size) return result; } -static inline output_gadget_t function_gadget(void (*function)(char, void *), void *extra_arg) +static inline __no_instrument_function output_gadget_t function_gadget(void (*function)(char, void *), void *extra_arg) { output_gadget_t result = discarding_gadget(); result.function = function; @@ -394,7 +394,7 @@ static inline output_gadget_t function_gadget(void (*function)(char, void *), vo return result; } -static inline output_gadget_t extern_putchar_gadget(void) +static inline __no_instrument_function output_gadget_t extern_putchar_gadget(void) { return function_gadget(putchar_wrapper, NULL); } @@ -403,7 +403,7 @@ static inline output_gadget_t extern_putchar_gadget(void) // @return The length of the string (excluding the terminating 0) limited by 'maxsize' // @note strlen uses size_t, but wes only use this function with printf_size_t // variables - hence the signature. -static inline printf_size_t strnlen_s_(const char *str, printf_size_t maxsize) +static inline __no_instrument_function printf_size_t strnlen_s_(const char *str, printf_size_t maxsize) { const char *s; for (s = str; *s && maxsize--; ++s) @@ -413,13 +413,13 @@ static inline printf_size_t strnlen_s_(const char *str, printf_size_t maxsize) // internal test if char is a digit (0-9) // @return true if char is a digit -static inline bool is_digit_(char ch) +static inline __no_instrument_function bool is_digit_(char ch) { return (ch >= '0') && (ch <= '9'); } // internal ASCII string to printf_size_t conversion -static printf_size_t atou_(const char **str) +static __no_instrument_function printf_size_t atou_(const char **str) { printf_size_t i = 0U; while (is_digit_(**str)) @@ -430,7 +430,7 @@ static printf_size_t atou_(const char **str) } // output the specified string in reverse, taking care of any zero-padding -static void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len, printf_size_t width, printf_flags_t flags) +static __no_instrument_function void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len, printf_size_t width, printf_flags_t flags) { const printf_size_t start_pos = output->pos; @@ -461,7 +461,7 @@ static void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len // Invoked by print_integer after the actual number has been printed, performing necessary // work on the number's prefix (as the number is initially printed in reverse order) -static void print_integer_finalization(output_gadget_t *output, char *buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) +static __no_instrument_function void print_integer_finalization(output_gadget_t *output, char *buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) { printf_size_t unpadded_len = len; @@ -545,7 +545,7 @@ static void print_integer_finalization(output_gadget_t *output, char *buf, print } // An internal itoa-like function -static void print_integer(output_gadget_t *output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) +static __no_instrument_function void print_integer(output_gadget_t *output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) { char buf[PRINTF_INTEGER_BUFFER_SIZE]; printf_size_t len = 0U; @@ -604,7 +604,7 @@ static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { // Break up a double number - which is known to be a finite non-negative number - // into its base-10 parts: integral - before the decimal point, and fractional - after it. // Taken the precision into account, but does not change it even internally. -static struct double_components get_components(double number, printf_size_t precision) +static struct __no_instrument_function double_components get_components(double number, printf_size_t precision) { struct double_components number_; number_.is_negative = get_sign_bit(number); @@ -741,7 +741,7 @@ static struct double_components get_normalized_components(bool negative, printf_ } #endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS -static void print_broken_up_decimal( +static __no_instrument_function void print_broken_up_decimal( struct double_components number_, output_gadget_t *output, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) { @@ -843,7 +843,7 @@ static void print_broken_up_decimal( } // internal ftoa for fixed decimal floating point -static void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) +static __no_instrument_function void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) { struct double_components value_ = get_components(number, precision); print_broken_up_decimal(value_, output, precision, width, flags, buf, len); @@ -916,7 +916,7 @@ static double pow10_of_int(int floored_exp10) return dwba.F; } -static void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) +static __no_instrument_function void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) { const bool negative = get_sign_bit(number); // This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it @@ -1039,7 +1039,7 @@ static void print_exponential_number(output_gadget_t *output, double number, pri } #endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS -static void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential) +static __no_instrument_function void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential) { char buf[PRINTF_DECIMAL_BUFFER_SIZE]; printf_size_t len = 0U; @@ -1098,7 +1098,7 @@ static void print_floating_point(output_gadget_t *output, double value, printf_s // Advances the format pointer past the flags, and returns the parsed flags // due to the characters passed -static printf_flags_t parse_flags(const char **format) +static __no_instrument_function printf_flags_t parse_flags(const char **format) { printf_flags_t flags = 0U; do @@ -1131,7 +1131,7 @@ static printf_flags_t parse_flags(const char **format) } while (true); } -static inline void format_string_loop(output_gadget_t *output, const char *format, va_list args) +static inline __no_instrument_function void format_string_loop(output_gadget_t *output, const char *format, va_list args) { #if PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER #define ADVANCE_IN_FORMAT_STRING(cptr_) \ @@ -1513,7 +1513,7 @@ static inline void format_string_loop(output_gadget_t *output, const char *forma } // internal vsnprintf - used for implementing _all library functions -static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args) +static __no_instrument_function int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args) { // Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is // possible to call this function with a non-zero pos value for some "remedial printing". @@ -1528,30 +1528,30 @@ static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list a /////////////////////////////////////////////////////////////////////////////// -int vprintf_(const char *format, va_list arg) +__no_instrument_function int vprintf_(const char *format, va_list arg) { output_gadget_t gadget = extern_putchar_gadget(); return vsnprintf_impl(&gadget, format, arg); } -int vsnprintf_(char *s, size_t n, const char *format, va_list arg) +__no_instrument_function int vsnprintf_(char *s, size_t n, const char *format, va_list arg) { output_gadget_t gadget = buffer_gadget(s, n); return vsnprintf_impl(&gadget, format, arg); } -int vsprintf_(char *s, const char *format, va_list arg) +__no_instrument_function int vsprintf_(char *s, const char *format, va_list arg) { return vsnprintf_(s, PRINTF_MAX_POSSIBLE_BUFFER_SIZE, format, arg); } -int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg) +__no_instrument_function int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg) { output_gadget_t gadget = function_gadget(out, extra_arg); return vsnprintf_impl(&gadget, format, arg); } -int printf_(const char *format, ...) +__no_instrument_function int printf_(const char *format, ...) { va_list args; va_start(args, format); @@ -1560,7 +1560,7 @@ int printf_(const char *format, ...) return ret; } -int sprintf_(char *s, const char *format, ...) +__no_instrument_function int sprintf_(char *s, const char *format, ...) { va_list args; va_start(args, format); @@ -1569,7 +1569,7 @@ int sprintf_(char *s, const char *format, ...) return ret; } -int snprintf_(char *s, size_t n, const char *format, ...) +__no_instrument_function int snprintf_(char *s, size_t n, const char *format, ...) { va_list args; va_start(args, format); @@ -1578,7 +1578,7 @@ int snprintf_(char *s, size_t n, const char *format, ...) return ret; } -int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...) +__no_instrument_function int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...) { va_list args; va_start(args, format); diff --git a/Makefile b/Makefile index 7232406..dbc3b9f 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,8 @@ CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/a endif HEADERS = $(sort $(dir $(wildcard ./include/*))) OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o) +STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su) +GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CPP_SOURCES:.cpp=.gcno) INCLUDE_DIR = ./include LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc @@ -79,7 +81,7 @@ LDFLAGS += -TArchitecture/i686/linker.ld \ else ifeq ($(OSARCH), aarch64) CFLAGS += -pipe -fno-builtin -fPIC -CFLAG_STACK_PROTECTOR := -fstack-protector-all +CFLAG_STACK_PROTECTOR := -fstack-protector-all -fstack-clash-protection LDFLAGS += -TArchitecture/aarch64/linker.ld -fPIC endif @@ -92,8 +94,12 @@ else ifeq ($(OSARCH), aarch64) NASMFLAGS := endif +# -finstrument-functions for __cyg_profile_func_enter & __cyg_profile_func_exit. Used for profiling and debugging. ifeq ($(DEBUG), 1) - CFLAGS += -DDEBUG -ggdb -O0 -fdiagnostics-color=always -fsanitize=undefined +# CFLAGS += --coverage +# CFLAGS += -pg +# CFLAGS += -finstrument-functions + CFLAGS += -DDEBUG -ggdb -g -O0 -fdiagnostics-color=always -fverbose-asm -fstack-usage -fstack-check -fsanitize=undefined LDFLAGS += -ggdb -O0 -g NASMFLAGS += -F dwarf -g WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable @@ -117,9 +123,9 @@ ifeq (,$(wildcard $(KERNEL_FILENAME))) $(error $(KERNEL_FILENAME) does not exist) endif $(info Dumping $(KERNEL_FILENAME) in AT T syntax...) - $(OBJDUMP) -D -d $(KERNEL_FILENAME) > kernel_dump.map + $(OBJDUMP) -D -g -s -d $(KERNEL_FILENAME) > kernel_dump.map $(info Dumping $(KERNEL_FILENAME) in Intel syntax...) - $(OBJDUMP) -M intel -D -d $(KERNEL_FILENAME) > kernel_dump_intel.map + $(OBJDUMP) -M intel -D -g -s -d $(KERNEL_FILENAME) > kernel_dump_intel.map $(KERNEL_FILENAME): $(OBJ) $(CC) $(LDFLAGS) $(OBJ) -o $@ @@ -168,4 +174,4 @@ endif $(NM) $@ clean: - rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(KERNEL_FILENAME) + rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(STACK_USAGE_OBJ) $(GCNO_OBJ) $(KERNEL_FILENAME) diff --git a/Profiling/cyg.cpp b/Profiling/cyg.cpp new file mode 100644 index 0000000..87577e3 --- /dev/null +++ b/Profiling/cyg.cpp @@ -0,0 +1,87 @@ +#include +#include +#include + +#include "../kernel.h" + +bool EnableProfiler = false; +bool Wait = false; +unsigned long long LogDepth = 0; +unsigned int Level = 0; +using namespace UniversalAsynchronousReceiverTransmitter; + +static inline SafeFunction __no_instrument_function void profiler_uart_wrapper(char c, void *unused) +{ + bool renable = EnableProfiler; + EnableProfiler = false; + UART(COM2).Write(c); + (void)unused; + if (renable) + EnableProfiler = true; +} + +EXTERNC SafeFunction __no_instrument_function void __cyg_profile_func_enter(void *Function, void *CallSite) +{ + if (!EnableProfiler) + return; + + while (Wait) + asmv("pause"); + Wait = true; + + if (Level > 40) + Level--; + + Level++; + + if (!KernelSymbolTable) + fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[42m->\033[0m%*c \033[33m%p\033[0m - \033[33m%p\033[0m\n", + LogDepth++, + Level - 1, + Level, + ' ', + Function, + CallSite); + else + fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[42m->\033[0m%*c \033[33m%s\033[0m - \033[33m%s\033[0m\n", + LogDepth++, + Level - 1, + Level, + ' ', + KernelSymbolTable->GetSymbolFromAddress((uint64_t)Function), + KernelSymbolTable->GetSymbolFromAddress((uint64_t)CallSite)); + Wait = false; +} + +EXTERNC SafeFunction __no_instrument_function void __cyg_profile_func_exit(void *Function, void *CallSite) +{ + if (!EnableProfiler) + return; + + while (Wait) + asmv("pause"); + Wait = true; + + if (Level > 40) + Level--; + + Level--; + + if (!KernelSymbolTable) + fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[41m<-\033[0m%*c \033[33m%p\033[0m - \033[33m%p\033[0m\n", + LogDepth++, + Level - 1, + Level, + ' ', + Function, + CallSite); + else + fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[41m<-\033[0m%*c \033[33m%s\033[0m - \033[33m%s\033[0m\n", + LogDepth++, + Level - 1, + Level, + ' ', + KernelSymbolTable->GetSymbolFromAddress((uint64_t)Function), + KernelSymbolTable->GetSymbolFromAddress((uint64_t)CallSite)); + Wait = false; +} diff --git a/Profiling/gcov.cpp b/Profiling/gcov.cpp new file mode 100644 index 0000000..7769e8d --- /dev/null +++ b/Profiling/gcov.cpp @@ -0,0 +1,67 @@ +#include +#include +#include + +#include "../kernel.h" + +using namespace UniversalAsynchronousReceiverTransmitter; + +#if BITS_PER_LONG >= 64 +typedef long gcov_type; +#else +typedef long long gcov_type; +#endif + +struct gcov_fn_info +{ + unsigned int ident; + unsigned int checksum; + unsigned int n_ctrs[0]; +}; + +struct gcov_ctr_info +{ + unsigned int num; + gcov_type *values; + void (*merge)(gcov_type *, unsigned int); +}; + +struct gcov_info +{ + unsigned int version; + struct gcov_info *next; + unsigned int stamp; + const char *filename; + unsigned int n_functions; + const struct gcov_fn_info *functions; + unsigned int ctr_mask; + struct gcov_ctr_info counts[0]; +}; + +static inline SafeFunction __no_instrument_function void gcov_uart_wrapper(char c, void *unused) +{ + UART(COM2).Write(c); + (void)unused; +} + +// TODO: Implement + +EXTERNC SafeFunction __no_instrument_function void __gcov_init(gcov_info *p __unused) +{ +} + +EXTERNC SafeFunction __no_instrument_function void __gcov_exit(void) +{ +} + +EXTERNC SafeFunction __no_instrument_function void __gcov_flush(void) +{ +} + +EXTERNC SafeFunction __no_instrument_function void __gcov_merge_add(gcov_type *counters, unsigned int n_counters) +{ +} + +EXTERNC SafeFunction __no_instrument_function void __gcov_merge_single(gcov_type *counters, unsigned int n_counters) +{ +} diff --git a/Profiling/gprof.cpp b/Profiling/gprof.cpp new file mode 100644 index 0000000..40f03d7 --- /dev/null +++ b/Profiling/gprof.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +#include "../kernel.h" + +using namespace UniversalAsynchronousReceiverTransmitter; + +static inline SafeFunction __no_instrument_function void gprof_uart_wrapper(char c, void *unused) +{ + UART(COM2).Write(c); + (void)unused; +} + +EXTERNC SafeFunction __no_instrument_function void mcount(unsigned long frompc, unsigned long selfpc) +{ + // TODO: Implement + /* https://docs.kernel.org/trace/ftrace-design.html */ +} diff --git a/Recovery/RecoveryMain.cpp b/Recovery/RecoveryMain.cpp new file mode 100644 index 0000000..3f56df8 --- /dev/null +++ b/Recovery/RecoveryMain.cpp @@ -0,0 +1,2 @@ +#include + diff --git a/Tasking/InterProcessCommunication.cpp b/Tasking/InterProcessCommunication.cpp index 46e6988..4fef971 100644 --- a/Tasking/InterProcessCommunication.cpp +++ b/Tasking/InterProcessCommunication.cpp @@ -126,24 +126,10 @@ namespace InterProcessCommunication return IPCError{IPCIDNotFound}; } - void IPCServiceStub() - { - trace("IPC Service Started."); - TaskManager->GetCurrentThread()->SetPriority(1); - // TODO: do something useful here, like, IPC event viewer or smth... - while (1) - { - // The scheduler doesn't like CPU::Pause for some reason. :/ - } - } - IPC::IPC() { SmartLock(IPCLock); trace("Starting IPC Service..."); - Vector auxv; - Tasking::TCB *thd = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, nullptr, nullptr, auxv); - thd->Rename("IPC Service"); } IPC::~IPC() diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index a1b1142..bdeebfd 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -29,7 +29,7 @@ NewLock(SchedulerLock); namespace Tasking { - extern "C" __no_stack_protector void OneShot(int TimeSlice) + extern "C" SafeFunction __no_instrument_function void OneShot(int TimeSlice) { if (TimeSlice == 0) TimeSlice = 10; @@ -42,14 +42,15 @@ namespace Tasking void Task::Schedule() { - OneShot(100); + if (!StopScheduler) + OneShot(100); // APIC::InterruptCommandRegisterLow icr; // icr.Vector = CPU::x64::IRQ16; // icr.Level = APIC::APICLevel::Assert; // ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr); } - __attribute__((naked, used, no_stack_protector)) void IdleProcessLoop() + __naked __used __no_stack_protector __no_instrument_function void IdleProcessLoop() { #if defined(__amd64__) || defined(__i386__) asmv("IdleLoop:\n" @@ -62,7 +63,7 @@ namespace Tasking #endif } - __no_stack_protector bool Task::InvalidPCB(PCB *pcb) + SafeFunction __no_instrument_function bool Task::InvalidPCB(PCB *pcb) { if (!pcb) return true; @@ -73,7 +74,7 @@ namespace Tasking return false; } - __no_stack_protector bool Task::InvalidTCB(TCB *tcb) + SafeFunction __no_instrument_function bool Task::InvalidTCB(TCB *tcb) { if (!tcb) return true; @@ -84,7 +85,7 @@ namespace Tasking return false; } - __no_stack_protector void Task::RemoveThread(TCB *Thread) + SafeFunction __no_instrument_function void Task::RemoveThread(TCB *Thread) { for (uint64_t i = 0; i < Thread->Parent->Threads.size(); i++) if (Thread->Parent->Threads[i] == Thread) @@ -101,7 +102,7 @@ namespace Tasking } } - __no_stack_protector void Task::RemoveProcess(PCB *Process) + SafeFunction __no_instrument_function void Task::RemoveProcess(PCB *Process) { if (Process == nullptr) return; @@ -139,19 +140,19 @@ namespace Tasking } } - __no_stack_protector void Task::UpdateUserTime(TaskInfo *Info) + SafeFunction __no_instrument_function void Task::UpdateUserTime(TaskInfo *Info) { // TODO Info->UserTime++; } - __no_stack_protector void Task::UpdateKernelTime(TaskInfo *Info) + SafeFunction __no_instrument_function void Task::UpdateKernelTime(TaskInfo *Info) { // TODO Info->KernelTime++; } - __no_stack_protector void Task::UpdateUsage(TaskInfo *Info, int Core) + SafeFunction __no_instrument_function void Task::UpdateUsage(TaskInfo *Info, int Core) { if (Info->Affinity[Core] == true) { @@ -176,7 +177,7 @@ namespace Tasking } #if defined(__amd64__) - __no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) + SafeFunction __no_instrument_function bool Task::FindNewProcess(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; schedbg("%d processes", ListProcess.size()); @@ -225,7 +226,7 @@ namespace Tasking return false; } - __no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) + SafeFunction __no_instrument_function bool Task::GetNextAvailableThread(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -265,7 +266,7 @@ namespace Tasking return false; } - __no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) + SafeFunction __no_instrument_function bool Task::GetNextAvailableProcess(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -308,7 +309,7 @@ namespace Tasking return false; } - __no_stack_protector void Task::SchedulerCleanupProcesses() + SafeFunction __no_instrument_function void Task::SchedulerCleanupProcesses() { foreach (PCB *pcb in ListProcess) { @@ -318,7 +319,7 @@ namespace Tasking } } - __no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) + SafeFunction __no_instrument_function bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -346,7 +347,7 @@ namespace Tasking return false; } - __no_stack_protector void Task::Schedule(CPU::x64::TrapFrame *Frame) + SafeFunction __no_instrument_function void Task::Schedule(CPU::x64::TrapFrame *Frame) { SmartCriticalSection(SchedulerLock); if (StopScheduler) @@ -491,9 +492,10 @@ namespace Tasking if (CurrentCPU->CurrentThread->Registers.cs != GDT_USER_CODE || CurrentCPU->CurrentThread->Registers.ss != GDT_USER_DATA) { - warn("Wrong CS or SS for user process! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx)", + warn("Wrong CS or SS for user thread %s(%ld)! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx)", CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss, - GDT_USER_CODE, GDT_USER_DATA); + GDT_USER_CODE, GDT_USER_DATA, + CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID); CurrentCPU->CurrentThread->Registers.cs = GDT_USER_CODE; CurrentCPU->CurrentThread->Registers.ss = GDT_USER_DATA; } @@ -503,9 +505,10 @@ namespace Tasking if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE || CurrentCPU->CurrentThread->Registers.ss != GDT_KERNEL_DATA) { - warn("Wrong CS or SS for kernel process! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx", + warn("Wrong CS or SS for kernel thread %s(%ld)! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx", CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss, - GDT_KERNEL_CODE, GDT_KERNEL_DATA); + GDT_KERNEL_CODE, GDT_KERNEL_DATA, + CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID); CurrentCPU->CurrentThread->Registers.cs = GDT_KERNEL_CODE; CurrentCPU->CurrentThread->Registers.ss = GDT_KERNEL_DATA; } @@ -583,71 +586,71 @@ namespace Tasking } } - __no_stack_protector void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); } + SafeFunction __no_instrument_function void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); } #elif defined(__i386__) - __no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) + SafeFunction bool Task::FindNewProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) + SafeFunction bool Task::GetNextAvailableThread(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) + SafeFunction bool Task::GetNextAvailableProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector void Task::SchedulerCleanupProcesses() + SafeFunction void Task::SchedulerCleanupProcesses() { fixme("unimplemented"); } - __no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) + SafeFunction bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector void Task::Schedule(void *Frame) + SafeFunction void Task::Schedule(void *Frame) { fixme("unimplemented"); } - __no_stack_protector void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } + SafeFunction void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } #elif defined(__aarch64__) - __no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) + SafeFunction bool Task::FindNewProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) + SafeFunction bool Task::GetNextAvailableThread(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) + SafeFunction bool Task::GetNextAvailableProcess(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector void Task::SchedulerCleanupProcesses() + SafeFunction void Task::SchedulerCleanupProcesses() { fixme("unimplemented"); } - __no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) + SafeFunction bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) { fixme("unimplemented"); } - __no_stack_protector void Task::Schedule(void *Frame) + SafeFunction void Task::Schedule(void *Frame) { fixme("unimplemented"); } - __no_stack_protector void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } + SafeFunction void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } #endif void ThreadDoExit() @@ -853,8 +856,10 @@ namespace Tasking { while (argv[ArgvSize] != nullptr) { + debug("> ArgvSize: %d, ArgvStrSize: %d", ArgvSize, ArgvStrSize); ArgvSize++; ArgvStrSize += strlen(argv[ArgvSize]) + 1; + debug("< ArgvSize: %d, ArgvStrSize: %d", ArgvSize, ArgvStrSize); } } @@ -864,8 +869,10 @@ namespace Tasking { while (envp[EnvpSize] != nullptr) { + debug("> EnvpSize: %d, EnvpStrSize: %d", EnvpSize, EnvpStrSize); EnvpSize++; EnvpStrSize += strlen(envp[EnvpSize]) + 1; + debug("< EnvpSize: %d, EnvpStrSize: %d", EnvpSize, EnvpStrSize); } } @@ -881,15 +888,19 @@ namespace Tasking argv[i] = (char *)_argv; } + debug("argv done"); + for (uint64_t i = 0; i < EnvpSize; i++) { - void *Tmp = KernelAllocator.RequestPages(TO_PAGES(strlen(argv[i]) + 1)); + void *Tmp = KernelAllocator.RequestPages(TO_PAGES(strlen(envp[i]) + 1)); Memory::Virtual().Map(Tmp, Tmp, Memory::PTFlag::RW | Memory::PTFlag::US); _envp = (uint8_t *)Tmp; strcpy((char *)_envp, envp[i]); envp[i] = (char *)_envp; } + debug("envp done"); + Thread->Registers.rdi = ArgvSize; Thread->Registers.rsi = (uint64_t)_argv; Thread->Registers.rdx = (uint64_t)_envp; diff --git a/dump.sh b/dump.sh new file mode 100755 index 0000000..f03c7f0 --- /dev/null +++ b/dump.sh @@ -0,0 +1 @@ +make dump diff --git a/include/convert.h b/include/convert.h index 7b4770b..dcc290a 100644 --- a/include/convert.h +++ b/include/convert.h @@ -19,15 +19,18 @@ extern "C" int atoi(const char *String); double atof(const char *String); char *itoa(int Value, char *Buffer, int Base); + char *ltoa(long Value, char *Buffer, int Base); + char *ultoa(unsigned long Value, char *Buffer, int Base); - void *memcpy(void *dest, const void *src, size_t n); - void *memset(void *dest, int c, size_t n); - void *memmove(void *dest, const void *src, size_t n); + void *memcpy_unsafe(void *dest, const void *src, size_t n); + void *memset_unsafe(void *dest, int c, size_t n); + void *memmove_unsafe(void *dest, const void *src, size_t n); int memcmp(const void *vl, const void *vr, size_t n); + long unsigned strlen(const char s[]); int strncmp(const char *s1, const char *s2, unsigned long n); - char *strcat(char *destination, const char *source); - char *strcpy(char *destination, const char *source); + char *strcat_unsafe(char *destination, const char *source); + char *strcpy_unsafe(char *destination, const char *source); char *strncpy(char *destination, const char *source, unsigned long num); int strcmp(const char *l, const char *r); char *strstr(const char *haystack, const char *needle); @@ -38,6 +41,32 @@ extern "C" int strcasecmp(const char *lhs, const char *rhs); char *strtok(char *src, const char *delim); + void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen); + void *__memset_chk(void *dest, int val, size_t len, size_t slen); + void *__memmove_chk(void *dest, const void *src, size_t len, size_t slen); + char *__strcat_chk(char *dest, const char *src, size_t slen); + char *__strcpy_chk(char *dest, const char *src, size_t slen); + #ifdef __cplusplus } #endif + +#undef memcpy +#define memcpy(dest, src, n) \ + __memcpy_chk(dest, src, n, __builtin_object_size(dest, 0)) + +#undef memset +#define memset(dest, c, n) \ + __memset_chk(dest, c, n, __builtin_object_size(dest, 0)) + +#undef memmove +#define memmove(dest, src, n) \ + __memmove_chk(dest, src, n, __builtin_object_size(dest, 0)) + +#undef strcat +#define strcat(dest, src) \ + __strcat_chk(dest, src, __builtin_object_size(dest, 0)) + +#undef strcpy +#define strcpy(dest, src) \ + __strcpy_chk(dest, src, __builtin_object_size(dest, 0)) diff --git a/include/cpu.hpp b/include/cpu.hpp index 89b9d39..5edc3c6 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -143,7 +143,7 @@ namespace CPU /** * @brief Pause the CPU */ - __no_stack_protector static inline void Pause(bool Loop = false) + SafeFunction static inline void Pause(bool Loop = false) { do { @@ -158,7 +158,7 @@ namespace CPU /** * @brief Stop the CPU (infinite loop) */ - __no_stack_protector static inline void Stop() + SafeFunction static inline void Stop() { while (1) { @@ -177,7 +177,7 @@ namespace CPU /** * @brief Halt the CPU */ - __no_stack_protector static inline void Halt(bool Loop = false) + SafeFunction static inline void Halt(bool Loop = false) { do { @@ -213,7 +213,7 @@ namespace CPU namespace MemBar { - __no_stack_protector static inline void Barrier() + SafeFunction static inline void Barrier() { #if defined(__amd64__) || defined(__i386__) asmv("" :: @@ -224,7 +224,7 @@ namespace CPU #endif } - __no_stack_protector static inline void Fence() + SafeFunction static inline void Fence() { #if defined(__amd64__) || defined(__i386__) asmv("mfence" :: @@ -235,7 +235,7 @@ namespace CPU #endif } - __no_stack_protector static inline void StoreFence() + SafeFunction static inline void StoreFence() { #if defined(__amd64__) || defined(__i386__) asmv("sfence" :: @@ -246,7 +246,7 @@ namespace CPU #endif } - __no_stack_protector static inline void LoadFence() + SafeFunction static inline void LoadFence() { #if defined(__amd64__) || defined(__i386__) asmv("lfence" :: @@ -549,7 +549,7 @@ namespace CPU #endif } - __no_stack_protector static inline void invlpg(void *Address) + SafeFunction static inline void invlpg(void *Address) { #if defined(__i386__) asmv("invlpg (%0)" @@ -1670,7 +1670,7 @@ namespace CPU uint64_t raw; } SelectorErrorCode; - __no_stack_protector static inline void lgdt(void *gdt) + SafeFunction static inline void lgdt(void *gdt) { #if defined(__amd64__) asmv("lgdt (%0)" @@ -1679,7 +1679,7 @@ namespace CPU #endif } - __no_stack_protector static inline void lidt(void *idt) + SafeFunction static inline void lidt(void *idt) { #if defined(__amd64__) asmv("lidt (%0)" @@ -1688,7 +1688,7 @@ namespace CPU #endif } - __no_stack_protector static inline void ltr(uint16_t Segment) + SafeFunction static inline void ltr(uint16_t Segment) { #if defined(__amd64__) asmv("ltr %0" @@ -1697,7 +1697,7 @@ namespace CPU #endif } - __no_stack_protector static inline void invlpg(void *Address) + SafeFunction static inline void invlpg(void *Address) { #if defined(__amd64__) asmv("invlpg (%0)" @@ -1716,7 +1716,7 @@ namespace CPU * @param ecx ECX * @param edx EDX */ - __no_stack_protector static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) + SafeFunction static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { #if defined(__amd64__) asmv("cpuid" @@ -1732,14 +1732,14 @@ namespace CPU * * @return uint32_t */ - __no_stack_protector static inline uint32_t GetHighestLeaf() + SafeFunction static inline uint32_t GetHighestLeaf() { uint32_t eax, ebx, ecx, edx; cpuid(0x0, &eax, &ebx, &ecx, &edx); return eax; } - __no_stack_protector static inline uint64_t rdmsr(uint32_t msr) + SafeFunction static inline uint64_t rdmsr(uint32_t msr) { uint32_t Low, High; #if defined(__amd64__) @@ -1751,7 +1751,7 @@ namespace CPU return ((uint64_t)Low) | (((uint64_t)High) << 32); } - __no_stack_protector static inline void wrmsr(uint32_t msr, uint64_t Value) + SafeFunction static inline void wrmsr(uint32_t msr, uint64_t Value) { uint32_t Low = Value, High = Value >> 32; #if defined(__amd64__) @@ -1762,7 +1762,7 @@ namespace CPU #endif } - __no_stack_protector static inline CR0 readcr0() + SafeFunction static inline CR0 readcr0() { uint64_t Result; #if defined(__amd64__) @@ -1772,7 +1772,7 @@ namespace CPU return (CR0){.raw = Result}; } - __no_stack_protector static inline CR2 readcr2() + SafeFunction static inline CR2 readcr2() { uint64_t Result; #if defined(__amd64__) @@ -1782,7 +1782,7 @@ namespace CPU return (CR2){.raw = Result}; } - __no_stack_protector static inline CR3 readcr3() + SafeFunction static inline CR3 readcr3() { uint64_t Result; #if defined(__amd64__) @@ -1792,7 +1792,7 @@ namespace CPU return (CR3){.raw = Result}; } - __no_stack_protector static inline CR4 readcr4() + SafeFunction static inline CR4 readcr4() { uint64_t Result; #if defined(__amd64__) @@ -1802,7 +1802,7 @@ namespace CPU return (CR4){.raw = Result}; } - __no_stack_protector static inline CR8 readcr8() + SafeFunction static inline CR8 readcr8() { uint64_t Result; #if defined(__amd64__) @@ -1812,7 +1812,7 @@ namespace CPU return (CR8){.raw = Result}; } - __no_stack_protector static inline void writecr0(CR0 ControlRegister) + SafeFunction static inline void writecr0(CR0 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr0" @@ -1822,7 +1822,7 @@ namespace CPU #endif } - __no_stack_protector static inline void writecr2(CR2 ControlRegister) + SafeFunction static inline void writecr2(CR2 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr2" @@ -1832,7 +1832,7 @@ namespace CPU #endif } - __no_stack_protector static inline void writecr3(CR3 ControlRegister) + SafeFunction static inline void writecr3(CR3 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr3" @@ -1842,7 +1842,7 @@ namespace CPU #endif } - __no_stack_protector static inline void writecr4(CR4 ControlRegister) + SafeFunction static inline void writecr4(CR4 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr4" @@ -1852,7 +1852,7 @@ namespace CPU #endif } - __no_stack_protector static inline void writecr8(CR8 ControlRegister) + SafeFunction static inline void writecr8(CR8 ControlRegister) { #if defined(__amd64__) asmv("mov %[ControlRegister], %%cr8" @@ -1862,7 +1862,7 @@ namespace CPU #endif } - __no_stack_protector static inline void fxsave(char *FXSaveArea) + SafeFunction static inline void fxsave(char *FXSaveArea) { #if defined(__amd64__) if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000) @@ -1876,7 +1876,7 @@ namespace CPU #endif } - __no_stack_protector static inline void fxrstor(char *FXRstorArea) + SafeFunction static inline void fxrstor(char *FXRstorArea) { #if defined(__amd64__) if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000) diff --git a/include/display.hpp b/include/display.hpp index 208fb67..191e7a7 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -156,8 +156,10 @@ namespace Video void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index) { - if (X >= this->Buffers[Index]->Width || Y >= this->Buffers[Index]->Height) - return; + if (X >= this->Buffers[Index]->Width) + X = this->Buffers[Index]->Width - 1; + if (Y >= this->Buffers[Index]->Height) + Y = this->Buffers[Index]->Height - 1; uint32_t *Pixel = (uint32_t *)((uint64_t)this->Buffers[Index]->Buffer + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8)); *Pixel = Color; } diff --git a/include/filesystem.hpp b/include/filesystem.hpp index 8a41215..3b29398 100644 --- a/include/filesystem.hpp +++ b/include/filesystem.hpp @@ -89,7 +89,7 @@ namespace FileSystem FS_MOUNTPOINT = 0x08 }; - struct FileSystemOpeations + struct FileSystemOperations { char Name[FILENAME_LENGTH]; OperationMount Mount = nullptr; @@ -113,7 +113,7 @@ namespace FileSystem uint64_t Address = 0; uint64_t Length = 0; FileSystemNode *Parent = nullptr; - FileSystemOpeations *Operator = nullptr; + FileSystemOperations *Operator = nullptr; /* For root node: 0 - root "/" 1 - etc @@ -150,13 +150,13 @@ namespace FileSystem char *NormalizePath(FileSystemNode *Parent, const char *Path); FileStatus FileExists(FileSystemNode *Parent, const char *Path); - FILE *Mount(FileSystemOpeations *Operator, const char *Path); + FILE *Mount(FileSystemOperations *Operator, const char *Path); FileStatus Unmount(FILE *File); FILE *Open(const char *Path, FileSystemNode *Parent = nullptr); uint64_t Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size); uint64_t Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size); FileStatus Close(FILE *File); - FileSystemNode *CreateRoot(FileSystemOpeations *Operator, const char *RootName); + FileSystemNode *CreateRoot(FileSystemOperations *Operator, const char *RootName); FileSystemNode *Create(FileSystemNode *Parent, const char *Path); Virtual(); diff --git a/include/filesystem/mounts.hpp b/include/filesystem/mounts.hpp index b959490..6bc9935 100644 --- a/include/filesystem/mounts.hpp +++ b/include/filesystem/mounts.hpp @@ -11,7 +11,7 @@ namespace FileSystem class Device { public: - FileSystemNode *AddFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags); + FileSystemNode *AddFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags); Device(); ~Device(); }; @@ -20,7 +20,7 @@ namespace FileSystem class Mount { public: - FileSystemNode *MountFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name); + FileSystemNode *MountFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name); void DetectAndMountFS(void *drive); Mount(); ~Mount(); @@ -38,7 +38,7 @@ namespace FileSystem class Driver { public: - FileSystemNode *AddDriver(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags); + FileSystemNode *AddDriver(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags); Driver(); ~Driver(); }; @@ -47,7 +47,7 @@ namespace FileSystem class Network { public: - FileSystemNode *AddNetworkCard(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags); + FileSystemNode *AddNetworkCard(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags); Network(); ~Network(); }; diff --git a/include/interrupts.hpp b/include/interrupts.hpp index 35e7797..54e3b80 100644 --- a/include/interrupts.hpp +++ b/include/interrupts.hpp @@ -6,17 +6,26 @@ namespace Interrupts { +#ifdef DEBUG // For performance reasons +#define INT_FRAMES_MAX 512 +#else +#define INT_FRAMES_MAX 8 +#endif + #if defined(__amd64__) - /* APIC::APIC */ extern void *apic[256]; // MAX_CPU + /* APIC::APIC */ extern void *apic[256]; // MAX_CPU /* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU #elif defined(__i386__) - /* APIC::APIC */ extern void *apic[256]; // MAX_CPU + /* APIC::APIC */ extern void *apic[256]; // MAX_CPU /* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU #elif defined(__aarch64__) #endif + extern void *InterruptFrames[INT_FRAMES_MAX]; + void Initialize(int Core); void Enable(int Core); void InitializeTimer(int Core); + void RemoveAll(); class Handler { diff --git a/include/kconfig.hpp b/include/kconfig.hpp index 613b4d4..cca7375 100644 --- a/include/kconfig.hpp +++ b/include/kconfig.hpp @@ -12,6 +12,7 @@ struct KernelConfig char InitPath[256]; bool InterruptsOnCrash; int Cores; + bool UnlockDeadLock; }; KernelConfig ParseConfig(char *Config); diff --git a/include/recovery.hpp b/include/recovery.hpp new file mode 100644 index 0000000..d084071 --- /dev/null +++ b/include/recovery.hpp @@ -0,0 +1,11 @@ +#ifndef __FENNIX_KERNEL_RECOVERY_H__ +#define __FENNIX_KERNEL_RECOVERY_H__ + +#include + +namespace Recovery +{ + +} + +#endif // !__FENNIX_KERNEL_RECOVERY_H__ diff --git a/include/task.hpp b/include/task.hpp index 55e263a..ff717e9 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -101,6 +101,7 @@ namespace Tasking void Rename(const char *name) { + CriticalSection cs; if (!Name[0]) { warn("Tried to rename thread %d to NULL", ID); @@ -117,6 +118,7 @@ namespace Tasking void SetPriority(int priority) { + CriticalSection cs; trace("Setting priority of thread %s to %d", Name, priority); Info.Priority = priority; } @@ -125,6 +127,7 @@ namespace Tasking void SetCritical(bool critical) { + CriticalSection cs; trace("Setting criticality of thread %s to %s", Name, critical ? "true" : "false"); Security.IsCritical = critical; } @@ -215,7 +218,13 @@ namespace Tasking Vector GetProcessList() { return ListProcess; } void Panic() { StopScheduler = true; } void Schedule(); - long GetUsage(int Core) { return 100 - IdleProcess->Info.Usage[Core]; } + long GetUsage(int Core) + { + if (IdleProcess) + return 100 - IdleProcess->Info.Usage[Core]; + else + return 0; + } void KillThread(TCB *tcb, int Code) { tcb->Status = TaskStatus::Terminated; diff --git a/include/types.h b/include/types.h index 3d91f4e..446bc88 100644 --- a/include/types.h +++ b/include/types.h @@ -207,7 +207,6 @@ typedef __SIZE_TYPE__ size_t; #define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40))) #define b64(x) __builtin_bswap64(x) - #define O0 __attribute__((optimize("O0"))) #define O1 __attribute__((optimize("O1"))) #define O2 __attribute__((optimize("O2"))) @@ -220,6 +219,7 @@ typedef __SIZE_TYPE__ size_t; #define __unused __attribute__((unused)) #define __packed __attribute__((packed)) +#define __naked __attribute__((naked)) #define __aligned(x) __attribute__((aligned(x))) #define __section(x) __attribute__((section(x))) #define __noreturn __attribute__((noreturn)) @@ -252,12 +252,17 @@ typedef __SIZE_TYPE__ size_t; #define __nonnull_all __attribute__((nonnull)) #define __warn_unused_result __attribute__((warn_unused_result)) #define __no_stack_protector __attribute__((no_stack_protector)) +#define __no_instrument_function __attribute__((no_instrument_function)) + // sanitizer #define __no_sanitize_address __attribute__((no_sanitize_address)) #define __no_sanitize_undefined __attribute__((no_sanitize_undefined)) #define __no_address_safety_analysis __attribute__((no_address_safety_analysis)) #define __no_sanitize_thread __attribute__((no_sanitize_thread)) -#define __no_sanitize_memory __attribute__((no_sanitize_memory)) -#define __no_sanitize_hwaddress __attribute__((no_sanitize_hwaddress)) + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#define SafeFunction __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_address_safety_analysis __no_sanitize_thread #endif // !__FENNIX_KERNEL_TYPES_H__ diff --git a/include/uart.hpp b/include/uart.hpp index c6c3fb0..c0ad085 100644 --- a/include/uart.hpp +++ b/include/uart.hpp @@ -51,7 +51,7 @@ namespace UniversalAsynchronousReceiverTransmitter * @brief Get the Registered Port object * @return SerialPorts */ - SerialPorts GetRegisteredPort() { return this->Port; } + SafeFunction __no_instrument_function SerialPorts GetRegisteredPort() { return this->Port; } /** * @brief Called when a character is sent. diff --git a/include/vector.hpp b/include/vector.hpp index e9c37db..1fbcd55 100644 --- a/include/vector.hpp +++ b/include/vector.hpp @@ -13,7 +13,7 @@ private: public: typedef T *iterator; - Vector() + __no_instrument_function Vector() { #ifdef DEBUG_MEM_ALLOCATION debug("VECTOR INIT: Vector( )"); @@ -23,7 +23,7 @@ public: VectorBuffer = 0; } - Vector(uint64_t Size) + __no_instrument_function Vector(uint64_t Size) { VectorCapacity = Size; VectorSize = Size; @@ -33,7 +33,7 @@ public: VectorBuffer = new T[Size]; } - Vector(uint64_t Size, const T &Initial) + __no_instrument_function Vector(uint64_t Size, const T &Initial) { VectorSize = Size; VectorCapacity = Size; @@ -45,7 +45,7 @@ public: VectorBuffer[i] = Initial; } - Vector(const Vector &Vector) + __no_instrument_function Vector(const Vector &Vector) { VectorSize = Vector.VectorSize; VectorCapacity = Vector.VectorCapacity; @@ -57,7 +57,7 @@ public: VectorBuffer[i] = Vector.VectorBuffer[i]; } - ~Vector() + __no_instrument_function ~Vector() { #ifdef DEBUG_MEM_ALLOCATION debug("VECTOR INIT: ~Vector( ~%lx )", VectorBuffer); @@ -65,7 +65,7 @@ public: delete[] VectorBuffer; } - void remove(uint64_t Position) + __no_instrument_function void remove(uint64_t Position) { if (Position >= VectorSize) return; @@ -77,30 +77,30 @@ public: VectorSize--; } - uint64_t capacity() const { return VectorCapacity; } + __no_instrument_function uint64_t capacity() const { return VectorCapacity; } - uint64_t size() const { return VectorSize; } + __no_instrument_function uint64_t size() const { return VectorSize; } - bool empty() const; + __no_instrument_function bool empty() const; - iterator begin() { return VectorBuffer; } + __no_instrument_function iterator begin() { return VectorBuffer; } - iterator end() { return VectorBuffer + size(); } + __no_instrument_function iterator end() { return VectorBuffer + size(); } - T &front() { return VectorBuffer[0]; } + __no_instrument_function T &front() { return VectorBuffer[0]; } - T &back() { return VectorBuffer[VectorSize - 1]; } + __no_instrument_function T &back() { return VectorBuffer[VectorSize - 1]; } - void push_back(const T &Value) + __no_instrument_function void push_back(const T &Value) { if (VectorSize >= VectorCapacity) reserve(VectorCapacity + 5); VectorBuffer[VectorSize++] = Value; } - void pop_back() { VectorSize--; } + __no_instrument_function void pop_back() { VectorSize--; } - void reverse() + __no_instrument_function void reverse() { if (VectorSize <= 1) return; @@ -112,7 +112,7 @@ public: } } - void reserve(uint64_t Capacity) + __no_instrument_function void reserve(uint64_t Capacity) { if (VectorBuffer == 0) { @@ -134,15 +134,15 @@ public: VectorBuffer = Newbuffer; } - void resize(uint64_t Size) + __no_instrument_function void resize(uint64_t Size) { reserve(Size); VectorSize = Size; } - T &operator[](uint64_t Index) { return VectorBuffer[Index]; } + __no_instrument_function T &operator[](uint64_t Index) { return VectorBuffer[Index]; } - Vector &operator=(const Vector &Vector) + __no_instrument_function Vector &operator=(const Vector &Vector) { delete[] VectorBuffer; VectorSize = Vector.VectorSize; @@ -156,12 +156,12 @@ public: return *this; } - void clear() + __no_instrument_function void clear() { VectorCapacity = 0; VectorSize = 0; VectorBuffer = 0; } - T *data() { return VectorBuffer; } + __no_instrument_function T *data() { return VectorBuffer; } }; diff --git a/kernel.h b/kernel.h index bfb6cff..55d8a9b 100644 --- a/kernel.h +++ b/kernel.h @@ -38,6 +38,7 @@ extern Disk::Manager *DiskManager; EXTERNC void putchar(char c); EXTERNC void KPrint(const char *format, ...); EXTERNC void Entry(struct BootInfo *Info); +EXTERNC void BeforeShutdown(); EXTERNC void TaskingPanic(); EXTERNC void KernelMainThread();