Add guard page debug malloc.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-10-09 15:28:16 +02:00
parent f876667cc5
commit 7a7ddc2d73
4 changed files with 151 additions and 16 deletions

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
This file is part of the Sortix C Library.
@ -79,6 +79,27 @@ int heap_get_paranoia(void);
#endif
#endif
#if !defined(HEAP_GUARD_DEBUG) && \
defined(__is_sortix_kernel) && defined(HEAP_GUARD_DEBUG_KERNEL)
#define HEAP_GUARD_DEBUG
#endif
#if !defined(MALLOC_GUARD_DEBUG) && \
__STDC_HOSTED__ && defined(HEAP_GUARD_DEBUG_USERLAND)
#define HEAP_GUARD_DEBUG
#endif
#if defined(HEAP_GUARD_DEBUG) && !defined(__is_sortix_kernel)
struct heap_alloc
{
uintptr_t from;
size_t size;
};
#define HEAP_PAGE_SIZE 4096UL
#define HEAP_ALIGN_PAGEDOWN(x) ((x) & ~(HEAP_PAGE_SIZE - 1))
#define HEAP_ALIGN_PAGEUP(x) (-(-(x) & ~(HEAP_PAGE_SIZE - 1)))
#endif
/* A magic value to identify a heap part edge. The value is selected such
that it is not appropriately aligned like a real heap chunk pointer, such
that there are no ambiguous cases. */

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of the Sortix C Library.
@ -25,16 +25,14 @@
#include <malloc.h>
#include <stdlib.h>
#if __is_sortix_kernel
#include <sortix/kernel/kernel.h>
#endif
#if defined(HEAP_NO_ASSERT)
#define __heap_verify() ((void) 0)
#undef assert
#define assert(x) do { ((void) 0); } while ( 0 )
#endif
#if !defined(HEAP_GUARD_DEBUG)
extern "C" void free(void* addr)
{
if ( !addr )
@ -55,3 +53,33 @@ extern "C" void free(void* addr)
__heap_verify();
__heap_unlock();
}
#else
#if defined(__is_sortix_kernel)
#include <sortix/kernel/addralloc.h>
#include <sortix/kernel/memorymanagement.h>
#else
#include <sys/mman.h>
#endif
extern "C" void free(void* addr)
{
if ( !addr )
return;
#if defined(__is_sortix_kernel)
using namespace Sortix;
addralloc_t* alloc_ptr = (addralloc_t*) Page::AlignDown((uintptr_t) addr - 16);
assert(alloc_ptr->from == (uintptr_t) alloc_ptr);
addralloc_t alloc = *alloc_ptr;
Memory::UnmapRange(alloc.from, alloc.size - Page::Size(), PAGE_USAGE_KERNEL_HEAP);
FreeKernelAddress(&alloc);
#else
struct heap_alloc* alloc_ptr =
(struct heap_alloc*) HEAP_ALIGN_PAGEDOWN((uintptr_t) addr - 16);
munmap((void*) alloc_ptr->from, alloc_ptr->size);
#endif
}
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of the Sortix C Library.
@ -28,16 +28,14 @@
#include <stdlib.h>
#include <string.h>
#if __is_sortix_kernel
#include <sortix/kernel/kernel.h>
#endif
#if defined(HEAP_NO_ASSERT)
#define __heap_verify() ((void) 0)
#undef assert
#define assert(x) do { ((void) 0); } while ( 0 )
#endif
#if !defined(HEAP_GUARD_DEBUG)
extern "C" void* malloc(size_t original_size)
{
if ( !heap_size_has_bin(original_size) )
@ -102,3 +100,55 @@ extern "C" void* malloc(size_t original_size)
// Return the inner data associated with the chunk to the caller.
return heap_chunk_to_data(result_chunk);
}
#else
#if defined(__is_sortix_kernel)
#include <sortix/mman.h>
#include <sortix/kernel/addralloc.h>
#include <sortix/kernel/memorymanagement.h>
#else
#include <sys/mman.h>
#endif
extern "C" void* malloc(size_t original_size)
{
if ( !original_size )
original_size = 1;
size_t size = -(-original_size & ~15UL);
size_t needed = 16 + size;
#if defined(__is_sortix_kernel)
using namespace Sortix;
needed = Page::AlignUp(needed);
size_t virtsize = needed + Page::Size();
addralloc_t addralloc;
if ( !AllocateKernelAddress(&addralloc, virtsize) )
return NULL;
if ( !Memory::MapRange(addralloc.from, addralloc.size - Page::Size(),
PROT_KREAD | PROT_KWRITE, PAGE_USAGE_KERNEL_HEAP) )
{
FreeKernelAddress(&addralloc);
return NULL;
}
Memory::Flush();
addralloc_t* addralloc_ptr = (addralloc_t*) (addralloc.from);
*addralloc_ptr = addralloc;
#else
needed = HEAP_ALIGN_PAGEUP(needed);
size_t virtsize = needed + HEAP_PAGE_SIZE;
void* from = mmap(NULL, virtsize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if ( from == MAP_FAILED )
return NULL;
void* guard = (char*) from + needed;
if ( mprotect(guard, HEAP_PAGE_SIZE, PROT_NONE) < 0 )
return munmap(from, virtsize), (void*) NULL;
struct heap_alloc* addralloc_ptr = (struct heap_alloc*) from;
addralloc_ptr->from = (uintptr_t) from;
addralloc_ptr->size = virtsize;
#endif
size_t offset = needed - size;
return (void*) (addralloc_ptr->from + offset);
}
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of the Sortix C Library.
@ -28,16 +28,14 @@
#include <stdlib.h>
#include <string.h>
#if __is_sortix_kernel
#include <sortix/kernel/kernel.h>
#endif
#if defined(HEAP_NO_ASSERT)
#define __heap_verify() ((void) 0)
#undef assert
#define assert(x) do { ((void) 0); } while ( 0 )
#endif
#if !defined(HEAP_GUARD_DEBUG)
extern "C" void* realloc(void* ptr, size_t requested_size)
{
if ( !ptr )
@ -125,3 +123,41 @@ extern "C" void* realloc(void* ptr, size_t requested_size)
return result;
}
#else
#if defined(__is_sortix_kernel)
#include <sortix/kernel/addralloc.h>
#include <sortix/kernel/memorymanagement.h>
#endif
extern "C" void* realloc(void* ptr, size_t requested_size)
{
if ( !ptr )
return malloc(requested_size);
#if defined(__is_sortix_kernel)
using namespace Sortix;
addralloc_t* alloc_ptr =
(addralloc_t*) Page::AlignDown((uintptr_t) ptr - 16);
assert(alloc_ptr->from == (uintptr_t) alloc_ptr);
addralloc_t alloc = *alloc_ptr;
size_t size = (alloc.from + alloc.size - Page::Size()) - (uintptr_t) ptr;
#else
struct heap_alloc* alloc_ptr =
(struct heap_alloc*) HEAP_ALIGN_PAGEDOWN((uintptr_t) ptr - 16);
assert(alloc_ptr->from == (uintptr_t) alloc_ptr);
struct heap_alloc alloc = *alloc_ptr;
size_t size = (alloc.from + alloc.size - HEAP_PAGE_SIZE) - (uintptr_t) ptr;
#endif
if ( requested_size <= size )
return ptr;
void* replacement = malloc(requested_size);
if ( !replacement )
return NULL;
memcpy(replacement, ptr, size);
free(ptr);
return replacement;
}
#endif