dos.library: add special handling for ACTION_PARENT_FH on NIL: handler
[AROS.git] / compiler / purify / src / hash.c
blob2a12102c3e622c41bce896f71020ef7ff257937d
1 #include <stdio.h>
2 #include <assert.h>
3 #include <limits.h>
4 #include "hash.h"
5 #include "util.h"
6 #include "error.h"
7 #include "memory.h"
8 #include "debug.h"
10 MemHashTable memHash;
11 MemHash * Purify_LastNode;
13 #define CalcHash(addr) \
14 ({ unsigned long x; \
15 x = (long)(addr); \
16 x >>= 16; \
17 ((x & 0xFF) ^ (x >> 8)) & 0xFF; \
20 MemHash * Purify_AddMemory (void * memory, int size, int flag, int type)
22 MemHash * node = xmalloc (sizeof (MemHash));
23 int hashcode;
25 node->mem = memory;
26 node->flags = xmalloc (size);
27 node->size = size;
28 node->type = type;
29 node->data = NULL;
31 if (flag != -1)
32 Purify_SetMemoryFlags (node, 0, size, flag);
34 hashcode = CalcHash (memory);
36 node->next = memHash[hashcode];
37 memHash[hashcode] = node;
39 return node;
42 void Purify_RemMemory (const void * mem)
44 int hashcode = CalcHash (mem);
45 MemHash * node = (MemHash *)&memHash[hashcode], * next;
47 #if LDEBUG
48 printf ("Purify_FindMemory (mem=%p)\n", mem);
49 #endif
51 for ( ; (next=node->next); node=next)
53 #if LDEBUG
54 printf (" Checking against %p:%d (%p)\n",
55 node->mem, node->size, node->mem+node->size);
56 #endif
57 if (next->mem <= mem && next->mem+next->size > mem)
59 #if LDEBUG
60 printf (" Node found\n");
61 #endif
62 node->next = next->next;
63 xfree (next);
64 if (Purify_LastNode == next)
65 Purify_LastNode = NULL;
66 return;
70 #if LDEBUG
71 printf (" Nothing found\n");
72 #endif
76 void Purify_SetMemoryFlags (MemHash * mem, int offset, int size, int flag)
78 char * ptr;
80 #if 0
81 printf ("SetMemoryFlags (hash=%p, offset=%d, size=%d, flag=%d)\n",
82 mem, offset, size, flag
84 #endif
86 passert (offset+size <= mem->size);
88 ptr = mem->flags + offset;
90 while (size--)
91 *ptr ++ = flag;
94 void Purify_ModifyMemoryFlags (MemHash * mem, int offset, int size, int flag,
95 int mask)
97 char * ptr;
99 passert (offset+size <= mem->size);
101 ptr = mem->flags + offset;
103 flag &= mask;
104 mask = ~mask;
106 while (size--)
108 *ptr = (*ptr & mask) | flag;
109 ptr ++;
113 #undef LDEBUG
114 #define LDEBUG 0
116 MemHash * Purify_FindMemory (const void * mem)
118 int hashcode = CalcHash (mem);
119 MemHash * node = memHash[hashcode];
121 #if LDEBUG
122 printf ("Purify_FindMemory (mem=%p)\n", mem);
123 #endif
125 for ( ; node; node=node->next)
127 #if LDEBUG
128 printf (" Checking against %p:%d (%p)\n",
129 node->mem, node->size, node->mem+node->size);
130 #endif
131 if (node->mem <= mem && node->mem+node->size > mem)
133 Purify_LastNode = node;
134 #if LDEBUG
135 printf (" Node found\n");
136 #endif
137 return node;
141 Purify_LastNode = NULL;
142 Purify_Error = NotOwnMemory;
144 #if LDEBUG
145 printf (" Nothing found\n");
146 #endif
147 return NULL;
150 int Purify_CheckMemoryAccess (const void * mem, int size, int access)
152 MemHash * node = Purify_FindMemory (mem);
153 long offset, cnt;
154 char * ptr;
156 if (!node)
157 return 0;
159 offset = (long)mem - (long)node->mem;
161 if (offset+size > node->size)
163 Purify_Error = BorderAccess;
164 return 0;
167 ptr = node->flags + offset;
169 if (access == PURIFY_MemAccess_Read)
171 cnt = size;
172 while (cnt--)
174 if (!(*ptr & PURIFY_MemFlag_Readable) )
176 if (*ptr & PURIFY_MemFlag_Free)
178 Purify_Error = (node->type == PURIFY_MemType_Stack)
179 ? FreeStackRead : FreeRead;
180 return 0;
182 else if (*ptr & PURIFY_MemFlag_Empty)
184 Purify_Error = UndefRead;
185 return 0;
187 else
189 Purify_Error = IllRead;
190 return 0;
194 ptr ++;
197 else /* write */
199 if (node->type == PURIFY_MemType_Code)
201 Purify_Error = CodeWrite;
202 return 0;
205 cnt=size;
206 while (cnt--)
208 if (!(*ptr & PURIFY_MemFlag_Writable) )
210 if (*ptr & PURIFY_MemFlag_Free)
212 Purify_Error =
213 (node->type == PURIFY_MemType_Stack)
214 ? FreeStackWrite
215 : FreeWrite;
216 return 0;
218 else
220 Purify_Error = IllWrite;
221 return 0;
225 ptr ++;
228 Purify_ModifyMemoryFlags (node, offset, size,
229 PURIFY_MemFlag_Readable,
230 PURIFY_MemFlag_Readable|PURIFY_MemFlag_Empty
234 return 1;
237 void Purify_PrintMemory (void)
239 MemHash * node;
240 int i;
241 #if 0
242 int t, cnt;
243 #endif
245 for (i=0; i<256; i++)
247 if ((node = memHash[i]))
249 printf ("Hashline %3d:\n", i);
251 for ( ;
252 node;
253 node=node->next
256 printf (" Node %p: Memory=%p Size=%d Type=",
257 node,
258 node->mem,
259 node->size
262 switch (node->type)
264 case PURIFY_MemType_Heap: printf ("heap "); break;
265 case PURIFY_MemType_Stack: printf ("stack"); break;
266 case PURIFY_MemType_Code: printf ("code "); break;
267 case PURIFY_MemType_Data: printf ("data "); break;
270 if (node->data)
272 switch (node->type)
274 case PURIFY_MemType_Stack:
275 case PURIFY_MemType_Code:
276 case PURIFY_MemType_Data:
277 printf (" name=\"%s\"", (char *)node->data);
278 break;
280 case PURIFY_MemType_Heap:
282 PMemoryNode * mem = (PMemoryNode *)(node->data);
284 printf (" %s()", mem->alloc.current.functionname);
286 break;
290 putchar ('\n');
292 #if 0
293 #define WIDTH 56
295 for (cnt=0,t=0; t<node->size; t++,cnt++)
297 if (cnt == 0)
298 printf ("\t%4d: ", t);
300 printf ("%x", node->flags[t]);
302 if (cnt == WIDTH-1)
304 putchar ('\n');
305 cnt = -1;
307 else if ((cnt & 7) == 7)
308 putchar (' ');
311 if (((t-1) & WIDTH) != WIDTH-1)
312 putchar ('\n');
313 #endif
319 #ifndef ABS
320 # define ABS(x) (((x) < 0) ? -(x) : (x))
321 #endif
323 MemHash * Purify_FindNextMemory (const void * mem, int * offsetptr)
325 MemHash * node, * next;
326 int i, offset, o;
328 next = NULL;
329 offset = INT_MAX;
331 for (i=0; i<256; i++)
333 for (node = memHash[i];
334 node;
335 node=node->next
338 o = (long)mem - (long)node->mem;
340 if (o > 0)
342 if (o < node->size)
344 *offsetptr = o;
345 return node;
347 else
349 o -= node->size;
353 if (ABS(o) < ABS(offset)
354 || (ABS(o) == ABS(offset) && o > 0)
357 offset = o;
358 next = node;
363 *offsetptr = offset;
364 return next;