aboutsummaryrefslogtreecommitdiff
path: root/EASTL-compat/kcrt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'EASTL-compat/kcrt.cpp')
-rw-r--r--EASTL-compat/kcrt.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/EASTL-compat/kcrt.cpp b/EASTL-compat/kcrt.cpp
new file mode 100644
index 0000000..7a8fc52
--- /dev/null
+++ b/EASTL-compat/kcrt.cpp
@@ -0,0 +1,208 @@
+/*
+ * Shameless copy pasta from: https://github.com/sidyhe/dxx
+ */
+
+#include <cstdio>
+#include <cstdlib>
+
+#include <ntddk.h>
+
+#define KCRT_POOL_DEFAULT_TAG 0xDEADBEEF
+
+typedef struct _MALLOC_HEADER
+{
+ ULONG32 Tags;
+ ULONG32 _Resv0;
+ ULONG_PTR Size;
+} MALLOC_HEADER, *PMALLOC_HEADER;
+C_ASSERT(sizeof(MALLOC_HEADER) % sizeof(void *) == 0);
+
+// dynamic memory mgmt
+
+PMALLOC_HEADER GET_MALLOC_HEADER(PVOID ptr)
+{
+ return (MALLOC_HEADER *)((PUCHAR)ptr - sizeof(MALLOC_HEADER));
+}
+
+PVOID GET_MALLOC_ADDRESS(PMALLOC_HEADER header)
+{
+ return (PVOID)((PUCHAR)header + sizeof(MALLOC_HEADER));
+}
+
+ULONG_PTR GET_MALLOC_SIZE(PVOID ptr)
+{
+ PMALLOC_HEADER header = GET_MALLOC_HEADER(ptr);
+
+ if (header->Tags != KCRT_POOL_DEFAULT_TAG)
+ KeBugCheckEx(BAD_POOL_HEADER, 0, 0, 0, 0);
+
+ return header->Size;
+}
+
+// c runtime
+
+void __cdecl free(void * ptr)
+{
+ if (ptr)
+ {
+ MALLOC_HEADER * mhdr = GET_MALLOC_HEADER(ptr);
+
+ if (mhdr->Tags != KCRT_POOL_DEFAULT_TAG)
+ KeBugCheckEx(BAD_POOL_HEADER, 0, 0, 0, 0);
+
+ ExFreePool(mhdr);
+ }
+}
+
+void * __cdecl malloc(size_t size)
+{
+ PMALLOC_HEADER mhdr = NULL;
+ const size_t new_size = size + sizeof(MALLOC_HEADER);
+
+ mhdr = (PMALLOC_HEADER)ExAllocatePoolWithTag(NonPagedPool, new_size, KCRT_POOL_DEFAULT_TAG);
+ if (mhdr)
+ {
+ RtlZeroMemory(mhdr, new_size);
+
+ mhdr->Tags = KCRT_POOL_DEFAULT_TAG;
+ mhdr->Size = size;
+ return GET_MALLOC_ADDRESS(mhdr);
+ }
+
+ return NULL;
+}
+
+void * __cdecl realloc(void * ptr, size_t new_size)
+{
+ if (!ptr)
+ {
+ return malloc(new_size);
+ }
+ else if (new_size == 0)
+ {
+ free(ptr);
+ return NULL;
+ }
+ else
+ {
+ size_t old_size = GET_MALLOC_SIZE(ptr);
+
+ if (new_size <= old_size)
+ {
+ return ptr;
+ }
+ else
+ {
+ void * new_ptr = malloc(new_size);
+
+ if (new_ptr)
+ {
+ memcpy(new_ptr, ptr, old_size);
+ free(ptr);
+ return new_ptr;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+// new & delete
+
+void * __cdecl operator new(std::size_t size)
+{
+ return malloc(size);
+}
+
+void * __cdecl operator new[](size_t size)
+{
+ return malloc(size);
+}
+
+void __cdecl operator delete(void * ptr)
+{
+ free(ptr);
+}
+
+void __cdecl operator delete(void * ptr, size_t)
+{
+ free(ptr);
+}
+
+void __cdecl operator delete[](void * ptr, long long unsigned int)
+{
+ free(ptr);
+}
+
+void __cdecl operator delete[](void * ptr)
+{
+ free(ptr);
+}
+
+// EASTL
+
+void * operator new[](size_t size, const char *, int, unsigned, const char *, int)
+{
+ return malloc(size);
+}
+void * operator new[](size_t size, size_t, size_t, const char *, int, unsigned, const char *, int)
+{
+ return malloc(size);
+}
+
+extern "C" void __cxa_pure_virtual(void)
+{
+}
+
+// stolen from musl: https://elixir.bootlin.com/musl/v1.1.9/source/src/math/ceilf.c
+#define FORCE_EVAL(x) \
+ do \
+ { \
+ if (sizeof(x) == sizeof(float)) \
+ { \
+ volatile float __x __attribute__((unused)); \
+ __x = (x); \
+ } \
+ else if (sizeof(x) == sizeof(double)) \
+ { \
+ volatile double __x __attribute__((unused)); \
+ __x = (x); \
+ } \
+ else \
+ { \
+ volatile long double __x __attribute__((unused)); \
+ __x = (x); \
+ } \
+ } while (0)
+
+extern "C" float ceilf(float x)
+{
+ union {
+ float f;
+ UINT32 i;
+ } u = {x};
+ int e = (int)(u.i >> 23 & 0xff) - 0x7f;
+ UINT32 m;
+
+ if (e >= 23)
+ return x;
+ if (e >= 0)
+ {
+ m = 0x007fffff >> e;
+ if ((u.i & m) == 0)
+ return x;
+ FORCE_EVAL(x + 0x1p120f);
+ if (u.i >> 31 == 0)
+ u.i += m;
+ u.i &= ~m;
+ }
+ else
+ {
+ FORCE_EVAL(x + 0x1p120f);
+ if (u.i >> 31)
+ u.f = -0.0;
+ else if (u.i << 1)
+ u.f = 1.0;
+ }
+ return u.f;
+}