1 /*---------------------------------------------------------------------------*
2   Project: malloc overload Library
3   File:    cos_def_malloc.c
4 
5   Copyright 2012 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.     They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13  *---------------------------------------------------------------------------*/
14 #include <string.h>
15 #include <cafe/mem.h>
16 #include "../libsys/inderrno.h"
17 
18 #define COS_DEF_MALLOC_OVERHEAD             8
19 #define COS_DEF_MALLOC_ALIGN                8
20 #define COS_DEF_MALLOC_GUARDWORD_OFFSET     0
21 #define COS_DEF_MALLOC_SIZE_OFFSET          4
22 
23 #define COS_DEF_MALLOC_GUARDWORD    0xcafe4321
24 
25 /*---------------------------------------------------------------------------*
26   Name:           COS_DEF_MALLOC_GETSIZE
27 
28   Description:    return the size of a malloc ptr
29 
30   Arguments:      malloced pointer
31 
32   Return:         size of pointer (if valid)
33                   in debug case returns zero if pointer is no valid
34 
35  *---------------------------------------------------------------------------*/
36 
COS_DEF_MALLOC_GETSIZE(void * ptr)37 static size_t COS_DEF_MALLOC_GETSIZE (void *ptr)
38 {
39     u32 *rawptr = (ptr - COS_DEF_MALLOC_OVERHEAD);
40 #ifdef _DEBUG
41     ASSERT(*rawptr == COS_DEF_MALLOC_GUARDWORD);
42 #endif
43     if (*rawptr != COS_DEF_MALLOC_GUARDWORD) {
44         return 0;
45     }
46     return (size_t) *(rawptr + COS_DEF_MALLOC_SIZE_OFFSET);
47 }
48 
49 /*---------------------------------------------------------------------------*
50   Name:           malloc
51 
52   Description:    allocate memory by calling MEMAllocFromDefaultHeapEx
53 
54   Arguments:      size       size to allocate
55 
56   Return:         pointer to allocated memory if success
57                   NULL if failing to allocate memory and set errno to ENOMEM
58 
59  *---------------------------------------------------------------------------*/
60 
malloc(size_t size)61 void *malloc (size_t size)
62 {
63     void *retAddr = MEMAllocFromDefaultHeapEx(size + COS_DEF_MALLOC_OVERHEAD, COS_DEF_MALLOC_ALIGN);
64 
65     if (retAddr == NULL) {
66         __gh_set_errno(ENOMEM);
67         return NULL;
68     }
69 
70     *(size_t *)(retAddr + COS_DEF_MALLOC_GUARDWORD_OFFSET) = COS_DEF_MALLOC_GUARDWORD;
71     *(size_t *)(retAddr + COS_DEF_MALLOC_SIZE_OFFSET) = size;
72 
73     return retAddr + COS_DEF_MALLOC_OVERHEAD;
74 }
75 
76 /*---------------------------------------------------------------------------*
77   Name:           free
78 
79   Description:    free memory by calling MEMFreeToDefaultHeap
80 
81   Arguments:      ptr       address to free up memory
82 
83   Return:         none
84 
85  *---------------------------------------------------------------------------*/
86 
free(void * ptr)87 void free (void *ptr)
88 {
89 
90     if (ptr != NULL) {
91         u32 *rawptr = (u32 *) (((char *)ptr) - COS_DEF_MALLOC_OVERHEAD);
92 #ifdef _DEBUG
93         ASSERT(*rawptr == COS_DEF_MALLOC_GUARDWORD);
94 #endif
95         MEMFreeToDefaultHeap(rawptr);
96     }
97 }
98 
99 /*---------------------------------------------------------------------------*
100   Name:           realloc
101 
102   Description:    change the size of the memory object pointed to by ptr to
103                   the size specified by size
104 
105   Arguments:      origPtr   address of the memory object
106                   newSize   size to change
107 
108   Return:         pointer to allocated memory if success
109                   NULL if failing to allocate memory and set errno to ENOMEM
110 
111  *---------------------------------------------------------------------------*/
112 
realloc(void * origPtr,size_t newSize)113 void *realloc (void *origPtr, size_t newSize)
114 {
115     void *newPtr;
116     size_t origSize, copySize;
117 
118     if (newSize == 0)
119     {
120         free(origPtr);
121         return NULL;
122     }
123 
124     if (origPtr == NULL)
125     {
126         return malloc(newSize);
127     }
128 
129     newPtr = malloc(newSize);
130 
131 
132     origSize = COS_DEF_MALLOC_GETSIZE(origPtr);
133 
134     /* copy the smaller of new vs old */
135     copySize = newSize < origSize ? newSize : origSize;
136 
137     memcpy (newPtr, origPtr, copySize);
138 
139     free(origPtr);
140 
141     return newPtr;
142 }
143 
144 /*---------------------------------------------------------------------------*
145   Name:           calloc
146 
147   Description:    allocate unused space for an array of nelem elements each of
148                   whose size in bytes is elsize. The space shall be initialized
149                   to all bits 0
150 
151   Arguments:      nelem       number of elements
152                   elsize      element size
153 
154   Return:         void pointer to allocated memory if success
155                   NULL if failing to allocate memory and set errno to ENOMEM
156 
157  *---------------------------------------------------------------------------*/
158 
calloc(size_t nelem,size_t elsize)159 void *calloc(size_t nelem, size_t elsize)
160 {
161     void * retAddr;
162     size_t totalSize = elsize * nelem;
163 
164     retAddr = malloc(totalSize);
165     if (retAddr) {
166         memset(retAddr, 0, totalSize);
167     }
168 
169     return retAddr;
170 }
171