1 /***************************************************************************
2 * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
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 **************************************************************************/
14 #define MODULE_NAME "UNWARMMEM"
16 /***************************************************************************
18 **************************************************************************/
22 #include "unwarmmem.h"
25 /***************************************************************************
27 **************************************************************************/
30 /***************************************************************************
32 **************************************************************************/
35 /***************************************************************************
37 **************************************************************************/
40 /***************************************************************************
42 **************************************************************************/
45 #define M_IsIdxUsed(a, v) (((a)[v >> 3] & (1 << (v & 0x7))) ? TRUE : FALSE)
47 #define M_SetIdxUsed(a, v) ((a)[v >> 3] |= (1 << (v & 0x7)))
49 #define M_ClrIdxUsed(a, v) ((a)[v >> 3] &= ~(1 << (v & 0x7)))
51 /***************************************************************************
53 **************************************************************************/
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.
59 static SignedInt16
memHashIndex(MemData
* const memData
,
62 const Int16 v
= addr
% MEM_HASH_SIZE
;
67 /* Check if the element is occupied */
68 if(M_IsIdxUsed(memData
->used
, s
))
70 /* Check if it is occupied with the sought data */
71 if(memData
->a
[s
] == addr
)
78 /* Item is free, this is where the item should be stored */
82 /* Search the next entry */
91 /* Search failed, hash is full and the address not stored */
97 /***************************************************************************
99 **************************************************************************/
101 Boolean
UnwMemHashRead(MemData
* const memData
,
104 Boolean
* const tracked
)
106 SignedInt16 i
= memHashIndex(memData
, addr
);
108 if(i
>= 0 && M_IsIdxUsed(memData
->used
, i
) && memData
->a
[i
] == addr
)
110 *data
= memData
->v
[i
];
111 *tracked
= M_IsIdxUsed(memData
->tracked
, i
);
116 /* Address not found in the hash */
121 Boolean
UnwMemHashWrite(MemData
* const memData
,
126 SignedInt16 i
= memHashIndex(memData
, addr
);
136 memData
->a
[i
] = addr
;
137 M_SetIdxUsed(memData
->used
, i
);
142 M_SetIdxUsed(memData
->tracked
, i
);
146 #if defined(UNW_DEBUG)
147 memData
->v
[i
] = 0xdeadbeef;
149 M_ClrIdxUsed(memData
->tracked
, i
);
157 void UnwMemHashGC(UnwState
* const state
)
159 const Int32 minValidAddr
= state
->regData
[13].v
;
160 MemData
* const memData
= &state
->memData
;
163 for(t
= 0; t
< MEM_HASH_SIZE
; t
++)
165 if(M_IsIdxUsed(memData
->used
, t
) && (memData
->a
[t
] < minValidAddr
))
167 UnwPrintd3("MemHashGC: Free elem %d, addr 0x%08x\n",
170 M_ClrIdxUsed(memData
->used
, t
);