mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 14:04:36 +00:00
Changed a lot of files. Summary: profiler support; "SafeFunction"; UnlockDeadLock kernel config; Code optimization & more
This commit is contained in:
parent
2fba834d41
commit
0289054900
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,8 @@
|
||||
*.o
|
||||
*.su
|
||||
*.gcno
|
||||
*.map
|
||||
*.fsys
|
||||
*.log
|
||||
Files/*.psf
|
||||
.dccache
|
||||
|
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
@ -40,7 +40,8 @@
|
||||
"-Wl,-static,--no-dynamic-linker,-ztext",
|
||||
"-shared",
|
||||
"-zmax-page-size=0x1000",
|
||||
"-nostdinc++"
|
||||
"-nostdinc++",
|
||||
"-fsanitize=undefined"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"); }
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
@ -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__)
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
__no_stack_protector void DisplayConsoleScreen(CRData data)
|
||||
SafeFunction void DisplayConsoleScreen(CRData data)
|
||||
{
|
||||
EHPrint("TODO");
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
__no_stack_protector void DisplayTasksScreen(CRData data)
|
||||
SafeFunction void DisplayTasksScreen(CRData data)
|
||||
{
|
||||
const char *StatusColor[7] = {
|
||||
"FF0000", // Unknown
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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
131
Core/Driver/DriverAPI.cpp
Normal 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
10
Core/Driver/api.hpp
Normal 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__
|
@ -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__)
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
25
DAPI.hpp
25
DAPI.hpp
@ -14,6 +14,7 @@ enum DriverReturnCode
|
||||
NOT_ACCEPTED,
|
||||
INVALID_KERNEL_API,
|
||||
DEVICE_NOT_SUPPORTED,
|
||||
SYSTEM_NOT_SUPPORTED,
|
||||
KERNEL_API_VERSION_NOT_SUPPORTED
|
||||
};
|
||||
|
||||
@ -22,7 +23,8 @@ enum DriverBindType
|
||||
BIND_NULL,
|
||||
BIND_INTERRUPT,
|
||||
BIND_PROCESS,
|
||||
BIND_PCI
|
||||
BIND_PCI,
|
||||
BIND_INPUT
|
||||
};
|
||||
|
||||
struct KernelAPI
|
||||
@ -80,7 +82,7 @@ struct KernelAPI
|
||||
void (*WriteSector)(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port);
|
||||
} AHCI;
|
||||
} Disk;
|
||||
} Commmand;
|
||||
} Command;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
@ -95,7 +97,8 @@ enum CallbackReason
|
||||
BindReason,
|
||||
UnbindReason,
|
||||
InterruptReason,
|
||||
ProcessReason
|
||||
ProcessReason,
|
||||
InputReason,
|
||||
};
|
||||
|
||||
struct KernelCallback
|
||||
@ -130,6 +133,22 @@ struct KernelCallback
|
||||
} Fetch;
|
||||
} DiskCallback;
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned long X;
|
||||
unsigned long Y;
|
||||
unsigned long Z;
|
||||
struct
|
||||
{
|
||||
bool Left;
|
||||
bool Right;
|
||||
bool Middle;
|
||||
} Buttons;
|
||||
} Mouse;
|
||||
} InputCallback;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned char Vector;
|
||||
|
6
Fex.hpp
6
Fex.hpp
@ -87,6 +87,12 @@ struct FexExtended
|
||||
unsigned short SubClass;
|
||||
unsigned short ProgIF;
|
||||
} PCI;
|
||||
|
||||
struct
|
||||
{
|
||||
bool AttachToMouse;
|
||||
bool AttachToKeyboard;
|
||||
} Input;
|
||||
} Bind;
|
||||
} Driver;
|
||||
} __attribute__((packed));
|
||||
|
@ -19,7 +19,7 @@ namespace FileSystem
|
||||
return Size;
|
||||
}
|
||||
|
||||
FileSystemOpeations ustar = {
|
||||
FileSystemOperations ustar = {
|
||||
.Name = "ustar",
|
||||
.Read = USTAR_Read,
|
||||
};
|
||||
|
@ -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!");
|
||||
}
|
||||
}
|
||||
|
22
KConfig.cpp
22
KConfig.cpp
@ -49,11 +49,17 @@ static struct cag_option ConfigOptions[] = {
|
||||
.value_name = "PATH",
|
||||
.description = "Path to init program"},
|
||||
|
||||
{.identifier = 'l',
|
||||
.access_letters = NULL,
|
||||
.access_name = "udl",
|
||||
.value_name = "BOOL",
|
||||
.description = "Unlock the deadlock after 10 retries"},
|
||||
|
||||
{.identifier = 'o',
|
||||
.access_letters = NULL,
|
||||
.access_name = "ioc",
|
||||
.value_name = "BOOL",
|
||||
.description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash."},
|
||||
.description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash"},
|
||||
|
||||
{.identifier = 'h',
|
||||
.access_letters = "h",
|
||||
@ -71,7 +77,8 @@ KernelConfig ParseConfig(char *Config)
|
||||
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'},
|
||||
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'},
|
||||
false,
|
||||
0};
|
||||
0,
|
||||
false};
|
||||
|
||||
if (Config == NULL)
|
||||
{
|
||||
@ -331,14 +338,14 @@ ParseSuccess:
|
||||
case 'd':
|
||||
{
|
||||
value = cag_option_get_value(&context);
|
||||
strcpy(config.DriverDirectory, value);
|
||||
strncpy(config.DriverDirectory, value, strlen(value));
|
||||
KPrint("\eAAFFAAUsing %s as driver directory", value);
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
{
|
||||
value = cag_option_get_value(&context);
|
||||
strcpy(config.InitPath, value);
|
||||
strncpy(config.InitPath, value, strlen(value));
|
||||
KPrint("\eAAFFAAUsing %s as init program", value);
|
||||
break;
|
||||
}
|
||||
@ -349,6 +356,13 @@ ParseSuccess:
|
||||
KPrint("\eAAFFAAInterrupts on crash: %s", value);
|
||||
break;
|
||||
}
|
||||
case 'l':
|
||||
{
|
||||
value = cag_option_get_value(&context);
|
||||
strcmp(value, "true") ? config.UnlockDeadLock = false : config.UnlockDeadLock = true;
|
||||
KPrint("\eAAFFAAUnlocking the deadlock after 10 retires");
|
||||
break;
|
||||
}
|
||||
case 'h':
|
||||
{
|
||||
KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration.");
|
||||
|
64
KThread.cpp
64
KThread.cpp
@ -14,65 +14,33 @@
|
||||
Driver::Driver *DriverManager = nullptr;
|
||||
Disk::Manager *DiskManager = nullptr;
|
||||
|
||||
void StartFilesystem()
|
||||
{
|
||||
KPrint("Initializing Filesystem...");
|
||||
vfs = new FileSystem::Virtual;
|
||||
new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
|
||||
KPrint("Initializing Disk Manager...");
|
||||
DiskManager = new Disk::Manager;
|
||||
/* ... */
|
||||
TEXIT(0);
|
||||
}
|
||||
|
||||
void LoadDrivers()
|
||||
{
|
||||
KPrint("Loading Drivers...");
|
||||
DriverManager = new Driver::Driver;
|
||||
TEXIT(0);
|
||||
}
|
||||
|
||||
void FetchDisks()
|
||||
{
|
||||
KPrint("Fetching Disks...");
|
||||
foreach (auto Driver in DriverManager->GetDrivers())
|
||||
{
|
||||
FexExtended *DrvExtHdr = (FexExtended *)((uint64_t)Driver->Address + EXTENDED_SECTION_ADDRESS);
|
||||
|
||||
if (DrvExtHdr->Driver.Type == FexDriverType::FexDriverType_Storage)
|
||||
DiskManager->FetchDisks(Driver->DriverUID);
|
||||
}
|
||||
TEXIT(0);
|
||||
}
|
||||
|
||||
void KernelMainThread()
|
||||
{
|
||||
TaskManager->InitIPC();
|
||||
TaskManager->GetCurrentThread()->SetPriority(100);
|
||||
Vector<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());
|
||||
|
34
Kernel.cpp
34
Kernel.cpp
@ -27,6 +27,8 @@ FileSystem::Virtual *vfs = nullptr;
|
||||
KernelConfig Config;
|
||||
Time::Clock BootClock;
|
||||
|
||||
extern bool EnableProfiler;
|
||||
|
||||
// For the Display class. Printing on first buffer as default.
|
||||
EXTERNC void putchar(char c) { Display->Print(c, 0); }
|
||||
|
||||
@ -43,10 +45,8 @@ EXTERNC void KPrint(const char *Format, ...)
|
||||
Display->SetBuffer(0);
|
||||
}
|
||||
|
||||
EXTERNC void Entry(BootInfo *Info)
|
||||
EXTERNC __no_instrument_function void PostEntry(BootInfo *Info)
|
||||
{
|
||||
trace("Hello, World!");
|
||||
InitializeMemoryManagement(Info);
|
||||
BootClock = Time::ReadClock();
|
||||
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
|
||||
memcpy(bInfo, Info, sizeof(BootInfo));
|
||||
@ -167,6 +167,34 @@ EXTERNC void Entry(BootInfo *Info)
|
||||
CPU::Halt(true);
|
||||
}
|
||||
|
||||
EXTERNC void __guard_setup(void);
|
||||
|
||||
typedef void (*CallPtr)(void);
|
||||
extern CallPtr __init_array_start[0], __init_array_end[0];
|
||||
extern CallPtr __fini_array_start[0], __fini_array_end[0];
|
||||
|
||||
EXTERNC __no_stack_protector __no_instrument_function void Entry(BootInfo *Info)
|
||||
{
|
||||
trace("Hello, World!");
|
||||
|
||||
// https://wiki.osdev.org/Calling_Global_Constructors
|
||||
for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
|
||||
(*func)();
|
||||
|
||||
InitializeMemoryManagement(Info);
|
||||
EnableProfiler = true;
|
||||
PostEntry(Info);
|
||||
}
|
||||
|
||||
EXTERNC __no_stack_protector __no_instrument_function void BeforeShutdown()
|
||||
{
|
||||
// https://wiki.osdev.org/Calling_Global_Constructors
|
||||
debug("Calling destructors...");
|
||||
for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++)
|
||||
(*func)();
|
||||
debug("Done.");
|
||||
}
|
||||
|
||||
EXTERNC void TaskingPanic()
|
||||
{
|
||||
if (TaskManager)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
16
Makefile
16
Makefile
@ -36,6 +36,8 @@ CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/a
|
||||
endif
|
||||
HEADERS = $(sort $(dir $(wildcard ./include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CPP_SOURCES:.cpp=.gcno)
|
||||
INCLUDE_DIR = ./include
|
||||
|
||||
LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc
|
||||
@ -79,7 +81,7 @@ LDFLAGS += -TArchitecture/i686/linker.ld \
|
||||
else ifeq ($(OSARCH), aarch64)
|
||||
|
||||
CFLAGS += -pipe -fno-builtin -fPIC
|
||||
CFLAG_STACK_PROTECTOR := -fstack-protector-all
|
||||
CFLAG_STACK_PROTECTOR := -fstack-protector-all -fstack-clash-protection
|
||||
LDFLAGS += -TArchitecture/aarch64/linker.ld -fPIC
|
||||
|
||||
endif
|
||||
@ -92,8 +94,12 @@ else ifeq ($(OSARCH), aarch64)
|
||||
NASMFLAGS :=
|
||||
endif
|
||||
|
||||
# -finstrument-functions for __cyg_profile_func_enter & __cyg_profile_func_exit. Used for profiling and debugging.
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb -O0 -fdiagnostics-color=always -fsanitize=undefined
|
||||
# CFLAGS += --coverage
|
||||
# CFLAGS += -pg
|
||||
# CFLAGS += -finstrument-functions
|
||||
CFLAGS += -DDEBUG -ggdb -g -O0 -fdiagnostics-color=always -fverbose-asm -fstack-usage -fstack-check -fsanitize=undefined
|
||||
LDFLAGS += -ggdb -O0 -g
|
||||
NASMFLAGS += -F dwarf -g
|
||||
WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable
|
||||
@ -117,9 +123,9 @@ ifeq (,$(wildcard $(KERNEL_FILENAME)))
|
||||
$(error $(KERNEL_FILENAME) does not exist)
|
||||
endif
|
||||
$(info Dumping $(KERNEL_FILENAME) in AT T syntax...)
|
||||
$(OBJDUMP) -D -d $(KERNEL_FILENAME) > kernel_dump.map
|
||||
$(OBJDUMP) -D -g -s -d $(KERNEL_FILENAME) > kernel_dump.map
|
||||
$(info Dumping $(KERNEL_FILENAME) in Intel syntax...)
|
||||
$(OBJDUMP) -M intel -D -d $(KERNEL_FILENAME) > kernel_dump_intel.map
|
||||
$(OBJDUMP) -M intel -D -g -s -d $(KERNEL_FILENAME) > kernel_dump_intel.map
|
||||
|
||||
$(KERNEL_FILENAME): $(OBJ)
|
||||
$(CC) $(LDFLAGS) $(OBJ) -o $@
|
||||
@ -168,4 +174,4 @@ endif
|
||||
$(NM) $@
|
||||
|
||||
clean:
|
||||
rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(KERNEL_FILENAME)
|
||||
rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(STACK_USAGE_OBJ) $(GCNO_OBJ) $(KERNEL_FILENAME)
|
||||
|
87
Profiling/cyg.cpp
Normal file
87
Profiling/cyg.cpp
Normal 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
67
Profiling/gcov.cpp
Normal 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
19
Profiling/gprof.cpp
Normal 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 */
|
||||
}
|
2
Recovery/RecoveryMain.cpp
Normal file
2
Recovery/RecoveryMain.cpp
Normal file
@ -0,0 +1,2 @@
|
||||
#include <recovery.hpp>
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
11
include/recovery.hpp
Normal 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__
|
@ -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;
|
||||
|
@ -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__
|
||||
|
@ -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.
|
||||
|
@ -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; }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user