bdk: heap: add more safe guards
- Use magic for used regions - Deduplicate calloc Enable a print/abort in _heap_free() for debugging.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (c) 2018-2024 CTCaer
|
* Copyright (c) 2018-2025 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include <gfx_utils.h>
|
#include <gfx_utils.h>
|
||||||
|
|
||||||
|
#define HEAP_USED_MAGIC 0x50414548 // "HEAP".
|
||||||
|
|
||||||
heap_t _heap;
|
heap_t _heap;
|
||||||
|
|
||||||
static void _heap_create(void *start)
|
static void _heap_create(void *start)
|
||||||
@@ -40,7 +42,7 @@ static void *_heap_alloc(u32 size)
|
|||||||
if (!_heap.first)
|
if (!_heap.first)
|
||||||
{
|
{
|
||||||
node = (hnode_t *)_heap.start;
|
node = (hnode_t *)_heap.start;
|
||||||
node->used = 1;
|
node->used = HEAP_USED_MAGIC;
|
||||||
node->size = size;
|
node->size = size;
|
||||||
node->prev = NULL;
|
node->prev = NULL;
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
@@ -85,7 +87,7 @@ static void *_heap_alloc(u32 size)
|
|||||||
size += new_size;
|
size += new_size;
|
||||||
|
|
||||||
node->size = size;
|
node->size = size;
|
||||||
node->used = 1;
|
node->used = HEAP_USED_MAGIC;
|
||||||
|
|
||||||
return (void *)node + sizeof(hnode_t);
|
return (void *)node + sizeof(hnode_t);
|
||||||
}
|
}
|
||||||
@@ -100,7 +102,7 @@ static void *_heap_alloc(u32 size)
|
|||||||
|
|
||||||
// No unused node found, create a new one.
|
// No unused node found, create a new one.
|
||||||
new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + node->size);
|
new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + node->size);
|
||||||
new_node->used = 1;
|
new_node->used = HEAP_USED_MAGIC;
|
||||||
new_node->size = size;
|
new_node->size = size;
|
||||||
new_node->prev = node;
|
new_node->prev = node;
|
||||||
new_node->next = NULL;
|
new_node->next = NULL;
|
||||||
@@ -114,6 +116,14 @@ static void *_heap_alloc(u32 size)
|
|||||||
static void _heap_free(void *addr)
|
static void _heap_free(void *addr)
|
||||||
{
|
{
|
||||||
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
|
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
|
||||||
|
|
||||||
|
// Check if heap owns this node.
|
||||||
|
if (addr < _heap.start || node->used != HEAP_USED_MAGIC)
|
||||||
|
{
|
||||||
|
//! BUGPRINTF("free error: addr %08p, used %08X!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
node->used = 0;
|
node->used = 0;
|
||||||
node = _heap.first;
|
node = _heap.first;
|
||||||
|
|
||||||
@@ -152,24 +162,21 @@ void *malloc(u32 size)
|
|||||||
return _heap_alloc(size);
|
return _heap_alloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *calloc(u32 num, u32 size)
|
|
||||||
{
|
|
||||||
void *res = (void *)_heap_alloc(num * size);
|
|
||||||
memset(res, 0, ALIGN(num * size, sizeof(hnode_t))); // Clear the aligned size.
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *zalloc(u32 size)
|
void *zalloc(u32 size)
|
||||||
{
|
{
|
||||||
void *res = (void *)_heap_alloc(size);
|
void *buf = (void *)_heap_alloc(size);
|
||||||
memset(res, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
|
memset(buf, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
|
||||||
return res;
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *calloc(u32 num, u32 size)
|
||||||
|
{
|
||||||
|
return zalloc(num * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void *buf)
|
void free(void *buf)
|
||||||
{
|
{
|
||||||
if (buf >= _heap.start)
|
_heap_free(buf);
|
||||||
_heap_free(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||||
|
|||||||
Reference in New Issue
Block a user