Prusa MINI Firmware overview
unwarm.h
Go to the documentation of this file.
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: Internal interface between the ARM unwinding sub-modules.
12  **************************************************************************/
13 
14 #pragma once
15 
16 #include "unwinder.h"
17 
18 /** The maximum number of instructions to interpet in a function.
19  * Unwinding will be unconditionally stopped and UNWIND_EXHAUSTED returned
20  * if more than this number of instructions are interpreted in a single
21  * function without unwinding a stack frame. This prevents infinite loops
22  * or corrupted program memory from preventing unwinding from progressing.
23  */
24 #define UNW_MAX_INSTR_COUNT 500
25 
26 /** The size of the hash used to track reads and writes to memory.
27  * This should be a prime value for efficiency.
28  */
29 #define MEM_HASH_SIZE 31
30 
31 /***************************************************************************
32  * Type Definitions
33  **************************************************************************/
34 
35 typedef enum {
36  /** Invalid value. */
42 } RegValOrigin;
43 
44 
45 /** Type for tracking information about a register.
46  * This stores the register value, as well as other data that helps unwinding.
47  */
48 typedef struct {
49 
50  /** The value held in the register. */
51  uint32_t v;
52 
53  /** The origin of the register value.
54  * This is used to track how the value in the register was loaded.
55  */
56  int o; /* (RegValOrigin) */
57 } RegData;
58 
59 
60 /** Structure used to track reads and writes to memory.
61  * This structure is used as a hash to store a small number of writes
62  * to memory.
63  */
64 typedef struct {
65  /** Memory contents. */
66  uint32_t v[MEM_HASH_SIZE];
67 
68  /** Address at which v[n] represents. */
69  uint32_t a[MEM_HASH_SIZE];
70 
71  /** Indicates whether the data in v[n] and a[n] is occupied.
72  * Each bit represents one hash value.
73  */
74  uint8_t used[(MEM_HASH_SIZE + 7) / 8];
75 
76  /** Indicates whether the data in v[n] is valid.
77  * This allows a[n] to be set, but for v[n] to be marked as invalid.
78  * Specifically this is needed for when an untracked register value
79  * is written to memory.
80  */
81  uint8_t tracked[(MEM_HASH_SIZE + 7) / 8];
82 } MemData;
83 
84 
85 /** Structure that is used to keep track of unwinding meta-data.
86  * This data is passed between all the unwinding functions.
87  */
88 typedef struct {
89  /** The register values and meta-data. */
90  RegData regData[16];
91 
92  /** Memory tracking data. */
93  MemData memData;
94 
95  /** Pointer to the callback functions */
96  const UnwindCallbacks *cb;
97 
98  /** Pointer to pass to the report function. */
99  const void *reportData;
100 } UnwState;
101 
102 /***************************************************************************
103  * Macros
104  **************************************************************************/
105 
106 #define M_IsOriginValid(v) !!((v) & 0x7F)
107 #define M_Origin2Str(v) ((v) ? "VALID" : "INVALID")
108 
109 #ifdef UNW_DEBUG
110 #define UnwPrintd1(a) state->cb->printf(a)
111 #define UnwPrintd2(a,b) state->cb->printf(a,b)
112 #define UnwPrintd3(a,b,c) state->cb->printf(a,b,c)
113 #define UnwPrintd4(a,b,c,d) state->cb->printf(a,b,c,d)
114 #define UnwPrintd5(a,b,c,d,e) state->cb->printf(a,b,c,d,e)
115 #define UnwPrintd6(a,b,c,d,e,f) state->cb->printf(a,b,c,d,e,f)
116 #define UnwPrintd7(a,b,c,d,e,f,g) state->cb->printf(a,b,c,d,e,f,g)
117 #define UnwPrintd8(a,b,c,d,e,f,g,h) state->cb->printf(a,b,c,d,e,f,g,h)
118 #else
119 #define UnwPrintd1(a)
120 #define UnwPrintd2(a,b)
121 #define UnwPrintd3(a,b,c)
122 #define UnwPrintd4(a,b,c,d)
123 #define UnwPrintd5(a,b,c,d,e)
124 #define UnwPrintd6(a,b,c,d,e,f)
125 #define UnwPrintd7(a,b,c,d,e,f,g)
126 #define UnwPrintd8(a,b,c,d,e,f,g,h)
127 #endif
128 
129 /***************************************************************************
130  * Function Prototypes
131  **************************************************************************/
132 
135 void UnwInvalidateRegisterFile(RegData *regFile);
136 void UnwInitState(UnwState * const state, const UnwindCallbacks *cb, void *rptData, uint32_t pcValue, uint32_t spValue);
137 bool UnwReportRetAddr(UnwState * const state, uint32_t addr);
138 bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegData * const reg);
139 bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg);
140 void UnwMemHashGC(UnwState * const state);
unwarm.h
UnwInitState
void UnwInitState(UnwState *const state, const UnwindCallbacks *cb, void *rptData, uint32_t pcValue, uint32_t spValue)
RegData::o
int o
Definition: unwarm.h:55
REG_VAL_FROM_STACK
Definition: unwarm.h:38
UnwInvalidateRegisterFile
void UnwInvalidateRegisterFile(RegData *regFile)
UnwState
Definition: unwarm.h:87
UnwStartThumb
UnwResult UnwStartThumb(UnwState *const state)
UnwReport
Definition: unwinder.h:97
__attribute__
bool boolean __attribute__((deprecated))
Definition: wiring_constants.h:110
UnwMemWriteRegister
bool UnwMemWriteRegister(UnwState *const state, const uint32_t addr, const RegData *const reg)
MEM_HASH_SIZE
#define MEM_HASH_SIZE
Definition: unwarm.h:29
state
static volatile fsensor_t state
Definition: filament_sensor.c:23
REG_VAL_FROM_CONST
Definition: unwarm.h:40
REG_VAL_INVALID
Definition: unwarm.h:37
REG_VAL_FROM_MEMORY
Definition: unwarm.h:39
UnwMemHashGC
void UnwMemHashGC(UnwState *const state)
UnwReportRetAddr
bool UnwReportRetAddr(UnwState *const state, uint32_t addr)
UnwPrintd3
#define UnwPrintd3(a, b, c)
Definition: unwarm.h:119
unwinder.h
unwarmmem.h
UnwMemHashWrite
bool UnwMemHashWrite(MemData *const memData, uint32_t addr, uint32_t val, bool valValid)
RegData
Definition: unwarm.h:47
UnwReport::address
uint32_t address
Definition: unwinder.h:100
createSpeedLookupTable.a
list a
Definition: createSpeedLookupTable.py:29
MemData
Definition: unwarm.h:63
UnwMemHashRead
bool UnwMemHashRead(MemData *const memData, uint32_t addr, uint32_t *const data, bool *const tracked)
REG_VAL_ARITHMETIC
Definition: unwarm.h:41
uint8_t
const uint8_t[]
Definition: 404_html.c:3
M_IsOriginValid
#define M_IsOriginValid(v)
Definition: unwarm.h:104
UnwStartArm
UnwResult UnwStartArm(UnwState *const state)
UnwReport::function
uint32_t function
Definition: unwinder.h:98
RegValOrigin
RegValOrigin
Definition: unwarm.h:34
UnwReport::name
const char * name
Definition: unwinder.h:99
RegData::v
uint32_t v
Definition: unwarm.h:50
UnwindCallbacks
Definition: unwinder.h:119
createSpeedLookupTable.args
args
Definition: createSpeedLookupTable.py:17
UnwResult
UnwResult
Definition: unwinder.h:30
UnwMemReadRegister
bool UnwMemReadRegister(UnwState *const state, const uint32_t addr, RegData *const reg)