diff options
Diffstat (limited to 'lib/unwarminder/unwarmmem.c')
-rw-r--r-- | lib/unwarminder/unwarmmem.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/lib/unwarminder/unwarmmem.c b/lib/unwarminder/unwarmmem.c new file mode 100644 index 0000000000..5991720412 --- /dev/null +++ b/lib/unwarminder/unwarmmem.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /*************************************************************************** | ||
2 | * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk | ||
3 | * | ||
4 | * This program is PUBLIC DOMAIN. | ||
5 | * This means that there is no copyright and anyone is able to take a copy | ||
6 | * for free and use it as they wish, with or without modifications, and in | ||
7 | * any context, commerically or otherwise. The only limitation is that I | ||
8 | * don't guarantee that the software is fit for any purpose or accept any | ||
9 | * liablity for it's use or misuse - this software is without warranty. | ||
10 | *************************************************************************** | ||
11 | * File Description: Implementation of the memory tracking sub-system. | ||
12 | **************************************************************************/ | ||
13 | |||
14 | #define MODULE_NAME "UNWARMMEM" | ||
15 | |||
16 | /*************************************************************************** | ||
17 | * Include Files | ||
18 | **************************************************************************/ | ||
19 | |||
20 | #include "types.h" | ||
21 | #include <stdio.h> | ||
22 | #include "unwarmmem.h" | ||
23 | #include "unwarm.h" | ||
24 | |||
25 | /*************************************************************************** | ||
26 | * Manifest Constants | ||
27 | **************************************************************************/ | ||
28 | |||
29 | |||
30 | /*************************************************************************** | ||
31 | * Type Definitions | ||
32 | **************************************************************************/ | ||
33 | |||
34 | |||
35 | /*************************************************************************** | ||
36 | * Variables | ||
37 | **************************************************************************/ | ||
38 | |||
39 | |||
40 | /*************************************************************************** | ||
41 | * Macros | ||
42 | **************************************************************************/ | ||
43 | |||
44 | |||
45 | #define M_IsIdxUsed(a, v) (((a)[v >> 3] & (1 << (v & 0x7))) ? TRUE : FALSE) | ||
46 | |||
47 | #define M_SetIdxUsed(a, v) ((a)[v >> 3] |= (1 << (v & 0x7))) | ||
48 | |||
49 | #define M_ClrIdxUsed(a, v) ((a)[v >> 3] &= ~(1 << (v & 0x7))) | ||
50 | |||
51 | /*************************************************************************** | ||
52 | * Local Functions | ||
53 | **************************************************************************/ | ||
54 | |||
55 | /** Search the memory hash to see if an entry is stored in the hash already. | ||
56 | * This will search the hash and either return the index where the item is | ||
57 | * stored, or -1 if the item was not found. | ||
58 | */ | ||
59 | static SignedInt16 memHashIndex(MemData * const memData, | ||
60 | const Int32 addr) | ||
61 | { | ||
62 | const Int16 v = addr % MEM_HASH_SIZE; | ||
63 | Int16 s = v; | ||
64 | |||
65 | do | ||
66 | { | ||
67 | /* Check if the element is occupied */ | ||
68 | if(M_IsIdxUsed(memData->used, s)) | ||
69 | { | ||
70 | /* Check if it is occupied with the sought data */ | ||
71 | if(memData->a[s] == addr) | ||
72 | { | ||
73 | return s; | ||
74 | } | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | /* Item is free, this is where the item should be stored */ | ||
79 | return s; | ||
80 | } | ||
81 | |||
82 | /* Search the next entry */ | ||
83 | s++; | ||
84 | if(s > MEM_HASH_SIZE) | ||
85 | { | ||
86 | s = 0; | ||
87 | } | ||
88 | } | ||
89 | while(s != v); | ||
90 | |||
91 | /* Search failed, hash is full and the address not stored */ | ||
92 | return -1; | ||
93 | } | ||
94 | |||
95 | |||
96 | |||
97 | /*************************************************************************** | ||
98 | * Global Functions | ||
99 | **************************************************************************/ | ||
100 | |||
101 | Boolean UnwMemHashRead(MemData * const memData, | ||
102 | Int32 addr, | ||
103 | Int32 * const data, | ||
104 | Boolean * const tracked) | ||
105 | { | ||
106 | SignedInt16 i = memHashIndex(memData, addr); | ||
107 | |||
108 | if(i >= 0 && M_IsIdxUsed(memData->used, i) && memData->a[i] == addr) | ||
109 | { | ||
110 | *data = memData->v[i]; | ||
111 | *tracked = M_IsIdxUsed(memData->tracked, i); | ||
112 | return TRUE; | ||
113 | } | ||
114 | else | ||
115 | { | ||
116 | /* Address not found in the hash */ | ||
117 | return FALSE; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | Boolean UnwMemHashWrite(MemData * const memData, | ||
122 | Int32 addr, | ||
123 | Int32 val, | ||
124 | Boolean valValid) | ||
125 | { | ||
126 | SignedInt16 i = memHashIndex(memData, addr); | ||
127 | |||
128 | if(i < 0) | ||
129 | { | ||
130 | /* Hash full */ | ||
131 | return FALSE; | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | /* Store the item */ | ||
136 | memData->a[i] = addr; | ||
137 | M_SetIdxUsed(memData->used, i); | ||
138 | |||
139 | if(valValid) | ||
140 | { | ||
141 | memData->v[i] = val; | ||
142 | M_SetIdxUsed(memData->tracked, i); | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | #if defined(UNW_DEBUG) | ||
147 | memData->v[i] = 0xdeadbeef; | ||
148 | #endif | ||
149 | M_ClrIdxUsed(memData->tracked, i); | ||
150 | } | ||
151 | |||
152 | return TRUE; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | |||
157 | void UnwMemHashGC(UnwState * const state) | ||
158 | { | ||
159 | const Int32 minValidAddr = state->regData[13].v; | ||
160 | MemData * const memData = &state->memData; | ||
161 | Int16 t; | ||
162 | |||
163 | for(t = 0; t < MEM_HASH_SIZE; t++) | ||
164 | { | ||
165 | if(M_IsIdxUsed(memData->used, t) && (memData->a[t] < minValidAddr)) | ||
166 | { | ||
167 | UnwPrintd3("MemHashGC: Free elem %d, addr 0x%08x\n", | ||
168 | t, memData->a[t]); | ||
169 | |||
170 | M_ClrIdxUsed(memData->used, t); | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | /* END OF FILE */ | ||