Changed a lot of files. Summary: profiler support; "SafeFunction"; UnlockDeadLock kernel config; Code optimization & more

This commit is contained in:
Alex 2022-11-28 08:25:37 +02:00
parent 2fba834d41
commit 0289054900
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
62 changed files with 1462 additions and 558 deletions

3
.gitignore vendored
View File

@ -1,5 +1,8 @@
*.o *.o
*.su
*.gcno
*.map *.map
*.fsys *.fsys
*.log *.log
Files/*.psf Files/*.psf
.dccache

View File

@ -40,7 +40,8 @@
"-Wl,-static,--no-dynamic-linker,-ztext", "-Wl,-static,--no-dynamic-linker,-ztext",
"-shared", "-shared",
"-zmax-page-size=0x1000", "-zmax-page-size=0x1000",
"-nostdinc++" "-nostdinc++",
"-fsanitize=undefined"
] ]
} }
], ],

View File

@ -42,7 +42,7 @@ static volatile struct limine_smbios_request SmbiosRequest = {
.id = LIMINE_SMBIOS_REQUEST, .id = LIMINE_SMBIOS_REQUEST,
.revision = 0}; .revision = 0};
void init_limine() SafeFunction __no_instrument_function void init_limine()
{ {
struct BootInfo binfo; struct BootInfo binfo;
struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response; 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); binfo.Modules[i].Address = (void *)((uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000);
strcpy(binfo.Modules[i].Path, ModuleResponse->modules[i]->path); strncpy(binfo.Modules[i].Path,
strcpy(binfo.Modules[i].CommandLine, ModuleResponse->modules[i]->cmdline); 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; binfo.Modules[i].Size = ModuleResponse->modules[i]->size;
debug("Module %d:\nAddress: %p\nPath: %s\nCommand Line: %s\nSize: %ld", i, debug("Module %d:\nAddress: %p\nPath: %s\nCommand Line: %s\nSize: %ld", i,
(uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000, ModuleResponse->modules[i]->path, (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.PhysicalBase = (void *)KernelAddressResponse->physical_base;
binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base; binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base;
binfo.Kernel.FileBase = KernelFileResponse->kernel_file->address; 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; binfo.Kernel.Size = KernelFileResponse->kernel_file->size;
trace("Kernel physical address: %p", KernelAddressResponse->physical_base); trace("Kernel physical address: %p", KernelAddressResponse->physical_base);
trace("Kernel virtual address: %p", KernelAddressResponse->virtual_base); trace("Kernel virtual address: %p", KernelAddressResponse->virtual_base);
strcpy(binfo.Bootloader.Name, BootloaderInfoResponse->name); strncpy(binfo.Bootloader.Name,
strcpy(binfo.Bootloader.Version, BootloaderInfoResponse->version); BootloaderInfoResponse->name,
strlen(BootloaderInfoResponse->name) + 1);
strncpy(binfo.Bootloader.Version,
BootloaderInfoResponse->version,
strlen(BootloaderInfoResponse->version) + 1);
// Call kernel entry point // Call kernel entry point
Entry(&binfo); Entry(&binfo);

View File

@ -89,7 +89,7 @@ namespace GlobalDescriptorTable
void *CPUStackPointer[MAX_CPU]; void *CPUStackPointer[MAX_CPU];
__no_stack_protector void Init(int Core) SafeFunction void Init(int Core)
{ {
memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries)); memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]}; gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]};
@ -143,7 +143,7 @@ namespace GlobalDescriptorTable
trace("Global Descriptor Table initialized"); trace("Global Descriptor Table initialized");
} }
__no_stack_protector void SetKernelStack(void *Stack) SafeFunction void SetKernelStack(void *Stack)
{ {
if (Stack) if (Stack)
tss[GetCurrentCPU()->ID].StackPointer[0] = (uint64_t)Stack; tss[GetCurrentCPU()->ID].StackPointer[0] = (uint64_t)Stack;

View File

@ -29,6 +29,24 @@ SECTIONS
_kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE)); _kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += 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 : .bss :
{ {
*(COMMON) *(COMMON)

View File

@ -92,12 +92,16 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
{ {
case MULTIBOOT_TAG_TYPE_CMDLINE: 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; break;
} }
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: 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; break;
} }
case MULTIBOOT_TAG_TYPE_MODULE: case MULTIBOOT_TAG_TYPE_MODULE:
@ -106,8 +110,9 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
static int module_count = 0; static int module_count = 0;
binfo.Modules[module_count++].Address = (void *)module->mod_start; binfo.Modules[module_count++].Address = (void *)module->mod_start;
binfo.Modules[module_count++].Size = module->size; binfo.Modules[module_count++].Size = module->size;
strcpy(binfo.Modules[module_count++].Path, "(null)"); strncpy(binfo.Modules[module_count++].Path, "(null)", 6);
strcpy(binfo.Modules[module_count++].CommandLine, module->cmdline); strncpy(binfo.Modules[module_count++].CommandLine, module->cmdline,
strlen(module->cmdline));
break; break;
} }
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
@ -332,7 +337,7 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
vm[12] = 0x0579; vm[12] = 0x0579;
vm[13] = 0x0565; vm[13] = 0x0565;
vm[14] = 0x0574; vm[14] = 0x0574;
CPU::Stop(); CPU::Stop();
// Entry(&binfo); // Entry(&binfo);
} }

View File

@ -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 to a non-present page entry\n",
"User process tried to write a page and caused a protection fault\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"); 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("\eDD2920System crashed!\n");
CrashHandler::EHPrint("Kernel triggered debug exception.\n"); CrashHandler::EHPrint("Kernel triggered debug exception.\n");
} }
__no_stack_protector void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); } SafeFunction void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); }
__no_stack_protector void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); } SafeFunction void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); }
__no_stack_protector void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); } SafeFunction void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); }
__no_stack_protector void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); } SafeFunction void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); }
__no_stack_protector void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame) SafeFunction void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame)
{ {
CrashHandler::EHPrint("\eDD2920System crashed!\n"); CrashHandler::EHPrint("\eDD2920System crashed!\n");
CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n"); CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n");
} }
__no_stack_protector void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); } SafeFunction void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); }
__no_stack_protector void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); } SafeFunction void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); }
__no_stack_protector void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); } SafeFunction void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
__no_stack_protector void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); } SafeFunction void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); }
__no_stack_protector void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); } SafeFunction void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); }
__no_stack_protector void StackFaultExceptionHandler(CHArchTrapFrame *Frame) SafeFunction void StackFaultExceptionHandler(CHArchTrapFrame *Frame)
{ {
CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode};
CrashHandler::EHPrint("\eDD2920System crashed!\n"); 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("Index: %#x\n", SelCode.Idx);
CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode); CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode);
} }
__no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame) SafeFunction void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame)
{ {
// staticbuffer(descbuf); // staticbuffer(descbuf);
// staticbuffer(desc_ext); // staticbuffer(desc_ext);
@ -97,7 +97,7 @@ __no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Fra
CrashHandler::EHPrint("Table: %d\n", SelCode.Table); CrashHandler::EHPrint("Table: %d\n", SelCode.Table);
CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); 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}; CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode};
CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF"); CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF");
@ -120,10 +120,10 @@ __no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
else else
CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]); CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]);
} }
__no_stack_protector void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); } SafeFunction void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); }
__no_stack_protector void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); } SafeFunction void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); }
__no_stack_protector void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); } SafeFunction void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); }
__no_stack_protector void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); } SafeFunction void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); }
__no_stack_protector void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); } SafeFunction void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); }
__no_stack_protector void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); } SafeFunction void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); }
__no_stack_protector void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); } SafeFunction void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); }

View File

@ -22,15 +22,16 @@ NewLock(UserInputLock);
namespace CrashHandler namespace CrashHandler
{ {
void *EHIntFrames[INT_FRAMES_MAX];
static bool ExceptionOccurred = false; static bool ExceptionOccurred = false;
int SBIdx = 255; int SBIdx = 255;
__no_stack_protector void printfWrapper(char c, void *unused) SafeFunction void printfWrapper(char c, void *unused)
{ {
Display->Print(c, SBIdx, true); Display->Print(c, SBIdx, true);
UNUSED(unused); UNUSED(unused);
} }
__no_stack_protector void EHPrint(const char *Format, ...) SafeFunction void EHPrint(const char *Format, ...)
{ {
va_list args; va_list args;
va_start(args, Format); va_start(args, Format);
@ -38,7 +39,7 @@ namespace CrashHandler
va_end(args); va_end(args);
} }
__no_stack_protector char *trimwhitespace(char *str) SafeFunction char *TrimWhiteSpace(char *str)
{ {
char *end; char *end;
while (*str == ' ') while (*str == ' ')
@ -54,7 +55,7 @@ namespace CrashHandler
CRData crashdata = {}; CRData crashdata = {};
__no_stack_protector void DisplayTopOverlay() SafeFunction void DisplayTopOverlay()
{ {
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
Video::Font *f = Display->GetCurrentFont(); Video::Font *f = Display->GetCurrentFont();
@ -108,7 +109,7 @@ namespace CrashHandler
Display->SetBufferCursor(SBIdx, 0, fi.Height + 10); Display->SetBufferCursor(SBIdx, 0, fi.Height + 10);
} }
__no_stack_protector void DisplayBottomOverlay() SafeFunction void DisplayBottomOverlay()
{ {
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
Video::Font *f = Display->GetCurrentFont(); Video::Font *f = Display->GetCurrentFont();
@ -122,7 +123,7 @@ namespace CrashHandler
EHPrint("\eAAAAAA> \eFAFAFA"); EHPrint("\eAAAAAA> \eFAFAFA");
} }
__no_stack_protector void ArrowInput(uint8_t key) SafeFunction void ArrowInput(uint8_t key)
{ {
switch (key) switch (key)
{ {
@ -193,7 +194,7 @@ namespace CrashHandler
Display->SetBuffer(SBIdx); Display->SetBuffer(SBIdx);
} }
__no_stack_protector void UserInput(char *Input) SafeFunction void UserInput(char *Input)
{ {
SmartCriticalSection(UserInputLock); SmartCriticalSection(UserInputLock);
Display->ClearBuffer(SBIdx); Display->ClearBuffer(SBIdx);
@ -209,6 +210,7 @@ namespace CrashHandler
EHPrint("showbuf <INDEX> - Display the contents of a screen buffer.\n"); EHPrint("showbuf <INDEX> - 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(" - 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(" - \eFF4400WARNING: This can crash the system if a wrong buffer is selected.\eFAFAFA\n");
EHPrint("ifr <COUNT> - Show interrupt frames.\n");
EHPrint("main - Show the main screen.\n"); EHPrint("main - Show the main screen.\n");
EHPrint("details - Show the details screen.\n"); EHPrint("details - Show the details screen.\n");
EHPrint("frames - Show the stack frame screen.\n"); EHPrint("frames - Show the stack frame screen.\n");
@ -223,25 +225,66 @@ namespace CrashHandler
{ {
PowerManager->Shutdown(); PowerManager->Shutdown();
EHPrint("\eFFFFFFNow it's safe to turn off your computer."); EHPrint("\eFFFFFFNow it's safe to turn off your computer.");
Display->SetBuffer(SBIdx);
CPU::Stop(); CPU::Stop();
} }
else if (strcmp(Input, "reboot") == 0) else if (strcmp(Input, "reboot") == 0)
{ {
PowerManager->Reboot(); PowerManager->Reboot();
EHPrint("\eFFFFFFNow it's safe to reboot your computer."); EHPrint("\eFFFFFFNow it's safe to reboot your computer.");
Display->SetBuffer(SBIdx);
CPU::Stop(); CPU::Stop();
} }
else if (strncmp(Input, "showbuf", 7) == 0) else if (strncmp(Input, "showbuf", 7) == 0)
{ {
char *arg = trimwhitespace(Input + 7); char *arg = TrimWhiteSpace(Input + 7);
int tmpidx = SBIdx; int tmpidx = SBIdx;
SBIdx = atoi(arg); SBIdx = atoi(arg);
Display->SetBuffer(SBIdx); Display->SetBuffer(SBIdx);
for (int i = 0; i < 1000000; i++) for (int i = 0; i < 5000000; i++)
inb(0x80); inb(0x80);
SBIdx = tmpidx; SBIdx = tmpidx;
Display->SetBuffer(SBIdx); 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) else if (strcmp(Input, "main") == 0)
{ {
SBIdx = 255; SBIdx = 255;
@ -286,11 +329,14 @@ namespace CrashHandler
Display->SetBuffer(SBIdx); Display->SetBuffer(SBIdx);
} }
__no_stack_protector void Handle(void *Data) SafeFunction void Handle(void *Data)
{ {
// TODO: SUPPORT SMP // TODO: SUPPORT SMP
CPU::Interrupts(CPU::Disable); CPU::Interrupts(CPU::Disable);
error("An exception occurred!"); error("An exception occurred!");
for (size_t i = 0; i < INT_FRAMES_MAX; i++)
EHIntFrames[i] = Interrupts::InterruptFrames[i];
SBIdx = 255; SBIdx = 255;
CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data; CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data;
#if defined(__amd64__) #if defined(__amd64__)
@ -299,27 +345,11 @@ namespace CrashHandler
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA) if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
{ {
debug("Exception in kernel mode"); 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) if (TaskManager)
TaskManager->Panic(); TaskManager->Panic();
debug("ePanicSchedStop");
Display->CreateBuffer(0, 0, SBIdx); Display->CreateBuffer(0, 0, SBIdx);
debug("e0");
} }
else else
{ {
@ -348,7 +378,9 @@ namespace CrashHandler
{ {
SBIdx = 255; SBIdx = 255;
Display->ClearBuffer(SBIdx); Display->ClearBuffer(SBIdx);
debug("e0-1");
Display->SetBufferCursor(SBIdx, 0, 0); Display->SetBufferCursor(SBIdx, 0, 0);
debug("e0-2");
CPU::x64::CR0 cr0 = CPU::x64::readcr0(); CPU::x64::CR0 cr0 = CPU::x64::readcr0();
CPU::x64::CR2 cr2 = CPU::x64::readcr2(); CPU::x64::CR2 cr2 = CPU::x64::readcr2();
@ -405,6 +437,7 @@ namespace CrashHandler
} }
ExceptionOccurred = true; ExceptionOccurred = true;
Interrupts::RemoveAll();
debug("Reading control registers..."); debug("Reading control registers...");
crashdata.Frame = Frame; crashdata.Frame = Frame;

View File

@ -103,11 +103,11 @@ namespace CrashHandler
static char UserInputBuffer[1024]; static char UserInputBuffer[1024];
#if defined(__amd64__) #if defined(__amd64__)
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame) SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
#elif defined(__i386__) #elif defined(__i386__)
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame) SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
#elif defined(__aarch64__) #elif defined(__aarch64__)
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame) SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
#endif #endif
{ {
uint8_t scanCode = inb(0x60); 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. 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. // CPU::Halt(true); // This is an infinite loop.
} }
} }

View File

@ -23,7 +23,7 @@ namespace CrashHandler
uint64_t rip; uint64_t rip;
}; };
__no_stack_protector void TraceFrames(CHArchTrapFrame *Frame, int Count) SafeFunction void TraceFrames(CHArchTrapFrame *Frame, int Count)
{ {
#if defined(__amd64__) #if defined(__amd64__)

View File

@ -17,7 +17,7 @@
namespace CrashHandler namespace CrashHandler
{ {
__no_stack_protector void DisplayConsoleScreen(CRData data) SafeFunction void DisplayConsoleScreen(CRData data)
{ {
EHPrint("TODO"); EHPrint("TODO");
} }

View File

@ -17,7 +17,7 @@
namespace CrashHandler namespace CrashHandler
{ {
__no_stack_protector void DisplayDetailsScreen(CRData data) SafeFunction void DisplayDetailsScreen(CRData data)
{ {
if (data.Process) if (data.Process)
EHPrint("\e7981FCCurrent Process: %s(%ld)\n", EHPrint("\e7981FCCurrent Process: %s(%ld)\n",

View File

@ -27,7 +27,7 @@ static const char *PagefaultDescriptions[8] = {
namespace CrashHandler namespace CrashHandler
{ {
__no_stack_protector void DisplayMainScreen(CRData data) SafeFunction void DisplayMainScreen(CRData data)
{ {
CHArchTrapFrame *Frame = data.Frame; CHArchTrapFrame *Frame = data.Frame;

View File

@ -1,6 +1,7 @@
#include "../../crashhandler.hpp" #include "../../crashhandler.hpp"
#include "../chfcts.hpp" #include "../chfcts.hpp"
#include <interrupts.hpp>
#include <display.hpp> #include <display.hpp>
#include <printf.h> #include <printf.h>
#include <debug.h> #include <debug.h>
@ -17,9 +18,29 @@
namespace CrashHandler namespace CrashHandler
{ {
__no_stack_protector void DisplayStackFrameScreen(CRData data) SafeFunction void DisplayStackFrameScreen(CRData data)
{ {
EHPrint("\eFAFAFATracing 40 frames...\n"); EHPrint("\eFAFAFATracing 40 frames...\n");
TraceFrames(data.Frame, 40); 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");
}
}
} }
} }

View File

@ -17,7 +17,7 @@
namespace CrashHandler namespace CrashHandler
{ {
__no_stack_protector void DisplayTasksScreen(CRData data) SafeFunction void DisplayTasksScreen(CRData data)
{ {
const char *StatusColor[7] = { const char *StatusColor[7] = {
"FF0000", // Unknown "FF0000", // Unknown

View File

@ -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 to a non-present page entry\n",
"User process tried to write a page and caused a protection fault\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; CriticalSection cs;
debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No"); debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No");

View File

@ -8,13 +8,13 @@ NewLock(DebuggerLock);
using namespace UniversalAsynchronousReceiverTransmitter; 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); UART(COM1).Write(c);
(void)unused; (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; const char *DbgLvlString;
switch (Level) switch (Level)
@ -52,7 +52,7 @@ static inline void WritePrefix(DebugLevel Level, const char *File, int Line, con
namespace SysDbg 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); WritePrefix(Level, File, Line, Function);
va_list args; va_list args;
@ -61,7 +61,7 @@ namespace SysDbg
va_end(args); 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); // SmartLock(DebuggerLock);
WritePrefix(Level, File, Line, Function); WritePrefix(Level, File, Line, Function);
@ -74,7 +74,7 @@ namespace SysDbg
} }
// C compatibility // 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); WritePrefix(Level, File, Line, Function);
va_list args; va_list args;
@ -84,7 +84,7 @@ extern "C" void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, c
} }
// C compatibility // 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); WritePrefix(Level, File, Line, Function);
va_list args; va_list args;

View File

@ -2,19 +2,19 @@
#include <interrupts.hpp> #include <interrupts.hpp>
#include <memory.hpp> #include <memory.hpp>
#include <dumper.hpp>
#include <task.hpp> #include <task.hpp>
#include <lock.hpp> #include <lock.hpp>
#include <printf.h> #include <printf.h>
#include <cwalk.h> #include <cwalk.h>
#include <md5.h> #include <md5.h>
#include "../kernel.h" #include "../../kernel.h"
#include "../DAPI.hpp" #include "../../DAPI.hpp"
#include "../Fex.hpp" #include "../../Fex.hpp"
#include "api.hpp"
NewLock(DriverInitLock); NewLock(DriverInitLock);
NewLock(DriverDisplayPrintLock); NewLock(DriverInterruptLock);
namespace Driver namespace Driver
{ {
@ -28,127 +28,6 @@ namespace Driver
"Input", "Input",
"Audio"}; "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) int Driver::IOCB(unsigned long DUID, void *KCB)
{ {
foreach (auto var in Drivers) foreach (auto var in Drivers)
@ -411,7 +290,48 @@ namespace Driver
} }
case FexDriverType::FexDriverType_Input: 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; break;
} }
case FexDriverType::FexDriverType_Audio: case FexDriverType::FexDriverType_Audio:
@ -430,6 +350,68 @@ namespace Driver
{ {
fixme("Process driver: %s", DrvExtHdr->Driver.Name); 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 else
{ {
error("Unknown driver bind type: %d", DrvExtHdr->Driver.Bind.Type); error("Unknown driver bind type: %d", DrvExtHdr->Driver.Bind.Type);
@ -454,9 +436,9 @@ namespace Driver
if (!strcmp(extension, ".fex")) if (!strcmp(extension, ".fex"))
{ {
uint64_t ret = this->LoadDriver(driver->Address, driver->Length); uint64_t ret = this->LoadDriver(driver->Address, driver->Length);
char retstring[64]; char retstring[128];
if (ret == DriverCode::OK) if (ret == DriverCode::OK)
strcpy(retstring, "\e058C19OK"); strncpy(retstring, "\e058C19OK", 64);
else else
sprintf_(retstring, "\eE85230FAILED (%#lx)", ret); sprintf_(retstring, "\eE85230FAILED (%#lx)", ret);
KPrint("%s %s", driver->Name, retstring); KPrint("%s %s", driver->Name, retstring);
@ -477,7 +459,7 @@ namespace Driver
void DriverInterruptHook::OnInterruptReceived(void *Frame) void DriverInterruptHook::OnInterruptReceived(void *Frame)
#endif #endif
{ {
CriticalSection cs; // or SmartCriticalSection(DriverInitLock); ? SmartCriticalSection(DriverInterruptLock);
((int (*)(void *))(Handle))(Data); ((int (*)(void *))(Handle))(Data);
} }

131
Core/Driver/DriverAPI.cpp Normal file
View File

@ -0,0 +1,131 @@
#include <driver.hpp>
#include <dumper.hpp>
#include <lock.hpp>
#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,
},
},
},
};

10
Core/Driver/api.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef __FENNIX_KERNEL_DRIVER_API_H__
#define __FENNIX_KERNEL_DRIVER_API_H__
#include <types.h>
#include "../../DAPI.hpp"
extern KernelAPI KAPI;
#endif // !__FENNIX_KERNEL_DRIVER_API_H__

View File

@ -19,7 +19,7 @@
#include "../crashhandler.hpp" #include "../crashhandler.hpp"
#include "../kernel.h" #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 namespace Interrupts
{ {
@ -32,6 +32,7 @@ namespace Interrupts
/* APIC::APIC */ void *apic[MAX_CPU]; /* APIC::APIC */ void *apic[MAX_CPU];
#elif defined(__aarch64__) #elif defined(__aarch64__)
#endif #endif
void *InterruptFrames[INT_FRAMES_MAX];
void Initialize(int Core) void Initialize(int Core)
{ {
@ -103,25 +104,42 @@ namespace Interrupts
#endif #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__) #if defined(__amd64__)
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data; CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
int Core = GetCurrentCPU()->ID;
Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber); memmove(InterruptFrames + 1, InterruptFrames, sizeof(InterruptFrames) - sizeof(InterruptFrames[0]));
if (handler != (Handler *)0xdeadbeef) InterruptFrames[0] = (void *)Frame->rip;
handler->OnInterruptReceived(Frame);
else CPUData *CoreData = GetCurrentCPU();
error("Unhandled IRQ%d on CPU %d.", Frame->InterruptNumber - 32, Core); 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(); Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber);
// TODO: Handle PIC too if (likely(handler != (Handler *)0xdeadbeef))
return; 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__) #elif defined(__i386__)
void *Frame = Data; void *Frame = Data;
#elif defined(__aarch64__) #elif defined(__aarch64__)

View File

@ -20,6 +20,15 @@ void LockClass::DeadLock(SpinLockData Lock)
this->DeadLocks++; 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) if (TaskManager)
TaskManager->Schedule(); TaskManager->Schedule();
} }

View File

@ -2,6 +2,72 @@
namespace Xalloc 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 class SmartSMAPClass
{ {
private: private:
@ -20,6 +86,7 @@ namespace Xalloc
AllocatorV1::AllocatorV1(void *Address, bool UserMode, bool SMAPEnabled) AllocatorV1::AllocatorV1(void *Address, bool UserMode, bool SMAPEnabled)
{ {
SmartSMAP; SmartSMAP;
XSL;
void *Position = Address; void *Position = Address;
UserMapping = UserMode; UserMapping = UserMode;
SMAPUsed = SMAPEnabled; SMAPUsed = SMAPEnabled;
@ -47,6 +114,7 @@ namespace Xalloc
AllocatorV1::~AllocatorV1() AllocatorV1::~AllocatorV1()
{ {
SmartSMAP; SmartSMAP;
XSL;
Xalloc_trace("Destructor not implemented yet."); Xalloc_trace("Destructor not implemented yet.");
} }
@ -81,6 +149,7 @@ namespace Xalloc
void *AllocatorV1::Malloc(Xuint64_t Size) void *AllocatorV1::Malloc(Xuint64_t Size)
{ {
SmartSMAP; SmartSMAP;
XSL;
if (this->HeapStart == nullptr) if (this->HeapStart == nullptr)
{ {
Xalloc_err("Memory allocation not initialized yet!"); Xalloc_err("Memory allocation not initialized yet!");
@ -136,12 +205,14 @@ namespace Xalloc
CurrentSegment = CurrentSegment->Next; CurrentSegment = CurrentSegment->Next;
} }
ExpandHeap(Size); ExpandHeap(Size);
XLock.Unlock();
return this->Malloc(Size); return this->Malloc(Size);
} }
void AllocatorV1::Free(void *Address) void AllocatorV1::Free(void *Address)
{ {
SmartSMAP; SmartSMAP;
XSL;
if (this->HeapStart == nullptr) if (this->HeapStart == nullptr)
{ {
Xalloc_err("Memory allocation not initialized yet!"); Xalloc_err("Memory allocation not initialized yet!");
@ -156,6 +227,7 @@ namespace Xalloc
void *AllocatorV1::Calloc(Xuint64_t NumberOfBlocks, Xuint64_t Size) void *AllocatorV1::Calloc(Xuint64_t NumberOfBlocks, Xuint64_t Size)
{ {
SmartSMAP; SmartSMAP;
XSL;
if (this->HeapStart == nullptr) if (this->HeapStart == nullptr)
{ {
Xalloc_err("Memory allocation not initialized yet!"); Xalloc_err("Memory allocation not initialized yet!");
@ -168,7 +240,10 @@ namespace Xalloc
Size = 0x10; Size = 0x10;
} }
XLock.Unlock();
void *Block = this->Malloc(NumberOfBlocks * Size); void *Block = this->Malloc(NumberOfBlocks * Size);
XLock.Lock(__FUNCTION__);
if (Block) if (Block)
Xmemset(Block, 0, NumberOfBlocks * Size); Xmemset(Block, 0, NumberOfBlocks * Size);
return Block; return Block;
@ -177,6 +252,7 @@ namespace Xalloc
void *AllocatorV1::Realloc(void *Address, Xuint64_t Size) void *AllocatorV1::Realloc(void *Address, Xuint64_t Size)
{ {
SmartSMAP; SmartSMAP;
XSL;
if (this->HeapStart == nullptr) if (this->HeapStart == nullptr)
{ {
Xalloc_err("Memory allocation not initialized yet!"); Xalloc_err("Memory allocation not initialized yet!");
@ -184,11 +260,13 @@ namespace Xalloc
} }
if (!Address && Size == 0) if (!Address && Size == 0)
{ {
XLock.Unlock();
this->Free(Address); this->Free(Address);
return nullptr; return nullptr;
} }
else if (!Address) else if (!Address)
{ {
XLock.Unlock();
return this->Calloc(Size, sizeof(char)); return this->Calloc(Size, sizeof(char));
} }
@ -198,7 +276,9 @@ namespace Xalloc
Size = 0x10; Size = 0x10;
} }
XLock.Unlock();
void *newAddress = this->Calloc(Size, sizeof(char)); void *newAddress = this->Calloc(Size, sizeof(char));
XLock.Lock(__FUNCTION__);
Xmemcpy(newAddress, Address, Size); Xmemcpy(newAddress, Address, Size);
return newAddress; return newAddress;
} }

View File

@ -16,7 +16,7 @@ static MemoryAllocatorType AllocatorType = MemoryAllocatorType::None;
Xalloc::AllocatorV1 *XallocV1Allocator = nullptr; Xalloc::AllocatorV1 *XallocV1Allocator = nullptr;
#ifdef DEBUG #ifdef DEBUG
void tracepagetable(PageTable *pt) __no_instrument_function void tracepagetable(PageTable *pt)
{ {
for (int i = 0; i < 512; i++) for (int i = 0; i < 512; i++)
{ {
@ -37,11 +37,12 @@ void tracepagetable(PageTable *pt)
} }
#endif #endif
void MapFromZero(PageTable *PT, BootInfo *Info) __no_instrument_function void MapFromZero(PageTable *PT, BootInfo *Info)
{ {
Virtual va = Virtual(PT); Virtual va = Virtual(PT);
uint64_t VirtualOffsetNormalVMA = NORMAL_VMA_OFFSET; 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 *)t, (void *)t, PTFlag::RW);
va.Map((void *)VirtualOffsetNormalVMA, (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); Virtual va = Virtual(PT);
int itrfb = 0; 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 /* KernelStart KernelTextEnd KernelRoDataEnd KernelEnd
Kernel Start & Text Start ------ Text End ------ Kernel Rodata End ------ Kernel Data End & Kernel End 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 KernelEnd = (uint64_t)&_kernel_end;
uint64_t BaseKernelMapAddress = (uint64_t)Info->Kernel.PhysicalBase; 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); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.LockPage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; 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); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.LockPage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; 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); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::P);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.LockPage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; 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); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.LockPage((void *)BaseKernelMapAddress);
@ -111,8 +114,9 @@ void MapKernel(PageTable *PT, BootInfo *Info)
KernelStart, KernelTextEnd, KernelRoDataEnd, KernelEnd, Info->Kernel.PhysicalBase, BaseKernelMapAddress - PAGE_SIZE); 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++) for (uint64_t i = 0; i < Info->Memory.Entries; i++)
{ {
uint64_t Base = reinterpret_cast<uint64_t>(Info->Memory.Entry[i].BaseAddress); uint64_t Base = reinterpret_cast<uint64_t>(Info->Memory.Entry[i].BaseAddress);
@ -122,7 +126,7 @@ void InitializeMemoryManagement(BootInfo *Info)
switch (Info->Memory.Entry[i].Type) switch (Info->Memory.Entry[i].Type)
{ {
case Usable: case likely(Usable):
Type = "Usable"; Type = "Usable";
break; break;
case Reserved: case Reserved:
@ -150,12 +154,13 @@ void InitializeMemoryManagement(BootInfo *Info)
break; break;
} }
trace("%lld: %#016llx-%#016llx %s", debug("%lld: %#016llx-%#016llx %s",
i, i,
Base, Base,
End, End,
Type); Type);
} }
#endif
trace("Initializing Physical Memory Manager"); trace("Initializing Physical Memory Manager");
KernelAllocator = Physical(); KernelAllocator = Physical();
@ -177,7 +182,8 @@ void InitializeMemoryManagement(BootInfo *Info)
debug("Mapping from 0x0 to %#llx", Info->Memory.Size); debug("Mapping from 0x0 to %#llx", Info->Memory.Size);
MapFromZero(KernelPageTable, Info); MapFromZero(KernelPageTable, Info);
debug("Mapping from 0x0 %#llx for Userspace Page Table", Info->Memory.Size); 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 */ /* Mapping Framebuffer address */
debug("Mapping Framebuffer"); debug("Mapping Framebuffer");
@ -219,10 +225,14 @@ void *HeapMalloc(uint64_t Size)
{ {
switch (AllocatorType) switch (AllocatorType)
{ {
case MemoryAllocatorType::Pages: case unlikely(MemoryAllocatorType::Pages):
return KernelAllocator.RequestPages(TO_PAGES(Size)); return KernelAllocator.RequestPages(TO_PAGES(Size));
case MemoryAllocatorType::XallocV1: case MemoryAllocatorType::XallocV1:
return XallocV1Allocator->Malloc(Size); {
void *ret = XallocV1Allocator->Malloc(Size);
memset(ret, 0, Size);
return ret;
}
case MemoryAllocatorType::liballoc11: case MemoryAllocatorType::liballoc11:
{ {
void *ret = PREFIX(malloc)(Size); void *ret = PREFIX(malloc)(Size);
@ -238,10 +248,14 @@ void *HeapCalloc(uint64_t n, uint64_t Size)
{ {
switch (AllocatorType) switch (AllocatorType)
{ {
case MemoryAllocatorType::Pages: case unlikely(MemoryAllocatorType::Pages):
return KernelAllocator.RequestPages(TO_PAGES(n * Size)); return KernelAllocator.RequestPages(TO_PAGES(n * Size));
case MemoryAllocatorType::XallocV1: case MemoryAllocatorType::XallocV1:
return XallocV1Allocator->Calloc(n, Size); {
void *ret = XallocV1Allocator->Calloc(n, Size);
memset(ret, 0, n * Size);
return ret;
}
case MemoryAllocatorType::liballoc11: case MemoryAllocatorType::liballoc11:
{ {
void *ret = PREFIX(calloc)(n, Size); void *ret = PREFIX(calloc)(n, Size);
@ -257,10 +271,14 @@ void *HeapRealloc(void *Address, uint64_t Size)
{ {
switch (AllocatorType) switch (AllocatorType)
{ {
case MemoryAllocatorType::Pages: case unlikely(MemoryAllocatorType::Pages):
return KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak return KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak
case MemoryAllocatorType::XallocV1: case MemoryAllocatorType::XallocV1:
return XallocV1Allocator->Realloc(Address, Size); {
void *ret = XallocV1Allocator->Realloc(Address, Size);
memset(ret, 0, Size);
return ret;
}
case MemoryAllocatorType::liballoc11: case MemoryAllocatorType::liballoc11:
{ {
void *ret = PREFIX(realloc)(Address, Size); void *ret = PREFIX(realloc)(Address, Size);
@ -276,11 +294,12 @@ void HeapFree(void *Address)
{ {
switch (AllocatorType) switch (AllocatorType)
{ {
case MemoryAllocatorType::Pages: case unlikely(MemoryAllocatorType::Pages):
KernelAllocator.FreePage(Address); // WARNING: Potential memory leak KernelAllocator.FreePage(Address); // WARNING: Potential memory leak
break; break;
case MemoryAllocatorType::XallocV1: case MemoryAllocatorType::XallocV1:
XallocV1Allocator->Free(Address); if (XallocV1Allocator)
XallocV1Allocator->Free(Address);
break; break;
case MemoryAllocatorType::liballoc11: case MemoryAllocatorType::liballoc11:
PREFIX(free) PREFIX(free)
@ -291,20 +310,32 @@ void HeapFree(void *Address)
} }
} }
void *operator new(size_t Size) { void *operator new(size_t Size)
return HeapMalloc(Size); } {
void *operator new[](size_t Size) { return HeapMalloc(Size);
return HeapMalloc(Size); } }
void *operator new[](size_t Size)
{
return HeapMalloc(Size);
}
void *operator new(unsigned long Size, std::align_val_t Alignment) void *operator new(unsigned long Size, std::align_val_t Alignment)
{ {
fixme("operator new with alignment(%#lx) is not implemented", Alignment); fixme("operator new with alignment(%#lx) is not implemented", Alignment);
return HeapMalloc(Size); return HeapMalloc(Size);
} }
void operator delete(void *Pointer) { void operator delete(void *Pointer)
HeapFree(Pointer); } {
void operator delete[](void *Pointer) { HeapFree(Pointer);
HeapFree(Pointer); } }
void operator delete(void *Pointer, long unsigned int Size) { void operator delete[](void *Pointer)
HeapFree(Pointer); } {
void operator delete[](void *Pointer, long unsigned int Size) { HeapFree(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);
}

View File

@ -265,7 +265,7 @@ namespace Memory
trace("Reserving pages..."); trace("Reserving pages...");
this->ReservePages(0, MemorySize / PAGE_SIZE + 1); 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++) for (uint64_t i = 0; i < Info->Memory.Entries; i++)
if (Info->Memory.Entry[i].Type == Usable) if (Info->Memory.Entry[i].Type == Usable)
this->UnreservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1); this->UnreservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1);

View File

@ -14,6 +14,8 @@ namespace Power
{ {
void Power::Reboot() void Power::Reboot()
{ {
BeforeShutdown();
if (((ACPI::ACPI *)this->acpi)->FADT) if (((ACPI::ACPI *)this->acpi)->FADT)
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported) if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
((ACPI::DSDT *)this->dsdt)->Reboot(); ((ACPI::DSDT *)this->dsdt)->Reboot();
@ -42,6 +44,8 @@ namespace Power
void Power::Shutdown() void Power::Shutdown()
{ {
BeforeShutdown();
if (((ACPI::ACPI *)this->acpi)->FADT) if (((ACPI::ACPI *)this->acpi)->FADT)
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported) if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
((ACPI::DSDT *)this->dsdt)->Shutdown(); ((ACPI::DSDT *)this->dsdt)->Shutdown();

View File

@ -5,37 +5,32 @@
#ifndef STACK_CHK_GUARD_VALUE #ifndef STACK_CHK_GUARD_VALUE
#if UINTPTR_MAX == UINT32_MAX #if UINTPTR_MAX == UINT32_MAX
#define STACK_CHK_GUARD_VALUE 0x25F6CC8D #define STACK_CHK_GUARD_VALUE 0xDEAD57AC
#else #else
#define STACK_CHK_GUARD_VALUE 0xBADFE2EC255A8572 #define STACK_CHK_GUARD_VALUE 0xDEAD57AC00000000
#endif #endif
#endif #endif
__attribute__((weak)) uintptr_t __stack_chk_guard = 0; __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; 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) if (__stack_chk_guard == 0)
__stack_chk_guard = __stack_chk_guard_init(); __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) __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
{ {
TaskingPanic(); 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!"); KPrint("\eFF0000Stack smashing detected!");
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
while (1) 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) __attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void)
{ {
TaskingPanic(); TaskingPanic();
error("Buffer overflow detected!"); for (short i = 0; i < 10; i++)
error("Buffer overflow detected!");
KPrint("\eFF0000Buffer overflow detected!"); KPrint("\eFF0000Buffer overflow detected!");
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
while (1) while (1)

View File

@ -123,7 +123,7 @@ namespace SymbolResolver
Symbols::~Symbols() {} Symbols::~Symbols() {}
const char *Symbols::GetSymbolFromAddress(uint64_t Address) const __no_instrument_function char *Symbols::GetSymbolFromAddress(uint64_t Address)
{ {
Symbols::SymbolTable Result{0, (char *)"<unknown>"}; Symbols::SymbolTable Result{0, (char *)"<unknown>"};
for (size_t i = 0; i < TotalEntries; i++) for (size_t i = 0; i < TotalEntries; i++)

View File

@ -115,27 +115,41 @@ const char *Type_Check_Kinds[] = {
"Cast to virtual base of", "Cast to virtual base of",
}; };
// Prevent huge spam from ubsan
bool UBSANMsg(const char *file, uint32_t line, uint32_t column) bool UBSANMsg(const char *file, uint32_t line, uint32_t column)
{ {
// blacklist // 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; return false;
static char *onceFile[512] = {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}; if (strstr(file, "SystemManagementBIOS.cpp") &&
static uint32_t onceLine[512] = {0}; ((line == 30 && column == 21) ||
static uint32_t onceColumn[512] = {0}; (line == 27 && column == 49) ||
static uint32_t onceCount = 0; (line == 45 && column == 26)))
return false;
for (uint32_t i = 0; i < onceCount; i++) if (strstr(file, "cwalk.c") &&
if ((!strcmp(onceFile[i], file)) && onceLine[i] == line && onceColumn[i] == column) ((line == 1047 && column == 15)))
return false; 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); ubsan("\t\tIn File: %s:%i:%i", file, line, column);
onceCount++;
return true; return true;
} }

View File

@ -2,11 +2,28 @@
#include <vector.hpp> #include <vector.hpp>
#include <debug.h> #include <debug.h>
#include <io.h>
volatile bool serialports[8] = {false, false, false, false, false, false, false, false}; volatile bool serialports[8] = {false, false, false, false, false, false, false, false};
Vector<UniversalAsynchronousReceiverTransmitter::Events *> RegisteredEvents; Vector<UniversalAsynchronousReceiverTransmitter::Events *> 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 namespace UniversalAsynchronousReceiverTransmitter
{ {
#define SERIAL_ENABLE_DLAB 0x80 #define SERIAL_ENABLE_DLAB 0x80
@ -14,7 +31,7 @@ namespace UniversalAsynchronousReceiverTransmitter
#define SERIAL_RATE_38400_HI 0x00 #define SERIAL_RATE_38400_HI 0x00
#define SERIAL_BUFFER_EMPTY 0x20 #define SERIAL_BUFFER_EMPTY 0x20
UART::UART(SerialPorts Port) SafeFunction __no_instrument_function UART::UART(SerialPorts Port)
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
if (Port == COMNULL) if (Port == COMNULL)
@ -57,16 +74,16 @@ namespace UniversalAsynchronousReceiverTransmitter
return; return;
// Initialize the serial port // Initialize the serial port
outb(Port + 1, 0x00); // Disable all interrupts NoProfiler_outportb(Port + 1, 0x00); // Disable all interrupts
outb(Port + 3, SERIAL_ENABLE_DLAB); // Enable DLAB (set baud rate divisor) NoProfiler_outportb(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 NoProfiler_outportb(Port + 0, SERIAL_RATE_38400_LO); // Set divisor to 3 (lo byte) 38400 baud
outb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte) NoProfiler_outportb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte)
outb(Port + 3, 0x03); // 8 bits, no parity, one stop bit NoProfiler_outportb(Port + 3, 0x03); // 8 bits, no parity, one stop bit
outb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold NoProfiler_outportb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set NoProfiler_outportb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
// Check if the serial port is faulty. // Check if the serial port is faulty.
if (inb(Port + 0) != 0xAE) if (NoProfiler_inportb(Port + 0) != 0xAE)
{ {
static int once = 0; static int once = 0;
if (!once++) if (!once++)
@ -76,50 +93,50 @@ namespace UniversalAsynchronousReceiverTransmitter
} }
// Set to normal operation mode. // Set to normal operation mode.
outb(Port + 4, 0x0F); NoProfiler_outportb(Port + 4, 0x0F);
serialports[PortNumber] = true; serialports[PortNumber] = true;
#endif #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__) #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 #endif
foreach (auto e in RegisteredEvents) foreach (auto e in RegisteredEvents)
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL) if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
e->OnSent(Char); e->OnSent(Char);
} }
uint8_t UART::Read() SafeFunction __no_instrument_function uint8_t UART::Read()
{ {
#if defined(__amd64__) || defined(__i386__) #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 #endif
foreach (auto e in RegisteredEvents) foreach (auto e in RegisteredEvents)
{ {
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL) if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
e->OnReceived(inb(Port)); e->OnReceived(NoProfiler_inportb(Port));
#endif #endif
} }
} }
} }
Events::Events(SerialPorts Port) SafeFunction __no_instrument_function Events::Events(SerialPorts Port)
{ {
this->Port = Port; this->Port = Port;
RegisteredEvents.push_back(this); RegisteredEvents.push_back(this);
} }
Events::~Events() SafeFunction __no_instrument_function Events::~Events()
{ {
for (uint64_t i = 0; i < RegisteredEvents.size(); i++) for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
if (RegisteredEvents[i] == this) if (RegisteredEvents[i] == this)

View File

@ -2,10 +2,14 @@
#define __FENNIX_KERNEL_CRASH_HANDELR_H__ #define __FENNIX_KERNEL_CRASH_HANDELR_H__
#include <types.h> #include <types.h>
#include <interrupts.hpp>
#include <cpu.hpp> #include <cpu.hpp>
namespace CrashHandler namespace CrashHandler
{ {
extern void *EHIntFrames[INT_FRAMES_MAX];
void EHPrint(const char *Format, ...); void EHPrint(const char *Format, ...);
void Handle(void *Data); void Handle(void *Data);
} }

View File

@ -14,6 +14,7 @@ enum DriverReturnCode
NOT_ACCEPTED, NOT_ACCEPTED,
INVALID_KERNEL_API, INVALID_KERNEL_API,
DEVICE_NOT_SUPPORTED, DEVICE_NOT_SUPPORTED,
SYSTEM_NOT_SUPPORTED,
KERNEL_API_VERSION_NOT_SUPPORTED KERNEL_API_VERSION_NOT_SUPPORTED
}; };
@ -22,7 +23,8 @@ enum DriverBindType
BIND_NULL, BIND_NULL,
BIND_INTERRUPT, BIND_INTERRUPT,
BIND_PROCESS, BIND_PROCESS,
BIND_PCI BIND_PCI,
BIND_INPUT
}; };
struct KernelAPI 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); void (*WriteSector)(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port);
} AHCI; } AHCI;
} Disk; } Disk;
} Commmand; } Command;
} __attribute__((packed)); } __attribute__((packed));
@ -95,7 +97,8 @@ enum CallbackReason
BindReason, BindReason,
UnbindReason, UnbindReason,
InterruptReason, InterruptReason,
ProcessReason ProcessReason,
InputReason,
}; };
struct KernelCallback struct KernelCallback
@ -130,6 +133,22 @@ struct KernelCallback
} Fetch; } Fetch;
} DiskCallback; } DiskCallback;
struct
{
struct
{
unsigned long X;
unsigned long Y;
unsigned long Z;
struct
{
bool Left;
bool Right;
bool Middle;
} Buttons;
} Mouse;
} InputCallback;
struct struct
{ {
unsigned char Vector; unsigned char Vector;

View File

@ -87,6 +87,12 @@ struct FexExtended
unsigned short SubClass; unsigned short SubClass;
unsigned short ProgIF; unsigned short ProgIF;
} PCI; } PCI;
struct
{
bool AttachToMouse;
bool AttachToKeyboard;
} Input;
} Bind; } Bind;
} Driver; } Driver;
} __attribute__((packed)); } __attribute__((packed));

View File

@ -19,7 +19,7 @@ namespace FileSystem
return Size; return Size;
} }
FileSystemOpeations ustar = { FileSystemOperations ustar = {
.Name = "ustar", .Name = "ustar",
.Read = USTAR_Read, .Read = USTAR_Read,
}; };

View File

@ -60,7 +60,7 @@ namespace FileSystem
if (strcmp(Parent->Name, Path)) if (strcmp(Parent->Name, Path))
{ {
cwk_segment segment; 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."); error("Path doesn't have any segments.");
return nullptr; return nullptr;
@ -104,13 +104,13 @@ namespace FileSystem
vfsdbg("AddNewChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name); vfsdbg("AddNewChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
FileSystemNode *newNode = new FileSystemNode; FileSystemNode *newNode = new FileSystemNode;
newNode->Parent = Parent; newNode->Parent = Parent;
strcpy(newNode->Name, Name); strncpy(newNode->Name, Name, FILENAME_LENGTH);
if (Parent) if (likely(Parent))
newNode->Operator = Parent->Operator; newNode->Operator = Parent->Operator;
else else
newNode->Operator = nullptr; newNode->Operator = nullptr;
if (Parent) if (likely(Parent))
Parent->Children.push_back(newNode); Parent->Children.push_back(newNode);
vfsdbg("AddNewChild()->\"%s\"", newNode->Name); vfsdbg("AddNewChild()->\"%s\"", newNode->Name);
return newNode; return newNode;
@ -119,7 +119,7 @@ namespace FileSystem
FileSystemNode *GetChild(FileSystemNode *Parent, const char *Name) FileSystemNode *GetChild(FileSystemNode *Parent, const char *Name)
{ {
vfsdbg("GetChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name); vfsdbg("GetChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
if (Parent) if (likely(Parent))
foreach (auto var in Parent->Children) foreach (auto var in Parent->Children)
if (strcmp(var->Name, Name) == 0) if (strcmp(var->Name, Name) == 0)
{ {
@ -181,7 +181,7 @@ namespace FileSystem
char *NormalizedPath = NormalizePath(Parent, Path); char *NormalizedPath = NormalizePath(Parent, Path);
FileSystemNode *Node = GetNodeFromPath(Parent, NormalizedPath); FileSystemNode *Node = GetNodeFromPath(Parent, NormalizedPath);
if (Node == nullptr) if (!Node)
{ {
vfsdbg("FileExists()->NOT_FOUND"); vfsdbg("FileExists()->NOT_FOUND");
return FileStatus::NOT_FOUND; return FileStatus::NOT_FOUND;
@ -204,7 +204,7 @@ namespace FileSystem
FileSystemNode *CurrentParent = nullptr; FileSystemNode *CurrentParent = nullptr;
if (Parent == nullptr) if (!Parent)
{ {
if (FileSystemRoot->Children.size() >= 1) if (FileSystemRoot->Children.size() >= 1)
{ {
@ -270,27 +270,27 @@ namespace FileSystem
return nullptr; return nullptr;
} }
FileSystemNode *Virtual::CreateRoot(FileSystemOpeations *Operator, const char *RootName) FileSystemNode *Virtual::CreateRoot(FileSystemOperations *Operator, const char *RootName)
{ {
if (Operator == nullptr) if (Operator == nullptr)
return nullptr; return nullptr;
vfsdbg("Setting root to %s", RootName); vfsdbg("Setting root to %s", RootName);
FileSystemNode *newNode = new FileSystemNode; FileSystemNode *newNode = new FileSystemNode;
strcpy(newNode->Name, RootName); strncpy(newNode->Name, RootName, FILENAME_LENGTH);
newNode->Flags = NodeFlags::FS_DIRECTORY; newNode->Flags = NodeFlags::FS_DIRECTORY;
newNode->Operator = Operator; newNode->Operator = Operator;
FileSystemRoot->Children.push_back(newNode); FileSystemRoot->Children.push_back(newNode);
return newNode; return newNode;
} }
FILE *Virtual::Mount(FileSystemOpeations *Operator, const char *Path) FILE *Virtual::Mount(FileSystemOperations *Operator, const char *Path)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (Operator == nullptr) if (unlikely(!Operator))
return nullptr; return nullptr;
if (isempty((char *)Path)) if (unlikely(isempty((char *)Path)))
return nullptr; return nullptr;
vfsdbg("Mounting %s", Path); vfsdbg("Mounting %s", Path);
@ -306,7 +306,7 @@ namespace FileSystem
FileStatus Virtual::Unmount(FILE *File) FileStatus Virtual::Unmount(FILE *File)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (File == nullptr) if (unlikely(File))
return FileStatus::INVALID_PARAMETER; return FileStatus::INVALID_PARAMETER;
vfsdbg("Unmounting %s", File->Name); vfsdbg("Unmounting %s", File->Name);
return FileStatus::OK; return FileStatus::OK;
@ -322,7 +322,7 @@ namespace FileSystem
FILE *file = new FILE; FILE *file = new FILE;
FileStatus filestatus = FileStatus::OK; FileStatus filestatus = FileStatus::OK;
file->Node = Parent; file->Node = Parent;
if (file->Node == nullptr) if (unlikely(!file->Node))
file->Status = FileStatus::NOT_FOUND; file->Status = FileStatus::NOT_FOUND;
const char *basename; const char *basename;
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr); cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
@ -338,7 +338,7 @@ namespace FileSystem
FILE *file = new FILE; FILE *file = new FILE;
FileStatus filestatus = FileStatus::OK; FileStatus filestatus = FileStatus::OK;
file->Node = Parent; file->Node = Parent;
if (file->Node == nullptr) if (!file->Node)
file->Status = FileStatus::NOT_FOUND; file->Status = FileStatus::NOT_FOUND;
const char *basename; const char *basename;
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr); cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
@ -388,7 +388,7 @@ namespace FileSystem
} }
file->Node = GetNodeFromPath(FileSystemRoot->Children[0], CleanPath); file->Node = GetNodeFromPath(FileSystemRoot->Children[0], CleanPath);
if (file->Node != nullptr) if (file->Node)
{ {
const char *basename; const char *basename;
cwk_path_get_basename(GetPathFromNode(file->Node), &basename, nullptr); cwk_path_get_basename(GetPathFromNode(file->Node), &basename, nullptr);
@ -403,7 +403,7 @@ namespace FileSystem
else else
{ {
file->Node = GetNodeFromPath(Parent, CleanPath); file->Node = GetNodeFromPath(Parent, CleanPath);
if (file->Node == nullptr) if (unlikely(!file->Node))
file->Status = FileStatus::NOT_FOUND; file->Status = FileStatus::NOT_FOUND;
const char *basename; const char *basename;
cwk_path_get_basename(CleanPath, &basename, nullptr); 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) uint64_t Virtual::Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (File == nullptr) if (unlikely(!File))
return 0; return 0;
File->Status = FileStatus::OK; File->Status = FileStatus::OK;
if (File->Node == nullptr) if (unlikely(!File->Node))
{ {
File->Status = FileStatus::INVALID_PARAMETER; File->Status = FileStatus::INVALID_PARAMETER;
return 0; return 0;
} }
if (File->Node->Operator == nullptr) if (unlikely(!File->Node->Operator))
{ {
File->Status = FileStatus::INVALID_PARAMETER; File->Status = FileStatus::INVALID_PARAMETER;
return 0; return 0;
@ -440,18 +440,18 @@ namespace FileSystem
uint64_t Virtual::Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size) uint64_t Virtual::Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (File == nullptr) if (unlikely(!File))
return 0; return 0;
File->Status = FileStatus::OK; File->Status = FileStatus::OK;
if (File->Node == nullptr) if (unlikely(!File->Node))
{ {
File->Status = FileStatus::INVALID_PARAMETER; File->Status = FileStatus::INVALID_PARAMETER;
return 0; return 0;
} }
if (File->Node->Operator == nullptr) if (unlikely(!File->Node->Operator))
{ {
File->Status = FileStatus::INVALID_PARAMETER; File->Status = FileStatus::INVALID_PARAMETER;
return 0; return 0;
@ -463,7 +463,7 @@ namespace FileSystem
FileStatus Virtual::Close(FILE *File) FileStatus Virtual::Close(FILE *File)
{ {
SmartLock(VFSLock); SmartLock(VFSLock);
if (File == nullptr) if (unlikely(!File))
return FileStatus::INVALID_HANDLE; return FileStatus::INVALID_HANDLE;
vfsdbg("Closing %s", File->Name); vfsdbg("Closing %s", File->Name);
delete File; delete File;
@ -477,12 +477,12 @@ namespace FileSystem
FileSystemRoot->Flags = NodeFlags::FS_MOUNTPOINT; FileSystemRoot->Flags = NodeFlags::FS_MOUNTPOINT;
FileSystemRoot->Operator = nullptr; FileSystemRoot->Operator = nullptr;
FileSystemRoot->Parent = nullptr; FileSystemRoot->Parent = nullptr;
strcpy(FileSystemRoot->Name, "root"); strncpy(FileSystemRoot->Name, "root", 4);
cwk_path_set_style(CWK_STYLE_UNIX); cwk_path_set_style(CWK_STYLE_UNIX);
} }
Virtual::~Virtual() Virtual::~Virtual()
{ {
warn("Tried to uninitialize Virtual File System!"); warn("Tried to deinitialize Virtual File System!");
} }
} }

View File

@ -49,11 +49,17 @@ static struct cag_option ConfigOptions[] = {
.value_name = "PATH", .value_name = "PATH",
.description = "Path to init program"}, .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', {.identifier = 'o',
.access_letters = NULL, .access_letters = NULL,
.access_name = "ioc", .access_name = "ioc",
.value_name = "BOOL", .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', {.identifier = 'h',
.access_letters = "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', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'},
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'}, {'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'},
false, false,
0}; 0,
false};
if (Config == NULL) if (Config == NULL)
{ {
@ -331,14 +338,14 @@ ParseSuccess:
case 'd': case 'd':
{ {
value = cag_option_get_value(&context); value = cag_option_get_value(&context);
strcpy(config.DriverDirectory, value); strncpy(config.DriverDirectory, value, strlen(value));
KPrint("\eAAFFAAUsing %s as driver directory", value); KPrint("\eAAFFAAUsing %s as driver directory", value);
break; break;
} }
case 'i': case 'i':
{ {
value = cag_option_get_value(&context); value = cag_option_get_value(&context);
strcpy(config.InitPath, value); strncpy(config.InitPath, value, strlen(value));
KPrint("\eAAFFAAUsing %s as init program", value); KPrint("\eAAFFAAUsing %s as init program", value);
break; break;
} }
@ -349,6 +356,13 @@ ParseSuccess:
KPrint("\eAAFFAAInterrupts on crash: %s", value); KPrint("\eAAFFAAInterrupts on crash: %s", value);
break; 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': case 'h':
{ {
KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration."); KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration.");

View File

@ -14,65 +14,33 @@
Driver::Driver *DriverManager = nullptr; Driver::Driver *DriverManager = nullptr;
Disk::Manager *DiskManager = 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() void KernelMainThread()
{ {
TaskManager->InitIPC(); TaskManager->InitIPC();
TaskManager->GetCurrentThread()->SetPriority(100);
Vector<AuxiliaryVector> auxv; Vector<AuxiliaryVector> auxv;
Tasking::TCB *CurrentWorker = nullptr; Tasking::TCB *CurrentWorker = nullptr;
KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD); KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD);
KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus); KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus);
TaskManager->GetCurrentThread()->SetPriority(1);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem, nullptr, nullptr, auxv); KPrint("Initializing Filesystem...");
CurrentWorker->Rename("Filesystems"); vfs = new FileSystem::Virtual;
CurrentWorker->SetPriority(100); new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
TaskManager->WaitForThread(CurrentWorker); KPrint("Initializing Disk Manager...");
DiskManager = new Disk::Manager;
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)LoadDrivers, nullptr, nullptr, auxv); KPrint("Loading Drivers...");
CurrentWorker->Rename("Drivers"); DriverManager = new Driver::Driver;
CurrentWorker->SetPriority(100);
TaskManager->WaitForThread(CurrentWorker);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks, nullptr, nullptr, auxv); KPrint("Fetching Disks...");
CurrentWorker->Rename("Disks"); foreach (auto Driver in DriverManager->GetDrivers())
CurrentWorker->SetPriority(100); if (((FexExtended *)((uint64_t)Driver->Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Storage)
TaskManager->WaitForThread(CurrentWorker); DiskManager->FetchDisks(Driver->DriverUID);
KPrint("Setting up userspace..."); KPrint("Setting up userspace...");
const char *envp[] = { const char *envp[9] = {
"PATH=/system:/system/bin", "PATH=/system:/system/bin",
"TERM=tty", "TERM=tty",
"HOME=/", "HOME=/",
@ -83,12 +51,11 @@ void KernelMainThread()
"TZ=UTC", "TZ=UTC",
nullptr}; nullptr};
const char *argv[] = { const char *argv[3] = {
"--init", "--init",
"--critical", "--critical",
nullptr}; nullptr};
// TODO: Untested!
bool ien = CPU::Interrupts(CPU::Check); bool ien = CPU::Interrupts(CPU::Check);
CPU::Interrupts(CPU::Disable); CPU::Interrupts(CPU::Disable);
Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argv, envp); Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argv, envp);
@ -100,9 +67,12 @@ void KernelMainThread()
goto Exit; goto Exit;
} }
ret.Thread->SetCritical(true); ret.Thread->SetCritical(true);
debug("%s interrupts", ien ? "Enabling" : "Disabling");
if (ien) if (ien)
CPU::Interrupts(CPU::Enable); CPU::Interrupts(CPU::Enable);
debug("After interrupts boolean");
KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath); KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath);
TaskManager->GetCurrentThread()->SetPriority(1);
TaskManager->WaitForThread(ret.Thread); TaskManager->WaitForThread(ret.Thread);
KPrint("\eE85230Userspace process exited with code %d", ret.Thread->GetExitCode()); KPrint("\eE85230Userspace process exited with code %d", ret.Thread->GetExitCode());
error("Userspace process exited with code %d (%#x)", ret.Thread->GetExitCode(), ret.Thread->GetExitCode()); error("Userspace process exited with code %d (%#x)", ret.Thread->GetExitCode(), ret.Thread->GetExitCode());

View File

@ -27,6 +27,8 @@ FileSystem::Virtual *vfs = nullptr;
KernelConfig Config; KernelConfig Config;
Time::Clock BootClock; Time::Clock BootClock;
extern bool EnableProfiler;
// For the Display class. Printing on first buffer as default. // For the Display class. Printing on first buffer as default.
EXTERNC void putchar(char c) { Display->Print(c, 0); } EXTERNC void putchar(char c) { Display->Print(c, 0); }
@ -43,10 +45,8 @@ EXTERNC void KPrint(const char *Format, ...)
Display->SetBuffer(0); Display->SetBuffer(0);
} }
EXTERNC void Entry(BootInfo *Info) EXTERNC __no_instrument_function void PostEntry(BootInfo *Info)
{ {
trace("Hello, World!");
InitializeMemoryManagement(Info);
BootClock = Time::ReadClock(); BootClock = Time::ReadClock();
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo))); bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
memcpy(bInfo, Info, sizeof(BootInfo)); memcpy(bInfo, Info, sizeof(BootInfo));
@ -167,6 +167,34 @@ EXTERNC void Entry(BootInfo *Info)
CPU::Halt(true); 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() EXTERNC void TaskingPanic()
{ {
if (TaskManager) if (TaskManager)

View File

@ -1,6 +1,7 @@
#include <convert.h> #include <convert.h>
#include <types.h>
#include <memory.hpp> #include <memory.hpp>
#include <debug.h>
// TODO: Replace mem* with assembly code // 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. 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; unsigned char *d = dest;
const unsigned char *s = src; const unsigned char *s = src;
@ -193,7 +194,7 @@ void *memcpy(void *dest, const void *src, size_t n)
return dest; 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; unsigned char *s = dest;
size_t k; size_t k;
@ -264,7 +265,7 @@ void *memset(void *dest, int c, size_t n)
return dest; 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__ #ifdef __GNUC__
typedef __attribute__((__may_alias__)) size_t WT; typedef __attribute__((__may_alias__)) size_t WT;
@ -362,9 +363,9 @@ long unsigned strlen(const char s[])
return i; 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; return NULL;
char *start = destination; char *start = destination;
while (*start != '\0') while (*start != '\0')
@ -379,7 +380,7 @@ char *strcat(char *destination, const char *source)
return destination; return destination;
} }
char *strcpy(char *destination, const char *source) char *strcpy_unsafe(char *destination, const char *source)
{ {
if (destination == NULL) if (destination == NULL)
return NULL; return NULL;
@ -446,7 +447,7 @@ char *strchr(const char *String, int Char)
char *strdup(const char *String) char *strdup(const char *String)
{ {
char *OutBuffer = kmalloc(strlen((char *)String) + 1); char *OutBuffer = kmalloc(strlen((char *)String) + 1);
strcpy(OutBuffer, String); strncpy(OutBuffer, String, strlen(String) + 1);
return OutBuffer; return OutBuffer;
} }
@ -611,3 +612,232 @@ char *itoa(int Value, char *Buffer, int Base)
Buffer[i] = '\0'; Buffer[i] = '\0';
return reverse(Buffer, 0, i - 1); 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);
}

View File

@ -208,6 +208,8 @@ uint8_t *md5String(char *input)
md5Finalize(&ctx); md5Finalize(&ctx);
uint8_t *result = kmalloc(16); uint8_t *result = kmalloc(16);
if (result == NULL)
return (uint8_t *)"error";
memcpy(result, ctx.digest, 16); memcpy(result, ctx.digest, 16);
return result; return result;
} }
@ -236,6 +238,8 @@ uint8_t *md5File(uint8_t *buffer, size_t input_len)
md5Finalize(&ctx); md5Finalize(&ctx);
uint8_t *result = kmalloc(16); uint8_t *result = kmalloc(16);
if (result == NULL)
return (uint8_t *)"error";
memcpy(result, ctx.digest, 16); memcpy(result, ctx.digest, 16);
return result; return result;
} }

View File

@ -266,14 +266,14 @@ typedef union
// 1. Some compilers are finicky about this; // 1. Some compilers are finicky about this;
// 2. Some people may want to convert this to C89; // 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 // 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; double_with_bit_access dwba;
dwba.F = x; dwba.F = x;
return dwba; 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 // The sign is stored in the highest bit
return (int)(get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1)); 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 // or alternatively, that '\0' can be passed to the function in the output
// gadget. The former assumption holds within the printf library. It also // gadget. The former assumption holds within the printf library. It also
// assumes that the output gadget has been properly initialized. // 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++; printf_size_t write_pos = gadget->pos++;
// We're _always_ increasing pos, so as to count how may characters // 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 // 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) 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 // We can't use putchar_ as is, since our output gadget
// only takes pointers to functions with an extra argument // 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; (void)unused;
putchar(c); 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; output_gadget_t gadget;
gadget.function = NULL; gadget.function = NULL;
@ -373,7 +373,7 @@ static inline output_gadget_t discarding_gadget(void)
return gadget; 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; 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(); 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; 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(); output_gadget_t result = discarding_gadget();
result.function = function; result.function = function;
@ -394,7 +394,7 @@ static inline output_gadget_t function_gadget(void (*function)(char, void *), vo
return result; 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); 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' // @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 // @note strlen uses size_t, but wes only use this function with printf_size_t
// variables - hence the signature. // 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; const char *s;
for (s = str; *s && maxsize--; ++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) // internal test if char is a digit (0-9)
// @return true if char is a digit // @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'); return (ch >= '0') && (ch <= '9');
} }
// internal ASCII string to printf_size_t conversion // 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; printf_size_t i = 0U;
while (is_digit_(**str)) 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 // 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; 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 // 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) // 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; 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 // 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]; char buf[PRINTF_INTEGER_BUFFER_SIZE];
printf_size_t len = 0U; 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 - // 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. // 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. // 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_; struct double_components number_;
number_.is_negative = get_sign_bit(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 #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, 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) 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 // 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); struct double_components value_ = get_components(number, precision);
print_broken_up_decimal(value_, output, precision, width, flags, buf, len); 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; 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); const bool negative = get_sign_bit(number);
// This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it // 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 #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]; char buf[PRINTF_DECIMAL_BUFFER_SIZE];
printf_size_t len = 0U; 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 // Advances the format pointer past the flags, and returns the parsed flags
// due to the characters passed // 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; printf_flags_t flags = 0U;
do do
@ -1131,7 +1131,7 @@ static printf_flags_t parse_flags(const char **format)
} while (true); } 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 #if PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER
#define ADVANCE_IN_FORMAT_STRING(cptr_) \ #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 // 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 // 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". // 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(); output_gadget_t gadget = extern_putchar_gadget();
return vsnprintf_impl(&gadget, format, arg); 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); output_gadget_t gadget = buffer_gadget(s, n);
return vsnprintf_impl(&gadget, format, arg); 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); 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); output_gadget_t gadget = function_gadget(out, extra_arg);
return vsnprintf_impl(&gadget, format, arg); return vsnprintf_impl(&gadget, format, arg);
} }
int printf_(const char *format, ...) __no_instrument_function int printf_(const char *format, ...)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@ -1560,7 +1560,7 @@ int printf_(const char *format, ...)
return ret; return ret;
} }
int sprintf_(char *s, const char *format, ...) __no_instrument_function int sprintf_(char *s, const char *format, ...)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@ -1569,7 +1569,7 @@ int sprintf_(char *s, const char *format, ...)
return ret; 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_list args;
va_start(args, format); va_start(args, format);
@ -1578,7 +1578,7 @@ int snprintf_(char *s, size_t n, const char *format, ...)
return ret; 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_list args;
va_start(args, format); va_start(args, format);

View File

@ -36,6 +36,8 @@ CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/a
endif endif
HEADERS = $(sort $(dir $(wildcard ./include/*))) 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) 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 INCLUDE_DIR = ./include
LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc
@ -79,7 +81,7 @@ LDFLAGS += -TArchitecture/i686/linker.ld \
else ifeq ($(OSARCH), aarch64) else ifeq ($(OSARCH), aarch64)
CFLAGS += -pipe -fno-builtin -fPIC 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 LDFLAGS += -TArchitecture/aarch64/linker.ld -fPIC
endif endif
@ -92,8 +94,12 @@ else ifeq ($(OSARCH), aarch64)
NASMFLAGS := NASMFLAGS :=
endif endif
# -finstrument-functions for __cyg_profile_func_enter & __cyg_profile_func_exit. Used for profiling and debugging.
ifeq ($(DEBUG), 1) 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 LDFLAGS += -ggdb -O0 -g
NASMFLAGS += -F dwarf -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 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) $(error $(KERNEL_FILENAME) does not exist)
endif endif
$(info Dumping $(KERNEL_FILENAME) in AT T syntax...) $(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...) $(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) $(KERNEL_FILENAME): $(OBJ)
$(CC) $(LDFLAGS) $(OBJ) -o $@ $(CC) $(LDFLAGS) $(OBJ) -o $@
@ -168,4 +174,4 @@ endif
$(NM) $@ $(NM) $@
clean: 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)

87
Profiling/cyg.cpp Normal file
View File

@ -0,0 +1,87 @@
#include <types.h>
#include <printf.h>
#include <uart.hpp>
#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;
}

67
Profiling/gcov.cpp Normal file
View File

@ -0,0 +1,67 @@
#include <types.h>
#include <printf.h>
#include <uart.hpp>
#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)
{
}

19
Profiling/gprof.cpp Normal file
View File

@ -0,0 +1,19 @@
#include <types.h>
#include <printf.h>
#include <uart.hpp>
#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 */
}

View File

@ -0,0 +1,2 @@
#include <recovery.hpp>

View File

@ -126,24 +126,10 @@ namespace InterProcessCommunication
return IPCError{IPCIDNotFound}; 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() IPC::IPC()
{ {
SmartLock(IPCLock); SmartLock(IPCLock);
trace("Starting IPC Service..."); trace("Starting IPC Service...");
Vector<AuxiliaryVector> auxv;
Tasking::TCB *thd = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, nullptr, nullptr, auxv);
thd->Rename("IPC Service");
} }
IPC::~IPC() IPC::~IPC()

View File

@ -29,7 +29,7 @@ NewLock(SchedulerLock);
namespace Tasking namespace Tasking
{ {
extern "C" __no_stack_protector void OneShot(int TimeSlice) extern "C" SafeFunction __no_instrument_function void OneShot(int TimeSlice)
{ {
if (TimeSlice == 0) if (TimeSlice == 0)
TimeSlice = 10; TimeSlice = 10;
@ -42,14 +42,15 @@ namespace Tasking
void Task::Schedule() void Task::Schedule()
{ {
OneShot(100); if (!StopScheduler)
OneShot(100);
// APIC::InterruptCommandRegisterLow icr; // APIC::InterruptCommandRegisterLow icr;
// icr.Vector = CPU::x64::IRQ16; // icr.Vector = CPU::x64::IRQ16;
// icr.Level = APIC::APICLevel::Assert; // icr.Level = APIC::APICLevel::Assert;
// ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr); // ((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__) #if defined(__amd64__) || defined(__i386__)
asmv("IdleLoop:\n" asmv("IdleLoop:\n"
@ -62,7 +63,7 @@ namespace Tasking
#endif #endif
} }
__no_stack_protector bool Task::InvalidPCB(PCB *pcb) SafeFunction __no_instrument_function bool Task::InvalidPCB(PCB *pcb)
{ {
if (!pcb) if (!pcb)
return true; return true;
@ -73,7 +74,7 @@ namespace Tasking
return false; return false;
} }
__no_stack_protector bool Task::InvalidTCB(TCB *tcb) SafeFunction __no_instrument_function bool Task::InvalidTCB(TCB *tcb)
{ {
if (!tcb) if (!tcb)
return true; return true;
@ -84,7 +85,7 @@ namespace Tasking
return false; 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++) for (uint64_t i = 0; i < Thread->Parent->Threads.size(); i++)
if (Thread->Parent->Threads[i] == Thread) 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) if (Process == nullptr)
return; 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 // TODO
Info->UserTime++; Info->UserTime++;
} }
__no_stack_protector void Task::UpdateKernelTime(TaskInfo *Info) SafeFunction __no_instrument_function void Task::UpdateKernelTime(TaskInfo *Info)
{ {
// TODO // TODO
Info->KernelTime++; 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) if (Info->Affinity[Core] == true)
{ {
@ -176,7 +177,7 @@ namespace Tasking
} }
#if defined(__amd64__) #if defined(__amd64__)
__no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) SafeFunction __no_instrument_function bool Task::FindNewProcess(void *CPUDataPointer)
{ {
CPUData *CurrentCPU = (CPUData *)CPUDataPointer; CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
schedbg("%d processes", ListProcess.size()); schedbg("%d processes", ListProcess.size());
@ -225,7 +226,7 @@ namespace Tasking
return false; return false;
} }
__no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) SafeFunction __no_instrument_function bool Task::GetNextAvailableThread(void *CPUDataPointer)
{ {
CPUData *CurrentCPU = (CPUData *)CPUDataPointer; CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
@ -265,7 +266,7 @@ namespace Tasking
return false; return false;
} }
__no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) SafeFunction __no_instrument_function bool Task::GetNextAvailableProcess(void *CPUDataPointer)
{ {
CPUData *CurrentCPU = (CPUData *)CPUDataPointer; CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
@ -308,7 +309,7 @@ namespace Tasking
return false; return false;
} }
__no_stack_protector void Task::SchedulerCleanupProcesses() SafeFunction __no_instrument_function void Task::SchedulerCleanupProcesses()
{ {
foreach (PCB *pcb in ListProcess) 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; CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
@ -346,7 +347,7 @@ namespace Tasking
return false; 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); SmartCriticalSection(SchedulerLock);
if (StopScheduler) if (StopScheduler)
@ -491,9 +492,10 @@ namespace Tasking
if (CurrentCPU->CurrentThread->Registers.cs != GDT_USER_CODE || if (CurrentCPU->CurrentThread->Registers.cs != GDT_USER_CODE ||
CurrentCPU->CurrentThread->Registers.ss != GDT_USER_DATA) 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, 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.cs = GDT_USER_CODE;
CurrentCPU->CurrentThread->Registers.ss = GDT_USER_DATA; CurrentCPU->CurrentThread->Registers.ss = GDT_USER_DATA;
} }
@ -503,9 +505,10 @@ namespace Tasking
if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE || if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE ||
CurrentCPU->CurrentThread->Registers.ss != GDT_KERNEL_DATA) 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, 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.cs = GDT_KERNEL_CODE;
CurrentCPU->CurrentThread->Registers.ss = GDT_KERNEL_DATA; 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__) #elif defined(__i386__)
__no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) SafeFunction bool Task::FindNewProcess(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) SafeFunction bool Task::GetNextAvailableThread(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) SafeFunction bool Task::GetNextAvailableProcess(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector void Task::SchedulerCleanupProcesses() SafeFunction void Task::SchedulerCleanupProcesses()
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) SafeFunction bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector void Task::Schedule(void *Frame) SafeFunction void Task::Schedule(void *Frame)
{ {
fixme("unimplemented"); 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__) #elif defined(__aarch64__)
__no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer) SafeFunction bool Task::FindNewProcess(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer) SafeFunction bool Task::GetNextAvailableThread(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer) SafeFunction bool Task::GetNextAvailableProcess(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector void Task::SchedulerCleanupProcesses() SafeFunction void Task::SchedulerCleanupProcesses()
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) SafeFunction bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector void Task::Schedule(void *Frame) SafeFunction void Task::Schedule(void *Frame)
{ {
fixme("unimplemented"); fixme("unimplemented");
} }
__no_stack_protector void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } SafeFunction void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); }
#endif #endif
void ThreadDoExit() void ThreadDoExit()
@ -853,8 +856,10 @@ namespace Tasking
{ {
while (argv[ArgvSize] != nullptr) while (argv[ArgvSize] != nullptr)
{ {
debug("> ArgvSize: %d, ArgvStrSize: %d", ArgvSize, ArgvStrSize);
ArgvSize++; ArgvSize++;
ArgvStrSize += strlen(argv[ArgvSize]) + 1; ArgvStrSize += strlen(argv[ArgvSize]) + 1;
debug("< ArgvSize: %d, ArgvStrSize: %d", ArgvSize, ArgvStrSize);
} }
} }
@ -864,8 +869,10 @@ namespace Tasking
{ {
while (envp[EnvpSize] != nullptr) while (envp[EnvpSize] != nullptr)
{ {
debug("> EnvpSize: %d, EnvpStrSize: %d", EnvpSize, EnvpStrSize);
EnvpSize++; EnvpSize++;
EnvpStrSize += strlen(envp[EnvpSize]) + 1; EnvpStrSize += strlen(envp[EnvpSize]) + 1;
debug("< EnvpSize: %d, EnvpStrSize: %d", EnvpSize, EnvpStrSize);
} }
} }
@ -881,15 +888,19 @@ namespace Tasking
argv[i] = (char *)_argv; argv[i] = (char *)_argv;
} }
debug("argv done");
for (uint64_t i = 0; i < EnvpSize; i++) 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); Memory::Virtual().Map(Tmp, Tmp, Memory::PTFlag::RW | Memory::PTFlag::US);
_envp = (uint8_t *)Tmp; _envp = (uint8_t *)Tmp;
strcpy((char *)_envp, envp[i]); strcpy((char *)_envp, envp[i]);
envp[i] = (char *)_envp; envp[i] = (char *)_envp;
} }
debug("envp done");
Thread->Registers.rdi = ArgvSize; Thread->Registers.rdi = ArgvSize;
Thread->Registers.rsi = (uint64_t)_argv; Thread->Registers.rsi = (uint64_t)_argv;
Thread->Registers.rdx = (uint64_t)_envp; Thread->Registers.rdx = (uint64_t)_envp;

1
dump.sh Executable file
View File

@ -0,0 +1 @@
make dump

View File

@ -19,15 +19,18 @@ extern "C"
int atoi(const char *String); int atoi(const char *String);
double atof(const char *String); double atof(const char *String);
char *itoa(int Value, char *Buffer, int Base); 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 *memcpy_unsafe(void *dest, const void *src, size_t n);
void *memset(void *dest, int c, size_t n); void *memset_unsafe(void *dest, int c, size_t n);
void *memmove(void *dest, const void *src, 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); int memcmp(const void *vl, const void *vr, size_t n);
long unsigned strlen(const char s[]); long unsigned strlen(const char s[]);
int strncmp(const char *s1, const char *s2, unsigned long n); int strncmp(const char *s1, const char *s2, unsigned long n);
char *strcat(char *destination, const char *source); char *strcat_unsafe(char *destination, const char *source);
char *strcpy(char *destination, const char *source); char *strcpy_unsafe(char *destination, const char *source);
char *strncpy(char *destination, const char *source, unsigned long num); char *strncpy(char *destination, const char *source, unsigned long num);
int strcmp(const char *l, const char *r); int strcmp(const char *l, const char *r);
char *strstr(const char *haystack, const char *needle); char *strstr(const char *haystack, const char *needle);
@ -38,6 +41,32 @@ extern "C"
int strcasecmp(const char *lhs, const char *rhs); int strcasecmp(const char *lhs, const char *rhs);
char *strtok(char *src, const char *delim); 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 #ifdef __cplusplus
} }
#endif #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))

View File

@ -143,7 +143,7 @@ namespace CPU
/** /**
* @brief Pause the CPU * @brief Pause the CPU
*/ */
__no_stack_protector static inline void Pause(bool Loop = false) SafeFunction static inline void Pause(bool Loop = false)
{ {
do do
{ {
@ -158,7 +158,7 @@ namespace CPU
/** /**
* @brief Stop the CPU (infinite loop) * @brief Stop the CPU (infinite loop)
*/ */
__no_stack_protector static inline void Stop() SafeFunction static inline void Stop()
{ {
while (1) while (1)
{ {
@ -177,7 +177,7 @@ namespace CPU
/** /**
* @brief Halt the CPU * @brief Halt the CPU
*/ */
__no_stack_protector static inline void Halt(bool Loop = false) SafeFunction static inline void Halt(bool Loop = false)
{ {
do do
{ {
@ -213,7 +213,7 @@ namespace CPU
namespace MemBar namespace MemBar
{ {
__no_stack_protector static inline void Barrier() SafeFunction static inline void Barrier()
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
asmv("" :: asmv("" ::
@ -224,7 +224,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void Fence() SafeFunction static inline void Fence()
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
asmv("mfence" :: asmv("mfence" ::
@ -235,7 +235,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void StoreFence() SafeFunction static inline void StoreFence()
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
asmv("sfence" :: asmv("sfence" ::
@ -246,7 +246,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void LoadFence() SafeFunction static inline void LoadFence()
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
asmv("lfence" :: asmv("lfence" ::
@ -549,7 +549,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void invlpg(void *Address) SafeFunction static inline void invlpg(void *Address)
{ {
#if defined(__i386__) #if defined(__i386__)
asmv("invlpg (%0)" asmv("invlpg (%0)"
@ -1670,7 +1670,7 @@ namespace CPU
uint64_t raw; uint64_t raw;
} SelectorErrorCode; } SelectorErrorCode;
__no_stack_protector static inline void lgdt(void *gdt) SafeFunction static inline void lgdt(void *gdt)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("lgdt (%0)" asmv("lgdt (%0)"
@ -1679,7 +1679,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void lidt(void *idt) SafeFunction static inline void lidt(void *idt)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("lidt (%0)" asmv("lidt (%0)"
@ -1688,7 +1688,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void ltr(uint16_t Segment) SafeFunction static inline void ltr(uint16_t Segment)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("ltr %0" asmv("ltr %0"
@ -1697,7 +1697,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void invlpg(void *Address) SafeFunction static inline void invlpg(void *Address)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("invlpg (%0)" asmv("invlpg (%0)"
@ -1716,7 +1716,7 @@ namespace CPU
* @param ecx ECX * @param ecx ECX
* @param edx EDX * @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__) #if defined(__amd64__)
asmv("cpuid" asmv("cpuid"
@ -1732,14 +1732,14 @@ namespace CPU
* *
* @return uint32_t * @return uint32_t
*/ */
__no_stack_protector static inline uint32_t GetHighestLeaf() SafeFunction static inline uint32_t GetHighestLeaf()
{ {
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
cpuid(0x0, &eax, &ebx, &ecx, &edx); cpuid(0x0, &eax, &ebx, &ecx, &edx);
return eax; 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; uint32_t Low, High;
#if defined(__amd64__) #if defined(__amd64__)
@ -1751,7 +1751,7 @@ namespace CPU
return ((uint64_t)Low) | (((uint64_t)High) << 32); 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; uint32_t Low = Value, High = Value >> 32;
#if defined(__amd64__) #if defined(__amd64__)
@ -1762,7 +1762,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline CR0 readcr0() SafeFunction static inline CR0 readcr0()
{ {
uint64_t Result; uint64_t Result;
#if defined(__amd64__) #if defined(__amd64__)
@ -1772,7 +1772,7 @@ namespace CPU
return (CR0){.raw = Result}; return (CR0){.raw = Result};
} }
__no_stack_protector static inline CR2 readcr2() SafeFunction static inline CR2 readcr2()
{ {
uint64_t Result; uint64_t Result;
#if defined(__amd64__) #if defined(__amd64__)
@ -1782,7 +1782,7 @@ namespace CPU
return (CR2){.raw = Result}; return (CR2){.raw = Result};
} }
__no_stack_protector static inline CR3 readcr3() SafeFunction static inline CR3 readcr3()
{ {
uint64_t Result; uint64_t Result;
#if defined(__amd64__) #if defined(__amd64__)
@ -1792,7 +1792,7 @@ namespace CPU
return (CR3){.raw = Result}; return (CR3){.raw = Result};
} }
__no_stack_protector static inline CR4 readcr4() SafeFunction static inline CR4 readcr4()
{ {
uint64_t Result; uint64_t Result;
#if defined(__amd64__) #if defined(__amd64__)
@ -1802,7 +1802,7 @@ namespace CPU
return (CR4){.raw = Result}; return (CR4){.raw = Result};
} }
__no_stack_protector static inline CR8 readcr8() SafeFunction static inline CR8 readcr8()
{ {
uint64_t Result; uint64_t Result;
#if defined(__amd64__) #if defined(__amd64__)
@ -1812,7 +1812,7 @@ namespace CPU
return (CR8){.raw = Result}; return (CR8){.raw = Result};
} }
__no_stack_protector static inline void writecr0(CR0 ControlRegister) SafeFunction static inline void writecr0(CR0 ControlRegister)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr0" asmv("mov %[ControlRegister], %%cr0"
@ -1822,7 +1822,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void writecr2(CR2 ControlRegister) SafeFunction static inline void writecr2(CR2 ControlRegister)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr2" asmv("mov %[ControlRegister], %%cr2"
@ -1832,7 +1832,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void writecr3(CR3 ControlRegister) SafeFunction static inline void writecr3(CR3 ControlRegister)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr3" asmv("mov %[ControlRegister], %%cr3"
@ -1842,7 +1842,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void writecr4(CR4 ControlRegister) SafeFunction static inline void writecr4(CR4 ControlRegister)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr4" asmv("mov %[ControlRegister], %%cr4"
@ -1852,7 +1852,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void writecr8(CR8 ControlRegister) SafeFunction static inline void writecr8(CR8 ControlRegister)
{ {
#if defined(__amd64__) #if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr8" asmv("mov %[ControlRegister], %%cr8"
@ -1862,7 +1862,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void fxsave(char *FXSaveArea) SafeFunction static inline void fxsave(char *FXSaveArea)
{ {
#if defined(__amd64__) #if defined(__amd64__)
if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000) if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
@ -1876,7 +1876,7 @@ namespace CPU
#endif #endif
} }
__no_stack_protector static inline void fxrstor(char *FXRstorArea) SafeFunction static inline void fxrstor(char *FXRstorArea)
{ {
#if defined(__amd64__) #if defined(__amd64__)
if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000) if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)

View File

@ -156,8 +156,10 @@ namespace Video
void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index) void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index)
{ {
if (X >= this->Buffers[Index]->Width || Y >= this->Buffers[Index]->Height) if (X >= this->Buffers[Index]->Width)
return; 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)); uint32_t *Pixel = (uint32_t *)((uint64_t)this->Buffers[Index]->Buffer + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8));
*Pixel = Color; *Pixel = Color;
} }

View File

@ -89,7 +89,7 @@ namespace FileSystem
FS_MOUNTPOINT = 0x08 FS_MOUNTPOINT = 0x08
}; };
struct FileSystemOpeations struct FileSystemOperations
{ {
char Name[FILENAME_LENGTH]; char Name[FILENAME_LENGTH];
OperationMount Mount = nullptr; OperationMount Mount = nullptr;
@ -113,7 +113,7 @@ namespace FileSystem
uint64_t Address = 0; uint64_t Address = 0;
uint64_t Length = 0; uint64_t Length = 0;
FileSystemNode *Parent = nullptr; FileSystemNode *Parent = nullptr;
FileSystemOpeations *Operator = nullptr; FileSystemOperations *Operator = nullptr;
/* For root node: /* For root node:
0 - root "/" 0 - root "/"
1 - etc 1 - etc
@ -150,13 +150,13 @@ namespace FileSystem
char *NormalizePath(FileSystemNode *Parent, const char *Path); char *NormalizePath(FileSystemNode *Parent, const char *Path);
FileStatus FileExists(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); FileStatus Unmount(FILE *File);
FILE *Open(const char *Path, FileSystemNode *Parent = nullptr); FILE *Open(const char *Path, FileSystemNode *Parent = nullptr);
uint64_t Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size); 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); uint64_t Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size);
FileStatus Close(FILE *File); 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); FileSystemNode *Create(FileSystemNode *Parent, const char *Path);
Virtual(); Virtual();

View File

@ -11,7 +11,7 @@ namespace FileSystem
class Device class Device
{ {
public: 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();
~Device(); ~Device();
}; };
@ -20,7 +20,7 @@ namespace FileSystem
class Mount class Mount
{ {
public: 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); void DetectAndMountFS(void *drive);
Mount(); Mount();
~Mount(); ~Mount();
@ -38,7 +38,7 @@ namespace FileSystem
class Driver class Driver
{ {
public: 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();
~Driver(); ~Driver();
}; };
@ -47,7 +47,7 @@ namespace FileSystem
class Network class Network
{ {
public: 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();
~Network(); ~Network();
}; };

View File

@ -6,17 +6,26 @@
namespace Interrupts namespace Interrupts
{ {
#ifdef DEBUG // For performance reasons
#define INT_FRAMES_MAX 512
#else
#define INT_FRAMES_MAX 8
#endif
#if defined(__amd64__) #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 /* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
#elif defined(__i386__) #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 /* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
#elif defined(__aarch64__) #elif defined(__aarch64__)
#endif #endif
extern void *InterruptFrames[INT_FRAMES_MAX];
void Initialize(int Core); void Initialize(int Core);
void Enable(int Core); void Enable(int Core);
void InitializeTimer(int Core); void InitializeTimer(int Core);
void RemoveAll();
class Handler class Handler
{ {

View File

@ -12,6 +12,7 @@ struct KernelConfig
char InitPath[256]; char InitPath[256];
bool InterruptsOnCrash; bool InterruptsOnCrash;
int Cores; int Cores;
bool UnlockDeadLock;
}; };
KernelConfig ParseConfig(char *Config); KernelConfig ParseConfig(char *Config);

11
include/recovery.hpp Normal file
View File

@ -0,0 +1,11 @@
#ifndef __FENNIX_KERNEL_RECOVERY_H__
#define __FENNIX_KERNEL_RECOVERY_H__
#include <types.h>
namespace Recovery
{
}
#endif // !__FENNIX_KERNEL_RECOVERY_H__

View File

@ -101,6 +101,7 @@ namespace Tasking
void Rename(const char *name) void Rename(const char *name)
{ {
CriticalSection cs;
if (!Name[0]) if (!Name[0])
{ {
warn("Tried to rename thread %d to NULL", ID); warn("Tried to rename thread %d to NULL", ID);
@ -117,6 +118,7 @@ namespace Tasking
void SetPriority(int priority) void SetPriority(int priority)
{ {
CriticalSection cs;
trace("Setting priority of thread %s to %d", Name, priority); trace("Setting priority of thread %s to %d", Name, priority);
Info.Priority = priority; Info.Priority = priority;
} }
@ -125,6 +127,7 @@ namespace Tasking
void SetCritical(bool critical) void SetCritical(bool critical)
{ {
CriticalSection cs;
trace("Setting criticality of thread %s to %s", Name, critical ? "true" : "false"); trace("Setting criticality of thread %s to %s", Name, critical ? "true" : "false");
Security.IsCritical = critical; Security.IsCritical = critical;
} }
@ -215,7 +218,13 @@ namespace Tasking
Vector<PCB *> GetProcessList() { return ListProcess; } Vector<PCB *> GetProcessList() { return ListProcess; }
void Panic() { StopScheduler = true; } void Panic() { StopScheduler = true; }
void Schedule(); 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) void KillThread(TCB *tcb, int Code)
{ {
tcb->Status = TaskStatus::Terminated; tcb->Status = TaskStatus::Terminated;

View File

@ -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 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 b64(x) __builtin_bswap64(x)
#define O0 __attribute__((optimize("O0"))) #define O0 __attribute__((optimize("O0")))
#define O1 __attribute__((optimize("O1"))) #define O1 __attribute__((optimize("O1")))
#define O2 __attribute__((optimize("O2"))) #define O2 __attribute__((optimize("O2")))
@ -220,6 +219,7 @@ typedef __SIZE_TYPE__ size_t;
#define __unused __attribute__((unused)) #define __unused __attribute__((unused))
#define __packed __attribute__((packed)) #define __packed __attribute__((packed))
#define __naked __attribute__((naked))
#define __aligned(x) __attribute__((aligned(x))) #define __aligned(x) __attribute__((aligned(x)))
#define __section(x) __attribute__((section(x))) #define __section(x) __attribute__((section(x)))
#define __noreturn __attribute__((noreturn)) #define __noreturn __attribute__((noreturn))
@ -252,12 +252,17 @@ typedef __SIZE_TYPE__ size_t;
#define __nonnull_all __attribute__((nonnull)) #define __nonnull_all __attribute__((nonnull))
#define __warn_unused_result __attribute__((warn_unused_result)) #define __warn_unused_result __attribute__((warn_unused_result))
#define __no_stack_protector __attribute__((no_stack_protector)) #define __no_stack_protector __attribute__((no_stack_protector))
#define __no_instrument_function __attribute__((no_instrument_function))
// sanitizer // sanitizer
#define __no_sanitize_address __attribute__((no_sanitize_address)) #define __no_sanitize_address __attribute__((no_sanitize_address))
#define __no_sanitize_undefined __attribute__((no_sanitize_undefined)) #define __no_sanitize_undefined __attribute__((no_sanitize_undefined))
#define __no_address_safety_analysis __attribute__((no_address_safety_analysis)) #define __no_address_safety_analysis __attribute__((no_address_safety_analysis))
#define __no_sanitize_thread __attribute__((no_sanitize_thread)) #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__ #endif // !__FENNIX_KERNEL_TYPES_H__

View File

@ -51,7 +51,7 @@ namespace UniversalAsynchronousReceiverTransmitter
* @brief Get the Registered Port object * @brief Get the Registered Port object
* @return SerialPorts * @return SerialPorts
*/ */
SerialPorts GetRegisteredPort() { return this->Port; } SafeFunction __no_instrument_function SerialPorts GetRegisteredPort() { return this->Port; }
/** /**
* @brief Called when a character is sent. * @brief Called when a character is sent.

View File

@ -13,7 +13,7 @@ private:
public: public:
typedef T *iterator; typedef T *iterator;
Vector() __no_instrument_function Vector()
{ {
#ifdef DEBUG_MEM_ALLOCATION #ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR INIT: Vector( )"); debug("VECTOR INIT: Vector( )");
@ -23,7 +23,7 @@ public:
VectorBuffer = 0; VectorBuffer = 0;
} }
Vector(uint64_t Size) __no_instrument_function Vector(uint64_t Size)
{ {
VectorCapacity = Size; VectorCapacity = Size;
VectorSize = Size; VectorSize = Size;
@ -33,7 +33,7 @@ public:
VectorBuffer = new T[Size]; VectorBuffer = new T[Size];
} }
Vector(uint64_t Size, const T &Initial) __no_instrument_function Vector(uint64_t Size, const T &Initial)
{ {
VectorSize = Size; VectorSize = Size;
VectorCapacity = Size; VectorCapacity = Size;
@ -45,7 +45,7 @@ public:
VectorBuffer[i] = Initial; VectorBuffer[i] = Initial;
} }
Vector(const Vector<T> &Vector) __no_instrument_function Vector(const Vector<T> &Vector)
{ {
VectorSize = Vector.VectorSize; VectorSize = Vector.VectorSize;
VectorCapacity = Vector.VectorCapacity; VectorCapacity = Vector.VectorCapacity;
@ -57,7 +57,7 @@ public:
VectorBuffer[i] = Vector.VectorBuffer[i]; VectorBuffer[i] = Vector.VectorBuffer[i];
} }
~Vector() __no_instrument_function ~Vector()
{ {
#ifdef DEBUG_MEM_ALLOCATION #ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR INIT: ~Vector( ~%lx )", VectorBuffer); debug("VECTOR INIT: ~Vector( ~%lx )", VectorBuffer);
@ -65,7 +65,7 @@ public:
delete[] VectorBuffer; delete[] VectorBuffer;
} }
void remove(uint64_t Position) __no_instrument_function void remove(uint64_t Position)
{ {
if (Position >= VectorSize) if (Position >= VectorSize)
return; return;
@ -77,30 +77,30 @@ public:
VectorSize--; 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) if (VectorSize >= VectorCapacity)
reserve(VectorCapacity + 5); reserve(VectorCapacity + 5);
VectorBuffer[VectorSize++] = Value; VectorBuffer[VectorSize++] = Value;
} }
void pop_back() { VectorSize--; } __no_instrument_function void pop_back() { VectorSize--; }
void reverse() __no_instrument_function void reverse()
{ {
if (VectorSize <= 1) if (VectorSize <= 1)
return; return;
@ -112,7 +112,7 @@ public:
} }
} }
void reserve(uint64_t Capacity) __no_instrument_function void reserve(uint64_t Capacity)
{ {
if (VectorBuffer == 0) if (VectorBuffer == 0)
{ {
@ -134,15 +134,15 @@ public:
VectorBuffer = Newbuffer; VectorBuffer = Newbuffer;
} }
void resize(uint64_t Size) __no_instrument_function void resize(uint64_t Size)
{ {
reserve(Size); reserve(Size);
VectorSize = Size; VectorSize = Size;
} }
T &operator[](uint64_t Index) { return VectorBuffer[Index]; } __no_instrument_function T &operator[](uint64_t Index) { return VectorBuffer[Index]; }
Vector<T> &operator=(const Vector<T> &Vector) __no_instrument_function Vector<T> &operator=(const Vector<T> &Vector)
{ {
delete[] VectorBuffer; delete[] VectorBuffer;
VectorSize = Vector.VectorSize; VectorSize = Vector.VectorSize;
@ -156,12 +156,12 @@ public:
return *this; return *this;
} }
void clear() __no_instrument_function void clear()
{ {
VectorCapacity = 0; VectorCapacity = 0;
VectorSize = 0; VectorSize = 0;
VectorBuffer = 0; VectorBuffer = 0;
} }
T *data() { return VectorBuffer; } __no_instrument_function T *data() { return VectorBuffer; }
}; };

View File

@ -38,6 +38,7 @@ extern Disk::Manager *DiskManager;
EXTERNC void putchar(char c); EXTERNC void putchar(char c);
EXTERNC void KPrint(const char *format, ...); EXTERNC void KPrint(const char *format, ...);
EXTERNC void Entry(struct BootInfo *Info); EXTERNC void Entry(struct BootInfo *Info);
EXTERNC void BeforeShutdown();
EXTERNC void TaskingPanic(); EXTERNC void TaskingPanic();
EXTERNC void KernelMainThread(); EXTERNC void KernelMainThread();