summaryrefslogtreecommitdiff
path: root/lib/unwarminder/unwarmmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/unwarminder/unwarmmem.c')
-rw-r--r--lib/unwarminder/unwarmmem.c175
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 */
59static 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
101Boolean 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
121Boolean 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
157void 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 */