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