From 1fe24d0cd0b547a771c00f6fca8f50ba6ca2fb2c Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 3 Dec 2011 20:03:20 +0100 Subject: [PATCH] Add heap with guard pages to detect out of bound reads/writes. This is a very simple heap implementation that allocates memory so that the end of each allocation always coincides with a page end and is followed by a guard page which is marked non-present. Out of bounds access (both read and write) therefore cause a crash (unhandled page fault). Note that this allocator is neither speed nor space efficient, indeed it wastes huge amounts of pages and address space so it is quite easy to hit limits. It is intended as a pure debug feature. --- build/config_headers/kernel_debug_config.h | 18 +- build/config_headers/tracing_config.h | 2 + src/system/kernel/Jamfile | 1 + src/system/kernel/guarded_heap.cpp | 679 +++++++++++++++++++++ src/system/kernel/heap.cpp | 30 +- src/system/kernel/vm/vm.cpp | 8 +- 6 files changed, 718 insertions(+), 20 deletions(-) create mode 100644 src/system/kernel/guarded_heap.cpp diff --git a/build/config_headers/kernel_debug_config.h b/build/config_headers/kernel_debug_config.h index ca5cb3a42b..5029ab6d48 100644 --- a/build/config_headers/kernel_debug_config.h +++ b/build/config_headers/kernel_debug_config.h @@ -101,12 +101,28 @@ // Enables swap support. #define ENABLE_SWAP_SUPPORT 1 -// Use the slab allocator as generic memory allocator (malloc()/free()). +// Use the selected allocator as generic memory allocator (malloc()/free()). +#define USE_DEBUG_HEAP_FOR_MALLOC 0 + // Heap implementation with additional debugging facilities. +#define USE_GUARDED_HEAP_FOR_MALLOC 0 + // Heap implementation that allocates memory so that the end of the + // allocation always coincides with a page end and is followed by a guard + // page which is marked non-present. Out of bounds access (both read and + // write) therefore cause a crash (unhandled page fault). Note that this + // allocator is neither speed nor space efficient, indeed it wastes huge + // amounts of pages and address space so it is quite easy to hit limits. #define USE_SLAB_ALLOCATOR_FOR_MALLOC 1 + // Heap implementation based on the slab allocator (for production use). // Enables additional sanity checks in the slab allocator's memory manager. #define DEBUG_SLAB_MEMORY_MANAGER_PARANOID_CHECKS 0 +// Disables memory re-use in the guarded heap (freed memory is never reused and +// stays invalid causing every access to crash). Note that this is a magnitude +// more space inefficient than the guarded heap itself. Fully booting may not +// work at all due to address space waste. +#define DEBUG_GUARDED_HEAP_DISABLE_MEMORY_REUSE 0 + // When set limits the amount of available RAM (in MB). //#define LIMIT_AVAILABLE_MEMORY 256 diff --git a/build/config_headers/tracing_config.h b/build/config_headers/tracing_config.h index 4cbf14e560..a38408752d 100644 --- a/build/config_headers/tracing_config.h +++ b/build/config_headers/tracing_config.h @@ -28,6 +28,8 @@ #define BMESSAGE_TRACING 0 #define FILE_DESCRIPTOR_TRACING 0 #define FILE_DESCRIPTOR_TRACING_STACK_TRACE 0 /* stack trace depth */ +#define GUARDED_HEAP_TRACING 0 +#define GUARDED_HEAP_TRACING_STACK_TRACE 0 /* stack trace depth */ #define IO_CONTEXT_TRACING 0 #define IO_CONTEXT_TRACING_STACK_TRACE 0 /* stack trace depth */ #define KERNEL_HEAP_TRACING 0 diff --git a/src/system/kernel/Jamfile b/src/system/kernel/Jamfile index bfc433f38a..04b3719298 100644 --- a/src/system/kernel/Jamfile +++ b/src/system/kernel/Jamfile @@ -30,6 +30,7 @@ KernelMergeObject kernel_core.o : cpu.cpp DPC.cpp elf.cpp + guarded_heap.cpp heap.cpp image.cpp int.cpp diff --git a/src/system/kernel/guarded_heap.cpp b/src/system/kernel/guarded_heap.cpp new file mode 100644 index 0000000000..09aabb4ce7 --- /dev/null +++ b/src/system/kernel/guarded_heap.cpp @@ -0,0 +1,679 @@ +/* + * Copyright 2011, Michael Lotz . + * Distributed under the terms of the MIT License. + */ + + +#include +#include + +#include +#include +#include +#include +#include +#include + + +#if USE_GUARDED_HEAP_FOR_MALLOC + + +#define GUARDED_HEAP_PAGE_FLAG_USED 0x01 +#define GUARDED_HEAP_PAGE_FLAG_FIRST 0x02 +#define GUARDED_HEAP_PAGE_FLAG_GUARD 0x04 +#define GUARDED_HEAP_PAGE_FLAG_DEAD 0x08 + + +struct guarded_heap; + +struct guarded_heap_page { + uint8 flags; + size_t allocation_size; + void* allocation_base; + size_t alignment; + thread_id thread; +}; + +struct guarded_heap_area { + guarded_heap* heap; + guarded_heap_area* next; + area_id area; + addr_t base; + size_t size; + size_t page_count; + size_t used_pages; + void* protection_cookie; + mutex lock; + guarded_heap_page pages[0]; +}; + +struct guarded_heap { + rw_lock lock; + size_t page_count; + size_t used_pages; + vint32 area_creation_counter; + guarded_heap_area* areas; +}; + + +static guarded_heap sGuardedHeap = { + RW_LOCK_INITIALIZER("guarded heap lock"), + 0, 0, 0, NULL +}; + + +#if GUARDED_HEAP_TRACING + +namespace GuardedHeapTracing { + + +class GuardedHeapTraceEntry + : public TRACE_ENTRY_SELECTOR(GUARDED_HEAP_TRACING_STACK_TRACE) { + public: + GuardedHeapTraceEntry(guarded_heap* heap) + : + TraceEntryBase(GUARDED_HEAP_TRACING_STACK_TRACE, 0, true), + fHeap(heap) + { + } + + protected: + guarded_heap* fHeap; +}; + + +class Allocate : public GuardedHeapTraceEntry { + public: + Allocate(guarded_heap* heap, void* pageBase, uint32 flags) + : + GuardedHeapTraceEntry(heap), + fPageBase(pageBase), + fFlags(flags) + { + Initialized(); + } + + virtual void AddDump(TraceOutput& out) + { + out.Print("guarded heap allocate: heap: %p; page: %p; " + "flags:%s%s%s%s", fHeap, fPageBase, + (fFlags & GUARDED_HEAP_PAGE_FLAG_USED) != 0 ? " used" : "", + (fFlags & GUARDED_HEAP_PAGE_FLAG_FIRST) != 0 ? " first" : "", + (fFlags & GUARDED_HEAP_PAGE_FLAG_GUARD) != 0 ? " guard" : "", + (fFlags & GUARDED_HEAP_PAGE_FLAG_DEAD) != 0 ? " dead" : ""); + } + + private: + void* fPageBase; + uint32 fFlags; +}; + + +class Free : public GuardedHeapTraceEntry { + public: + Free(guarded_heap* heap, void* pageBase) + : + GuardedHeapTraceEntry(heap), + fPageBase(pageBase) + { + Initialized(); + } + + virtual void AddDump(TraceOutput& out) + { + out.Print("guarded heap free: heap: %p; page: %p", fHeap, + fPageBase); + } + + private: + void* fPageBase; +}; + + +} // namespace GuardedHeapTracing + +# define T(x) new(std::nothrow) GuardedHeapTracing::x +#else +# define T(x) +#endif // GUARDED_HEAP_TRACING + + +static void +guarded_heap_page_protect(guarded_heap_area& area, size_t pageIndex, + uint32 protection) +{ + if (area.area < 0) + return; + + addr_t address = area.base + pageIndex * B_PAGE_SIZE; + vm_set_kernel_area_debug_protection(area.protection_cookie, (void*)address, + B_PAGE_SIZE, protection); +} + + +static void +guarded_heap_page_allocate(guarded_heap_area& area, size_t startPageIndex, + size_t pagesNeeded, size_t allocationSize, size_t alignment, + void* allocationBase) +{ + if (pagesNeeded < 2) { + panic("need to allocate at least 2 pages, one for guard\n"); + return; + } + + guarded_heap_page* firstPage = NULL; + for (size_t i = 0; i < pagesNeeded; i++) { + guarded_heap_page& page = area.pages[startPageIndex + i]; + page.flags = GUARDED_HEAP_PAGE_FLAG_USED; + if (i == 0) { + page.thread = find_thread(NULL); + page.allocation_size = allocationSize; + page.allocation_base = allocationBase; + page.alignment = alignment; + page.flags |= GUARDED_HEAP_PAGE_FLAG_FIRST; + firstPage = &page; + } else { + page.thread = firstPage->thread; + page.allocation_size = allocationSize; + page.allocation_base = allocationBase; + page.alignment = alignment; + } + + if (i == pagesNeeded - 1) { + page.flags |= GUARDED_HEAP_PAGE_FLAG_GUARD; + guarded_heap_page_protect(area, startPageIndex + i, 0); + } else { + guarded_heap_page_protect(area, startPageIndex + i, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + } + + T(Allocate(area.heap, + (void*)(area.base + (startPageIndex + i) * B_PAGE_SIZE), + page.flags)); + } +} + + +static void +guarded_heap_free_page(guarded_heap_area& area, size_t pageIndex, + bool force = false) +{ + guarded_heap_page& page = area.pages[pageIndex]; + +#if DEBUG_GUARDED_HEAP_DISABLE_MEMORY_REUSE + if (force || area.area < 0) + page.flags = 0; + else + page.flags |= GUARDED_HEAP_PAGE_FLAG_DEAD; +#else + page.flags = 0; +#endif + + page.allocation_size = 0; + page.thread = find_thread(NULL); + + guarded_heap_page_protect(area, pageIndex, 0); + + T(Free(area.heap, (void*)(area.base + pageIndex * B_PAGE_SIZE))); +} + + +static bool +guarded_heap_pages_allocated(guarded_heap& heap, size_t pagesAllocated) +{ + return (atomic_add((vint32*)&heap.used_pages, pagesAllocated) + + pagesAllocated) + >= heap.page_count - HEAP_GROW_SIZE / B_PAGE_SIZE / 2; +} + + +static void* +guarded_heap_area_allocate(guarded_heap_area& area, size_t size, + size_t alignment, uint32 flags, bool& grow) +{ + if (alignment > B_PAGE_SIZE) { + panic("alignment of %" B_PRIuSIZE " not supported", alignment); + return NULL; + } + + size_t pagesNeeded = (size + B_PAGE_SIZE - 1) / B_PAGE_SIZE + 1; + if (pagesNeeded > area.page_count) { + panic("huge allocation of %" B_PRIuSIZE " pages not supported", + pagesNeeded); + return NULL; + } + + for (size_t i = 0; i <= area.page_count - pagesNeeded; i++) { + guarded_heap_page& page = area.pages[i]; + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_USED) != 0) + continue; + + // Candidate, check if we have enough pages going forward + // (including the guard page). + bool candidate = true; + for (size_t j = 1; j < pagesNeeded; j++) { + if ((area.pages[i + j].flags & GUARDED_HEAP_PAGE_FLAG_USED) + != 0) { + candidate = false; + break; + } + } + + if (!candidate) + continue; + + if (alignment == 0) + alignment = 1; + + size_t offset = size & (B_PAGE_SIZE - 1); + void* result = (void*)((area.base + i * B_PAGE_SIZE + + (offset > 0 ? B_PAGE_SIZE - offset : 0)) & ~(alignment - 1)); + + guarded_heap_page_allocate(area, i, pagesNeeded, size, alignment, + result); + + area.used_pages += pagesNeeded; + grow = guarded_heap_pages_allocated(*area.heap, pagesNeeded); + return result; + } + + return NULL; +} + + +static bool +guarded_heap_area_init(guarded_heap& heap, area_id id, void* baseAddress, + size_t size, uint32 flags) +{ + guarded_heap_area* area = (guarded_heap_area*)baseAddress; + area->heap = &heap; + area->area = id; + area->size = size; + area->page_count = area->size / B_PAGE_SIZE; + area->used_pages = 0; + + size_t pagesNeeded = (sizeof(guarded_heap_area) + + area->page_count * sizeof(guarded_heap_page)) / B_PAGE_SIZE; + + area->page_count -= pagesNeeded; + area->size = area->page_count * B_PAGE_SIZE; + area->base = (addr_t)baseAddress + pagesNeeded * B_PAGE_SIZE; + + if (area->area >= 0 && vm_prepare_kernel_area_debug_protection(area->area, + &area->protection_cookie) != B_OK) { + return false; + } + + mutex_init(&area->lock, "guarded_heap_area_lock"); + + for (size_t i = 0; i < area->page_count; i++) + guarded_heap_free_page(*area, i, true); + + WriteLocker areaListWriteLocker(heap.lock); + area->next = heap.areas; + heap.areas = area; + heap.page_count += area->page_count; + + return true; +} + + +static bool +guarded_heap_area_create(guarded_heap& heap, uint32 flags) +{ + void* baseAddress = NULL; + area_id id = create_area("guarded_heap_area", &baseAddress, + B_ANY_KERNEL_ADDRESS, HEAP_GROW_SIZE, B_FULL_LOCK, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + + if (id < 0) + return false; + + return guarded_heap_area_init(heap, id, baseAddress, HEAP_GROW_SIZE, flags); +} + + +static bool +guarded_heap_add_area(guarded_heap& heap, int32 counter, uint32 flags) +{ + if ((flags & (HEAP_DONT_LOCK_KERNEL_SPACE | HEAP_DONT_WAIT_FOR_MEMORY)) + != 0) { + return false; + } + + if (atomic_test_and_set((vint32*)&heap.area_creation_counter, + counter + 1, counter) == counter) { + return guarded_heap_area_create(heap, flags); + } + + return false; +} + + +static void* +guarded_heap_allocate(guarded_heap& heap, size_t size, size_t alignment, + uint32 flags) +{ + bool grow = false; + void* result = NULL; + ReadLocker areaListReadLocker(heap.lock); + for (guarded_heap_area* area = heap.areas; area != NULL; + area = area->next) { + + MutexLocker locker(area->lock); + result = guarded_heap_area_allocate(*area, size, alignment, flags, + grow); + if (result != NULL) + break; + } + + int32 counter = atomic_get(&heap.area_creation_counter); + areaListReadLocker.Unlock(); + + if (result == NULL || grow) { + bool added = guarded_heap_add_area(heap, counter, flags); + if (result == NULL && added) + return guarded_heap_allocate(heap, size, alignment, flags); + } + + if (result == NULL) + panic("ran out of memory"); + + return result; +} + + +static guarded_heap_area* +guarded_heap_get_locked_area_for(guarded_heap& heap, void* address) +{ + ReadLocker areaListReadLocker(heap.lock); + for (guarded_heap_area* area = heap.areas; area != NULL; + area = area->next) { + if ((addr_t)address < area->base) + continue; + + if ((addr_t)address >= area->base + area->size) + continue; + + mutex_lock(&area->lock); + return area; + } + + panic("guarded heap area for address %p not found", address); + return NULL; +} + + +static size_t +guarded_heap_area_page_index_for(guarded_heap_area& area, void* address) +{ + size_t pageIndex = ((addr_t)address - area.base) / B_PAGE_SIZE; + guarded_heap_page& page = area.pages[pageIndex]; + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_USED) == 0) { + panic("tried to free %p which points at page %" B_PRIuSIZE + " which is not marked in use", address, pageIndex); + return area.page_count; + } + + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_GUARD) != 0) { + panic("tried to free %p which points at page %" B_PRIuSIZE + " which is a guard page", address, pageIndex); + return area.page_count; + } + + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_FIRST) == 0) { + panic("tried to free %p which points at page %" B_PRIuSIZE + " which is not an allocation first page", address, pageIndex); + return area.page_count; + } + + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_DEAD) != 0) { + panic("tried to free %p which points at page %" B_PRIuSIZE + " which is a dead page", address, pageIndex); + return area.page_count; + } + + return pageIndex; +} + + +static void +guarded_heap_area_free(guarded_heap_area& area, void* address, uint32 flags) +{ + size_t pageIndex = guarded_heap_area_page_index_for(area, address); + if (pageIndex >= area.page_count) + return; + + size_t pagesFreed = 0; + guarded_heap_page* page = &area.pages[pageIndex]; + while ((page->flags & GUARDED_HEAP_PAGE_FLAG_GUARD) == 0) { + // Mark the allocation page as free. + guarded_heap_free_page(area, pageIndex); + + pagesFreed++; + pageIndex++; + page = &area.pages[pageIndex]; + } + + // Mark the guard page as free as well. + guarded_heap_free_page(area, pageIndex); + pagesFreed++; + +#if !DEBUG_GUARDED_HEAP_DISABLE_MEMORY_REUSE + area.used_pages -= pagesFreed; + atomic_add((vint32*)&area.heap->used_pages, -pagesFreed); +#endif +} + + +static void +guarded_heap_free(void* address, uint32 flags) +{ + if (address == NULL) + return; + + guarded_heap_area* area = guarded_heap_get_locked_area_for(sGuardedHeap, + address); + if (area == NULL) + return; + + MutexLocker locker(area->lock, true); + guarded_heap_area_free(*area, address, flags); +} + + +static void* +guarded_heap_realloc(void* address, size_t newSize) +{ + guarded_heap_area* area = guarded_heap_get_locked_area_for(sGuardedHeap, + address); + if (area == NULL) + return NULL; + + MutexLocker locker(area->lock, true); + + size_t pageIndex = guarded_heap_area_page_index_for(*area, address); + if (pageIndex >= area->page_count) + return NULL; + + guarded_heap_page& page = area->pages[pageIndex]; + size_t oldSize = page.allocation_size; + locker.Unlock(); + + if (oldSize == newSize) + return address; + + void* newBlock = memalign(0, newSize); + if (newBlock == NULL) + return NULL; + + memcpy(newBlock, address, min_c(oldSize, newSize)); + + free(address); + + return newBlock; +} + + +// #pragma mark - Debugger commands + + +static int +dump_guarded_heap_page(int argc, char** argv) +{ + if (argc != 2) { + print_debugger_command_usage(argv[0]); + return 0; + } + + addr_t address = parse_expression(argv[1]); + + // Find the area that contains this page. + guarded_heap_area* area = NULL; + for (guarded_heap_area* candidate = sGuardedHeap.areas; candidate != NULL; + candidate = candidate->next) { + if ((addr_t)address < candidate->base) + continue; + if ((addr_t)address >= candidate->base + candidate->size) + continue; + + area = candidate; + break; + } + + if (area == NULL) { + kprintf("didn't find area for address\n"); + return 1; + } + + size_t pageIndex = ((addr_t)address - area->base) / B_PAGE_SIZE; + guarded_heap_page& page = area->pages[pageIndex]; + + kprintf("page index: %" B_PRIuSIZE "\n", pageIndex); + kprintf("flags:"); + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_USED) != 0) + kprintf(" used"); + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_FIRST) != 0) + kprintf(" first"); + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_GUARD) != 0) + kprintf(" guard"); + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_DEAD) != 0) + kprintf(" dead"); + kprintf("\n"); + + kprintf("allocation size: %" B_PRIuSIZE "\n", page.allocation_size); + kprintf("allocation base: %p\n", page.allocation_base); + kprintf("alignment: %" B_PRIuSIZE "\n", page.alignment); + kprintf("allocating thread: %" B_PRId32 "\n", page.thread); + return 0; +} + + +// #pragma mark - public API + + +status_t +heap_init(addr_t address, size_t size) +{ + return guarded_heap_area_init(sGuardedHeap, -1, (void*)address, size, 0) + ? B_OK : B_ERROR; +} + + +status_t +heap_init_post_area() +{ + return B_OK; +} + + +status_t +heap_init_post_sem() +{ + for (guarded_heap_area* area = sGuardedHeap.areas; area != NULL; + area = area->next) { + if (area->area >= 0) + continue; + + area_id id = area_for((void*)area->base); + if (id < 0 || vm_prepare_kernel_area_debug_protection(id, + &area->protection_cookie) != B_OK) { + panic("failed to prepare initial guarded heap for protection"); + continue; + } + + area->area = id; + for (size_t i = 0; i < area->page_count; i++) { + guarded_heap_page& page = area->pages[i]; + if ((page.flags & GUARDED_HEAP_PAGE_FLAG_USED) != 0 + && (page.flags & GUARDED_HEAP_PAGE_FLAG_GUARD) == 0 + && (page.flags & GUARDED_HEAP_PAGE_FLAG_DEAD) == 0) { + guarded_heap_page_protect(*area, i, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + } else + guarded_heap_page_protect(*area, i, 0); + } + } + + add_debugger_command_etc("guarded_heap_page", &dump_guarded_heap_page, + "Dump info about a guarded heap page", + "
\nDump info about guarded heap page at address.\n", 0); + + return B_OK; +} + + +void* +memalign(size_t alignment, size_t size) +{ + return memalign_etc(alignment, size, 0); +} + + +void * +memalign_etc(size_t alignment, size_t size, uint32 flags) +{ + if (size == 0) + size = 1; + + return guarded_heap_allocate(sGuardedHeap, size, alignment, flags); +} + + +void +free_etc(void *address, uint32 flags) +{ + guarded_heap_free(address, flags); +} + + +void* +malloc(size_t size) +{ + return memalign_etc(0, size, 0); +} + + +void +free(void* address) +{ + free_etc(address, 0); +} + + +void* +realloc(void* address, size_t newSize) +{ + if (newSize == 0) { + free(address); + return NULL; + } + + if (address == NULL) + return memalign(0, newSize); + + return guarded_heap_realloc(address, newSize); +} + + +#endif // USE_GUARDED_HEAP_FOR_MALLOC diff --git a/src/system/kernel/heap.cpp b/src/system/kernel/heap.cpp index 49cd2edbab..38c4dea880 100644 --- a/src/system/kernel/heap.cpp +++ b/src/system/kernel/heap.cpp @@ -32,7 +32,7 @@ #endif -#if USE_SLAB_ALLOCATOR_FOR_MALLOC +#if !USE_DEBUG_HEAP_FOR_MALLOC # undef KERNEL_HEAP_LEAK_CHECK #endif @@ -146,7 +146,7 @@ typedef SinglyLinkedList DeferredFreeList; typedef SinglyLinkedList DeferredDeletableList; -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC #define VIP_HEAP_SIZE 1024 * 1024 @@ -198,7 +198,7 @@ static sem_id sHeapGrowSem = -1; static sem_id sHeapGrownNotify = -1; static bool sAddGrowHeap = false; -#endif // !USE_SLAB_ALLOCATOR_FOR_MALLOC +#endif // USE_DEBUG_HEAP_FOR_MALLOC static DeferredFreeList sDeferredFreeList; static DeferredDeletableList sDeferredDeletableList; @@ -376,7 +376,7 @@ dump_allocator(heap_allocator *heap, bool areas, bool bins) static int dump_heap_list(int argc, char **argv) { -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC if (argc == 2 && strcmp(argv[1], "grow") == 0) { // only dump dedicated grow heap info kprintf("dedicated grow heap:\n"); @@ -400,7 +400,7 @@ dump_heap_list(int argc, char **argv) } if (heapAddress == 0) { -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC // dump default kernel heaps for (uint32 i = 0; i < sHeapCount; i++) dump_allocator(sHeaps[i], !stats, !stats); @@ -434,7 +434,7 @@ dump_allocations(int argc, char **argv) size_t totalSize = 0; uint32 totalCount = 0; -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC for (uint32 heapIndex = 0; heapIndex < sHeapCount; heapIndex++) { heap_allocator *heap = sHeaps[heapIndex]; if (heapAddress != 0) @@ -1764,7 +1764,7 @@ heap_set_get_caller(heap_allocator* heap, addr_t (*getCaller)()) #endif -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC static status_t @@ -1993,7 +1993,7 @@ heap_grow_thread(void *) } -#endif // !USE_SLAB_ALLOCATOR_FOR_MALLOC +#endif // USE_DEBUG_HEAP_FOR_MALLOC static void @@ -2025,7 +2025,7 @@ deferred_deleter(void *arg, int iteration) // #pragma mark - -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC status_t @@ -2153,13 +2153,13 @@ heap_init_post_sem() } -#endif // !USE_SLAB_ALLOCATOR_FOR_MALLOC +#endif // USE_DEBUG_HEAP_FOR_MALLOC status_t heap_init_post_thread() { -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC sHeapGrowThread = spawn_kernel_thread(heap_grow_thread, "heap grower", B_URGENT_PRIORITY, NULL); if (sHeapGrowThread < 0) { @@ -2193,7 +2193,7 @@ heap_init_post_thread() resume_thread(sHeapGrowThread); -#else // !USE_SLAB_ALLOCATOR_FOR_MALLOC +#else // USE_DEBUG_HEAP_FOR_MALLOC // set up some debug commands add_debugger_command_etc("heap", &dump_heap_list, @@ -2208,7 +2208,7 @@ heap_init_post_thread() "If the optional argument \"stats\" is specified, only the allocation\n" "counts and no individual allocations are printed.\n", 0); #endif // KERNEL_HEAP_LEAK_CHECK -#endif // USE_SLAB_ALLOCATOR_FOR_MALLOC +#endif // !USE_DEBUG_HEAP_FOR_MALLOC // run the deferred deleter roughly once a second if (register_kernel_daemon(deferred_deleter, NULL, 10) != B_OK) @@ -2221,7 +2221,7 @@ heap_init_post_thread() // #pragma mark - Public API -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC void * @@ -2472,7 +2472,7 @@ realloc(void *address, size_t newSize) } -#endif // !USE_SLAB_ALLOCATOR_FOR_MALLOC +#endif // USE_DEBUG_HEAP_FOR_MALLOC void * diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 902a1ec2bd..f62b205d32 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -3786,7 +3786,7 @@ vm_init(kernel_args* args) slab_init(args); -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC || USE_GUARDED_HEAP_FOR_MALLOC size_t heapSize = INITIAL_HEAP_SIZE; // try to accomodate low memory systems while (heapSize > sAvailableMemory / 8) @@ -3816,7 +3816,7 @@ vm_init(kernel_args* args) VMAddressSpace::Init(); reserve_boot_loader_ranges(args); -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC || USE_GUARDED_HEAP_FOR_MALLOC heap_init_post_area(); #endif @@ -3829,7 +3829,7 @@ vm_init(kernel_args* args) // allocate areas to represent stuff that already exists -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC || USE_GUARDED_HEAP_FOR_MALLOC address = (void*)ROUNDDOWN(heapBase, B_PAGE_SIZE); create_area("kernel heap", &address, B_EXACT_ADDRESS, heapSize, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); @@ -3937,7 +3937,7 @@ vm_init_post_sem(kernel_args* args) slab_init_post_sem(); -#if !USE_SLAB_ALLOCATOR_FOR_MALLOC +#if USE_DEBUG_HEAP_FOR_MALLOC || USE_GUARDED_HEAP_FOR_MALLOC heap_init_post_sem(); #endif