|
@@ -25,7 +25,8 @@
|
25
|
25
|
|
26
|
26
|
#if defined(UNW_DEBUG)
|
27
|
27
|
|
28
|
|
-/** Printf wrapper.
|
|
28
|
+/**
|
|
29
|
+ * Printf wrapper.
|
29
|
30
|
* This is used such that alternative outputs for any output can be selected
|
30
|
31
|
* by modification of this wrapper function.
|
31
|
32
|
*/
|
|
@@ -37,10 +38,10 @@ void UnwPrintf(const char *format, ...) {
|
37
|
38
|
}
|
38
|
39
|
#endif
|
39
|
40
|
|
40
|
|
-/** Invalidate all general purpose registers.
|
|
41
|
+/**
|
|
42
|
+ * Invalidate all general purpose registers.
|
41
|
43
|
*/
|
42
|
44
|
void UnwInvalidateRegisterFile(RegData *regFile) {
|
43
|
|
-
|
44
|
45
|
uint8_t t = 0;
|
45
|
46
|
do {
|
46
|
47
|
regFile[t].o = REG_VAL_INVALID;
|
|
@@ -49,7 +50,8 @@ void UnwInvalidateRegisterFile(RegData *regFile) {
|
49
|
50
|
}
|
50
|
51
|
|
51
|
52
|
|
52
|
|
-/** Initialise the data used for unwinding.
|
|
53
|
+/**
|
|
54
|
+ * Initialise the data used for unwinding.
|
53
|
55
|
*/
|
54
|
56
|
void UnwInitState(UnwState * const state, /**< Pointer to structure to fill. */
|
55
|
57
|
const UnwindCallbacks *cb, /**< Callbacks. */
|
|
@@ -77,12 +79,12 @@ void UnwInitState(UnwState * const state, /**< Pointer to structure to fill.
|
77
|
79
|
|
78
|
80
|
// Detect if function names are available
|
79
|
81
|
static int __attribute__ ((noinline)) has_function_names(void) {
|
80
|
|
-
|
81
|
82
|
uint32_t flag_word = ((uint32_t*)(((uint32_t)(&has_function_names)) & (-4))) [-1];
|
82
|
83
|
return ((flag_word & 0xff000000) == 0xff000000) ? 1 : 0;
|
83
|
84
|
}
|
84
|
85
|
|
85
|
|
-/** Call the report function to indicate some return address.
|
|
86
|
+/**
|
|
87
|
+ * Call the report function to indicate some return address.
|
86
|
88
|
* This returns the value of the report function, which if true
|
87
|
89
|
* indicates that unwinding may continue.
|
88
|
90
|
*/
|
|
@@ -108,11 +110,9 @@ bool UnwReportRetAddr(UnwState * const state, uint32_t addr) {
|
108
|
110
|
while(state->cb->readW(pf-4,&v)) {
|
109
|
111
|
|
110
|
112
|
// Check if name descriptor is valid
|
111
|
|
- if ((v & 0xffffff00) == 0xff000000 &&
|
112
|
|
- (v & 0xff) > 1) {
|
113
|
|
-
|
|
113
|
+ if ((v & 0xFFFFFF00) == 0xFF000000 && (v & 0xFF) > 1) {
|
114
|
114
|
// Assume the name was found!
|
115
|
|
- entry.name = ((const char*)pf) - 4 - (v & 0xff);
|
|
115
|
+ entry.name = ((const char*)pf) - 4 - (v & 0xFF);
|
116
|
116
|
entry.function = pf;
|
117
|
117
|
break;
|
118
|
118
|
}
|
|
@@ -129,7 +129,8 @@ bool UnwReportRetAddr(UnwState * const state, uint32_t addr) {
|
129
|
129
|
}
|
130
|
130
|
|
131
|
131
|
|
132
|
|
-/** Write some register to memory.
|
|
132
|
+/**
|
|
133
|
+ * Write some register to memory.
|
133
|
134
|
* This will store some register and meta data onto the virtual stack.
|
134
|
135
|
* The address for the write
|
135
|
136
|
* \param state [in/out] The unwinding state.
|
|
@@ -141,7 +142,8 @@ bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegD
|
141
|
142
|
return UnwMemHashWrite(&state->memData, addr, reg->v, M_IsOriginValid(reg->o));
|
142
|
143
|
}
|
143
|
144
|
|
144
|
|
-/** Read a register from memory.
|
|
145
|
+/**
|
|
146
|
+ * Read a register from memory.
|
145
|
147
|
* This will read a register from memory, and setup the meta data.
|
146
|
148
|
* If the register has been previously written to memory using
|
147
|
149
|
* UnwMemWriteRegister, the local hash will be used to return the
|
|
@@ -156,23 +158,18 @@ bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegD
|
156
|
158
|
* false is the data could not be read.
|
157
|
159
|
*/
|
158
|
160
|
bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg) {
|
159
|
|
-
|
160
|
161
|
bool tracked;
|
161
|
162
|
|
162
|
|
- /* Check if the value can be found in the hash */
|
163
|
|
- if(UnwMemHashRead(&state->memData, addr, ®->v, &tracked)) {
|
|
163
|
+ // Check if the value can be found in the hash
|
|
164
|
+ if (UnwMemHashRead(&state->memData, addr, ®->v, &tracked)) {
|
164
|
165
|
reg->o = tracked ? REG_VAL_FROM_MEMORY : REG_VAL_INVALID;
|
165
|
166
|
return true;
|
166
|
167
|
}
|
167
|
|
- /* Not in the hash, so read from real memory */
|
168
|
|
- else if(state->cb->readW(addr, ®->v)) {
|
|
168
|
+ else if (state->cb->readW(addr, ®->v)) { // Not in the hash, so read from real memory
|
169
|
169
|
reg->o = REG_VAL_FROM_MEMORY;
|
170
|
170
|
return true;
|
171
|
171
|
}
|
172
|
|
- /* Not in the hash, and failed to read from memory */
|
173
|
|
- else {
|
174
|
|
- return false;
|
175
|
|
- }
|
|
172
|
+ else return false; // Not in the hash, and failed to read from memory
|
176
|
173
|
}
|
177
|
174
|
#endif
|
178
|
175
|
|