summaryrefslogtreecommitdiffhomepage
path: root/src/internal/ntux_memfn_impl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/ntux_memfn_impl.c')
-rw-r--r--src/internal/ntux_memfn_impl.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/internal/ntux_memfn_impl.c b/src/internal/ntux_memfn_impl.c
new file mode 100644
index 0000000..1bcc753
--- /dev/null
+++ b/src/internal/ntux_memfn_impl.c
@@ -0,0 +1,94 @@
+/***********************************************************/
+/* ntux: native translation und extension */
+/* Copyright (C) 2016 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */
+/***********************************************************/
+
+#include <stddef.h>
+#include <ntapi/ntapi.h>
+#include "ntux_memfn_impl.h"
+#include "ntux_driver_impl.h"
+
+void * ntux_calloc(size_t n, size_t size)
+{
+ struct ntux_memory_block block;
+
+ if (!n || (size > (size_t)(-1) / n))
+ return 0;
+
+ size *= n;
+ size += 0xf;
+ size &= ~(size_t)0xf;
+
+ block.addr = 0;
+ block.size = size + sizeof(block);
+
+ if (ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &block.addr,
+ 0,
+ &block.size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE))
+ return 0;
+
+ block.used = size;
+ block.avail = block.size - block.used;
+
+ return (char *)block.addr + offsetof(struct ntux_memory_block,buffer);
+}
+
+void * ntux_balloc(
+ struct ntux_memory_block * cache,
+ struct ntux_memory_block * block,
+ size_t n, size_t size)
+{
+ char * baddr;
+ void * addr = 0;
+
+ if (!n || (size > (size_t)(-1) / n))
+ return 0;
+
+ if (!cache || !cache->addr)
+ addr = ntux_calloc(n,size);
+
+ size *= n;
+ size += 0xf;
+ size &= ~(size_t)0xf;
+
+ if (size < block->avail)
+ addr = ntux_calloc(n,size);
+
+ /* newly allocated block? */
+ if (addr) {
+ baddr = addr;
+ baddr -= offsetof(struct ntux_memory_block,buffer);
+
+ ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)block,
+ (uintptr_t *)baddr,
+ sizeof(*block));
+
+ return addr;
+ }
+
+ /* cache */
+ addr = &block->buffer[block->used / sizeof(size_t)];
+ block->used += size;
+ block->avail -= size;
+ return addr;
+}
+
+void ntux_free(void * addr)
+{
+ struct ntux_memory_block block;
+
+ block.addr = addr;
+ block.size = 0;
+
+ ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &block.addr,
+ &block.size,
+ NT_MEM_RELEASE);
+}