/*---------------------------------------------------------------------------* Project: malloc overload Library File: cos_def_malloc.c Copyright (C) Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ #include #include #include "../libsys/inderrno.h" #define COS_DEF_MALLOC_OVERHEAD 8 #define COS_DEF_MALLOC_ALIGN 8 #define COS_DEF_MALLOC_GUARDWORD_OFFSET 0 #define COS_DEF_MALLOC_SIZE_OFFSET 4 #define COS_DEF_MALLOC_GUARDWORD 0xcafe4321 /*---------------------------------------------------------------------------* Name: COS_DEF_MALLOC_GETSIZE Description: return the size of a malloc ptr Arguments: malloced pointer Return: size of pointer (if valid) in debug case returns zero if pointer is no valid *---------------------------------------------------------------------------*/ static size_t COS_DEF_MALLOC_GETSIZE (void *ptr) { u32 *rawptr = (ptr - COS_DEF_MALLOC_OVERHEAD); #ifdef _DEBUG ASSERT(*rawptr == COS_DEF_MALLOC_GUARDWORD); #endif if (*rawptr != COS_DEF_MALLOC_GUARDWORD) { return 0; } return (size_t) *(rawptr + COS_DEF_MALLOC_SIZE_OFFSET); } /*---------------------------------------------------------------------------* Name: malloc Description: allocate memory by calling MEMAllocFromDefaultHeapEx Arguments: size size to allocate Return: pointer to allocated memory if success NULL if failing to allocate memory and set errno to ENOMEM *---------------------------------------------------------------------------*/ void *malloc (size_t size) { void *retAddr = MEMAllocFromDefaultHeapEx(size + COS_DEF_MALLOC_OVERHEAD, COS_DEF_MALLOC_ALIGN); if (retAddr == NULL) { __gh_set_errno(ENOMEM); return NULL; } *(size_t *)(retAddr + COS_DEF_MALLOC_GUARDWORD_OFFSET) = COS_DEF_MALLOC_GUARDWORD; *(size_t *)(retAddr + COS_DEF_MALLOC_SIZE_OFFSET) = size; return retAddr + COS_DEF_MALLOC_OVERHEAD; } /*---------------------------------------------------------------------------* Name: free Description: free memory by calling MEMFreeToDefaultHeap Arguments: ptr address to free up memory Return: none *---------------------------------------------------------------------------*/ void free (void *ptr) { if (ptr != NULL) { u32 *rawptr = (u32 *) (((char *)ptr) - COS_DEF_MALLOC_OVERHEAD); #ifdef _DEBUG ASSERT(*rawptr == COS_DEF_MALLOC_GUARDWORD); #endif MEMFreeToDefaultHeap(rawptr); } } /*---------------------------------------------------------------------------* Name: realloc Description: change the size of the memory object pointed to by ptr to the size specified by size Arguments: origPtr address of the memory object newSize size to change Return: pointer to allocated memory if success NULL if failing to allocate memory and set errno to ENOMEM *---------------------------------------------------------------------------*/ void *realloc (void *origPtr, size_t newSize) { void *newPtr; size_t origSize, copySize; if (newSize == 0) { free(origPtr); return NULL; } if (origPtr == NULL) { return malloc(newSize); } newPtr = malloc(newSize); origSize = COS_DEF_MALLOC_GETSIZE(origPtr); /* copy the smaller of new vs old */ copySize = newSize < origSize ? newSize : origSize; memcpy (newPtr, origPtr, copySize); free(origPtr); return newPtr; } /*---------------------------------------------------------------------------* Name: calloc Description: allocate unused space for an array of nelem elements each of whose size in bytes is elsize. The space shall be initialized to all bits 0 Arguments: nelem number of elements elsize element size Return: void pointer to allocated memory if success NULL if failing to allocate memory and set errno to ENOMEM *---------------------------------------------------------------------------*/ void *calloc(size_t nelem, size_t elsize) { void * retAddr; size_t totalSize = elsize * nelem; retAddr = malloc(totalSize); if (retAddr) { memset(retAddr, 0, totalSize); } return retAddr; }