176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * malloc.c 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Very simple linked-list based malloc()/free(). 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <syslinux/firmware.h> 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h> 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h> 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <errno.h> 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <dprintf.h> 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <minmax.h> 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "malloc.h" 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "thread.h" 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1876d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanDECLARE_INIT_SEMAPHORE(__malloc_semaphore, 1); 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void *__malloc_from_block(struct free_arena_header *fp, 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t size, malloc_tag_t tag) 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t fsize; 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct free_arena_header *nfp, *na; 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int heap = ARENA_HEAP_GET(fp->a.attrs); 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fsize = ARENA_SIZE_GET(fp->a.attrs); 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We need the 2* to account for the larger requirements of a free block */ 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( fsize >= size+2*sizeof(struct arena_header) ) { 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Bigger block than required -- split block */ 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nfp = (struct free_arena_header *)((char *)fp + size); 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman na = fp->a.next; 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_TYPE_SET(nfp->a.attrs, ARENA_TYPE_FREE); 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_HEAP_SET(nfp->a.attrs, heap); 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_SIZE_SET(nfp->a.attrs, fsize-size); 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nfp->a.tag = MALLOC_FREE; 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef DEBUG_MALLOC 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nfp->a.magic = ARENA_MAGIC; 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_TYPE_SET(fp->a.attrs, ARENA_TYPE_USED); 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_SIZE_SET(fp->a.attrs, size); 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fp->a.tag = tag; 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Insert into all-block chain */ 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nfp->a.prev = fp; 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nfp->a.next = na; 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman na->a.prev = nfp; 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fp->a.next = nfp; 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Replace current block on free chain */ 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nfp->next_free = fp->next_free; 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nfp->prev_free = fp->prev_free; 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fp->next_free->prev_free = nfp; 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fp->prev_free->next_free = nfp; 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Allocate the whole block */ 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_TYPE_SET(fp->a.attrs, ARENA_TYPE_USED); 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fp->a.tag = tag; 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Remove from free chain */ 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fp->next_free->prev_free = fp->prev_free; 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fp->prev_free->next_free = fp->next_free; 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (void *)(&fp->a + 1); 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid *bios_malloc(size_t size, enum heap heap, malloc_tag_t tag) 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct free_arena_header *fp; 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct free_arena_header *head = &__core_malloc_head[heap]; 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *p = NULL; 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (size) { 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Add the obligatory arena header, and round up */ 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK; 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( fp = head->next_free ; fp != head ; fp = fp->next_free ) { 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ARENA_SIZE_GET(fp->a.attrs) >= size ) { 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Found fit -- allocate out of this block */ 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = __malloc_from_block(fp, size, tag); 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return p; 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void *_malloc(size_t size, enum heap heap, malloc_tag_t tag) 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *p; 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("_malloc(%zu, %u, %u) @ %p = ", 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size, heap, tag, __builtin_return_address(0)); 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sem_down(&__malloc_semaphore, 0); 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = firmware->mem->malloc(size, heap, tag); 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sem_up(&__malloc_semaphore); 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("%p\n", p); 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return p; 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__export void *malloc(size_t size) 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return _malloc(size, HEAP_MAIN, MALLOC_CORE); 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__export void *lmalloc(size_t size) 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *p; 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p = _malloc(size, HEAP_LOWMEM, MALLOC_CORE); 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!p) 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman errno = ENOMEM; 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return p; 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid *pmapi_lmalloc(size_t size) 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return _malloc(size, HEAP_LOWMEM, MALLOC_MODULE); 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid *bios_realloc(void *ptr, size_t size) 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct free_arena_header *ah, *nah; 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct free_arena_header *head; 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *newptr; 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t newsize, oldsize, xsize; 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!ptr) 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return malloc(size); 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (size == 0) { 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free(ptr); 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return NULL; 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ah = (struct free_arena_header *) 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ((struct arena_header *)ptr - 1); 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman head = &__core_malloc_head[ARENA_HEAP_GET(ah->a.attrs)]; 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef DEBUG_MALLOC 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ah->a.magic != ARENA_MAGIC) 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("failed realloc() magic check: %p\n", ptr); 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Actual size of the old block */ 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman //oldsize = ah->a.size; 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman oldsize = ARENA_SIZE_GET(ah->a.attrs); 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Add the obligatory arena header, and round up */ 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman newsize = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK; 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (oldsize >= newsize && newsize >= (oldsize >> 2) && 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman oldsize - newsize < 4096) { 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* This allocation is close enough already. */ 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ptr; 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xsize = oldsize; 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah = ah->a.next; 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((char *)nah == (char *)ah + ARENA_SIZE_GET(ah->a.attrs) && 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_TYPE_GET(nah->a.attrs) == ARENA_TYPE_FREE && 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_SIZE_GET(nah->a.attrs) + oldsize >= newsize) { 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman //nah->a.type == ARENA_TYPE_FREE && 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman //oldsize + nah->a.size >= newsize) { 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Merge in subsequent free block */ 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ah->a.next = nah->a.next; 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ah->a.next->a.prev = ah; 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->next_free->prev_free = nah->prev_free; 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->prev_free->next_free = nah->next_free; 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_SIZE_SET(ah->a.attrs, ARENA_SIZE_GET(ah->a.attrs) + 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_SIZE_GET(nah->a.attrs)); 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xsize = ARENA_SIZE_GET(ah->a.attrs); 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (xsize >= newsize) { 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We can reallocate in place */ 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (xsize >= newsize + 2 * sizeof(struct arena_header)) { 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Residual free block at end */ 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah = (struct free_arena_header *)((char *)ah + newsize); 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_TYPE_SET(nah->a.attrs, ARENA_TYPE_FREE); 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_SIZE_SET(nah->a.attrs, xsize - newsize); 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_SIZE_SET(ah->a.attrs, newsize); 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARENA_HEAP_SET(nah->a.attrs, ARENA_HEAP_GET(ah->a.attrs)); 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef DEBUG_MALLOC 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->a.magic = ARENA_MAGIC; 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman //nah->a.type = ARENA_TYPE_FREE; 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman //nah->a.size = xsize - newsize; 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman //ah->a.size = newsize; 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Insert into block list */ 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->a.next = ah->a.next; 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ah->a.next = nah; 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->a.next->a.prev = nah; 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->a.prev = ah; 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Insert into free list */ 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (newsize > oldsize) { 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Hack: this free block is in the path of a memory object 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman which has already been grown at least once. As such, put 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman it at the *end* of the freelist instead of the beginning; 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman trying to save it for future realloc()s of the same block. */ 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->prev_free = head->prev_free; 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->next_free = head; 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman head->prev_free = nah; 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->prev_free->next_free = nah; 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->next_free = head->next_free; 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->prev_free = head; 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman head->next_free = nah; 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nah->next_free->prev_free = nah; 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* otherwise, use up the whole block */ 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ptr; 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Last resort: need to allocate a new block and copy */ 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman oldsize -= sizeof(struct arena_header); 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman newptr = malloc(size); 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (newptr) { 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(newptr, ptr, min(size, oldsize)); 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free(ptr); 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return newptr; 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__export void *realloc(void *ptr, size_t size) 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return firmware->mem->realloc(ptr, size); 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__export void *zalloc(size_t size) 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ptr; 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ptr = malloc(size); 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ptr) 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset(ptr, 0, size); 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ptr; 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 254