Mercurial > dropbear
diff dbmalloc.c @ 1361:f9f930e1a516 fuzz
add dbmalloc epoch cleanup
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 21 May 2017 10:54:11 +0800 |
parents | |
children | 9aa6cd66b51d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbmalloc.c Sun May 21 10:54:11 2017 +0800 @@ -0,0 +1,128 @@ +#include "dbmalloc.h" +#include "dbutil.h" + +#define LIST_SIZE 1000 + +struct dbmalloc_header { + unsigned int index; + unsigned int epoch; +}; + +static struct dbmalloc_header* dbmalloc_list[LIST_SIZE]; + +unsigned int current_epoch = 0; + +void m_malloc_set_epoch(unsigned int epoch) { + current_epoch = epoch; +} + +void m_malloc_free_epoch(unsigned int epoch) { + unsigned int i; + unsigned int freed = 0; + for (i = 0; i < LIST_SIZE; i++) { + if (dbmalloc_list[i] != NULL) { + assert(dbmalloc_list[i]->index == i); + if (dbmalloc_list[i]->epoch == epoch) { + free(dbmalloc_list[i]); + dbmalloc_list[i] = NULL; + freed++; + } + } + } + TRACE(("free_epoch freed %d", freed)) +} + +static void put_alloc(struct dbmalloc_header *header) { + unsigned int i; + for (i = 0; i < LIST_SIZE; i++) { + if (dbmalloc_list[i] == NULL) { + dbmalloc_list[i] = header; + header->index = i; + return; + } + } + dropbear_exit("ran out of dbmalloc entries"); +} + +static void remove_alloc(struct dbmalloc_header *header) { + assert(header->index < LIST_SIZE); + assert(dbmalloc_list[header->index] == header); + assert(header->epoch == current_epoch); + dbmalloc_list[header->index] = NULL; +} + +static struct dbmalloc_header* get_header(void* ptr) { + char* bptr = ptr; + return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)]; +} + +void * m_malloc(size_t size) { + char* mem = NULL; + struct dbmalloc_header* header = NULL; + + if (size == 0 || size > 1e9) { + dropbear_exit("m_malloc failed"); + } + + size = size + sizeof(struct dbmalloc_header); + + mem = calloc(1, size); + if (mem == NULL) { + dropbear_exit("m_malloc failed"); + } + header = (struct dbmalloc_header*)mem; + put_alloc(header); + header->epoch = current_epoch; + return &mem[sizeof(struct dbmalloc_header)]; +} + +void * m_calloc(size_t nmemb, size_t size) { + assert(nmemb <= 1000 && size <= 10000); + return m_malloc(nmemb*size); +} + +void * m_realloc(void* ptr, size_t size) { + char* mem = NULL; + struct dbmalloc_header* header = NULL; + if (size == 0 || size > 1e9) { + dropbear_exit("m_realloc failed"); + } + + header = get_header(ptr); + remove_alloc(header); + + size = size + sizeof(struct dbmalloc_header); + mem = realloc(header, size); + if (mem == NULL) { + dropbear_exit("m_realloc failed"); + } + + header = (struct dbmalloc_header*)mem; + put_alloc(header); + return &mem[sizeof(struct dbmalloc_header)]; +} + +void m_free_direct(void* ptr) { + struct dbmalloc_header* header = NULL; + if (!ptr) { + return; + } + header = get_header(ptr); + remove_alloc(header); + free(header); +} + +void * m_strdup(const char * str) { + char* ret; + unsigned int len; + len = strlen(str); + + ret = m_malloc(len+1); + if (ret == NULL) { + dropbear_exit("m_strdup failed"); + } + memcpy(ret, str, len+1); + return ret; +} + +