10 #define ALIGN(x) (char *)((((long)(x))+15) & -8)
12 void * Purify_malloc (size_t size
)
14 PMemoryNode
* node
= malloc (sizeof (PMemoryNode
) + size
);
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
37 void * Purify_calloc (size_t nemb
, size_t size
)
39 PMemoryNode
* node
= calloc (1, sizeof (PMemoryNode
) + nemb
*size
);
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
62 void * Purify_realloc (void * mem
, size_t size
)
64 PMemoryNode
* oldnode
, * newnode
;
65 MemHash
* oldmem
, * newmem
;
69 newnode
= malloc (sizeof (PMemoryNode
) + size
);
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
86 newmem
->data
= newnode
;
93 memcpy (newnode
->memptr
, mem
, size
);
98 oldmem
= Purify_FindMemory (mem
);
102 Purify_Error
= IllPointer
;
103 Purify_PrintError ("realloc(addr=%p, size=%ld)", mem
, size
);
107 oldnode
= (PMemoryNode
*)(oldmem
->data
);
111 if (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
);
136 Purify_Error
= IllPointer
;
137 Purify_PrintError ("free(addr=%p)", mem
);
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
;
152 PMemoryNode
* memnode
;
155 Purify_Error
= MemLeak
;
157 for (i
=0; i
<256; i
++)
159 for (node
=memHash
[i
];
164 if (node
->type
== PURIFY_MemType_Heap
)
166 memnode
= (PMemoryNode
*)(node
->data
);
168 if (memnode
->free
.nstack
== -1)
170 Purify_PrePrintError ();
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
)
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
)
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
)
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
);
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
294 strcpy (node
->memptr
, src
);