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
*.su
*.gcno
*.map
*.fsys
*.log
Files/*.psf
.dccache

View File

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

View File

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

View File

@ -29,6 +29,24 @@ SECTIONS
_kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += CONSTANT(MAXPAGESIZE);
.init_array :
{
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(.init_array .ctors))
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN(__fini_array_start = .);
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP(*(.fini_array .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
. += CONSTANT(MAXPAGESIZE);
.bss :
{
*(COMMON)

View File

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

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

View File

@ -22,15 +22,16 @@ NewLock(UserInputLock);
namespace CrashHandler
{
void *EHIntFrames[INT_FRAMES_MAX];
static bool ExceptionOccurred = false;
int SBIdx = 255;
__no_stack_protector void printfWrapper(char c, void *unused)
SafeFunction void printfWrapper(char c, void *unused)
{
Display->Print(c, SBIdx, true);
UNUSED(unused);
}
__no_stack_protector void EHPrint(const char *Format, ...)
SafeFunction void EHPrint(const char *Format, ...)
{
va_list args;
va_start(args, Format);
@ -38,7 +39,7 @@ namespace CrashHandler
va_end(args);
}
__no_stack_protector char *trimwhitespace(char *str)
SafeFunction char *TrimWhiteSpace(char *str)
{
char *end;
while (*str == ' ')
@ -54,7 +55,7 @@ namespace CrashHandler
CRData crashdata = {};
__no_stack_protector void DisplayTopOverlay()
SafeFunction void DisplayTopOverlay()
{
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
Video::Font *f = Display->GetCurrentFont();
@ -108,7 +109,7 @@ namespace CrashHandler
Display->SetBufferCursor(SBIdx, 0, fi.Height + 10);
}
__no_stack_protector void DisplayBottomOverlay()
SafeFunction void DisplayBottomOverlay()
{
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
Video::Font *f = Display->GetCurrentFont();
@ -122,7 +123,7 @@ namespace CrashHandler
EHPrint("\eAAAAAA> \eFAFAFA");
}
__no_stack_protector void ArrowInput(uint8_t key)
SafeFunction void ArrowInput(uint8_t key)
{
switch (key)
{
@ -193,7 +194,7 @@ namespace CrashHandler
Display->SetBuffer(SBIdx);
}
__no_stack_protector void UserInput(char *Input)
SafeFunction void UserInput(char *Input)
{
SmartCriticalSection(UserInputLock);
Display->ClearBuffer(SBIdx);
@ -209,6 +210,7 @@ namespace CrashHandler
EHPrint("showbuf <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(" - \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("details - Show the details screen.\n");
EHPrint("frames - Show the stack frame screen.\n");
@ -223,25 +225,66 @@ namespace CrashHandler
{
PowerManager->Shutdown();
EHPrint("\eFFFFFFNow it's safe to turn off your computer.");
Display->SetBuffer(SBIdx);
CPU::Stop();
}
else if (strcmp(Input, "reboot") == 0)
{
PowerManager->Reboot();
EHPrint("\eFFFFFFNow it's safe to reboot your computer.");
Display->SetBuffer(SBIdx);
CPU::Stop();
}
else if (strncmp(Input, "showbuf", 7) == 0)
{
char *arg = trimwhitespace(Input + 7);
char *arg = TrimWhiteSpace(Input + 7);
int tmpidx = SBIdx;
SBIdx = atoi(arg);
Display->SetBuffer(SBIdx);
for (int i = 0; i < 1000000; i++)
for (int i = 0; i < 5000000; i++)
inb(0x80);
SBIdx = tmpidx;
Display->SetBuffer(SBIdx);
}
else if (strncmp(Input, "ifr", 3) == 0)
{
char *arg = TrimWhiteSpace(Input + 3);
uint64_t CountI = atoi(arg);
uint64_t TotalCount = sizeof(EHIntFrames) / sizeof(EHIntFrames[0]);
debug("Printing %ld interrupt frames.", CountI);
if (CountI > TotalCount)
{
EHPrint("eFF4400Count too big! Maximum allowed is %ld\eFAFAFA\n", TotalCount);
Display->SetBuffer(SBIdx);
}
else
{
for (uint64_t i = 0; i < CountI; i++)
{
if (EHIntFrames[i])
{
if (!Memory::Virtual().Check(EHIntFrames[i]))
continue;
EHPrint("\n\e2565CC%p", EHIntFrames[i]);
EHPrint("\e7925CC-");
#if defined(__amd64__)
if ((uint64_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
#elif defined(__i386__)
if ((uint64_t)EHIntFrames[i] >= 0xC0000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
#elif defined(__aarch64__)
#endif
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uint64_t)EHIntFrames[i]));
else
EHPrint("\eFF4CA9Outside Kernel");
for (int i = 0; i < 20000; i++)
inb(0x80);
Display->SetBuffer(SBIdx);
}
}
}
}
else if (strcmp(Input, "main") == 0)
{
SBIdx = 255;
@ -286,11 +329,14 @@ namespace CrashHandler
Display->SetBuffer(SBIdx);
}
__no_stack_protector void Handle(void *Data)
SafeFunction void Handle(void *Data)
{
// TODO: SUPPORT SMP
CPU::Interrupts(CPU::Disable);
error("An exception occurred!");
for (size_t i = 0; i < INT_FRAMES_MAX; i++)
EHIntFrames[i] = Interrupts::InterruptFrames[i];
SBIdx = 255;
CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data;
#if defined(__amd64__)
@ -299,27 +345,11 @@ namespace CrashHandler
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
{
debug("Exception in kernel mode");
if (Frame->InterruptNumber == CPU::x64::PageFault)
{
CPUData *data = GetCurrentCPU();
if (data)
{
if (data->CurrentThread->Stack->Expand(CPU::x64::readcr2().raw))
{
debug("Stack expanded");
CPU::Interrupts(CPU::Enable);
return;
}
else
{
error("Stack expansion failed");
}
}
}
if (TaskManager)
TaskManager->Panic();
debug("ePanicSchedStop");
Display->CreateBuffer(0, 0, SBIdx);
debug("e0");
}
else
{
@ -348,7 +378,9 @@ namespace CrashHandler
{
SBIdx = 255;
Display->ClearBuffer(SBIdx);
debug("e0-1");
Display->SetBufferCursor(SBIdx, 0, 0);
debug("e0-2");
CPU::x64::CR0 cr0 = CPU::x64::readcr0();
CPU::x64::CR2 cr2 = CPU::x64::readcr2();
@ -405,6 +437,7 @@ namespace CrashHandler
}
ExceptionOccurred = true;
Interrupts::RemoveAll();
debug("Reading control registers...");
crashdata.Frame = Frame;

View File

@ -103,11 +103,11 @@ namespace CrashHandler
static char UserInputBuffer[1024];
#if defined(__amd64__)
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
#elif defined(__i386__)
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
#elif defined(__aarch64__)
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
#endif
{
uint8_t scanCode = inb(0x60);
@ -155,10 +155,10 @@ namespace CrashHandler
}
}
__no_stack_protector void HookKeyboard()
SafeFunction void HookKeyboard()
{
CrashKeyboardDriver kbd; // We don't want to allocate memory.
asmv("Loop: nop; jmp Loop;");
asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;");
// CPU::Halt(true); // This is an infinite loop.
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
#include "../../crashhandler.hpp"
#include "../chfcts.hpp"
#include <interrupts.hpp>
#include <display.hpp>
#include <printf.h>
#include <debug.h>
@ -17,9 +18,29 @@
namespace CrashHandler
{
__no_stack_protector void DisplayStackFrameScreen(CRData data)
SafeFunction void DisplayStackFrameScreen(CRData data)
{
EHPrint("\eFAFAFATracing 40 frames...\n");
TraceFrames(data.Frame, 40);
EHPrint("\n\n\eFAFAFATracing interrupt frames...\n");
for (uint64_t i = 0; i < 8; i++)
{
if (EHIntFrames[i])
{
if (!Memory::Virtual().Check(EHIntFrames[i]))
continue;
EHPrint("\n\e2565CC%p", EHIntFrames[i]);
EHPrint("\e7925CC-");
#if defined(__amd64__)
if ((uint64_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
#elif defined(__i386__)
if ((uint64_t)EHIntFrames[i] >= 0xC0000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
#elif defined(__aarch64__)
#endif
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uint64_t)EHIntFrames[i]));
else
EHPrint("\eFF4CA9Outside Kernel");
}
}
}
}

View File

@ -17,7 +17,7 @@
namespace CrashHandler
{
__no_stack_protector void DisplayTasksScreen(CRData data)
SafeFunction void DisplayTasksScreen(CRData data)
{
const char *StatusColor[7] = {
"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 a page and caused a protection fault\n"};
__no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame)
SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
{
CriticalSection cs;
debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No");

View File

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

View File

@ -2,19 +2,19 @@
#include <interrupts.hpp>
#include <memory.hpp>
#include <dumper.hpp>
#include <task.hpp>
#include <lock.hpp>
#include <printf.h>
#include <cwalk.h>
#include <md5.h>
#include "../kernel.h"
#include "../DAPI.hpp"
#include "../Fex.hpp"
#include "../../kernel.h"
#include "../../DAPI.hpp"
#include "../../Fex.hpp"
#include "api.hpp"
NewLock(DriverInitLock);
NewLock(DriverDisplayPrintLock);
NewLock(DriverInterruptLock);
namespace Driver
{
@ -28,127 +28,6 @@ namespace Driver
"Input",
"Audio"};
void DriverDebugPrint(char *String, unsigned long DriverUID)
{
SmartLock(DriverDisplayPrintLock);
trace("[%ld] %s", DriverUID, String);
}
void DriverDisplayPrint(char *String)
{
SmartLock(DriverDisplayPrintLock);
for (unsigned long i = 0; i < strlen(String); i++)
Display->Print(String[i], 0, true);
}
void *RequestPage(unsigned long Size)
{
SmartLock(DriverDisplayPrintLock);
debug("Requesting %ld pages from the kernel...", Size);
void *ret = KernelAllocator.RequestPages(Size);
debug("Got %#lx", ret);
return ret;
}
void FreePage(void *Page, unsigned long Size)
{
SmartLock(DriverDisplayPrintLock);
debug("Freeing %ld pages from the address %#lx...", Size, (unsigned long)Page);
KernelAllocator.FreePages(Page, Size);
}
void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags)
{
SmartLock(DriverDisplayPrintLock);
debug("Mapping %#lx to %#lx with flags %#lx...", (unsigned long)VirtualAddress, (unsigned long)PhysicalAddress, Flags);
Memory::Virtual().Map(VirtualAddress, PhysicalAddress, Flags);
}
void UnmapMemory(void *VirtualAddress)
{
SmartLock(DriverDisplayPrintLock);
debug("Unmapping %#lx...", (unsigned long)VirtualAddress);
Memory::Virtual().Unmap(VirtualAddress);
}
void *Drivermemcpy(void *Destination, void *Source, unsigned long Size)
{
SmartLock(DriverDisplayPrintLock);
debug("Copying %ld bytes from %#lx to %#lx...", Size, (unsigned long)Source, (unsigned long)Destination);
return memcpy(Destination, Source, Size);
}
void *Drivermemset(void *Destination, int Value, unsigned long Size)
{
SmartLock(DriverDisplayPrintLock);
debug("Setting %ld bytes from %#lx to %#x...", Size, (unsigned long)Destination, Value);
return memset(Destination, Value, Size);
}
void DriverNetSend(unsigned int DriverID, unsigned char *Data, unsigned short Size)
{
DumpData("DriverNetSend", Data, Size);
}
void DriverNetReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size)
{
DumpData("DriverNetReceive", Data, Size);
}
void DriverAHCIDiskRead(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
{
DumpData("DriverDiskRead", Data, SectorCount * 512);
}
void DriverAHCIDiskWrite(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
{
DumpData("DriverDiskWrite", Data, SectorCount * 512);
}
char *DriverPCIGetDeviceName(unsigned int VendorID, unsigned int DeviceID)
{
return (char *)"Unknown";
}
KernelAPI KAPI = {
.Version = {
.Major = 0,
.Minor = 0,
.Patch = 1},
.Info = {
.Offset = 0,
.DriverUID = 0,
},
.Memory = {
.PageSize = PAGE_SIZE,
.RequestPage = RequestPage,
.FreePage = FreePage,
.Map = MapMemory,
.Unmap = UnmapMemory,
},
.PCI = {
.GetDeviceName = DriverPCIGetDeviceName,
},
.Util = {
.DebugPrint = DriverDebugPrint,
.DisplayPrint = DriverDisplayPrint,
.memcpy = Drivermemcpy,
.memset = Drivermemset,
},
.Commmand = {
.Network = {
.SendPacket = DriverNetSend,
.ReceivePacket = DriverNetReceive,
},
.Disk = {
.AHCI = {
.ReadSector = DriverAHCIDiskRead,
.WriteSector = DriverAHCIDiskWrite,
},
},
},
};
int Driver::IOCB(unsigned long DUID, void *KCB)
{
foreach (auto var in Drivers)
@ -411,7 +290,48 @@ namespace Driver
}
case FexDriverType::FexDriverType_Input:
{
fixme("Input driver: %s", fexExtended->Driver.Name);
DriverInterruptHook *InterruptHook = nullptr;
if (DrvExtHdr->Driver.Bind.Interrupt.Vector[0] != 0)
InterruptHook = new DriverInterruptHook(DrvExtHdr->Driver.Bind.Interrupt.Vector[0] + 32, // x86
(void *)((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex),
KCallback);
for (unsigned long i = 0; i < sizeof(DrvExtHdr->Driver.Bind.Interrupt.Vector) / sizeof(DrvExtHdr->Driver.Bind.Interrupt.Vector[0]); i++)
{
if (DrvExtHdr->Driver.Bind.Interrupt.Vector[i] == 0)
break;
// InterruptHook = new DriverInterruptHook(DrvExtHdr->Driver.Bind.Interrupt.Vector[i] + 32, // x86
// (void *)((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex),
// KCallback);
fixme("TODO: MULTIPLE BIND INTERRUPT VECTORS %d", DrvExtHdr->Driver.Bind.Interrupt.Vector[i]);
}
KCallback->RawPtr = nullptr;
KCallback->Reason = CallbackReason::ConfigurationReason;
int callbackret = ((int (*)(KernelCallback *))((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex))(KCallback);
if (callbackret == DriverReturnCode::NOT_IMPLEMENTED)
{
KernelAllocator.FreePages(fex, TO_PAGES(Size));
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
error("Driver %s does not implement the configuration callback", fexExtended->Driver.Name);
break;
}
else if (callbackret != DriverReturnCode::OK)
{
KernelAllocator.FreePages(fex, TO_PAGES(Size));
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
error("Driver %s returned error %d", fexExtended->Driver.Name, callbackret);
break;
}
memset(KCallback, 0, sizeof(KernelCallback));
KCallback->Reason = CallbackReason::InterruptReason;
DriverFile *drvfile = new DriverFile;
drvfile->DriverUID = KAPI.Info.DriverUID;
drvfile->Address = (void *)fex;
drvfile->InterruptHook[0] = InterruptHook;
Drivers.push_back(drvfile);
break;
}
case FexDriverType::FexDriverType_Audio:
@ -430,6 +350,68 @@ namespace Driver
{
fixme("Process driver: %s", DrvExtHdr->Driver.Name);
}
else if (DrvExtHdr->Driver.Bind.Type == DriverBindType::BIND_INPUT)
{
Fex *fex = (Fex *)KernelAllocator.RequestPages(TO_PAGES(Size));
memcpy(fex, (void *)DriverAddress, Size);
FexExtended *fexExtended = (FexExtended *)((uint64_t)fex + EXTENDED_SECTION_ADDRESS);
#ifdef DEBUG
uint8_t *result = md5File((uint8_t *)fex, Size);
debug("MD5: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
kfree(result);
#endif
if (CallDriverEntryPoint(fex) != DriverCode::OK)
{
KernelAllocator.FreePages(fex, TO_PAGES(Size));
return DriverCode::DRIVER_RETURNED_ERROR;
}
debug("Starting driver %s (offset: %#lx)", fexExtended->Driver.Name, fex);
KernelCallback *KCallback = (KernelCallback *)KernelAllocator.RequestPages(TO_PAGES(sizeof(KernelCallback)));
switch (fexExtended->Driver.Type)
{
case FexDriverType::FexDriverType_Input:
{
fixme("Input driver: %s", fexExtended->Driver.Name);
KCallback->RawPtr = nullptr;
break;
KCallback->Reason = CallbackReason::ConfigurationReason;
int callbackret = ((int (*)(KernelCallback *))((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex))(KCallback);
if (callbackret == DriverReturnCode::NOT_IMPLEMENTED)
{
KernelAllocator.FreePages(fex, TO_PAGES(Size));
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
error("Driver %s does not implement the configuration callback", fexExtended->Driver.Name);
break;
}
else if (callbackret != DriverReturnCode::OK)
{
KernelAllocator.FreePages(fex, TO_PAGES(Size));
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
error("Driver %s returned error %d", fexExtended->Driver.Name, callbackret);
break;
}
KernelAllocator.FreePages(fex, TO_PAGES(Size));
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
DriverFile *drvfile = new DriverFile;
drvfile->DriverUID = KAPI.Info.DriverUID;
drvfile->Address = (void *)fex;
drvfile->InterruptHook[0] = nullptr;
Drivers.push_back(drvfile);
break;
}
default:
{
warn("Unknown driver type: %d", fexExtended->Driver.Type);
break;
}
}
}
else
{
error("Unknown driver bind type: %d", DrvExtHdr->Driver.Bind.Type);
@ -454,9 +436,9 @@ namespace Driver
if (!strcmp(extension, ".fex"))
{
uint64_t ret = this->LoadDriver(driver->Address, driver->Length);
char retstring[64];
char retstring[128];
if (ret == DriverCode::OK)
strcpy(retstring, "\e058C19OK");
strncpy(retstring, "\e058C19OK", 64);
else
sprintf_(retstring, "\eE85230FAILED (%#lx)", ret);
KPrint("%s %s", driver->Name, retstring);
@ -477,7 +459,7 @@ namespace Driver
void DriverInterruptHook::OnInterruptReceived(void *Frame)
#endif
{
CriticalSection cs; // or SmartCriticalSection(DriverInitLock); ?
SmartCriticalSection(DriverInterruptLock);
((int (*)(void *))(Handle))(Data);
}

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 "../kernel.h"
extern "C" __no_stack_protector void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); }
extern "C" SafeFunction void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); }
namespace Interrupts
{
@ -32,6 +32,7 @@ namespace Interrupts
/* APIC::APIC */ void *apic[MAX_CPU];
#elif defined(__aarch64__)
#endif
void *InterruptFrames[INT_FRAMES_MAX];
void Initialize(int Core)
{
@ -103,25 +104,42 @@ namespace Interrupts
#endif
}
extern "C" void MainInterruptHandler(void *Data)
void RemoveAll()
{
for (int i = 0; i < CPU::x64::IRQ223; i++)
RegisteredEvents->DeleteNode(i);
}
extern "C" SafeFunction void MainInterruptHandler(void *Data)
{
#if defined(__amd64__)
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
int Core = GetCurrentCPU()->ID;
Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber);
if (handler != (Handler *)0xdeadbeef)
handler->OnInterruptReceived(Frame);
else
error("Unhandled IRQ%d on CPU %d.", Frame->InterruptNumber - 32, Core);
memmove(InterruptFrames + 1, InterruptFrames, sizeof(InterruptFrames) - sizeof(InterruptFrames[0]));
InterruptFrames[0] = (void *)Frame->rip;
CPUData *CoreData = GetCurrentCPU();
int Core = 0;
if (likely(CoreData != nullptr))
Core = CoreData->ID;
if (apic[Core])
// If this is false, we have a big problem.
if (likely(Frame->InterruptNumber < CPU::x64::IRQ223 && Frame->InterruptNumber > CPU::x64::ISR0))
{
((APIC::APIC *)Interrupts::apic[Core])->EOI();
// TODO: Handle PIC too
return;
Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber);
if (likely(handler != (Handler *)0xdeadbeef))
handler->OnInterruptReceived(Frame);
else
error("Unhandled IRQ%ld on CPU %d.", Frame->InterruptNumber - 32, Core);
if (likely(apic[Core]))
{
((APIC::APIC *)Interrupts::apic[Core])->EOI();
// TODO: Handle PIC too
return;
}
// TODO: PIC
}
// TODO: PIC
#elif defined(__i386__)
void *Frame = Data;
#elif defined(__aarch64__)

View File

@ -20,6 +20,15 @@ void LockClass::DeadLock(SpinLockData Lock)
this->DeadLocks++;
if (Config.UnlockDeadLock && this->DeadLocks > 10)
{
warn("Unlocking lock '%s' held by '%s'! %ld locks in queue. Core %ld is being held by %ld.",
Lock.AttemptingToGet, Lock.CurrentHolder,
Lock.Count, CCore, Lock.Core);
this->DeadLocks = 0;
this->Unlock();
}
if (TaskManager)
TaskManager->Schedule();
}

View File

@ -2,6 +2,72 @@
namespace Xalloc
{
class XLockClass
{
struct SpinLockData
{
uint64_t LockData = 0x0;
const char *CurrentHolder = "(nul)";
const char *AttemptingToGet = "(nul)";
uint64_t Count = 0;
};
void DeadLock(SpinLockData Lock)
{
Xalloc_warn("Potential deadlock in lock '%s' held by '%s'! %ld locks in queue.", Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count);
}
private:
SpinLockData LockData;
bool IsLocked = false;
public:
int Lock(const char *FunctionName)
{
LockData.AttemptingToGet = FunctionName;
Retry:
unsigned int i = 0;
while (__atomic_exchange_n(&IsLocked, true, __ATOMIC_ACQUIRE) && ++i < 0x10000000)
;
if (i >= 0x10000000)
{
DeadLock(LockData);
goto Retry;
}
LockData.Count++;
LockData.CurrentHolder = FunctionName;
__sync_synchronize();
return 0;
}
int Unlock()
{
__sync_synchronize();
__atomic_store_n(&IsLocked, false, __ATOMIC_RELEASE);
LockData.Count--;
IsLocked = false;
return 0;
}
};
class XSmartLock
{
private:
XLockClass *LockPointer = nullptr;
public:
XSmartLock(XLockClass &Lock, const char *FunctionName)
{
this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName);
}
~XSmartLock() { this->LockPointer->Unlock(); }
};
XLockClass XLock;
#define XSL XSmartLock CONCAT(lock##_, __COUNTER__)(XLock, __FUNCTION__)
class SmartSMAPClass
{
private:
@ -20,6 +86,7 @@ namespace Xalloc
AllocatorV1::AllocatorV1(void *Address, bool UserMode, bool SMAPEnabled)
{
SmartSMAP;
XSL;
void *Position = Address;
UserMapping = UserMode;
SMAPUsed = SMAPEnabled;
@ -47,6 +114,7 @@ namespace Xalloc
AllocatorV1::~AllocatorV1()
{
SmartSMAP;
XSL;
Xalloc_trace("Destructor not implemented yet.");
}
@ -81,6 +149,7 @@ namespace Xalloc
void *AllocatorV1::Malloc(Xuint64_t Size)
{
SmartSMAP;
XSL;
if (this->HeapStart == nullptr)
{
Xalloc_err("Memory allocation not initialized yet!");
@ -136,12 +205,14 @@ namespace Xalloc
CurrentSegment = CurrentSegment->Next;
}
ExpandHeap(Size);
XLock.Unlock();
return this->Malloc(Size);
}
void AllocatorV1::Free(void *Address)
{
SmartSMAP;
XSL;
if (this->HeapStart == nullptr)
{
Xalloc_err("Memory allocation not initialized yet!");
@ -156,6 +227,7 @@ namespace Xalloc
void *AllocatorV1::Calloc(Xuint64_t NumberOfBlocks, Xuint64_t Size)
{
SmartSMAP;
XSL;
if (this->HeapStart == nullptr)
{
Xalloc_err("Memory allocation not initialized yet!");
@ -168,7 +240,10 @@ namespace Xalloc
Size = 0x10;
}
XLock.Unlock();
void *Block = this->Malloc(NumberOfBlocks * Size);
XLock.Lock(__FUNCTION__);
if (Block)
Xmemset(Block, 0, NumberOfBlocks * Size);
return Block;
@ -177,6 +252,7 @@ namespace Xalloc
void *AllocatorV1::Realloc(void *Address, Xuint64_t Size)
{
SmartSMAP;
XSL;
if (this->HeapStart == nullptr)
{
Xalloc_err("Memory allocation not initialized yet!");
@ -184,11 +260,13 @@ namespace Xalloc
}
if (!Address && Size == 0)
{
XLock.Unlock();
this->Free(Address);
return nullptr;
}
else if (!Address)
{
XLock.Unlock();
return this->Calloc(Size, sizeof(char));
}
@ -198,7 +276,9 @@ namespace Xalloc
Size = 0x10;
}
XLock.Unlock();
void *newAddress = this->Calloc(Size, sizeof(char));
XLock.Lock(__FUNCTION__);
Xmemcpy(newAddress, Address, Size);
return newAddress;
}

View File

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

View File

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

View File

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

View File

@ -5,37 +5,32 @@
#ifndef STACK_CHK_GUARD_VALUE
#if UINTPTR_MAX == UINT32_MAX
#define STACK_CHK_GUARD_VALUE 0x25F6CC8D
#define STACK_CHK_GUARD_VALUE 0xDEAD57AC
#else
#define STACK_CHK_GUARD_VALUE 0xBADFE2EC255A8572
#define STACK_CHK_GUARD_VALUE 0xDEAD57AC00000000
#endif
#endif
__attribute__((weak)) uintptr_t __stack_chk_guard = 0;
__attribute__((weak)) uintptr_t __stack_chk_guard_init(void)
__attribute__((weak, no_stack_protector)) uintptr_t __stack_chk_guard_init(void)
{
return STACK_CHK_GUARD_VALUE;
}
static void __attribute__((constructor, no_stack_protector)) __construct_stk_chk_guard()
extern __attribute__((constructor, no_stack_protector)) void __guard_setup(void)
{
debug("StackGuard: __guard_setup");
if (__stack_chk_guard == 0)
__stack_chk_guard = __stack_chk_guard_init();
}
// https://opensource.apple.com/source/xnu/xnu-1504.7.4/libkern/stack_protector.c.auto.html
// static void __guard_setup(void) __attribute__((constructor));
// static void __guard_setup(void)
// {
// read_random(__stack_chk_guard, sizeof(__stack_chk_guard));
// }
__attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
{
TaskingPanic();
error("Stack smashing detected!");
for (short i = 0; i < 10; i++)
error("Stack smashing detected!");
debug("%#lx", __stack_chk_guard);
KPrint("\eFF0000Stack smashing detected!");
#if defined(__amd64__) || defined(__i386__)
while (1)
@ -49,7 +44,8 @@ __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
__attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void)
{
TaskingPanic();
error("Buffer overflow detected!");
for (short i = 0; i < 10; i++)
error("Buffer overflow detected!");
KPrint("\eFF0000Buffer overflow detected!");
#if defined(__amd64__) || defined(__i386__)
while (1)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -49,11 +49,17 @@ static struct cag_option ConfigOptions[] = {
.value_name = "PATH",
.description = "Path to init program"},
{.identifier = 'l',
.access_letters = NULL,
.access_name = "udl",
.value_name = "BOOL",
.description = "Unlock the deadlock after 10 retries"},
{.identifier = 'o',
.access_letters = NULL,
.access_name = "ioc",
.value_name = "BOOL",
.description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash."},
.description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash"},
{.identifier = 'h',
.access_letters = "h",
@ -71,7 +77,8 @@ KernelConfig ParseConfig(char *Config)
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'},
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'},
false,
0};
0,
false};
if (Config == NULL)
{
@ -331,14 +338,14 @@ ParseSuccess:
case 'd':
{
value = cag_option_get_value(&context);
strcpy(config.DriverDirectory, value);
strncpy(config.DriverDirectory, value, strlen(value));
KPrint("\eAAFFAAUsing %s as driver directory", value);
break;
}
case 'i':
{
value = cag_option_get_value(&context);
strcpy(config.InitPath, value);
strncpy(config.InitPath, value, strlen(value));
KPrint("\eAAFFAAUsing %s as init program", value);
break;
}
@ -349,6 +356,13 @@ ParseSuccess:
KPrint("\eAAFFAAInterrupts on crash: %s", value);
break;
}
case 'l':
{
value = cag_option_get_value(&context);
strcmp(value, "true") ? config.UnlockDeadLock = false : config.UnlockDeadLock = true;
KPrint("\eAAFFAAUnlocking the deadlock after 10 retires");
break;
}
case 'h':
{
KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration.");

View File

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

View File

@ -27,6 +27,8 @@ FileSystem::Virtual *vfs = nullptr;
KernelConfig Config;
Time::Clock BootClock;
extern bool EnableProfiler;
// For the Display class. Printing on first buffer as default.
EXTERNC void putchar(char c) { Display->Print(c, 0); }
@ -43,10 +45,8 @@ EXTERNC void KPrint(const char *Format, ...)
Display->SetBuffer(0);
}
EXTERNC void Entry(BootInfo *Info)
EXTERNC __no_instrument_function void PostEntry(BootInfo *Info)
{
trace("Hello, World!");
InitializeMemoryManagement(Info);
BootClock = Time::ReadClock();
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
memcpy(bInfo, Info, sizeof(BootInfo));
@ -167,6 +167,34 @@ EXTERNC void Entry(BootInfo *Info)
CPU::Halt(true);
}
EXTERNC void __guard_setup(void);
typedef void (*CallPtr)(void);
extern CallPtr __init_array_start[0], __init_array_end[0];
extern CallPtr __fini_array_start[0], __fini_array_end[0];
EXTERNC __no_stack_protector __no_instrument_function void Entry(BootInfo *Info)
{
trace("Hello, World!");
// https://wiki.osdev.org/Calling_Global_Constructors
for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
(*func)();
InitializeMemoryManagement(Info);
EnableProfiler = true;
PostEntry(Info);
}
EXTERNC __no_stack_protector __no_instrument_function void BeforeShutdown()
{
// https://wiki.osdev.org/Calling_Global_Constructors
debug("Calling destructors...");
for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++)
(*func)();
debug("Done.");
}
EXTERNC void TaskingPanic()
{
if (TaskManager)

View File

@ -1,6 +1,7 @@
#include <convert.h>
#include <types.h>
#include <memory.hpp>
#include <debug.h>
// TODO: Replace mem* with assembly code
@ -29,7 +30,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
void *memcpy(void *dest, const void *src, size_t n)
void *memcpy_unsafe(void *dest, const void *src, size_t n)
{
unsigned char *d = dest;
const unsigned char *s = src;
@ -193,7 +194,7 @@ void *memcpy(void *dest, const void *src, size_t n)
return dest;
}
void *memset(void *dest, int c, size_t n)
void *memset_unsafe(void *dest, int c, size_t n)
{
unsigned char *s = dest;
size_t k;
@ -264,7 +265,7 @@ void *memset(void *dest, int c, size_t n)
return dest;
}
void *memmove(void *dest, const void *src, size_t n)
void *memmove_unsafe(void *dest, const void *src, size_t n)
{
#ifdef __GNUC__
typedef __attribute__((__may_alias__)) size_t WT;
@ -362,9 +363,9 @@ long unsigned strlen(const char s[])
return i;
}
char *strcat(char *destination, const char *source)
char *strcat_unsafe(char *destination, const char *source)
{
if ((destination == NULL) && (source == NULL))
if ((destination == NULL) || (source == NULL))
return NULL;
char *start = destination;
while (*start != '\0')
@ -379,7 +380,7 @@ char *strcat(char *destination, const char *source)
return destination;
}
char *strcpy(char *destination, const char *source)
char *strcpy_unsafe(char *destination, const char *source)
{
if (destination == NULL)
return NULL;
@ -446,7 +447,7 @@ char *strchr(const char *String, int Char)
char *strdup(const char *String)
{
char *OutBuffer = kmalloc(strlen((char *)String) + 1);
strcpy(OutBuffer, String);
strncpy(OutBuffer, String, strlen(String) + 1);
return OutBuffer;
}
@ -611,3 +612,232 @@ char *itoa(int Value, char *Buffer, int Base)
Buffer[i] = '\0';
return reverse(Buffer, 0, i - 1);
}
char *ltoa(long Value, char *Buffer, int Base)
{
if (Base < 2 || Base > 32)
return Buffer;
long n = abs(Value);
int i = 0;
while (n)
{
int r = n % Base;
if (r >= 10)
Buffer[i++] = 65 + (r - 10);
else
Buffer[i++] = 48 + r;
n = n / Base;
}
if (i == 0)
Buffer[i++] = '0';
if (Value < 0 && Base == 10)
Buffer[i++] = '-';
Buffer[i] = '\0';
return reverse(Buffer, 0, i - 1);
}
char *ultoa(unsigned long Value, char *Buffer, int Base)
{
if (Base < 2 || Base > 32)
return Buffer;
unsigned long n = Value;
int i = 0;
while (n)
{
int r = n % Base;
if (r >= 10)
Buffer[i++] = 65 + (r - 10);
else
Buffer[i++] = 48 + r;
n = n / Base;
}
if (i == 0)
Buffer[i++] = '0';
Buffer[i] = '\0';
return reverse(Buffer, 0, i - 1);
}
extern void __chk_fail(void) __attribute__((__noreturn__));
// #define DBG_CHK 1
__no_stack_protector void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen)
{
#ifdef DBG_CHK
debug("( dest:%#lx src:%#lx len:%llu slen:%llu )", dest, src, len, slen);
#endif
if (unlikely(dest == NULL))
{
error("dest is NULL");
while (1)
;
}
if (unlikely(src == NULL))
{
error("src is NULL");
while (1)
;
}
if (unlikely(len == 0))
{
error("len is 0");
while (1)
;
}
if (unlikely(slen == 0))
{
error("slen is 0");
while (1)
;
}
if (unlikely(len > slen))
__chk_fail();
return memcpy_unsafe(dest, src, len);
}
__no_stack_protector void *__memset_chk(void *dest, int val, size_t len, size_t slen)
{
#ifdef DBG_CHK
debug("( dest:%#lx val:%#x len:%llu slen:%llu )", dest, val, len, slen);
#endif
if (unlikely(dest == NULL))
{
error("dest is NULL");
while (1)
;
}
if (unlikely(len == 0))
{
error("len is 0");
while (1)
;
}
if (unlikely(slen == 0))
{
error("slen is 0");
while (1)
;
}
if (unlikely(len > slen))
__chk_fail();
return memset_unsafe(dest, val, len);
}
__no_stack_protector void *__memmove_chk(void *dest, const void *src, size_t len, size_t slen)
{
#ifdef DBG_CHK
debug("( dest:%#lx src:%#lx len:%llu slen:%llu )", dest, src, len, slen);
#endif
if (unlikely(dest == NULL))
{
error("dest is NULL");
while (1)
;
}
if (unlikely(src == NULL))
{
error("src is NULL");
while (1)
;
}
if (unlikely(len == 0))
{
error("len is 0");
while (1)
;
}
if (unlikely(slen == 0))
{
error("slen is 0");
while (1)
;
}
if (unlikely(len > slen))
__chk_fail();
return memmove_unsafe(dest, src, len);
}
__no_stack_protector char *__strcat_chk(char *dest, const char *src, size_t slen)
{
#ifdef DBG_CHK
debug("( dest:%#lx src:%#lx slen:%llu )", dest, src, slen);
#endif
if (unlikely(dest == NULL))
{
error("dest is NULL");
while (1)
;
}
if (unlikely(src == NULL))
{
error("src is NULL");
while (1)
;
}
if (unlikely(slen == 0))
{
error("slen is 0");
while (1)
;
}
size_t dest_len = strlen(dest);
if (unlikely(dest_len + strlen(src) + 1 > slen))
__chk_fail();
return strcat_unsafe(dest, src);
}
__no_stack_protector char *__strcpy_chk(char *dest, const char *src, size_t slen)
{
#ifdef DBG_CHK
debug("( dest:%#lx src:%#lx slen:%llu )", dest, src, slen);
#endif
if (unlikely(dest == NULL))
{
error("dest is NULL");
while (1)
;
}
if (unlikely(src == NULL))
{
error("src is NULL");
while (1)
;
}
if (unlikely(slen == 0))
{
error("slen is 0");
while (1)
;
}
size_t len = strlen(src);
if (unlikely(len >= slen))
__chk_fail();
return strcpy_unsafe(dest, src);
}

View File

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

View File

@ -266,14 +266,14 @@ typedef union
// 1. Some compilers are finicky about this;
// 2. Some people may want to convert this to C89;
// 3. If you try to use it as C++, only C++20 supports compound literals
static inline double_with_bit_access get_bit_access(double x)
static inline __no_instrument_function double_with_bit_access get_bit_access(double x)
{
double_with_bit_access dwba;
dwba.F = x;
return dwba;
}
static inline int get_sign_bit(double x)
static inline __no_instrument_function int get_sign_bit(double x)
{
// The sign is stored in the highest bit
return (int)(get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1));
@ -317,7 +317,7 @@ typedef struct
// or alternatively, that '\0' can be passed to the function in the output
// gadget. The former assumption holds within the printf library. It also
// assumes that the output gadget has been properly initialized.
static inline void putchar_via_gadget(output_gadget_t *gadget, char c)
static inline __no_instrument_function void putchar_via_gadget(output_gadget_t *gadget, char c)
{
printf_size_t write_pos = gadget->pos++;
// We're _always_ increasing pos, so as to count how may characters
@ -340,7 +340,7 @@ static inline void putchar_via_gadget(output_gadget_t *gadget, char c)
}
// Possibly-write the string-terminating '\0' character
static inline void append_termination_with_gadget(output_gadget_t *gadget)
static inline __no_instrument_function void append_termination_with_gadget(output_gadget_t *gadget)
{
if (gadget->function != NULL || gadget->max_chars == 0)
{
@ -356,13 +356,13 @@ static inline void append_termination_with_gadget(output_gadget_t *gadget)
// We can't use putchar_ as is, since our output gadget
// only takes pointers to functions with an extra argument
static inline void putchar_wrapper(char c, void *unused)
static inline __no_instrument_function void putchar_wrapper(char c, void *unused)
{
(void)unused;
putchar(c);
}
static inline output_gadget_t discarding_gadget(void)
static inline __no_instrument_function output_gadget_t discarding_gadget(void)
{
output_gadget_t gadget;
gadget.function = NULL;
@ -373,7 +373,7 @@ static inline output_gadget_t discarding_gadget(void)
return gadget;
}
static inline output_gadget_t buffer_gadget(char *buffer, size_t buffer_size)
static inline __no_instrument_function output_gadget_t buffer_gadget(char *buffer, size_t buffer_size)
{
printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ? PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t)buffer_size;
output_gadget_t result = discarding_gadget();
@ -385,7 +385,7 @@ static inline output_gadget_t buffer_gadget(char *buffer, size_t buffer_size)
return result;
}
static inline output_gadget_t function_gadget(void (*function)(char, void *), void *extra_arg)
static inline __no_instrument_function output_gadget_t function_gadget(void (*function)(char, void *), void *extra_arg)
{
output_gadget_t result = discarding_gadget();
result.function = function;
@ -394,7 +394,7 @@ static inline output_gadget_t function_gadget(void (*function)(char, void *), vo
return result;
}
static inline output_gadget_t extern_putchar_gadget(void)
static inline __no_instrument_function output_gadget_t extern_putchar_gadget(void)
{
return function_gadget(putchar_wrapper, NULL);
}
@ -403,7 +403,7 @@ static inline output_gadget_t extern_putchar_gadget(void)
// @return The length of the string (excluding the terminating 0) limited by 'maxsize'
// @note strlen uses size_t, but wes only use this function with printf_size_t
// variables - hence the signature.
static inline printf_size_t strnlen_s_(const char *str, printf_size_t maxsize)
static inline __no_instrument_function printf_size_t strnlen_s_(const char *str, printf_size_t maxsize)
{
const char *s;
for (s = str; *s && maxsize--; ++s)
@ -413,13 +413,13 @@ static inline printf_size_t strnlen_s_(const char *str, printf_size_t maxsize)
// internal test if char is a digit (0-9)
// @return true if char is a digit
static inline bool is_digit_(char ch)
static inline __no_instrument_function bool is_digit_(char ch)
{
return (ch >= '0') && (ch <= '9');
}
// internal ASCII string to printf_size_t conversion
static printf_size_t atou_(const char **str)
static __no_instrument_function printf_size_t atou_(const char **str)
{
printf_size_t i = 0U;
while (is_digit_(**str))
@ -430,7 +430,7 @@ static printf_size_t atou_(const char **str)
}
// output the specified string in reverse, taking care of any zero-padding
static void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len, printf_size_t width, printf_flags_t flags)
static __no_instrument_function void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len, printf_size_t width, printf_flags_t flags)
{
const printf_size_t start_pos = output->pos;
@ -461,7 +461,7 @@ static void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len
// Invoked by print_integer after the actual number has been printed, performing necessary
// work on the number's prefix (as the number is initially printed in reverse order)
static void print_integer_finalization(output_gadget_t *output, char *buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
static __no_instrument_function void print_integer_finalization(output_gadget_t *output, char *buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
{
printf_size_t unpadded_len = len;
@ -545,7 +545,7 @@ static void print_integer_finalization(output_gadget_t *output, char *buf, print
}
// An internal itoa-like function
static void print_integer(output_gadget_t *output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
static __no_instrument_function void print_integer(output_gadget_t *output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
{
char buf[PRINTF_INTEGER_BUFFER_SIZE];
printf_size_t len = 0U;
@ -604,7 +604,7 @@ static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = {
// Break up a double number - which is known to be a finite non-negative number -
// into its base-10 parts: integral - before the decimal point, and fractional - after it.
// Taken the precision into account, but does not change it even internally.
static struct double_components get_components(double number, printf_size_t precision)
static struct __no_instrument_function double_components get_components(double number, printf_size_t precision)
{
struct double_components number_;
number_.is_negative = get_sign_bit(number);
@ -741,7 +741,7 @@ static struct double_components get_normalized_components(bool negative, printf_
}
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
static void print_broken_up_decimal(
static __no_instrument_function void print_broken_up_decimal(
struct double_components number_, output_gadget_t *output, printf_size_t precision,
printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
{
@ -843,7 +843,7 @@ static void print_broken_up_decimal(
}
// internal ftoa for fixed decimal floating point
static void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
static __no_instrument_function void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
{
struct double_components value_ = get_components(number, precision);
print_broken_up_decimal(value_, output, precision, width, flags, buf, len);
@ -916,7 +916,7 @@ static double pow10_of_int(int floored_exp10)
return dwba.F;
}
static void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
static __no_instrument_function void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
{
const bool negative = get_sign_bit(number);
// This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it
@ -1039,7 +1039,7 @@ static void print_exponential_number(output_gadget_t *output, double number, pri
}
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
static void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential)
static __no_instrument_function void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential)
{
char buf[PRINTF_DECIMAL_BUFFER_SIZE];
printf_size_t len = 0U;
@ -1098,7 +1098,7 @@ static void print_floating_point(output_gadget_t *output, double value, printf_s
// Advances the format pointer past the flags, and returns the parsed flags
// due to the characters passed
static printf_flags_t parse_flags(const char **format)
static __no_instrument_function printf_flags_t parse_flags(const char **format)
{
printf_flags_t flags = 0U;
do
@ -1131,7 +1131,7 @@ static printf_flags_t parse_flags(const char **format)
} while (true);
}
static inline void format_string_loop(output_gadget_t *output, const char *format, va_list args)
static inline __no_instrument_function void format_string_loop(output_gadget_t *output, const char *format, va_list args)
{
#if PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER
#define ADVANCE_IN_FORMAT_STRING(cptr_) \
@ -1513,7 +1513,7 @@ static inline void format_string_loop(output_gadget_t *output, const char *forma
}
// internal vsnprintf - used for implementing _all library functions
static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args)
static __no_instrument_function int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args)
{
// Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is
// possible to call this function with a non-zero pos value for some "remedial printing".
@ -1528,30 +1528,30 @@ static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list a
///////////////////////////////////////////////////////////////////////////////
int vprintf_(const char *format, va_list arg)
__no_instrument_function int vprintf_(const char *format, va_list arg)
{
output_gadget_t gadget = extern_putchar_gadget();
return vsnprintf_impl(&gadget, format, arg);
}
int vsnprintf_(char *s, size_t n, const char *format, va_list arg)
__no_instrument_function int vsnprintf_(char *s, size_t n, const char *format, va_list arg)
{
output_gadget_t gadget = buffer_gadget(s, n);
return vsnprintf_impl(&gadget, format, arg);
}
int vsprintf_(char *s, const char *format, va_list arg)
__no_instrument_function int vsprintf_(char *s, const char *format, va_list arg)
{
return vsnprintf_(s, PRINTF_MAX_POSSIBLE_BUFFER_SIZE, format, arg);
}
int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg)
__no_instrument_function int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg)
{
output_gadget_t gadget = function_gadget(out, extra_arg);
return vsnprintf_impl(&gadget, format, arg);
}
int printf_(const char *format, ...)
__no_instrument_function int printf_(const char *format, ...)
{
va_list args;
va_start(args, format);
@ -1560,7 +1560,7 @@ int printf_(const char *format, ...)
return ret;
}
int sprintf_(char *s, const char *format, ...)
__no_instrument_function int sprintf_(char *s, const char *format, ...)
{
va_list args;
va_start(args, format);
@ -1569,7 +1569,7 @@ int sprintf_(char *s, const char *format, ...)
return ret;
}
int snprintf_(char *s, size_t n, const char *format, ...)
__no_instrument_function int snprintf_(char *s, size_t n, const char *format, ...)
{
va_list args;
va_start(args, format);
@ -1578,7 +1578,7 @@ int snprintf_(char *s, size_t n, const char *format, ...)
return ret;
}
int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...)
__no_instrument_function int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...)
{
va_list args;
va_start(args, format);

View File

@ -36,6 +36,8 @@ CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/a
endif
HEADERS = $(sort $(dir $(wildcard ./include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CPP_SOURCES:.cpp=.gcno)
INCLUDE_DIR = ./include
LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc
@ -79,7 +81,7 @@ LDFLAGS += -TArchitecture/i686/linker.ld \
else ifeq ($(OSARCH), aarch64)
CFLAGS += -pipe -fno-builtin -fPIC
CFLAG_STACK_PROTECTOR := -fstack-protector-all
CFLAG_STACK_PROTECTOR := -fstack-protector-all -fstack-clash-protection
LDFLAGS += -TArchitecture/aarch64/linker.ld -fPIC
endif
@ -92,8 +94,12 @@ else ifeq ($(OSARCH), aarch64)
NASMFLAGS :=
endif
# -finstrument-functions for __cyg_profile_func_enter & __cyg_profile_func_exit. Used for profiling and debugging.
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb -O0 -fdiagnostics-color=always -fsanitize=undefined
# CFLAGS += --coverage
# CFLAGS += -pg
# CFLAGS += -finstrument-functions
CFLAGS += -DDEBUG -ggdb -g -O0 -fdiagnostics-color=always -fverbose-asm -fstack-usage -fstack-check -fsanitize=undefined
LDFLAGS += -ggdb -O0 -g
NASMFLAGS += -F dwarf -g
WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable
@ -117,9 +123,9 @@ ifeq (,$(wildcard $(KERNEL_FILENAME)))
$(error $(KERNEL_FILENAME) does not exist)
endif
$(info Dumping $(KERNEL_FILENAME) in AT T syntax...)
$(OBJDUMP) -D -d $(KERNEL_FILENAME) > kernel_dump.map
$(OBJDUMP) -D -g -s -d $(KERNEL_FILENAME) > kernel_dump.map
$(info Dumping $(KERNEL_FILENAME) in Intel syntax...)
$(OBJDUMP) -M intel -D -d $(KERNEL_FILENAME) > kernel_dump_intel.map
$(OBJDUMP) -M intel -D -g -s -d $(KERNEL_FILENAME) > kernel_dump_intel.map
$(KERNEL_FILENAME): $(OBJ)
$(CC) $(LDFLAGS) $(OBJ) -o $@
@ -168,4 +174,4 @@ endif
$(NM) $@
clean:
rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(KERNEL_FILENAME)
rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(STACK_USAGE_OBJ) $(GCNO_OBJ) $(KERNEL_FILENAME)

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};
}
void IPCServiceStub()
{
trace("IPC Service Started.");
TaskManager->GetCurrentThread()->SetPriority(1);
// TODO: do something useful here, like, IPC event viewer or smth...
while (1)
{
// The scheduler doesn't like CPU::Pause for some reason. :/
}
}
IPC::IPC()
{
SmartLock(IPCLock);
trace("Starting IPC Service...");
Vector<AuxiliaryVector> auxv;
Tasking::TCB *thd = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, nullptr, nullptr, auxv);
thd->Rename("IPC Service");
}
IPC::~IPC()

View File

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

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);
double atof(const char *String);
char *itoa(int Value, char *Buffer, int Base);
char *ltoa(long Value, char *Buffer, int Base);
char *ultoa(unsigned long Value, char *Buffer, int Base);
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *dest, int c, size_t n);
void *memmove(void *dest, const void *src, size_t n);
void *memcpy_unsafe(void *dest, const void *src, size_t n);
void *memset_unsafe(void *dest, int c, size_t n);
void *memmove_unsafe(void *dest, const void *src, size_t n);
int memcmp(const void *vl, const void *vr, size_t n);
long unsigned strlen(const char s[]);
int strncmp(const char *s1, const char *s2, unsigned long n);
char *strcat(char *destination, const char *source);
char *strcpy(char *destination, const char *source);
char *strcat_unsafe(char *destination, const char *source);
char *strcpy_unsafe(char *destination, const char *source);
char *strncpy(char *destination, const char *source, unsigned long num);
int strcmp(const char *l, const char *r);
char *strstr(const char *haystack, const char *needle);
@ -38,6 +41,32 @@ extern "C"
int strcasecmp(const char *lhs, const char *rhs);
char *strtok(char *src, const char *delim);
void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen);
void *__memset_chk(void *dest, int val, size_t len, size_t slen);
void *__memmove_chk(void *dest, const void *src, size_t len, size_t slen);
char *__strcat_chk(char *dest, const char *src, size_t slen);
char *__strcpy_chk(char *dest, const char *src, size_t slen);
#ifdef __cplusplus
}
#endif
#undef memcpy
#define memcpy(dest, src, n) \
__memcpy_chk(dest, src, n, __builtin_object_size(dest, 0))
#undef memset
#define memset(dest, c, n) \
__memset_chk(dest, c, n, __builtin_object_size(dest, 0))
#undef memmove
#define memmove(dest, src, n) \
__memmove_chk(dest, src, n, __builtin_object_size(dest, 0))
#undef strcat
#define strcat(dest, src) \
__strcat_chk(dest, src, __builtin_object_size(dest, 0))
#undef strcpy
#define strcpy(dest, src) \
__strcpy_chk(dest, src, __builtin_object_size(dest, 0))

View File

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

View File

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

View File

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

View File

@ -11,7 +11,7 @@ namespace FileSystem
class Device
{
public:
FileSystemNode *AddFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
FileSystemNode *AddFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
Device();
~Device();
};
@ -20,7 +20,7 @@ namespace FileSystem
class Mount
{
public:
FileSystemNode *MountFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name);
FileSystemNode *MountFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name);
void DetectAndMountFS(void *drive);
Mount();
~Mount();
@ -38,7 +38,7 @@ namespace FileSystem
class Driver
{
public:
FileSystemNode *AddDriver(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
FileSystemNode *AddDriver(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
Driver();
~Driver();
};
@ -47,7 +47,7 @@ namespace FileSystem
class Network
{
public:
FileSystemNode *AddNetworkCard(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
FileSystemNode *AddNetworkCard(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
Network();
~Network();
};

View File

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

View File

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

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

View File

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

View File

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

View File

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