[WIP] Implementing "console" output and stuff.
This commit is contained in:
@@ -28,6 +28,8 @@ crtn_o = kernel_env.Object('src/crt/crtn.s')
|
||||
kernel_env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0].abspath} {crtbegin_o} $_LIBFLAGS -lgcc {crtend_o} {crtn_o[0].abspath}')
|
||||
|
||||
kernel_sources = env['KERNEL_SOURCES'] + Split('''
|
||||
src/cstdlib/memory.s
|
||||
|
||||
src/kernel/boot.s
|
||||
src/kernel/startup.cpp
|
||||
''')
|
||||
@@ -37,7 +39,7 @@ prog_kernel = kernel_env.Program(
|
||||
target = kernel_target,
|
||||
source = kernel_sources
|
||||
)
|
||||
kernel_env.Depends(prog_kernel, [crti_o, crtn_o])
|
||||
kernel_env.Depends(prog_kernel, [crti_o, crtn_o] + kernel_sources)
|
||||
kernel_env.Default(prog_kernel)
|
||||
|
||||
x86_64_iso_files = [
|
||||
@@ -69,7 +71,6 @@ uefi_env.Append(CPPPATH = ['/usr/include/efi', 'include'])
|
||||
|
||||
loader_sources = Split('''
|
||||
src/loader/main.cpp
|
||||
src/loader/minimalloc.cpp
|
||||
src/loader/miniprintf.cpp
|
||||
''')
|
||||
loader_target = uefi_env.File('#loader.x86_64.efi')
|
||||
|
||||
@@ -75,7 +75,34 @@ struct EfiDisplayInfo
|
||||
struct EfiBootInfo
|
||||
{
|
||||
EfiMemoryMap memoryMap;
|
||||
EfiDisplayInfo displayInfo;
|
||||
EfiDisplayInfo displayInfo = {};
|
||||
};
|
||||
|
||||
|
||||
inline bool isEfiMemoryTypeUsable(UINT32 type) noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EfiLoaderCode:
|
||||
case EfiLoaderData:
|
||||
case EfiBootServicesCode:
|
||||
case EfiBootServicesData:
|
||||
case EfiConventionalMemory:
|
||||
return true;
|
||||
case EfiReservedMemoryType:
|
||||
case EfiRuntimeServicesCode:
|
||||
case EfiRuntimeServicesData:
|
||||
case EfiUnusableMemory:
|
||||
case EfiACPIReclaimMemory:
|
||||
case EfiACPIMemoryNVS:
|
||||
case EfiMemoryMappedIO:
|
||||
case EfiMemoryMappedIOPortSpace:
|
||||
case EfiPalCode:
|
||||
case EfiMaxMemoryType:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // BOOT_HPP_INCLUDED
|
||||
|
||||
27
targets/x86_64/src/cstdlib/memory.s
Normal file
27
targets/x86_64/src/cstdlib/memory.s
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
.section .text
|
||||
.global memcpy
|
||||
.type memcpy @function
|
||||
|
||||
// int memcpy(void* dest [%rdi], void* src [%rsi], size_t count [%rdx])
|
||||
//
|
||||
memcpy:
|
||||
cmpq %rdx, 4
|
||||
jl memcpy_bytes
|
||||
movq (%rsi), %rax
|
||||
movq %rax, (%rdi)
|
||||
addq $4, %rsi
|
||||
addq $4, %rdi
|
||||
subq $4, %rdx
|
||||
jmp memcpy
|
||||
memcpy_bytes:
|
||||
cmpq %rdx, 0
|
||||
je memcpy_end
|
||||
movb (%rsi), %ah
|
||||
movb %ah, (%rdi)
|
||||
addq $1, %rsi
|
||||
addq $1, %rdi
|
||||
subq $1, %rdx
|
||||
jmp memcpy_bytes
|
||||
memcpy_end:
|
||||
ret
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "boot.hpp"
|
||||
|
||||
#include "os/draw.hpp"
|
||||
@@ -14,8 +15,7 @@ void initHeapFromEfiMemoryMap(const EfiMemoryMap& memoryMap) noexcept
|
||||
const uint64_t minAddr = reinterpret_cast<uint64_t>(&gKernelEnd);
|
||||
for (const EFI_MEMORY_DESCRIPTOR& descriptor : memoryMap)
|
||||
{
|
||||
// TODO: what about other types?
|
||||
if (descriptor.Type != EfiConventionalMemory)
|
||||
if (!isEfiMemoryTypeUsable(descriptor.Type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ void kernel_main()
|
||||
initGlobals();
|
||||
|
||||
// init the heap (required for the double buffer)
|
||||
initHeapFromEfiMemoryMap(gBootInfo->memoryMap);
|
||||
// initHeapFromEfiMemoryMap(gBootInfo->memoryMap);
|
||||
|
||||
// initialize the framebuffer
|
||||
draw::initializeDefaultFramebuffer({
|
||||
@@ -108,18 +108,27 @@ void kernel_main()
|
||||
});
|
||||
|
||||
// initialize terminal interface
|
||||
// tty::initialize();
|
||||
tty::initialize();
|
||||
|
||||
// std::printf("Kernel End: %p\n", &gKernelEnd);
|
||||
uint8_t test[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
uint8_t dest[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
std::memcpy(&dest[1], &test[3], 2);
|
||||
|
||||
for (int i = 0; i < 400; ++i)
|
||||
{
|
||||
std::printf("Hello font %d!\n", i);
|
||||
}
|
||||
#if 0
|
||||
for (int x = 0; x < 100; ++x)
|
||||
{
|
||||
for (int y = 0; y < 100; ++y)
|
||||
{
|
||||
draw::setPixel(x, y, {.red = 255});
|
||||
draw::setPixelDirect(x, y, {.red = 255});
|
||||
}
|
||||
}
|
||||
draw::flushPixels();
|
||||
#endif
|
||||
//draw::flushPixels();
|
||||
|
||||
/* Initialize the heap */
|
||||
// assert(gMultibootHeader->flags & MULTIBOOT_INFO_MEM_MAP);
|
||||
|
||||
@@ -5,13 +5,15 @@ extern "C"
|
||||
}
|
||||
#include "boot.hpp"
|
||||
#include "minielf.hpp"
|
||||
#include "minimalloc.hpp"
|
||||
#include "miniprintf.hpp"
|
||||
|
||||
// debug stuff
|
||||
// #define DUMP_DISPLAY_MODES
|
||||
// #define DUMP_MEMORY_MAP
|
||||
// #define DUMP_ELF
|
||||
#define PRINTLINE3(file, line) print(L"At: " file L":" #line L"\r\n")
|
||||
#define PRINTLINE2(file, line) PRINTLINE3(file, line)
|
||||
#define PRINTLINE() PRINTLINE2(__FILE__, __LINE__)
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -19,6 +21,21 @@ EFI_SYSTEM_TABLE* gSystemTable;
|
||||
EFI_BOOT_SERVICES* gBootServices;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL* gGraphicsOutputProtocol;
|
||||
|
||||
void* malloc(size_t size) noexcept
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
gBootServices->AllocatePool(EfiLoaderData, size, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void free(void* ptr) noexcept
|
||||
{
|
||||
// if (ptr != nullptr)
|
||||
// {
|
||||
// gBootServices->FreePool(ptr);
|
||||
// }
|
||||
}
|
||||
|
||||
EFI_STATUS openImageVolume(EFI_HANDLE image, EFI_FILE_HANDLE& outHandle)
|
||||
{
|
||||
EFI_LOADED_IMAGE* loadedImage = nullptr;
|
||||
@@ -112,18 +129,29 @@ EFI_STATUS getEfiMemoryMap(EfiMemoryMap& outMemoryMap)
|
||||
UINTN mapKey = 0;
|
||||
UINTN descriptorSize = 0;
|
||||
UINT32 descriptorVersion = 0;
|
||||
EFI_STATUS status = gBootServices->GetMemoryMap(&mapSize, nullptr, &mapKey, &descriptorSize, &descriptorVersion);
|
||||
if (status != EFI_BUFFER_TOO_SMALL) {
|
||||
return status;
|
||||
|
||||
EFI_STATUS status = EFI_BUFFER_TOO_SMALL;
|
||||
while (true)
|
||||
{
|
||||
status = gBootServices->GetMemoryMap(&mapSize, map, &mapKey, &descriptorSize, &descriptorVersion);
|
||||
if (status != EFI_BUFFER_TOO_SMALL) {
|
||||
break;
|
||||
}
|
||||
if (map != nullptr)
|
||||
{
|
||||
free(map);
|
||||
}
|
||||
map = static_cast<EFI_MEMORY_DESCRIPTOR*>(malloc(mapSize));
|
||||
if (map == nullptr) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
map = static_cast<EFI_MEMORY_DESCRIPTOR*>(malloc(mapSize));
|
||||
if (map == nullptr) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
status = gBootServices->GetMemoryMap(&mapSize, map, &mapKey, &descriptorSize, &descriptorVersion);
|
||||
if (EFI_ERROR(status))
|
||||
{
|
||||
free(map);
|
||||
if (map != nullptr)
|
||||
{
|
||||
gBootServices->FreePool(map);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
outMemoryMap.mapSize = mapSize;
|
||||
@@ -150,7 +178,7 @@ EFI_STATUS getEfiGraphicsOutputProtocol(EFI_GRAPHICS_OUTPUT_PROTOCOL*& outGOP)
|
||||
EFI_STATUS queryEfiDisplayModes(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION*& outModes)
|
||||
{
|
||||
UINTN sizeOfInfo = gGraphicsOutputProtocol->Mode->SizeOfInfo;
|
||||
outModes = new EFI_GRAPHICS_OUTPUT_MODE_INFORMATION[gGraphicsOutputProtocol->Mode->MaxMode];
|
||||
outModes = static_cast<EFI_GRAPHICS_OUTPUT_MODE_INFORMATION*>(malloc(gGraphicsOutputProtocol->Mode->MaxMode * sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)));
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* buffer = static_cast<EFI_GRAPHICS_OUTPUT_MODE_INFORMATION*>(malloc(sizeOfInfo));
|
||||
|
||||
for (UINT32 modeIdx = 0; modeIdx < gGraphicsOutputProtocol->Mode->MaxMode; ++modeIdx)
|
||||
@@ -158,7 +186,7 @@ EFI_STATUS queryEfiDisplayModes(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION*& outModes)
|
||||
EFI_STATUS status = gGraphicsOutputProtocol->QueryMode(gGraphicsOutputProtocol, modeIdx, &sizeOfInfo, &buffer);
|
||||
if (EFI_ERROR(status))
|
||||
{
|
||||
delete[] outModes;
|
||||
free(outModes);
|
||||
free(buffer);
|
||||
return status;
|
||||
}
|
||||
@@ -187,37 +215,86 @@ UINT32 findBestDisplayMode(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* displayModes)
|
||||
return bestMode;
|
||||
}
|
||||
|
||||
bool isEfiMemoryTypeUsable(EFI_MEMORY_TYPE type)
|
||||
const char* efiStatusToString(EFI_STATUS status)
|
||||
{
|
||||
switch (type)
|
||||
switch (status)
|
||||
{
|
||||
case EfiLoaderCode:
|
||||
case EfiLoaderData:
|
||||
case EfiBootServicesCode:
|
||||
case EfiBootServicesData:
|
||||
case EfiConventionalMemory:
|
||||
return true;
|
||||
case EfiReservedMemoryType:
|
||||
case EfiRuntimeServicesCode:
|
||||
case EfiRuntimeServicesData:
|
||||
case EfiUnusableMemory:
|
||||
case EfiACPIReclaimMemory:
|
||||
case EfiACPIMemoryNVS:
|
||||
case EfiMemoryMappedIO:
|
||||
case EfiMemoryMappedIOPortSpace:
|
||||
case EfiPalCode:
|
||||
case EfiMaxMemoryType:
|
||||
case EFI_SUCCESS:
|
||||
return "EFI_SUCCESS";
|
||||
case EFI_LOAD_ERROR:
|
||||
return "EFI_LOAD_ERROR";
|
||||
case EFI_INVALID_PARAMETER:
|
||||
return "EFI_INVALID_PARAMETER";
|
||||
case EFI_UNSUPPORTED:
|
||||
return "EFI_UNSUPPORTED";
|
||||
case EFI_BAD_BUFFER_SIZE:
|
||||
return "EFI_BAD_BUFFER_SIZE";
|
||||
case EFI_BUFFER_TOO_SMALL:
|
||||
return "EFI_BUFFER_TOO_SMALL";
|
||||
case EFI_NOT_READY:
|
||||
return "EFI_NOT_READY";
|
||||
case EFI_DEVICE_ERROR:
|
||||
return "EFI_DEVICE_ERROR";
|
||||
case EFI_WRITE_PROTECTED:
|
||||
return "EFI_WRITE_PROTECTED";
|
||||
case EFI_OUT_OF_RESOURCES:
|
||||
return "EFI_OUT_OF_RESOURCES";
|
||||
case EFI_VOLUME_CORRUPTED:
|
||||
return "EFI_VOLUME_CORRUPTED";
|
||||
case EFI_VOLUME_FULL:
|
||||
return "EFI_VOLUME_FULL";
|
||||
case EFI_NO_MEDIA:
|
||||
return "EFI_NO_MEDIA";
|
||||
case EFI_MEDIA_CHANGED:
|
||||
return "EFI_MEDIA_CHANGED";
|
||||
case EFI_NOT_FOUND:
|
||||
return "EFI_NOT_FOUND";
|
||||
case EFI_ACCESS_DENIED:
|
||||
return "EFI_ACCESS_DENIED";
|
||||
case EFI_NO_RESPONSE:
|
||||
return "EFI_NO_RESPONSE";
|
||||
case EFI_NO_MAPPING:
|
||||
return "EFI_NO_MAPPING";
|
||||
case EFI_TIMEOUT:
|
||||
return "EFI_TIMEOUT";
|
||||
case EFI_NOT_STARTED:
|
||||
return "EFI_NOT_STARTED";
|
||||
case EFI_ALREADY_STARTED:
|
||||
return "EFI_ALREADY_STARTED";
|
||||
case EFI_ABORTED:
|
||||
return "EFI_ABORTED";
|
||||
case EFI_ICMP_ERROR:
|
||||
return "EFI_ICMP_ERROR";
|
||||
case EFI_TFTP_ERROR:
|
||||
return "EFI_TFTP_ERROR";
|
||||
case EFI_PROTOCOL_ERROR:
|
||||
return "EFI_PROTOCOL_ERROR";
|
||||
case EFI_INCOMPATIBLE_VERSION:
|
||||
return "EFI_INCOMPATIBLE_VERSION";
|
||||
case EFI_SECURITY_VIOLATION:
|
||||
return "EFI_SECURITY_VIOLATION";
|
||||
case EFI_CRC_ERROR:
|
||||
return "EFI_CRC_ERROR";
|
||||
case EFI_END_OF_MEDIA:
|
||||
return "EFI_END_OF_MEDIA";
|
||||
case EFI_END_OF_FILE:
|
||||
return "EFI_END_OF_FILE";
|
||||
case EFI_INVALID_LANGUAGE:
|
||||
return "EFI_INVALID_LANGUAGE";
|
||||
case EFI_COMPROMISED_DATA:
|
||||
return "EFI_COMPROMISED_DATA";
|
||||
default:
|
||||
return false;
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define DIE_ON_ERROR(message) \
|
||||
if (EFI_ERROR(status)) \
|
||||
{ \
|
||||
printAndWait(message L"\r\n"); \
|
||||
return status; \
|
||||
#define DIE_ON_ERROR(message) \
|
||||
if (EFI_ERROR(status)) \
|
||||
{ \
|
||||
printf("Status: %s\n", efiStatusToString(status)); \
|
||||
printAndWait(message L"\r\n"); \
|
||||
return status; \
|
||||
}
|
||||
|
||||
extern "C" EFI_STATUS efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable)
|
||||
@@ -226,11 +303,10 @@ extern "C" EFI_STATUS efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemT
|
||||
gSystemTable = systemTable;
|
||||
gBootServices = systemTable->BootServices;
|
||||
|
||||
initMiniMalloc();
|
||||
initMiniPrintf(&putchar);
|
||||
|
||||
// this will be passed to the OS
|
||||
EfiBootInfo* bootInfo = new EfiBootInfo;
|
||||
EfiBootInfo* bootInfo = static_cast<EfiBootInfo*>(malloc(sizeof(EfiBootInfo)));
|
||||
|
||||
gSystemTable->ConOut->ClearScreen(gSystemTable->ConOut);
|
||||
|
||||
@@ -246,6 +322,10 @@ extern "C" EFI_STATUS efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemT
|
||||
status = gGraphicsOutputProtocol->SetMode(gGraphicsOutputProtocol, bestModeIdx);
|
||||
DIE_ON_ERROR(L"Error setting display mode.");
|
||||
|
||||
UINTN consoleColumns, consoleRows;
|
||||
status = gSystemTable->ConOut->QueryMode(gSystemTable->ConOut, gSystemTable->ConOut->Mode->Mode, &consoleColumns, &consoleRows);
|
||||
DIE_ON_ERROR(L"Error fetching console mode.");
|
||||
|
||||
bootInfo->displayInfo = {
|
||||
.frameBufferBase = reinterpret_cast<void*>(gGraphicsOutputProtocol->Mode->FrameBufferBase),
|
||||
.frameBufferSize = gGraphicsOutputProtocol->Mode->FrameBufferSize,
|
||||
@@ -329,14 +409,24 @@ extern "C" EFI_STATUS efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemT
|
||||
|
||||
#if defined(DUMP_MEMORY_MAP)
|
||||
int entry = -1;
|
||||
for (const EFI_MEMORY_DESCRIPTOR& descriptor : *memoryMap)
|
||||
{
|
||||
++entry;
|
||||
|
||||
// if (!isEfiMemoryTypeUsable(static_cast<EFI_MEMORY_TYPE>(descriptor->Type))) {
|
||||
if (descriptor.Type != EfiConventionalMemory) {
|
||||
UINTN leftThisPage = consoleRows - 1;
|
||||
printf("ltp: %d\n", static_cast<int>(leftThisPage));
|
||||
for (const EFI_MEMORY_DESCRIPTOR& descriptor : bootInfo->memoryMap)
|
||||
{
|
||||
if (!isEfiMemoryTypeUsable(descriptor.Type)) {
|
||||
// if (descriptor.Type != EfiBootServicesCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
++entry;
|
||||
if (leftThisPage == 0)
|
||||
{
|
||||
printAndWait(L"-- Any key to continue --\r\n");
|
||||
leftThisPage = consoleRows;
|
||||
}
|
||||
--leftThisPage;
|
||||
|
||||
printf(
|
||||
"Entry %d: type=%d, physicalStart=0x%lX, numberOfPages=%ld\n",
|
||||
entry,
|
||||
@@ -347,7 +437,7 @@ extern "C" EFI_STATUS efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemT
|
||||
}
|
||||
|
||||
// printing may have invalidated the map, get it again
|
||||
status = getEfiMemoryMap(*memoryMap);
|
||||
status = getEfiMemoryMap(bootInfo->memoryMap);
|
||||
DIE_ON_ERROR("Error getting EFI memory map.");
|
||||
#undef DUMP_MEMORY_MAP
|
||||
#endif // defined(DUMP_MEMORY_MAP)
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
inline const size_t INIT_MALLOC_SPACE_ELEMENTS = 1024;
|
||||
inline const size_t INIT_MALLOC_SPACE_BYTES = INIT_MALLOC_SPACE_ELEMENTS * sizeof(max_align_t);
|
||||
|
||||
max_align_t gInitMallocSpace[INIT_MALLOC_SPACE_ELEMENTS];
|
||||
|
||||
struct MallocBlock
|
||||
{
|
||||
size_t elements;
|
||||
MallocBlock* nextBlock;
|
||||
};
|
||||
struct AllocInfo
|
||||
{
|
||||
size_t elements;
|
||||
};
|
||||
static_assert(sizeof(MallocBlock) <= sizeof(max_align_t));
|
||||
static_assert(sizeof(AllocInfo) <= sizeof(max_align_t));
|
||||
|
||||
MallocBlock* gNextBlock;
|
||||
}
|
||||
|
||||
void initMiniMalloc()
|
||||
{
|
||||
gNextBlock = reinterpret_cast<MallocBlock*>(gInitMallocSpace);
|
||||
gNextBlock->elements = INIT_MALLOC_SPACE_ELEMENTS;
|
||||
gNextBlock->nextBlock = nullptr;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void* malloc(size_t size) noexcept
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const size_t requiredElements = (size + sizeof(max_align_t) - 1) / sizeof(max_align_t) + 1;
|
||||
MallocBlock* prevBlock = nullptr;
|
||||
for (MallocBlock* block = gNextBlock; block != nullptr; block = block->nextBlock)
|
||||
{
|
||||
if (block->elements >= requiredElements)
|
||||
{
|
||||
MallocBlock* newBlock = nullptr;
|
||||
if (block->elements > requiredElements)
|
||||
{
|
||||
newBlock = reinterpret_cast<MallocBlock*>(reinterpret_cast<max_align_t*>(block) + requiredElements);
|
||||
newBlock->nextBlock = block->nextBlock;
|
||||
newBlock->elements = block->elements - requiredElements;
|
||||
}
|
||||
else
|
||||
{
|
||||
newBlock = block->nextBlock;
|
||||
}
|
||||
if (prevBlock != nullptr)
|
||||
{
|
||||
prevBlock->nextBlock = newBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
gNextBlock = newBlock;
|
||||
}
|
||||
AllocInfo* allocInfo = reinterpret_cast<AllocInfo*>(block);
|
||||
allocInfo->elements = requiredElements;
|
||||
return reinterpret_cast<max_align_t*>(block) + 1;
|
||||
}
|
||||
prevBlock = block;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void free(void* memory) noexcept
|
||||
{
|
||||
if (memory == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MallocBlock* block = reinterpret_cast<MallocBlock*>(static_cast<max_align_t*>(memory) - 1);
|
||||
block->nextBlock = gNextBlock;
|
||||
gNextBlock = block;
|
||||
}
|
||||
}
|
||||
|
||||
void* operator new(size_t count)
|
||||
{
|
||||
if (void* ptr = malloc(count); ptr != nullptr)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
// TODO: some kind of abort
|
||||
}
|
||||
|
||||
void operator delete(void* data) noexcept
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
void* operator new[](size_t count)
|
||||
{
|
||||
if (void* ptr = malloc(count); ptr != nullptr)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
// TODO: some kind of abort
|
||||
}
|
||||
|
||||
void operator delete[](void* data) noexcept
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
void operator delete(void* data, size_t /* size */) noexcept
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
void operator delete[](void* data, size_t /* size */) noexcept
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
Reference in New Issue
Block a user