Fixed HiFi modes.
[AROS.git] / compiler / purify / src / memory.c
blobc6194487f1e4754fdf8e3e9f68e23eaabaa1d3ed
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "memory.h"
5 #include "hash.h"
6 #include "posinfo.h"
7 #include "error.h"
8 #include "util.h"
10 #define ALIGN(x) (char *)((((long)(x))+15) & -8)
12 void * Purify_malloc (size_t size)
14 PMemoryNode * node = malloc (sizeof (PMemoryNode) + size);
15 MemHash * hash;
17 if (!node)
18 return NULL;
20 Purify_RememberCallers (&node->alloc);
22 node->free.nstack = -1; /* Not freed yet */
24 node->memptr = ALIGN(node->mem);
26 hash = Purify_AddMemory (node->memptr, size,
27 PURIFY_MemFlag_Writable
28 | PURIFY_MemFlag_Empty
29 , PURIFY_MemType_Heap
32 hash->data = node;
34 return node->memptr;
37 void * Purify_calloc (size_t nemb, size_t size)
39 PMemoryNode * node = calloc (1, sizeof (PMemoryNode) + nemb*size);
40 MemHash * hash;
42 if (!node)
43 return NULL;
45 Purify_RememberCallers (&node->alloc);
47 node->free.nstack = -1; /* Not freed yet */
49 node->memptr = ALIGN(node->mem);
51 hash = Purify_AddMemory (node->memptr, nemb*size,
52 PURIFY_MemFlag_Readable
53 | PURIFY_MemFlag_Writable
54 , PURIFY_MemType_Heap
57 hash->data = node;
59 return node->memptr;
62 void * Purify_realloc (void * mem, size_t size)
64 PMemoryNode * oldnode, * newnode;
65 MemHash * oldmem, * newmem;
67 if (size)
69 newnode = malloc (sizeof (PMemoryNode) + size);
71 if (!newnode)
72 return NULL;
74 Purify_RememberCallers (&newnode->alloc);
76 newnode->free.nstack = -1; /* Not freed yet */
78 newnode->memptr = ALIGN(newnode->mem);
80 newmem = Purify_AddMemory (newnode->memptr, size,
81 PURIFY_MemFlag_Writable
82 | PURIFY_MemFlag_Empty
83 , PURIFY_MemType_Heap
86 newmem->data = newnode;
88 else
89 newnode = NULL;
91 if (mem && size)
93 memcpy (newnode->memptr, mem, size);
96 if (mem)
98 oldmem = Purify_FindMemory (mem);
100 if (!oldmem)
102 Purify_Error = IllPointer;
103 Purify_PrintError ("realloc(addr=%p, size=%ld)", mem, size);
105 else
107 oldnode = (PMemoryNode *)(oldmem->data);
109 if (newnode)
111 if (size > oldmem->size)
112 size = oldmem->size;
114 memcpy (newnode->memptr, oldnode->memptr, size);
116 Purify_SetMemoryFlags (newmem, 0, size,
117 PURIFY_MemFlag_Readable | PURIFY_MemFlag_Writable
121 Purify_SetMemoryFlags (oldmem, 0, oldmem->size, PURIFY_MemFlag_Free);
122 Purify_RememberCallers (&oldnode->free);
126 return newnode ? newnode->memptr : NULL;
129 void Purify_free (void * mem)
131 MemHash * hash = Purify_FindMemory (mem);
132 PMemoryNode * node;
134 if (!hash)
136 Purify_Error = IllPointer;
137 Purify_PrintError ("free(addr=%p)", mem);
139 else
141 node = (PMemoryNode *)(hash->data);
143 Purify_SetMemoryFlags (hash, 0, hash->size, PURIFY_MemFlag_Free);
144 Purify_RememberCallers (&node->free);
148 void Purify_MemoryExit (void)
150 extern MemHashTable memHash;
151 MemHash * node;
152 PMemoryNode * memnode;
153 int i;
155 Purify_Error = MemLeak;
157 for (i=0; i<256; i++)
159 for (node=memHash[i];
160 node;
161 node=node->next
164 if (node->type == PURIFY_MemType_Heap)
166 memnode = (PMemoryNode *)(node->data);
168 if (memnode->free.nstack == -1)
170 Purify_PrePrintError ();
171 fprintf (stderr,
172 "The memory block at %p with the size %d was allocated at\n",
173 node->mem, node->size
175 Purify_PrintCallers (&memnode->alloc);
176 Purify_PostPrintError ();
183 void * Purify_memmove (void *dest, const void *src, size_t n)
185 if (!Purify_CheckMemoryAccess (src, n, PURIFY_MemAccess_Read))
186 Purify_PrintAccessError ("memmove (src)", src, n);
187 if (!Purify_CheckMemoryAccess (dest, n, PURIFY_MemAccess_Write))
188 Purify_PrintAccessError ("memmove (dest)", dest, n);
190 return memmove (dest, src, n);
193 void * Purify_memset (void *dest, int c, size_t n)
195 if (!Purify_CheckMemoryAccess (dest, n, PURIFY_MemAccess_Write))
196 Purify_PrintAccessError ("memmove (dest)", dest, n);
198 return memset (dest, c, n);
201 void * Purify_memcpy (void *dest, const void *src, size_t n)
203 if (!Purify_CheckMemoryAccess (src, n, PURIFY_MemAccess_Read))
204 Purify_PrintAccessError ("memcpy (src)", src, n);
206 if (!Purify_CheckMemoryAccess (dest, n, PURIFY_MemAccess_Write))
207 Purify_PrintAccessError ("memcpy (dest)", dest, n);
209 return memcpy (dest, src, n);
212 char * Purify_strcpy (char *dest, const char *src)
214 int len;
216 if (!Purify_CheckMemoryAccess (src, 1, PURIFY_MemAccess_Read))
217 Purify_PrintAccessError ("strcpy (src)", src, 1);
219 len = strlen (src)+1;
221 if (!Purify_CheckMemoryAccess (src, len, PURIFY_MemAccess_Read))
222 Purify_PrintAccessError ("strcpy (src)", src, len);
224 if (!Purify_CheckMemoryAccess (dest, len, PURIFY_MemAccess_Write))
225 Purify_PrintAccessError ("strcpy (dest)", dest, len);
227 return strcpy (dest, src);
230 char * Purify_strcat (char *dest, const char *src)
232 int slen, dlen;
234 if (!Purify_CheckMemoryAccess (src, 1, PURIFY_MemAccess_Read))
235 Purify_PrintAccessError ("strcat (src)", src, 1);
237 slen = strlen (src)+1;
239 if (!Purify_CheckMemoryAccess (src, slen, PURIFY_MemAccess_Read))
240 Purify_PrintAccessError ("strcat (src)", src, slen);
242 if (!Purify_CheckMemoryAccess (src, 1, PURIFY_MemAccess_Read))
243 Purify_PrintAccessError ("strcat (dest)", dest, 1);
245 dlen = strlen (dest);
247 if (!Purify_CheckMemoryAccess (dest+dlen, slen, PURIFY_MemAccess_Write))
248 Purify_PrintAccessError ("strcat (dest)", dest+dlen, slen);
250 return strcpy (dest+dlen, src);
253 char * Purify_strncpy (char *dest, const char *src, size_t n)
255 if (!Purify_CheckMemoryAccess (src, n, PURIFY_MemAccess_Read))
256 Purify_PrintAccessError ("strncpy (src)", src, n);
258 if (!Purify_CheckMemoryAccess (dest, n, PURIFY_MemAccess_Write))
259 Purify_PrintAccessError ("strncpy (dest)", dest, n);
261 return strncpy (dest, src, n);
264 char * Purify_strdup (char * src)
266 PMemoryNode * node;
267 MemHash * hash;
268 int size;
270 if (!Purify_CheckMemoryAccess (src, 1, PURIFY_MemAccess_Read))
271 Purify_PrintAccessError ("strdup (src)", src, 1);
273 size = strlen (src) + 1;
275 node = malloc (sizeof (PMemoryNode) + size);
277 if (!node)
278 return NULL;
280 Purify_RememberCallers (&node->alloc);
282 node->free.nstack = -1; /* Not freed yet */
284 node->memptr = ALIGN(node->mem);
286 hash = Purify_AddMemory (node->memptr, size,
287 PURIFY_MemFlag_Writable
288 | PURIFY_MemFlag_Readable
289 , PURIFY_MemType_Heap
292 hash->data = node;
294 strcpy (node->memptr, src);
296 return node->memptr;