checkwps: harden filename extension checking.
[maemo-rb.git] / lib / unwarminder / unwarm.c
blob99f6a12ccb0476f7f7640247afd94ac508b67f2d
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, commercially or otherwise. The only limitation is that I
8 * don't guarantee that the software is fit for any purpose or accept any
9 * liability for it's use or misuse - this software is without warranty.
10 ***************************************************************************
11 * File Description: Utility functions and glue for ARM unwinding sub-modules.
12 **************************************************************************/
14 #define MODULE_NAME "UNWARM"
16 /***************************************************************************
17 * Include Files
18 **************************************************************************/
20 #include "types.h"
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include "unwarm.h"
25 #include "unwarmmem.h"
27 /***************************************************************************
28 * Manifest Constants
29 **************************************************************************/
32 /***************************************************************************
33 * Type Definitions
34 **************************************************************************/
37 /***************************************************************************
38 * Variables
39 **************************************************************************/
42 /***************************************************************************
43 * Macros
44 **************************************************************************/
47 /***************************************************************************
48 * Local Functions
49 **************************************************************************/
52 /***************************************************************************
53 * Global Functions
54 **************************************************************************/
56 #if defined(UNW_DEBUG)
57 /** Printf wrapper.
58 * This is used such that alternative outputs for any output can be selected
59 * by modification of this wrapper function.
61 void UnwPrintf(const char *format, ...)
63 va_list args;
65 va_start( args, format );
66 vprintf(format, args );
68 #endif
70 /** Invalidate all general purpose registers.
72 void UnwInvalidateRegisterFile(RegData *regFile)
74 Int8 t = 0;
78 regFile[t].o = REG_VAL_INVALID;
79 t++;
81 while(t < 13);
86 /** Initialise the data used for unwinding.
88 void UnwInitState(UnwState * const state, /**< Pointer to structure to fill. */
89 const UnwindCallbacks *cb, /**< Callbacks. */
90 void *rptData, /**< Data to pass to report function. */
91 Int32 pcValue, /**< PC at which to start unwinding. */
92 Int32 spValue) /**< SP at which to start unwinding. */
94 UnwInvalidateRegisterFile(state->regData);
96 /* Store the pointer to the callbacks */
97 state->cb = cb;
98 state->reportData = rptData;
100 /* Setup the SP and PC */
101 state->regData[13].v = spValue;
102 state->regData[13].o = REG_VAL_FROM_CONST;
103 state->regData[15].v = pcValue;
104 state->regData[15].o = REG_VAL_FROM_CONST;
106 UnwPrintd3("\nInitial: PC=0x%08x SP=0x%08x\n", pcValue, spValue);
108 /* Invalidate all memory addresses */
109 memset(state->memData.used, 0, sizeof(state->memData.used));
113 /** Call the report function to indicate some return address.
114 * This returns the value of the report function, which if TRUE
115 * indicates that unwinding may continue.
117 Boolean UnwReportRetAddr(UnwState * const state, Int32 addr)
119 /* Cast away const from reportData.
120 * The const is only to prevent the unw module modifying the data.
122 return state->cb->report((void *)state->reportData, addr);
126 /** Write some register to memory.
127 * This will store some register and meta data onto the virtual stack.
128 * The address for the write
129 * \param state [in/out] The unwinding state.
130 * \param wAddr [in] The address at which to write the data.
131 * \param reg [in] The register to store.
132 * \return TRUE if the write was successful, FALSE otherwise.
134 Boolean UnwMemWriteRegister(UnwState * const state,
135 const Int32 addr,
136 const RegData * const reg)
138 return UnwMemHashWrite(&state->memData,
139 addr,
140 reg->v,
141 M_IsOriginValid(reg->o));
144 /** Read a register from memory.
145 * This will read a register from memory, and setup the meta data.
146 * If the register has been previously written to memory using
147 * UnwMemWriteRegister, the local hash will be used to return the
148 * value while respecting whether the data was valid or not. If the
149 * register was previously written and was invalid at that point,
150 * REG_VAL_INVALID will be returned in *reg.
151 * \param state [in] The unwinding state.
152 * \param addr [in] The address to read.
153 * \param reg [out] The result, containing the data value and the origin
154 * which will be REG_VAL_FROM_MEMORY, or REG_VAL_INVALID.
155 * \return TRUE if the address could be read and *reg has been filled in.
156 * FALSE is the data could not be read.
158 Boolean UnwMemReadRegister(UnwState * const state,
159 const Int32 addr,
160 RegData * const reg)
162 Boolean tracked;
164 /* Check if the value can be found in the hash */
165 if(UnwMemHashRead(&state->memData, addr, &reg->v, &tracked))
167 reg->o = tracked ? REG_VAL_FROM_MEMORY : REG_VAL_INVALID;
168 return TRUE;
170 /* Not in the hash, so read from real memory */
171 else if(state->cb->readW(addr, &reg->v))
173 reg->o = REG_VAL_FROM_MEMORY;
174 return TRUE;
176 /* Not in the hash, and failed to read from memory */
177 else
179 return FALSE;
183 /* END OF FILE */