tools/adflib: build only host variant which is used by Sam440 target
[AROS.git] / compiler / purify / src / hash.c
blobdff443b7c68e19e17e7960cb7680c7f7499ff255
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <stdio.h>
7 #include <assert.h>
8 #include <limits.h>
9 #include "hash.h"
10 #include "util.h"
11 #include "error.h"
12 #include "memory.h"
13 #include "debug.h"
15 MemHashTable memHash;
16 MemHash * Purify_LastNode;
18 #define CalcHash(addr) \
19 ({ unsigned long x; \
20 x = (long)(addr); \
21 x >>= 16; \
22 ((x & 0xFF) ^ (x >> 8)) & 0xFF; \
25 MemHash * Purify_AddMemory (void * memory, int size, int flag, int type)
27 MemHash * node = xmalloc (sizeof (MemHash));
28 int hashcode;
30 node->mem = memory;
31 node->flags = xmalloc (size);
32 node->size = size;
33 node->type = type;
34 node->data = NULL;
36 if (flag != -1)
37 Purify_SetMemoryFlags (node, 0, size, flag);
39 hashcode = CalcHash (memory);
41 node->next = memHash[hashcode];
42 memHash[hashcode] = node;
44 return node;
47 void Purify_RemMemory (const void * mem)
49 int hashcode = CalcHash (mem);
50 MemHash * node = (MemHash *)&memHash[hashcode], * next;
52 #if LDEBUG
53 printf ("Purify_FindMemory (mem=%p)\n", mem);
54 #endif
56 for ( ; (next=node->next); node=next)
58 #if LDEBUG
59 printf (" Checking against %p:%d (%p)\n",
60 node->mem, node->size, node->mem+node->size);
61 #endif
62 if (next->mem <= mem && next->mem+next->size > mem)
64 #if LDEBUG
65 printf (" Node found\n");
66 #endif
67 node->next = next->next;
68 xfree (next);
69 if (Purify_LastNode == next)
70 Purify_LastNode = NULL;
71 return;
75 #if LDEBUG
76 printf (" Nothing found\n");
77 #endif
81 void Purify_SetMemoryFlags (MemHash * mem, int offset, int size, int flag)
83 char * ptr;
85 #if 0
86 printf ("SetMemoryFlags (hash=%p, offset=%d, size=%d, flag=%d)\n",
87 mem, offset, size, flag
89 #endif
91 passert (offset+size <= mem->size);
93 ptr = mem->flags + offset;
95 while (size--)
96 *ptr ++ = flag;
99 void Purify_ModifyMemoryFlags (MemHash * mem, int offset, int size, int flag,
100 int mask)
102 char * ptr;
104 passert (offset+size <= mem->size);
106 ptr = mem->flags + offset;
108 flag &= mask;
109 mask = ~mask;
111 while (size--)
113 *ptr = (*ptr & mask) | flag;
114 ptr ++;
118 #undef LDEBUG
119 #define LDEBUG 0
121 MemHash * Purify_FindMemory (const void * mem)
123 int hashcode = CalcHash (mem);
124 MemHash * node = memHash[hashcode];
126 #if LDEBUG
127 printf ("Purify_FindMemory (mem=%p)\n", mem);
128 #endif
130 for ( ; node; node=node->next)
132 #if LDEBUG
133 printf (" Checking against %p:%d (%p)\n",
134 node->mem, node->size, node->mem+node->size);
135 #endif
136 if (node->mem <= mem && node->mem+node->size > mem)
138 Purify_LastNode = node;
139 #if LDEBUG
140 printf (" Node found\n");
141 #endif
142 return node;
146 Purify_LastNode = NULL;
147 Purify_Error = NotOwnMemory;
149 #if LDEBUG
150 printf (" Nothing found\n");
151 #endif
152 return NULL;
155 int Purify_CheckMemoryAccess (const void * mem, int size, int access)
157 MemHash * node = Purify_FindMemory (mem);
158 long offset, cnt;
159 char * ptr;
161 if (!node)
162 return 0;
164 offset = (long)mem - (long)node->mem;
166 if (offset+size > node->size)
168 Purify_Error = BorderAccess;
169 return 0;
172 ptr = node->flags + offset;
174 if (access == PURIFY_MemAccess_Read)
176 cnt = size;
177 while (cnt--)
179 if (!(*ptr & PURIFY_MemFlag_Readable) )
181 if (*ptr & PURIFY_MemFlag_Free)
183 Purify_Error = (node->type == PURIFY_MemType_Stack)
184 ? FreeStackRead : FreeRead;
185 return 0;
187 else if (*ptr & PURIFY_MemFlag_Empty)
189 Purify_Error = UndefRead;
190 return 0;
192 else
194 Purify_Error = IllRead;
195 return 0;
199 ptr ++;
202 else /* write */
204 if (node->type == PURIFY_MemType_Code)
206 Purify_Error = CodeWrite;
207 return 0;
210 cnt=size;
211 while (cnt--)
213 if (!(*ptr & PURIFY_MemFlag_Writable) )
215 if (*ptr & PURIFY_MemFlag_Free)
217 Purify_Error =
218 (node->type == PURIFY_MemType_Stack)
219 ? FreeStackWrite
220 : FreeWrite;
221 return 0;
223 else
225 Purify_Error = IllWrite;
226 return 0;
230 ptr ++;
233 Purify_ModifyMemoryFlags (node, offset, size,
234 PURIFY_MemFlag_Readable,
235 PURIFY_MemFlag_Readable|PURIFY_MemFlag_Empty
239 return 1;
242 void Purify_PrintMemory (void)
244 MemHash * node;
245 int i;
246 #if 0
247 int t, cnt;
248 #endif
250 for (i=0; i<256; i++)
252 if ((node = memHash[i]))
254 printf ("Hashline %3d:\n", i);
256 for ( ;
257 node;
258 node=node->next
261 printf (" Node %p: Memory=%p Size=%d Type=",
262 node,
263 node->mem,
264 node->size
267 switch (node->type)
269 case PURIFY_MemType_Heap: printf ("heap "); break;
270 case PURIFY_MemType_Stack: printf ("stack"); break;
271 case PURIFY_MemType_Code: printf ("code "); break;
272 case PURIFY_MemType_Data: printf ("data "); break;
275 if (node->data)
277 switch (node->type)
279 case PURIFY_MemType_Stack:
280 case PURIFY_MemType_Code:
281 case PURIFY_MemType_Data:
282 printf (" name=\"%s\"", (char *)node->data);
283 break;
285 case PURIFY_MemType_Heap:
287 PMemoryNode * mem = (PMemoryNode *)(node->data);
289 printf (" %s()", mem->alloc.current.functionname);
291 break;
295 putchar ('\n');
297 #if 0
298 #define WIDTH 56
300 for (cnt=0,t=0; t<node->size; t++,cnt++)
302 if (cnt == 0)
303 printf ("\t%4d: ", t);
305 printf ("%x", node->flags[t]);
307 if (cnt == WIDTH-1)
309 putchar ('\n');
310 cnt = -1;
312 else if ((cnt & 7) == 7)
313 putchar (' ');
316 if (((t-1) & WIDTH) != WIDTH-1)
317 putchar ('\n');
318 #endif
324 #ifndef ABS
325 # define ABS(x) (((x) < 0) ? -(x) : (x))
326 #endif
328 MemHash * Purify_FindNextMemory (const void * mem, int * offsetptr)
330 MemHash * node, * next;
331 int i, offset, o;
333 next = NULL;
334 offset = INT_MAX;
336 for (i=0; i<256; i++)
338 for (node = memHash[i];
339 node;
340 node=node->next
343 o = (long)mem - (long)node->mem;
345 if (o > 0)
347 if (o < node->size)
349 *offsetptr = o;
350 return node;
352 else
354 o -= node->size;
358 if (ABS(o) < ABS(offset)
359 || (ABS(o) == ABS(offset) && o > 0)
362 offset = o;
363 next = node;
368 *offsetptr = offset;
369 return next;